def _edge_to_svg_polyline(self, topods_edge,scale=1): """ Returns a svgwrite.Path for the edge, and the 2d bounding box """ unit = self.UNIT tol = self.TOL points_3d = discretize_edge(topods_edge, tol) points_2d = [] box2d = Bnd_Box2d() for point in points_3d: # we tak only the first 2 coordinates (x and y, leave z) x_p = point[0] y_p = - point[1] box2d.Add(gp_Pnt2d(x_p, y_p)) points_2d.append((x_p, y_p)) return svgwrite.shapes.Polyline(points_2d, fill="none", class_='vectorEffectClass'), box2d
def edge_to_svg_polyline(topods_edge, tol=0.1, unit="mm"): """Returns a svgwrite.Path for the edge, and the 2d bounding box""" unit_factor = 1 # by default if unit == "mm": unit_factor = 1 elif unit == "m": unit_factor = 1e3 points_3d = discretize_edge(topods_edge, tol) points_2d = [] box2d = Bnd_Box2d() for point in points_3d: # we tak only the first 2 coordinates (x and y, leave z) x_p = -point[0] * unit_factor y_p = point[1] * unit_factor box2d.Add(gp_Pnt2d(x_p, y_p)) points_2d.append((x_p, y_p)) return svgwrite.shapes.Polyline(points_2d, fill="none"), box2d
def export_shape_to_svg(self, shape, filename=None, proj_ax=gp_Ax2(), scale=1, verbose=True, max_eadge=1): """ export a single shape to an svg file and/or string. shape: the TopoDS_Shape to export filename (optional): if provided, save to an svg file proj_ax (optional): projection transformation """ if shape.IsNull(): raise AssertionError("shape is Null") # find all edges visible_edges, hidden_edges = self._get_sorted_hlr_edges( shape, ax=proj_ax, export_hidden_edges=self.EXPORT_HIDDEN_EDGES) # compute polylines for all edges # we compute a global 2d bounding box as well, to be able to compute # the scale factor and translation vector to apply to all 2d edges so that # they fit the svg canva global_2d_bounding_box = Bnd_Box2d() polylines = [] polylines_hidden = [] for visible_edge in visible_edges: visible_svg_line, visible_edge_box2d = self._edge_to_svg_polyline(visible_edge) polylines.append(visible_svg_line) global_2d_bounding_box.Add(visible_edge_box2d) if self.EXPORT_HIDDEN_EDGES: for hidden_edge in hidden_edges: hidden_svg_line, hidden_edge_box2d = self._edge_to_svg_polyline(hidden_edge) # # hidden lines are dashed style # hidden_svg_line.dasharray([5, 5]) polylines_hidden.append(hidden_svg_line) global_2d_bounding_box.Add(hidden_edge_box2d) # translate and scale polylines # first compute shape translation and scale according to size/margins x_min, y_min, x_max, y_max = global_2d_bounding_box.Get() bb2d_width = x_max - x_min bb2d_height = y_max - y_min # build the svg drawing dwg = svgwrite.Drawing(filename, (self.WIDTH, self.HEIGHT), debug=True) # adjust the view box so that the lines fit then svg canvas # for abc step file # dwg.viewbox( # x_min - 1.4*max_eadge/2 + bb2d_width/2, # y_min - 1.4*max_eadge/2 + bb2d_height/2, # 1.4*max_eadge, # 1.4*max_eadge) # for csg step file dwg.viewbox( x_min - 1.7*max_eadge/2 + bb2d_width/2, y_min - 1.7*max_eadge/2 + bb2d_height/2, 1.7*max_eadge, 1.7*max_eadge) # make sure line width stays constant # https://github.com/mozman/svgwrite/issues/38 dwg.defs.add(dwg.style(""" .vectorEffectClass { vector-effect: non-scaling-stroke; } """)) #draw hidden line first if self.EXPORT_HIDDEN_EDGES: for polyline in polylines_hidden: polyline.stroke(self.COLOR_HIDDEN, width=self.LINE_WIDTH_HIDDEN, linecap="round") dwg.add(polyline) for polyline in polylines: # apply color and style polyline.stroke(self.COLOR, width=self.LINE_WIDTH, linecap="round") # then adds the polyline to the svg canva dwg.add(polyline) # export to string or file according to the user choice if filename is not None: dwg.save() if not os.path.isfile(filename): raise AssertionError("svg export failed") if not verbose: print("Shape successfully exported to %s" % filename) return True return dwg.tostring()
def export_shape_to_svg(shape, filename=None, width=800, height=600, margin_left=10, margin_top=30, export_hidden_edges=True, location=gp_Pnt(0, 0, 0), direction=gp_Dir(1, 1, 1), color="black", line_width="1px", unit="mm"): """ export a single shape to an svg file and/or string. shape: the TopoDS_Shape to export filename (optional): if provided, save to an svg file width, height (optional): integers, specify the canva size in pixels margin_left, margin_top (optional): integers, in pixel export_hidden_edges (optional): whether or not draw hidden edges using a dashed line location (optional): a gp_Pnt, the lookat direction (optional): to set up the projector direction color (optional), "default to "black". line_width (optional, default to 1): an integer """ if shape.IsNull(): raise AssertionError("shape is Null") if not HAVE_SVGWRITE: print( "svg exporter not available because the svgwrite package is not installed." ) print("please use '$ conda install -c conda-forge svgwrite'") return False # find all edges visible_edges, hidden_edges = get_sorted_hlr_edges( shape, position=location, direction=direction, export_hidden_edges=export_hidden_edges) # compute polylines for all edges # we compute a global 2d bounding box as well, to be able to compute # the scale factor and translation vector to apply to all 2d edges so that # they fit the svg canva global_2d_bounding_box = Bnd_Box2d() polylines = [] for visible_edge in visible_edges: visible_svg_line, visible_edge_box2d = edge_to_svg_polyline( visible_edge, 0.1, unit) polylines.append(visible_svg_line) global_2d_bounding_box.Add(visible_edge_box2d) if export_hidden_edges: for hidden_edge in hidden_edges: hidden_svg_line, hidden_edge_box2d = edge_to_svg_polyline( hidden_edge, 0.1, unit) # hidden lines are dashed style hidden_svg_line.dasharray([5, 5]) polylines.append(hidden_svg_line) global_2d_bounding_box.Add(hidden_edge_box2d) # translate and scale polylines # first compute shape translation and scale according to size/margins x_min, y_min, x_max, y_max = global_2d_bounding_box.Get() bb2d_width = x_max - x_min bb2d_height = y_max - y_min # build the svg drawing dwg = svgwrite.Drawing(filename, (width, height), debug=True) # adjust the view box so that the lines fit then svg canvas dwg.viewbox(x_min - margin_left, y_min - margin_top, bb2d_width + 2 * margin_left, bb2d_height + 2 * margin_top) for polyline in polylines: # apply color and style polyline.stroke(color, width=line_width, linecap="round") # then adds the polyline to the svg canva dwg.add(polyline) # export to string or file according to the user choice if filename is not None: dwg.save() if not os.path.isfile(filename): raise AssertionError("svg export failed") print("Shape successfully exported to %s" % filename) return True return dwg.tostring()
def add_to_bounding_box(points_2d): box2d = Bnd_Box2d() for p in points_2d: box2d.Add(gp_Pnt2d(*p)) return box2d
def export_shape_to_svg(shape, filename=None, width=800, height=600, margin_left=30, margin_top=30, export_hidden_edges=True, location=(0, 0, 0), direction=(1, 1, 1), bezier_degree=2, bezier_tol=0.01, color="black", line_width=0.5): """ export a single shape to an svg file and/or string. shape: the TopoDS_Shape to export filename (optional): if provided, save to an svg file width, height (optional): integers, specify the canva size in pixels margin_left, margin_top (optional): integers, in pixel export_hidden_edges (optional): whether or not draw hidden edges using a dashed line location (optional): a gp_Pnt, the lookat direction (optional): to set up the projector direction bezier_degree (optional): degree of Bezier curves bezier_tol (optional): tolerance for Bezier curves approximation color (optional), "default to "black". line_width (optional, default to 1): an integer """ if shape.IsNull(): raise AssertionError("shape is Null") # find all edges location = gp_Pnt(*location) direction = gp_Dir(*direction) camera_ax = gp_Ax2(location, direction) visible_edges, hidden_edges = get_sorted_hlr_edges( shape, position=location, direction=direction, export_hidden_edges=export_hidden_edges) # compute paths for all edges # we compute a global 2d bounding box as well, to be able to compute # the scale factor and translation vector to apply to all 2d edges so that # they fit the svg canva global_2d_bounding_box = Bnd_Box2d() paths = [] for visible_edge in visible_edges: visible_svg_line, visible_edge_box2d = edge_to_svg( visible_edge, bezier_degree=bezier_degree, bezier_tol=bezier_tol) if visible_svg_line: paths.append(visible_svg_line) global_2d_bounding_box.Add(visible_edge_box2d) if export_hidden_edges: for hidden_edge in hidden_edges: hidden_svg_line, hidden_edge_box2d = edge_to_svg( hidden_edge, bezier_degree=bezier_degree, bezier_tol=bezier_tol) if hidden_svg_line: # hidden lines are dashed style hidden_svg_line.dasharray([5, 5]) paths.append(hidden_svg_line) global_2d_bounding_box.Add(hidden_edge_box2d) # translate and scale paths # first compute shape translation and scale according to size/margins x_min, y_min, x_max, y_max = global_2d_bounding_box.Get() bb2d_width = x_max - x_min bb2d_height = y_max - y_min # build the svg drawing drawing = svgwrite.Drawing(filename, (width, height), debug=True) # adjust the view box so that the lines fit then svg canvas drawing.viewbox(x_min - margin_left, y_min - margin_top, bb2d_width + 2 * margin_left, bb2d_height + 2 * margin_top) for path in paths: path.stroke(color, width=line_width, linecap="round") drawing.add(path) # export to string or file according to the user choice if filename is not None: drawing.save() if not os.path.isfile(filename): raise AssertionError("svg export failed") print(f"Shape successfully exported to {filename}") return True return drawing.tostring()