Beispiel #1
0
    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
Beispiel #2
0
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
Beispiel #3
0
    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()
Beispiel #4
0
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()