def to_3d( component: Component, layer_set: LayerSet, layer_stack: LayerStack = LAYER_STACK, exclude_layers: Optional[Tuple[Layer, ...]] = None, ) -> Scene: """Return the Component 3D trimesh Scene. Args: component: layer_set: layer colors from Klayout Layer Properties file layer_stack: contains thickness and zmin for each layer exclude_layers: layers to exclude """ scene = Scene() layer_to_thickness = layer_stack.get_layer_to_thickness() layer_to_zmin = layer_stack.get_layer_to_zmin() exclude_layers = exclude_layers or [] for layer, polygons in component.get_polygons(by_spec=True).items(): if (layer not in exclude_layers and layer in layer_to_thickness and layer in layer_to_zmin): height = layer_to_thickness[layer] zmin = layer_to_zmin[layer] color_hex = layer_set.get_from_tuple(layer).color color_rgb = matplotlib.colors.to_rgb(color_hex) for polygon in polygons: p = shapely.geometry.Polygon(polygon) mesh = extrude_polygon(p, height=height) mesh.apply_translation((0, 0, zmin)) mesh.visual.face_colors = (*color_rgb, 0.5) scene.add_geometry(mesh) return scene
def extrude(polygon, height, thickness=0, cap_style='round', join_style='round', extrude_boundaries=False): assert height > 0, 'Extrude height must be greater than zero' if isinstance(polygon, Polygon) and not extrude_boundaries: assert polygon.is_valid, 'The input polygon object' \ ' is an invalid polygon shape' PCG_ROOT_LOGGER.info( 'Extruding a polygon to generate the model\'s mesh') processed_polygon = polygon elif isinstance(polygon, MultiPolygon) and not extrude_boundaries: processed_polygon = unary_union(polygon) else: assert thickness > 0, 'For any point or line-like input geometries, ' \ 'a thickness has to be provided to generate the polygon by' \ ' dilating the input object' cs_indexes = ['round', 'flat', 'square'] assert cap_style in cs_indexes, \ 'Invalid cap style to dilate the geometry' js_indexes = ['round', 'mitre', 'bevel'] assert join_style in js_indexes, \ 'Invalid join style to dilate the geometry' # In case the provided polygon are of type Polygon or MultiPolygon, # their boundaries will be extracted if isinstance(polygon, Polygon) or isinstance(polygon, MultiPolygon): input_poly = unary_union(polygon.boundary) else: input_poly = polygon PCG_ROOT_LOGGER.info( 'Dilating the input geometry, thickness={}, cap_style={}, ' 'join_style={}'.format(thickness, cap_style, join_style)) processed_polygon = input_poly.buffer( thickness, cap_style=cs_indexes.index(cap_style) + 1, join_style=js_indexes.index(join_style) + 1) if isinstance(processed_polygon, MultiPolygon): processed_polygon = unary_union(processed_polygon) if not hasattr(processed_polygon, 'exterior'): PCG_ROOT_LOGGER.warning( 'After dilating input polygon, the resulting polygon has no' ' \'exterior\' attribute, using the convex hull instead') processed_polygon = polygon.convex_hull return extrude_polygon(processed_polygon, height)
def build_finger_grasp_volume(grasp_width: float, w=0.032, h=0.035, bottom_width=0.007, base_height=0.005, tcp_z_finger_bottom=0.1915): one_side = [(bottom_width, 0), (w, h - base_height), (w, h * 3)] one_side = np.array(one_side) + (grasp_width, 0) poly = np.concatenate((one_side, one_side[::-1] * (-1, 1))) poly = Polygon(poly) mesh = extrude_polygon(poly, w) mesh.apply_translation((0, 0, -w / 2)) mesh.apply_transform(Transform(rotvec=(-np.pi / 2, 0, 0)).matrix) mesh.apply_translation((0, 0, tcp_z_finger_bottom)) return mesh
def to_stl( component: Component, filepath: str, layer_set: LayerSet, layer_stack: LayerStack = LAYER_STACK, exclude_layers: Optional[Tuple[Layer, ...]] = None, ) -> None: """Exports a Component into STL. Args: component: filepath: layer_set: layer colors from Klayout Layer Properties file layer_stack: contains thickness and zmin for each layer exclude_layers: layers to exclude """ from trimesh.creation import extrude_polygon layer_to_thickness = layer_stack.get_layer_to_thickness() layer_to_zmin = layer_stack.get_layer_to_zmin() filepath = pathlib.Path(filepath) exclude_layers = exclude_layers or [] for layer, polygons in component.get_polygons(by_spec=True).items(): if ( layer not in exclude_layers and layer in layer_to_thickness and layer in layer_to_zmin ): height = layer_to_thickness[layer] zmin = layer_to_zmin[layer] color_hex = layer_set.get_from_tuple(layer).color color_rgb = matplotlib.colors.to_rgb(color_hex) filepath_layer = ( filepath.parent / f"{filepath.stem}_{layer[0]}_{layer[1]}{filepath.suffix}" ) print(filepath_layer) for polygon in polygons: p = shapely.geometry.Polygon(polygon) mesh = extrude_polygon(p, height=height) mesh.apply_translation((0, 0, zmin)) mesh.visual.face_colors = (*color_rgb, 0.5) mesh.export(filepath_layer)