コード例 #1
0
    def update(self, line=None, normal=None):
        import WorkingPlane, DraftGeomUtils

        if not normal:
            normal = FreeCAD.DraftWorkingPlane.axis
        if line:
            if isinstance(line, list):
                bp = line[0]
                lvec = line[1].sub(line[0])
            else:
                lvec = DraftGeomUtils.vec(line.Shape.Edges[0])
                bp = line.Shape.Edges[0].Vertexes[0].Point
        elif self.baseline:
            lvec = DraftGeomUtils.vec(self.baseline.Shape.Edges[0])
            bp = self.baseline.Shape.Edges[0].Vertexes[0].Point
        else:
            return
        right = lvec.cross(normal)
        self.cube.width.setValue(lvec.Length)
        p = WorkingPlane.getPlacementFromPoints([bp, bp.add(lvec), bp.add(right)])
        if p:
            self.trans.rotation.setValue(p.Rotation.Q)
        bp = bp.add(lvec.multiply(0.5))
        bp = bp.add(DraftVecUtils.scaleTo(normal, self.cube.depth.getValue() / 2))
        self.pos(bp)
コード例 #2
0
ファイル: BimBox.py プロジェクト: yorikvanhavre/BIM_Workbench
    def setHeightUI(self):

        import FreeCADGui
        if (len(self.points) == 3) and self.HeightValue:
            cube = FreeCAD.ActiveDocument.addObject("Part::Box", "Cube")
            cube.Length = self.LengthValue
            cube.Width = self.WidthValue
            cube.Height = self.HeightValue
            # we get 3 points that define our cube orientation
            p1 = self.cubetracker[0].p1()
            p2 = self.cubetracker[0].p2()
            p3 = self.cubetracker[0].p4()
            FreeCADGui.Snapper.off()
            import WorkingPlane
            cube.Placement = WorkingPlane.getPlacementFromPoints([p1, p2, p3])
            if hasattr(FreeCAD, "DraftWorkingPlane"):
                FreeCAD.DraftWorkingPlane.restore()
            FreeCADGui.Snapper.setGrid()
            for c in self.cubetracker:
                c.off()
            FreeCADGui.Snapper.getPoint()
            FreeCADGui.Snapper.off()
            if hasattr(FreeCADGui, "draftToolBar"):
                FreeCADGui.draftToolBar.offUi()
            FreeCAD.ActiveDocument.recompute()
コード例 #3
0
 def update(self, line=None, normal=None):
     import WorkingPlane, DraftGeomUtils
     if not normal:
         normal = FreeCAD.DraftWorkingPlane.axis
     if line:
         if isinstance(line, list):
             bp = line[0]
             lvec = line[1].sub(line[0])
         else:
             lvec = DraftGeomUtils.vec(line.Shape.Edges[0])
             bp = line.Shape.Edges[0].Vertexes[0].Point
     elif self.baseline:
         lvec = DraftGeomUtils.vec(self.baseline.Shape.Edges[0])
         bp = self.baseline.Shape.Edges[0].Vertexes[0].Point
     else:
         return
     right = lvec.cross(normal)
     self.cube.width.setValue(lvec.Length)
     p = WorkingPlane.getPlacementFromPoints(
         [bp, bp.add(lvec), bp.add(right)])
     if p:
         self.trans.rotation.setValue(p.Rotation.Q)
     bp = bp.add(lvec.multiply(0.5))
     bp = bp.add(
         DraftVecUtils.scaleTo(normal,
                               self.cube.depth.getValue() / 2))
     self.pos(bp)
コード例 #4
0
    def __init__(self, placement):
        import WorkingPlane

        self.reset()
        self.wp = WorkingPlane.plane()
        self.wp.setFromPlacement(placement, rebase=True)

        if DEBUG:
            print("Renderer initialized on %s. %s, %s" %
                  (self.wp, self.wp.getPlacement().Base, self.wp.getNormal()))
コード例 #5
0
ファイル: importIFCHelper.py プロジェクト: zebscode/FreeCAD
def getRotation(entity):
    """returns a FreeCAD rotation from an IfcProduct with a IfcMappedItem representation"""
    try:
        u = FreeCAD.Vector(entity.Axis1.DirectionRatios)
        v = FreeCAD.Vector(entity.Axis2.DirectionRatios)
        w = FreeCAD.Vector(entity.Axis3.DirectionRatios)
    except AttributeError:
        return FreeCAD.Rotation()
    import WorkingPlane
    p = WorkingPlane.plane(u=u,v=v,w=w)
    return p.getRotation().Rotation
コード例 #6
0
    def buildSvgParts(self, obj, render, groups):
        faceHighlightDistance = obj.FaceHighlightDistance

        parts = render.getSvgParts(faceHighlightDistance.Value)

        wp = WorkingPlane.plane()
        wp.setFromPlacement(obj.Placement, rebase=True)

        self.sectionSVG = parts["sections"]
        self.secondaryFacesSVG = parts["secondaryFaces"]
        self.windowSVG = parts["windows"]
        self.patternSVG = parts["patterns"]
        self.draftSvg = getDraftSvg(groups["drafts"], wp)
        self.sectionCutSvg = parts["sectionCuts"]
        self.markerSvg = parts["markers"]
        self.boundBox = parts["boundBox"]

        self.boundBox.adaptFromDrafts(groups["drafts"])
コード例 #7
0
ファイル: wires.py プロジェクト: gentlebrother/FreeCAD
def flattenWire(wire):
    """Force a wire to get completely flat along its normal."""
    n = getNormal(wire)
    if not n:
        return

    o = wire.Vertexes[0].Point
    plane = WorkingPlane.plane()
    plane.alignToPointAndAxis(o, n, 0)
    verts = [o]

    for v in wire.Vertexes[1:]:
        verts.append(plane.projectPoint(v.Point))

    if wire.isClosed():
        verts.append(o)
    w = Part.makePolygon(verts)

    return w
コード例 #8
0
def flattenWire(wire):
    """Force a wire to get completely flat along its normal."""
    n = get_normal(wire)
    # for backward compatibility with previous getNormal implementation
    if n is None:
        n = App.Vector(0, 0, 1)

    o = wire.Vertexes[0].Point
    plane = WorkingPlane.plane()
    plane.alignToPointAndAxis(o, n, 0)
    verts = [o]

    for v in wire.Vertexes[1:]:
        verts.append(plane.projectPoint(v.Point))

    if wire.isClosed():
        verts.append(o)
    w = Part.makePolygon(verts)

    return w
コード例 #9
0
 def renderOutlineSVG(self, objs, direction):
     plane = None
     plane = WorkingPlane.plane()
     if direction != Vector(0, 0, 0):
         plane.alignToPointAndAxis(Vector(0, 0, 0), fcvec.neg(direction), 0)
     else:
         direction = Vector(0, 0, -1)
     faces = []
     for obj in objs:
         for face in obj.Shape.Faces:
             normal = face.normalAt(0, 0)
             if normal.getAngle(direction) > math.pi / 2:
                 faces.append(face)
     print "faces:", faces
     if faces:
         base = faces.pop()
         for face in faces:
             base = base.oldFuse(face)
     result = self.getPath(base, plane)
     return result
コード例 #10
0
 def __init__(self, wp=None):
     """
     Creates a renderer with a default Draft WorkingPlane
     Use like this:
     
     import ArchVRM
     p = ArchVRM.Renderer()
     p.add(App.ActiveDocument.ActiveObject)
     p.sort()
     p.buildDummy()
     """
     self.wp = wp
     self.faces = []
     self.oriented = False
     self.trimmed = False
     self.sorted = False
     if not self.wp:
         import WorkingPlane
         self.wp = WorkingPlane.plane()
     if DEBUG: print "Renderer initialized on " + str(self.wp)
コード例 #11
0
ファイル: ArchVRM.py プロジェクト: xhalo32/FreeCAD-1
    def __init__(self, wp=None):
        """
        Creates a renderer with a default Draft WorkingPlane
        Use like this:
        
        import ArchVRM
        p = ArchVRM.Renderer()
        p.add(App.ActiveDocument.ActiveObject)
        p.sort()
        p.buildDummy()
        """

        self.reset()
        if wp:
            self.wp = wp
        else:
            import WorkingPlane
            self.wp = WorkingPlane.plane()

        if DEBUG: print("Renderer initialized on " + str(self.wp))
コード例 #12
0
    def __init__(self,wp=None):

        """
        Creates a renderer with a default Draft WorkingPlane
        Use like this:
        
        import ArchVRM
        p = ArchVRM.Renderer()
        p.add(App.ActiveDocument.ActiveObject)
        p.sort()
        p.buildDummy()
        """
        
        self.reset()
        if wp:
            self.wp = wp
        else:
            import WorkingPlane
            self.wp = WorkingPlane.plane()
            
        if DEBUG: print "Renderer initialized on " + str(self.wp)
コード例 #13
0
    def order(self, face, right=False):
        """order(face,[right]): returns a list of vertices
        ordered clockwise. The first vertex will be the
        lefmost one, unless right is True, in which case the
        first vertex will be the rightmost one"""

        verts = [v.Point for v in face.OuterWire.OrderedVertexes]

        # flatten the polygon on the XY plane

        wp = WorkingPlane.plane()
        wp.alignToPointAndAxis(face.CenterOfMass, face.normalAt(0, 0))
        pverts = []
        for v in verts:
            vx = DraftVecUtils.project(v, wp.u)
            lx = vx.Length
            if vx.getAngle(wp.u) > 1:
                lx = -lx
            vy = DraftVecUtils.project(v, wp.v)
            ly = vy.Length
            if vy.getAngle(wp.v) > 1:
                ly = -ly
            pverts.append(FreeCAD.Vector(lx, ly, 0))
        pverts.append(pverts[0])

        # https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order

        s = 0
        for i in range(len(pverts) - 1):
            s += (pverts[i + 1].x - pverts[i].x) * (pverts[i + 1].y +
                                                    pverts[i].y)
        if s < 0:
            verts.reverse()
        elif s == 0:
            print("error computing winding direction")
            return

        return verts
コード例 #14
0
ファイル: ArchNesting.py プロジェクト: AjinkyaDahale/FreeCAD
    def order(self,face,right=False):

        """order(face,[right]): returns a list of vertices
        ordered clockwise. The first vertex will be the
        lefmost one, unless right is True, in which case the
        first vertex will be the rightmost one"""

        verts = [v.Point for v in face.OuterWire.OrderedVertexes]

        # flatten the polygon on the XY plane

        wp = WorkingPlane.plane()
        wp.alignToPointAndAxis(face.CenterOfMass,face.normalAt(0,0))
        pverts = []
        for v in verts:
            vx = DraftVecUtils.project(v,wp.u)
            lx = vx.Length
            if vx.getAngle(wp.u) > 1:
                lx = -lx
            vy = DraftVecUtils.project(v,wp.v)
            ly = vy.Length
            if vy.getAngle(wp.v) > 1:
                ly = -ly
            pverts.append(FreeCAD.Vector(lx,ly,0))
        pverts.append(pverts[0])

        # https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order

        s = 0
        for i in range(len(pverts)-1):
            s += (pverts[i+1].x-pverts[i].x)*(pverts[i+1].y+pverts[i].y)
        if s < 0:
            verts.reverse()
        elif s == 0:
            print("error computing winding direction")
            return

        return verts
コード例 #15
0
def create_window(wall, opening_ratio):
    faces = wall.Shape.Faces
    if not faces:
        return
    areas = [f.Area for f in faces]
    i = areas.index(max(areas))
    pl = WorkingPlane.getPlacementFromFace(wall.Shape.Faces[i])
    percent = math.sqrt(opening_ratio)
    height = percent * wall.Height
    width = percent * wall.Length
    # if width > height and width > 2:
    #     window_type = 'Open 2-pane'
    # elif width < height and height > 2:
    #     window_type = 'Sash 2-pane'
    # else:
    window_type = 'Fixed'
    win = Arch.makeWindowPreset(window_type,
                                width=width,
                                height=height,
                                h1=100.0,
                                h2=100.0,
                                h3=100.0,
                                w1=200.0,
                                w2=100.0,
                                o1=0.0,
                                o2=100.0,
                                placement=pl)
    # win.setExpression('Height', f'{percent} * {wall.Name}.Height')
    # win.setExpression('Width', f'{percent} * {wall.Name}.Length')
    win.recompute()
    v1 = wall.Shape.BoundBox.Center
    v2 = win.Shape.BoundBox.Center
    win.Placement.Base = v1.sub(v2)
    win.Hosts = [wall]
    win.recompute()
    return win
コード例 #16
0
def getSVGPlaneFromAxis(axis=FreeCAD.Vector(0, -1, 0)):
    view_plane = WorkingPlane.Plane()
    # axis is closed to +X axis
    if axis.getAngle(FreeCAD.Vector(1, 0, 0)) < 0.00001:
        view_plane.axis = FreeCAD.Vector(1, 0, 0)
        view_plane.u = FreeCAD.Vector(0, 1, 0)
        view_plane.v = FreeCAD.Vector(0, 0, -1)
    # axis is closed to -X axis
    elif axis.getAngle(FreeCAD.Vector(-1, 0, 0)) < 0.00001:
        view_plane.axis = FreeCAD.Vector(-1, 0, 0)
        view_plane.u = FreeCAD.Vector(0, -1, 0)
        view_plane.v = FreeCAD.Vector(0, 0, -1)
    else:
        view_plane.axis = axis
        y_axis = axis.cross(FreeCAD.Vector(1, 0, 0))
        y_axis.normalize()
        if y_axis.z > 0:
            y_axis = y_axis.negative()
        elif y_axis.y > 0:
            y_axis = y_axis.negative()
        view_plane.v = y_axis
        view_plane.u = DraftVecUtils.rotate(view_plane.v, math.pi / 2,
                                            view_plane.axis)
    return view_plane
コード例 #17
0
def getViewPlane(view):
    """getViewPlane(View):
    Returns view_plane corresponding to view, where view can be "Front", "Rear",
    "Left", "Right", "Top" or "Bottom".
    """
    if view == "Front":
        view_plane = WorkingPlane.plane()
        view_plane.axis = FreeCAD.Vector(0, -1, 0)
        view_plane.v = FreeCAD.Vector(0, 0, -1)
        view_plane.u = FreeCAD.Vector(1, 0, 0)
    elif view == "Rear":
        view_plane = WorkingPlane.plane()
        view_plane.axis = FreeCAD.Vector(0, 1, 0)
        view_plane.v = FreeCAD.Vector(0, 0, -1)
        view_plane.u = FreeCAD.Vector(-1, 0, 0)
    elif view == "Left":
        view_plane = WorkingPlane.plane()
        view_plane.axis = FreeCAD.Vector(-1, 0, 0)
        view_plane.v = FreeCAD.Vector(0, 0, -1)
        view_plane.u = FreeCAD.Vector(0, -1, 0)
    elif view == "Right":
        view_plane = WorkingPlane.plane()
        view_plane.axis = FreeCAD.Vector(1, 0, 0)
        view_plane.v = FreeCAD.Vector(0, 0, -1)
        view_plane.u = FreeCAD.Vector(0, 1, 0)
    elif view == "Top":
        view_plane = WorkingPlane.plane()
        view_plane.axis = FreeCAD.Vector(0, 0, 1)
        view_plane.v = FreeCAD.Vector(0, -1, 0)
        view_plane.u = FreeCAD.Vector(1, 0, 0)
    elif view == "Bottom":
        view_plane = WorkingPlane.plane()
        view_plane.axis = FreeCAD.Vector(0, 0, -1)
        view_plane.v = FreeCAD.Vector(0, 1, 0)
        view_plane.u = FreeCAD.Vector(1, 0, 0)
    else:
        FreeCAD.Console.PrintError(
            'Invalid/Unsupported view. Valid views are: "Front", "Rear", '
            '"Left", "Right" "Top" and "Bottom".\n')
        return None
    return view_plane
コード例 #18
0
def getSVG(section,allOn=False,renderMode="Wireframe",showHidden=False,showFill=False,scale=1,linewidth=1,fontsize=1,techdraw=False,rotation=0):
    """getSVG(section,[allOn,renderMode,showHidden,showFill,scale,linewidth,fontsize]) : 
    returns an SVG fragment from an Arch section plane. If
    allOn is True, all cut objects are shown, regardless if they are visible or not.
    renderMode can be Wireframe (default) or Solid to use the Arch solid renderer. If
    showHidden is True, the hidden geometry above the section plane is shown in dashed line.
    If showFill is True, the cut areas get filled with a pattern"""

    if not section.Objects:
        return
    import Part,DraftGeomUtils
    p = FreeCAD.Placement(section.Placement)
    direction = p.Rotation.multVec(FreeCAD.Vector(0,0,1))
    objs = Draft.getGroupContents(section.Objects,walls=True,addgroups=True)
    if not allOn:
            objs = Draft.removeHidden(objs)
    # separate spaces and Draft objects
    spaces = []
    nonspaces = []
    drafts = []
    windows = []
    cutface = None
    for o in objs:
        if Draft.getType(o) == "Space":
            spaces.append(o)
        elif Draft.getType(o) in ["Dimension","Annotation"]:
            drafts.append(o)
        elif o.isDerivedFrom("Part::Part2DObject"):
            drafts.append(o)
        else:
            nonspaces.append(o)
        if Draft.getType(o) == "Window":
            windows.append(o)
    objs = nonspaces
    svg = ''
    fillpattern = '<pattern id="sectionfill" patternUnits="userSpaceOnUse" patternTransform="matrix(5,0,0,5,0,0)"'
    fillpattern += ' x="0" y="0" width="10" height="10">'
    fillpattern += '<g>'
    fillpattern += '<rect width="10" height="10" style="stroke:none; fill:#ffffff" /><path style="stroke:#000000; stroke-width:1" d="M0,0 l10,10" /></g></pattern>'
    # generating SVG
    if renderMode in ["Solid",1]:
        # render using the Arch Vector Renderer
        import ArchVRM, WorkingPlane
        wp = WorkingPlane.plane()
        wp.setFromPlacement(section.Placement)
        #wp.inverse()
        render = ArchVRM.Renderer()
        render.setWorkingPlane(wp)
        render.addObjects(objs)
        if showHidden:
            render.cut(section.Shape,showHidden)
        else:
            render.cut(section.Shape)
        svg += '<g transform="scale(1,-1)">\n'
        svg += render.getViewSVG(linewidth="LWPlaceholder")
        svg += fillpattern
        svg += render.getSectionSVG(linewidth="SWPlaceholder",fillpattern="sectionfill")
        if showHidden:
            svg += render.getHiddenSVG(linewidth="LWPlaceholder")
        svg += '</g>\n'
        # print render.info()

    else:
        # render using the Drawing module
        import Drawing, Part
        shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume = getCutShapes(objs,section,showHidden)
        if shapes:
            baseshape = Part.makeCompound(shapes)
            svgf = Drawing.projectToSVG(baseshape,direction)
            if svgf:
                svgf = svgf.replace('stroke-width="0.35"','stroke-width="LWPlaceholder"')
                svgf = svgf.replace('stroke-width="1"','stroke-width="LWPlaceholder"')
                svgf = svgf.replace('stroke-width:0.01','stroke-width:LWPlaceholder')
                svg += svgf
        if hshapes:
            hshapes = Part.makeCompound(hshapes)
            svgh = Drawing.projectToSVG(hshapes,direction)
            if svgh:
                svgh = svgh.replace('stroke-width="0.35"','stroke-width="LWPlaceholder"')
                svgh = svgh.replace('stroke-width="1"','stroke-width="LWPlaceholder"')
                svgh = svgh.replace('stroke-width:0.01','stroke-width:LWPlaceholder')
                svgh = svgh.replace('fill="none"','fill="none"\nstroke-dasharray="DAPlaceholder"')
                svg += svgh
        if sshapes:
            svgs = ""
            if showFill:
                #svgs += fillpattern
                svgs += '<g transform="rotate(180)">\n'
                for s in sshapes:
                    if s.Edges:
                        #f = Draft.getSVG(s,direction=direction.negative(),linewidth=0,fillstyle="sectionfill",color=(0,0,0))
                        # temporarily disabling fill patterns
                        f = Draft.getSVG(s,direction=direction.negative(),linewidth=0,fillstyle="#aaaaaa",color=(0,0,0))
                        svgs += f
                svgs += "</g>\n"
            sshapes = Part.makeCompound(sshapes)
            svgs += Drawing.projectToSVG(sshapes,direction)
            if svgs:
                svgs = svgs.replace('stroke-width="0.35"','stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width="1"','stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width:0.01','stroke-width:SWPlaceholder')
                svgs = svgs.replace('stroke-width="0.35 px"','stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width:0.35','stroke-width:SWPlaceholder')
                svg += svgs
    scaledlinewidth = linewidth/scale
    st = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetFloat("CutLineThickness",2)
    yt = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetFloat("SymbolLineThickness",0.6)
    da = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetString("archHiddenPattern","30,10")
    da = da.replace(" ","")
    svg = svg.replace('LWPlaceholder', str(scaledlinewidth) + 'px')
    svg = svg.replace('SWPlaceholder', str(scaledlinewidth*st) + 'px')
    svg = svg.replace('DAPlaceholder', str(da))
    if drafts:
        if not techdraw:
            svg += '<g transform="scale(1,-1)">'
        for d in drafts:
            svg += Draft.getSVG(d,scale=scale,linewidth=linewidth*yt,fontsize=fontsize,direction=direction,techdraw=techdraw,rotation=rotation)
        if not techdraw:
            svg += '</g>'
    # filter out spaces not cut by the section plane
    if cutface and spaces:
        spaces = [s for s in spaces if s.Shape.BoundBox.intersect(cutface.BoundBox)]
    if spaces:
        if not techdraw:
            svg += '<g transform="scale(1,-1)">'
        for s in spaces:
            svg += Draft.getSVG(s,scale=scale,linewidth=linewidth*yt,fontsize=fontsize,direction=direction,techdraw=techdraw,rotation=rotation)
        if not techdraw:
            svg += '</g>'
    # add additional edge symbols from windows
    if cutface and windows:
        cutwindows = [w.Name for w in windows if w.Shape.BoundBox.intersect(cutface.BoundBox)]
    if windows:
        sh = []
        for w in windows:
            if not hasattr(w.Proxy,"sshapes"):
                w.Proxy.execute(w)
            if hasattr(w.Proxy,"sshapes"):
                if w.Proxy.sshapes and (w.Name in cutwindows):
                    c = Part.makeCompound(w.Proxy.sshapes)
                    c.Placement = w.Placement
                    sh.append(c)
            # buggy for now...
            #if hasattr(w.Proxy,"vshapes"):
            #    if w.Proxy.vshapes:
            #        c = Part.makeCompound(w.Proxy.vshapes)
            #        c.Placement = w.Placement
            #        sh.append(c)
        if sh:
            if not techdraw:
                svg += '<g transform="scale(1,-1)">'
            for s in sh:
                svg += Draft.getSVG(s,scale=scale,linewidth=linewidth*yt,fontsize=fontsize,fillstyle="none",direction=direction,techdraw=techdraw,rotation=rotation)
            if not techdraw:
                svg += '</g>'
            
    #print "complete node:",svg
    return svg
コード例 #19
0
def getSVG(section, renderMode="Wireframe", allOn=False, showHidden=False, scale=1, rotation=0, linewidth=1, lineColor=(0.0,0.0,0.0), fontsize=1, showFill=False, fillColor=(0.8,0.8,0.8), techdraw=False):

    """getSVG(section, [renderMode, allOn, showHidden, scale, rotation,
              linewidth, lineColor, fontsize, showFill, fillColor, techdraw]):

    returns an SVG fragment from an Arch section plane. If
    allOn is True, all cut objects are shown, regardless if they are visible or not.
    renderMode can be Wireframe (default) or Solid to use the Arch solid renderer. If
    showHidden is True, the hidden geometry above the section plane is shown in dashed line.
    If showFill is True, the cut areas get filled with a pattern.
    lineColor -- Color of lines for the renderMode "Wireframe".
    fillColor -- If showFill is True and renderMode is "Wireframe",
                 the cut areas are filled with fillColor.
    """

    if not section.Objects:
        return ""
    import Part,DraftGeomUtils
    p = FreeCAD.Placement(section.Placement)
    direction = p.Rotation.multVec(FreeCAD.Vector(0,0,1))
    objs = Draft.getGroupContents(section.Objects,walls=True,addgroups=True)
    if not allOn:
            objs = Draft.removeHidden(objs)

    # separate spaces and Draft objects
    spaces = []
    nonspaces = []
    drafts = []
    windows = []
    cutface = None
    for o in objs:
        if Draft.getType(o) == "Space":
            spaces.append(o)
        elif Draft.getType(o) in ["Dimension","Annotation","Label"]:
            drafts.append(o)
        elif o.isDerivedFrom("Part::Part2DObject"):
            drafts.append(o)
        else:
            nonspaces.append(o)
        if Draft.getType(o) == "Window":
            windows.append(o)
    objs = nonspaces

    archUserParameters = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
    scaledLineWidth = linewidth/scale
    svgLineWidth = str(scaledLineWidth) + 'px'
    st = archUserParameters.GetFloat("CutLineThickness",2)
    svgCutLineWidth = str(scaledLineWidth * st) + 'px'
    yt = archUserParameters.GetFloat("SymbolLineThickness",0.6)
    svgSymbolLineWidth = str(linewidth * yt)
    hiddenPattern = archUserParameters.GetString("archHiddenPattern","30,10")
    svgHiddenPattern = hiddenPattern.replace(" ","")
    fillpattern = '<pattern id="sectionfill" patternUnits="userSpaceOnUse" patternTransform="matrix(5,0,0,5,0,0)"'
    fillpattern += ' x="0" y="0" width="10" height="10">'
    fillpattern += '<g>'
    fillpattern += '<rect width="10" height="10" style="stroke:none; fill:#ffffff" /><path style="stroke:#000000; stroke-width:1" d="M0,0 l10,10" /></g></pattern>'
    svgLineColor = Draft.getrgb(lineColor)
    svg = ''

    # reading cached version
    svgcache = None
    if hasattr(section.Proxy,"svgcache") and section.Proxy.svgcache:
        svgcache = section.Proxy.svgcache[0]
        if section.Proxy.svgcache[1] != renderMode:
            svgcache = None
        if section.Proxy.svgcache[2] != showHidden:
            svgcache = None
        if section.Proxy.svgcache[3] != showFill:
            svgcache = None

    # generating SVG
    if renderMode in ["Solid",1]:
        if not svgcache:
            svgcache = ''
            # render using the Arch Vector Renderer
            import ArchVRM, WorkingPlane
            wp = WorkingPlane.plane()
            wp.setFromPlacement(section.Placement)
            #wp.inverse()
            render = ArchVRM.Renderer()
            render.setWorkingPlane(wp)
            render.addObjects(objs)
            if showHidden:
                render.cut(section.Shape,showHidden)
            else:
                render.cut(section.Shape)
            svgcache += '<g transform="scale(1,-1)">\n'
            svgcache += render.getViewSVG(linewidth="SVGLINEWIDTH")
            svgcache += fillpattern
            svgcache += render.getSectionSVG(linewidth="SVGCUTLINEWIDTH",
                                        fillpattern="sectionfill")
            if showHidden:
                svgcache += render.getHiddenSVG(linewidth="SVGLINEWIDTH")
            svgcache += '</g>\n'
            # print(render.info())
            section.Proxy.svgcache = [svgcache,renderMode,showHidden,showFill]
    else:
        if not svgcache:
            svgcache = ""
            # render using the Drawing module
            import Drawing, Part
            shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume = getCutShapes(objs,section,showHidden)
            if shapes:
                baseshape = Part.makeCompound(shapes)
                style = {'stroke':       "SVGLINECOLOR",
                         'stroke-width': "SVGLINEWIDTH"}
                svgcache += Drawing.projectToSVG(
                    baseshape, direction,
                    hStyle=style, h0Style=style, h1Style=style,
                    vStyle=style, v0Style=style, v1Style=style)
            if hshapes:
                hshapes = Part.makeCompound(hshapes)
                style = {'stroke':           "SVGLINECOLOR",
                         'stroke-width':     "SVGLINEWIDTH",
                         'stroke-dasharray': "SVGHIDDENPATTERN"}
                svgcache += Drawing.projectToSVG(
                    hshapes, direction,
                    hStyle=style, h0Style=style, h1Style=style,
                    vStyle=style, v0Style=style, v1Style=style)
            if sshapes:
                if showFill:
                    #svgcache += fillpattern
                    svgcache += '<g transform="rotate(180)">\n'
                    for s in sshapes:
                        if s.Edges:
                            #svg += Draft.getSVG(s,direction=direction.negative(),linewidth=0,fillstyle="sectionfill",color=(0,0,0))
                            # temporarily disabling fill patterns
                            svgcache += Draft.getSVG(s, direction=direction.negative(),
                                linewidth=0,
                                fillstyle=Draft.getrgb(fillColor),
                                color=lineColor)
                    svgcache += "</g>\n"
                sshapes = Part.makeCompound(sshapes)
                style = {'stroke':       "SVGLINECOLOR",
                         'stroke-width': "SVGCUTLINEWIDTH"}
                svgcache += Drawing.projectToSVG(
                    sshapes, direction,
                    hStyle=style, h0Style=style, h1Style=style,
                    vStyle=style, v0Style=style, v1Style=style)
            section.Proxy.svgcache = [svgcache,renderMode,showHidden,showFill]
    svgcache = svgcache.replace("SVGLINECOLOR",svgLineColor)
    svgcache = svgcache.replace("SVGLINEWIDTH",svgLineWidth)
    svgcache = svgcache.replace("SVGHIDDENPATTERN",svgHiddenPattern)
    svgcache = svgcache.replace("SVGCUTLINEWIDTH",svgCutLineWidth)
    svg += svgcache

    if drafts:
        if not techdraw:
            svg += '<g transform="scale(1,-1)">'
        for d in drafts:
            svg += Draft.getSVG(d, scale=scale, linewidth=svgSymbolLineWidth,
                                fontsize=fontsize, direction=direction, color=lineColor,
                                techdraw=techdraw, rotation=rotation)
        if not techdraw:
            svg += '</g>'

    # filter out spaces not cut by the section plane
    if cutface and spaces:
        spaces = [s for s in spaces if s.Shape.BoundBox.intersect(cutface.BoundBox)]
    if spaces:
        if not techdraw:
            svg += '<g transform="scale(1,-1)">'
        for s in spaces:
            svg += Draft.getSVG(s, scale=scale, linewidth=svgSymbolLineWidth,
                                fontsize=fontsize, direction=direction, color=lineColor,
                                techdraw=techdraw, rotation=rotation)
        if not techdraw:
            svg += '</g>'

    # add additional edge symbols from windows
    cutwindows = []
    if cutface and windows:
        cutwindows = [w.Name for w in windows if w.Shape.BoundBox.intersect(cutface.BoundBox)]
    if windows:
        sh = []
        for w in windows:
            if not hasattr(w.Proxy,"sshapes"):
                w.Proxy.execute(w)
            if hasattr(w.Proxy,"sshapes"):
                if w.Proxy.sshapes and (w.Name in cutwindows):
                    c = Part.makeCompound(w.Proxy.sshapes)
                    c.Placement = w.Placement
                    sh.append(c)
            # buggy for now...
            #if hasattr(w.Proxy,"vshapes"):
            #    if w.Proxy.vshapes:
            #        c = Part.makeCompound(w.Proxy.vshapes)
            #        c.Placement = w.Placement
            #        sh.append(c)
        if sh:
            if not techdraw:
                svg += '<g transform="scale(1,-1)">'
            for s in sh:
                svg += Draft.getSVG(s, scale=scale,
                                    linewidth=svgSymbolLineWidth,
                                    fontsize=fontsize, fillstyle="none",
                                    direction=direction, color=lineColor,
                                    techdraw=techdraw, rotation=rotation)
            if not techdraw:
                svg += '</g>'

    return svg
コード例 #20
0
def getSVG(obj,
           scale=1,
           linewidth=0.35,
           fontsize=12,
           fillstyle="shape color",
           direction=None,
           linestyle=None,
           color=None,
           linespacing=None,
           techdraw=False,
           rotation=0,
           fillSpaces=False,
           override=True):
    '''getSVG(object,[scale], [linewidth],[fontsize],[fillstyle],[direction],[linestyle],[color],[linespacing]):
    returns a string containing a SVG representation of the given object,
    with the given linewidth and fontsize (used if the given object contains
    any text). You can also supply an arbitrary projection vector. the
    scale parameter allows to scale linewidths down, so they are resolution-independant.'''

    import Part, DraftGeomUtils

    # if this is a group, gather all the svg views of its children
    if hasattr(obj, "isDerivedFrom"):
        if obj.isDerivedFrom("App::DocumentObjectGroup") or getType(
                obj) == "Layer":
            svg = ""
            for child in obj.Group:
                svg += getSVG(child, scale, linewidth, fontsize, fillstyle,
                              direction, linestyle, color, linespacing,
                              techdraw, rotation, fillSpaces, override)
            return svg

    pathdata = []
    svg = ""
    linewidth = float(linewidth) / scale
    if not override:
        if hasattr(obj, "ViewObject"):
            if hasattr(obj.ViewObject, "LineWidth"):
                if hasattr(obj.ViewObject.LineWidth, "Value"):
                    lw = obj.ViewObject.LineWidth.Value
                else:
                    lw = obj.ViewObject.LineWidth
                linewidth = lw * linewidth
    fontsize = (float(fontsize) / scale) / 2
    if linespacing:
        linespacing = float(linespacing) / scale
    else:
        linespacing = 0.5
    #print obj.Label," line spacing ",linespacing,"scale ",scale
    pointratio = .75  # the number of times the dots are smaller than the arrow size
    plane = None
    if direction:
        if isinstance(direction, FreeCAD.Vector):
            if direction != Vector(0, 0, 0):
                plane = WorkingPlane.plane()
                plane.alignToPointAndAxis_SVG(Vector(0, 0, 0),
                                              direction.negative().negative(),
                                              0)
        elif isinstance(direction, WorkingPlane.plane):
            plane = direction
    stroke = "#000000"
    if color and override:
        if "#" in color:
            stroke = color
        else:
            stroke = getrgb(color)
    elif gui:
        if hasattr(obj, "ViewObject"):
            if hasattr(obj.ViewObject, "LineColor"):
                stroke = getrgb(obj.ViewObject.LineColor)
            elif hasattr(obj.ViewObject, "TextColor"):
                stroke = getrgb(obj.ViewObject.TextColor)
    lstyle = "none"
    if override:
        lstyle = getLineStyle(linestyle, scale)
    else:
        if hasattr(obj, "ViewObject"):
            if hasattr(obj.ViewObject, "DrawStyle"):
                lstyle = getLineStyle(obj.ViewObject.DrawStyle, scale)

    def getPath(edges=[], wires=[], pathname=None):

        svg = "<path "
        if pathname is None:
            svg += 'id="%s" ' % obj.Name
        elif pathname != "":
            svg += 'id="%s" ' % pathname
        svg += ' d="'
        if not wires:
            egroups = Part.sortEdges(edges)
        else:
            egroups = []
            first = True
            for w in wires:
                w1 = w.copy()
                if first:
                    first = False
                else:
                    # invert further wires to create holes
                    w1 = DraftGeomUtils.invert(w1)
                w1.fixWire()
                egroups.append(Part.__sortEdges__(w1.Edges))
        for egroupindex, edges in enumerate(egroups):
            edata = ""
            vs = ()  #skipped for the first edge
            for edgeindex, e in enumerate(edges):
                previousvs = vs
                # vertexes of an edge (reversed if needed)
                vs = e.Vertexes
                if previousvs:
                    if (vs[0].Point - previousvs[-1].Point).Length > 1e-6:
                        vs.reverse()
                if edgeindex == 0:
                    v = getProj(vs[0].Point, plane)
                    edata += 'M ' + str(v.x) + ' ' + str(v.y) + ' '
                else:
                    if (vs[0].Point - previousvs[-1].Point).Length > 1e-6:
                        raise ValueError('edges not ordered')
                iscircle = DraftGeomUtils.geomType(e) == "Circle"
                isellipse = DraftGeomUtils.geomType(e) == "Ellipse"
                if iscircle or isellipse:
                    import math
                    if hasattr(FreeCAD, "DraftWorkingPlane"):
                        drawing_plane_normal = FreeCAD.DraftWorkingPlane.axis
                    else:
                        drawing_plane_normal = FreeCAD.Vector(0, 0, 1)
                    if plane: drawing_plane_normal = plane.axis
                    c = e.Curve
                    if round(c.Axis.getAngle(drawing_plane_normal),
                             2) in [0, 3.14]:
                        occversion = Part.OCC_VERSION.split(".")
                        done = False
                        if (int(occversion[0]) >= 7) and (int(occversion[1]) >=
                                                          1):
                            # if using occ >= 7.1, use HLR algorithm
                            import Drawing
                            snip = Drawing.projectToSVG(
                                e, drawing_plane_normal)
                            if snip:
                                try:
                                    a = "A " + snip.split("path d=\"")[
                                        1].split("\"")[0].split("A")[1]
                                except:
                                    pass
                                else:
                                    edata += a
                                    done = True
                        if not done:
                            if len(e.Vertexes
                                   ) == 1 and iscircle:  #complete curve
                                svg = getCircle(e)
                                return svg
                            elif len(e.Vertexes) == 1 and isellipse:
                                #svg = getEllipse(e)
                                #return svg
                                endpoints = [
                                    getProj(
                                        c.value((c.LastParameter -
                                                 c.FirstParameter) / 2.0),
                                        plane),
                                    getProj(vs[-1].Point, plane)
                                ]
                            else:
                                endpoints = [getProj(vs[-1].Point, plane)]
                            # arc
                            if iscircle:
                                rx = ry = c.Radius
                                rot = 0
                            else:  #ellipse
                                rx = c.MajorRadius
                                ry = c.MinorRadius
                                rot = math.degrees(c.AngleXU * (c.Axis * \
                                    FreeCAD.Vector(0,0,1)))
                                if rot > 90:
                                    rot -= 180
                                if rot < -90:
                                    rot += 180
                                #be careful with the sweep flag
                            flag_large_arc = (((e.ParameterRange[1] - \
                                    e.ParameterRange[0]) / math.pi) % 2) > 1
                            #flag_sweep = (c.Axis * drawing_plane_normal >= 0) \
                            #         == (e.LastParameter > e.FirstParameter)
                            #        == (e.Orientation == "Forward")
                            # other method: check the direction of the angle between tangents
                            t1 = e.tangentAt(e.FirstParameter)
                            t2 = e.tangentAt(
                                e.FirstParameter +
                                (e.LastParameter - e.FirstParameter) / 10)
                            flag_sweep = (DraftVecUtils.angle(
                                t1, t2, drawing_plane_normal) < 0)
                            for v in endpoints:
                                edata += 'A %s %s %s %s %s %s %s ' % \
                                        (str(rx),str(ry),str(rot),\
                                        str(int(flag_large_arc)),\
                                        str(int(flag_sweep)),str(v.x),str(v.y))
                    else:
                        edata += getDiscretized(e, plane)
                elif DraftGeomUtils.geomType(e) == "Line":
                    v = getProj(vs[-1].Point, plane)
                    edata += 'L ' + str(v.x) + ' ' + str(v.y) + ' '
                else:
                    bspline = e.Curve.toBSpline(e.FirstParameter,
                                                e.LastParameter)
                    if bspline.Degree > 3 or bspline.isRational():
                        try:
                            bspline = bspline.approximateBSpline(
                                0.05, 50, 3, 'C0')
                        except RuntimeError:
                            print("Debug: unable to approximate bspline")
                    if bspline.Degree <= 3 and not bspline.isRational():
                        for bezierseg in bspline.toBezier():
                            if bezierseg.Degree > 3:  #should not happen
                                raise AssertionError
                            elif bezierseg.Degree == 1:
                                edata += 'L '
                            elif bezierseg.Degree == 2:
                                edata += 'Q '
                            elif bezierseg.Degree == 3:
                                edata += 'C '
                            for pole in bezierseg.getPoles()[1:]:
                                v = getProj(pole, plane)
                                edata += str(v.x) + ' ' + str(v.y) + ' '
                    else:
                        print("Debug: one edge (hash ",e.hashCode(),\
                                ") has been discretized with parameter 0.1")
                        for linepoint in bspline.discretize(0.1)[1:]:
                            v = getProj(linepoint, plane)
                            edata += 'L ' + str(v.x) + ' ' + str(v.y) + ' '
            if fill != 'none':
                edata += 'Z '
            if edata in pathdata:
                # do not draw a path on another identical path
                return ""
            else:
                svg += edata
                pathdata.append(edata)
        svg += '" '
        svg += 'stroke="' + stroke + '" '
        svg += 'stroke-width="' + str(linewidth) + ' px" '
        svg += 'style="stroke-width:' + str(linewidth)
        svg += ';stroke-miterlimit:4'
        svg += ';stroke-dasharray:' + lstyle
        svg += ';fill:' + fill
        try:
            svg += ';fill-opacity:' + str(fill_opacity)
        except NameError:
            pass
        svg += ';fill-rule: evenodd "'
        svg += '/>\n'
        return svg

    def getCircle(edge):
        cen = getProj(edge.Curve.Center, plane)
        rad = edge.Curve.Radius
        if hasattr(FreeCAD, "DraftWorkingPlane"):
            drawing_plane_normal = FreeCAD.DraftWorkingPlane.axis
        else:
            drawing_plane_normal = FreeCAD.Vector(0, 0, 1)
        if plane: drawing_plane_normal = plane.axis
        if round(edge.Curve.Axis.getAngle(drawing_plane_normal),
                 2) in [0, 3.14]:
            # perpendicular projection: circle
            svg = '<circle cx="' + str(cen.x)
            svg += '" cy="' + str(cen.y)
            svg += '" r="' + str(rad) + '" '
        else:
            # any other projection: ellipse
            svg = '<path d="'
            svg += getDiscretized(edge, plane)
            svg += '" '
        svg += 'stroke="' + stroke + '" '
        svg += 'stroke-width="' + str(linewidth) + ' px" '
        svg += 'style="stroke-width:' + str(linewidth)
        svg += ';stroke-miterlimit:4'
        svg += ';stroke-dasharray:' + lstyle
        svg += ';fill:' + fill + '"'
        svg += '/>\n'
        return svg

    def getEllipse(edge):
        cen = getProj(edge.Curve.Center, plane)
        mir = edge.Curve.MinorRadius
        mar = edge.Curve.MajorRadius
        svg = '<ellipse cx="' + str(cen.x)
        svg += '" cy="' + str(cen.y)
        svg += '" rx="' + str(mar)
        svg += '" ry="' + str(mir) + '" '
        svg += 'stroke="' + stroke + '" '
        svg += 'stroke-width="' + str(linewidth) + ' px" '
        svg += 'style="stroke-width:' + str(linewidth)
        svg += ';stroke-miterlimit:4'
        svg += ';stroke-dasharray:' + lstyle
        svg += ';fill:' + fill + '"'
        svg += '/>\n'
        return svg

    def getArrow(arrowtype, point, arrowsize, color, linewidth, angle=0):
        svg = ""
        if gui:
            if not obj.ViewObject:
                return svg
            if obj.ViewObject.ArrowType == "Circle":
                svg += '<circle cx="' + str(point.x) + '" cy="' + str(point.y)
                svg += '" r="' + str(arrowsize) + '" '
                svg += 'fill="none" stroke="' + color + '" '
                svg += 'style="stroke-width:' + str(
                    linewidth) + ';stroke-miterlimit:4;stroke-dasharray:none" '
                svg += 'freecad:skip="1"'
                svg += '/>\n'
            elif obj.ViewObject.ArrowType == "Dot":
                svg += '<circle cx="' + str(point.x) + '" cy="' + str(point.y)
                svg += '" r="' + str(arrowsize) + '" '
                svg += 'fill="' + color + '" stroke="none" '
                svg += 'style="stroke-miterlimit:4;stroke-dasharray:none" '
                svg += 'freecad:skip="1"'
                svg += '/>\n'
            elif obj.ViewObject.ArrowType == "Arrow":
                svg += '<path transform="rotate(' + str(math.degrees(angle))
                svg += ',' + str(point.x) + ',' + str(point.y) + ') '
                svg += 'translate(' + str(point.x) + ',' + str(point.y) + ') '
                svg += 'scale(' + str(arrowsize) + ',' + str(
                    arrowsize) + ')" freecad:skip="1" '
                svg += 'fill="' + color + '" stroke="none" '
                svg += 'style="stroke-miterlimit:4;stroke-dasharray:none" '
                svg += 'd="M 0 0 L 4 1 L 4 -1 Z"/>\n'
            elif obj.ViewObject.ArrowType == "Tick":
                svg += '<path transform="rotate(' + str(math.degrees(angle))
                svg += ',' + str(point.x) + ',' + str(point.y) + ') '
                svg += 'translate(' + str(point.x) + ',' + str(point.y) + ') '
                svg += 'scale(' + str(arrowsize) + ',' + str(
                    arrowsize) + ')" freecad:skip="1" '
                svg += 'fill="' + color + '" stroke="none" '
                svg += 'style="stroke-miterlimit:4;stroke-dasharray:none" '
                svg += 'd="M -1 -2 L 0 2 L 1 2 L 0 -2 Z"/>\n'
            elif obj.ViewObject.ArrowType == "Tick-2":
                svg += '<line transform="rotate(' + str(
                    math.degrees(angle) + 45)
                svg += ',' + str(point.x) + ',' + str(point.y) + ') '
                svg += 'translate(' + str(point.x) + ',' + str(point.y) + ') '
                svg += '" freecad:skip="1" '
                svg += 'fill="none" stroke="' + color + '" '
                svg += 'style="stroke-dasharray:none;stroke-linecap:square;'
                svg += 'stroke-width:' + str(linewidth) + '" '
                svg += 'x1="-' + str(arrowsize * 2) + '" y1="0" '
                svg += 'x2="' + str(arrowsize * 2) + '" y2="0" />\n'
            else:
                print("getSVG: arrow type not implemented")
        return svg

    def getOvershoot(point, shootsize, color, linewidth, angle=0):
        svg = '<line transform="rotate(' + str(math.degrees(angle))
        svg += ',' + str(point.x) + ',' + str(point.y) + ') '
        svg += 'translate(' + str(point.x) + ',' + str(point.y) + ') '
        svg += '" freecad:skip="1" '
        svg += 'fill="none" stroke="' + color + '" '
        svg += 'style="stroke-dasharray:none;stroke-linecap:square;'
        svg += 'stroke-width:' + str(linewidth) + '" '
        svg += 'x1="0" y1="0" '
        svg += 'x2="' + str(shootsize * -1) + '" y2="0" />\n'
        return svg

    def getText(tcolor,
                fontsize,
                fontname,
                angle,
                base,
                text,
                linespacing=0.5,
                align="center",
                flip=True):
        if isinstance(angle, FreeCAD.Rotation):
            if not plane:
                angle = angle.Angle
            else:
                if plane.axis.getAngle(angle.Axis) < 0.001:
                    angle = angle.Angle
                elif abs(plane.axis.getAngle(angle.Axis) - math.pi) < 0.001:
                    if abs(angle.Angle) > 0.1:
                        angle = -angle.Angle
                    else:
                        angle = angle.Angle
                elif abs(plane.axis.getAngle(angle.Axis) -
                         math.pi / 2) < 0.001:
                    return ""  # text is perpendicular to view, so it shouldn't appear
                else:
                    angle = 0  #TODO maybe there is something better to do here?
        if not isinstance(text, list):
            text = text.split("\n")
        if align.lower() == "center":
            anchor = "middle"
        elif align.lower() == "left":
            anchor = "start"
        else:
            anchor = "end"
        if techdraw:
            svg = ""
            for i in range(len(text)):
                t = text[i].replace("&", "&amp;").replace("<", "&lt;").replace(
                    ">", "&gt;")
                if six.PY2 and not isinstance(t, six.text_type):
                    t = t.decode("utf8")
                # possible workaround if UTF8 is unsupported
                #    import unicodedata
                #    t = u"".join([c for c in unicodedata.normalize("NFKD",t) if not unicodedata.combining(c)]).encode("utf8")
                svg += '<text stroke-width="0" stroke="' + tcolor + '" fill="' + tcolor + '" font-size="' + str(
                    fontsize) + '" '
                svg += 'style="text-anchor:' + anchor + ';text-align:' + align.lower(
                ) + ';'
                svg += 'font-family:' + fontname + '" '
                svg += 'transform="rotate(' + str(math.degrees(angle))
                svg += ',' + str(
                    base.x) + ',' + str(base.y - linespacing * i) + ') '
                svg += 'translate(' + str(
                    base.x) + ',' + str(base.y - linespacing * i) + ') '
                svg += 'scale(1,-1)" '
                #svg += '" freecad:skip="1"'
                svg += '>\n' + t + '</text>\n'
        else:
            svg = '<text stroke-width="0" stroke="' + tcolor + '" fill="'
            svg += tcolor + '" font-size="'
            svg += str(fontsize) + '" '
            svg += 'style="text-anchor:' + anchor + ';text-align:' + align.lower(
            ) + ';'
            svg += 'font-family:' + fontname + '" '
            svg += 'transform="rotate(' + str(math.degrees(angle))
            svg += ',' + str(base.x) + ',' + str(base.y) + ') '
            if flip:
                svg += 'translate(' + str(base.x) + ',' + str(base.y) + ')'
            else:
                svg += 'translate(' + str(base.x) + ',' + str(-base.y) + ')'
            #svg += 'scale('+str(tmod/2000)+',-'+str(tmod/2000)+') '
            if flip:
                svg += ' scale(1,-1) '
            else:
                svg += ' scale(1,1) '
            svg += '" freecad:skip="1"'
            svg += '>\n'
            if len(text) == 1:
                try:
                    svg += text[0].replace("&", "&amp;").replace(
                        "<", "&lt;").replace(">", "&gt;")
                except:
                    svg += text[0].decode("utf8").replace(
                        "&", "&amp;").replace("<",
                                              "&lt;").replace(">", "&gt;")
            else:
                for i in range(len(text)):
                    if i == 0:
                        svg += '<tspan>'
                    else:
                        svg += '<tspan x="0" dy="' + str(linespacing) + '">'
                    try:
                        svg += text[i].replace("&", "&amp;").replace(
                            "<", "&lt;").replace(">", "&gt;")
                    except:
                        svg += text[i].decode("utf8").replace(
                            "&", "&amp;").replace("<",
                                                  "&lt;").replace(">", "&gt;")
                    svg += '</tspan>\n'
            svg += '</text>\n'
        return svg

    if not obj:
        pass

    elif isinstance(obj, Part.Shape):
        if "#" in fillstyle:
            fill = fillstyle
        elif fillstyle == "shape color":
            fill = "#888888"
        else:
            fill = 'url(#' + fillstyle + ')'
        svg += getPath(obj.Edges, pathname="")

    elif getType(obj) in ["Dimension", "LinearDimension"]:
        if gui:
            if not obj.ViewObject:
                print(
                    "export of dimensions to SVG is only available in GUI mode"
                )
            elif obj.ViewObject.Proxy:
                if hasattr(obj.ViewObject.Proxy, "p1"):
                    prx = obj.ViewObject.Proxy
                    ts = (len(prx.string) *
                          obj.ViewObject.FontSize.Value) / 4.0
                    rm = ((prx.p3.sub(prx.p2)).Length / 2.0) - ts
                    p2a = getProj(
                        prx.p2.add(
                            DraftVecUtils.scaleTo(prx.p3.sub(prx.p2), rm)),
                        plane)
                    p2b = getProj(
                        prx.p3.add(
                            DraftVecUtils.scaleTo(prx.p2.sub(prx.p3), rm)),
                        plane)
                    p1 = getProj(prx.p1, plane)
                    p2 = getProj(prx.p2, plane)
                    p3 = getProj(prx.p3, plane)
                    p4 = getProj(prx.p4, plane)
                    tbase = getProj(prx.tbase, plane)
                    r = prx.textpos.rotation.getValue().getValue()
                    rv = FreeCAD.Rotation(r[0], r[1], r[2], r[3]).multVec(
                        FreeCAD.Vector(1, 0, 0))
                    angle = -DraftVecUtils.angle(getProj(rv, plane))
                    #angle = -DraftVecUtils.angle(p3.sub(p2))

                    svg = ''
                    nolines = False
                    if hasattr(obj.ViewObject, "ShowLine"):
                        if not obj.ViewObject.ShowLine:
                            nolines = True

                    # drawing lines
                    if not nolines:
                        svg += '<path '
                    if obj.ViewObject.DisplayMode == "2D":
                        tangle = angle
                        if tangle > math.pi / 2:
                            tangle = tangle - math.pi
                        #elif (tangle <= -math.pi/2) or (tangle > math.pi/2):
                        #    tangle = tangle+math.pi
                        #tbase = tbase.add(DraftVecUtils.rotate(Vector(0,2/scale,0),tangle))
                        if rotation != 0:
                            #print "dim: tangle:",tangle," rot: ",rotation," text: ",prx.string
                            if abs(tangle + math.radians(rotation)) < 0.0001:
                                tangle += math.pi
                                tbase = tbase.add(
                                    DraftVecUtils.rotate(
                                        Vector(0, 2 / scale, 0), tangle))
                        if not nolines:
                            svg += 'd="M ' + str(p1.x) + ' ' + str(p1.y) + ' '
                            svg += 'L ' + str(p2.x) + ' ' + str(p2.y) + ' '
                            svg += 'L ' + str(p3.x) + ' ' + str(p3.y) + ' '
                            svg += 'L ' + str(p4.x) + ' ' + str(p4.y) + '" '
                    else:
                        tangle = 0
                        if rotation != 0:
                            tangle = -math.radians(rotation)
                        tbase = tbase.add(Vector(0, -2.0 / scale, 0))
                        if not nolines:
                            svg += 'd="M ' + str(p1.x) + ' ' + str(p1.y) + ' '
                            svg += 'L ' + str(p2.x) + ' ' + str(p2.y) + ' '
                            svg += 'L ' + str(p2a.x) + ' ' + str(p2a.y) + ' '
                            svg += 'M ' + str(p2b.x) + ' ' + str(p2b.y) + ' '
                            svg += 'L ' + str(p3.x) + ' ' + str(p3.y) + ' '
                            svg += 'L ' + str(p4.x) + ' ' + str(p4.y) + '" '

                    if not nolines:
                        svg += 'fill="none" stroke="'
                        svg += stroke + '" '
                        svg += 'stroke-width="' + str(linewidth) + ' px" '
                        svg += 'style="stroke-width:' + str(linewidth)
                        svg += ';stroke-miterlimit:4;stroke-dasharray:none" '
                        svg += 'freecad:basepoint1="' + str(p1.x) + ' ' + str(
                            p1.y) + '" '
                        svg += 'freecad:basepoint2="' + str(p4.x) + ' ' + str(
                            p4.y) + '" '
                        svg += 'freecad:dimpoint="' + str(p2.x) + ' ' + str(
                            p2.y) + '"'
                        svg += '/>\n'

                        # drawing dimension and extension lines overshoots
                        if hasattr(obj.ViewObject, "DimOvershoot"
                                   ) and obj.ViewObject.DimOvershoot.Value:
                            shootsize = obj.ViewObject.DimOvershoot.Value / pointratio
                            svg += getOvershoot(p2, shootsize, stroke,
                                                linewidth, angle)
                            svg += getOvershoot(p3, shootsize, stroke,
                                                linewidth, angle + math.pi)
                        if hasattr(obj.ViewObject, "ExtOvershoot"
                                   ) and obj.ViewObject.ExtOvershoot.Value:
                            shootsize = obj.ViewObject.ExtOvershoot.Value / pointratio
                            shootangle = -DraftVecUtils.angle(p1.sub(p2))
                            svg += getOvershoot(p2, shootsize, stroke,
                                                linewidth, shootangle)
                            svg += getOvershoot(p3, shootsize, stroke,
                                                linewidth, shootangle)

                        # drawing arrows
                        if hasattr(obj.ViewObject, "ArrowType"):
                            arrowsize = obj.ViewObject.ArrowSize.Value / pointratio
                            if hasattr(obj.ViewObject, "FlipArrows"):
                                if obj.ViewObject.FlipArrows:
                                    angle = angle + math.pi
                            svg += getArrow(obj.ViewObject.ArrowType, p2,
                                            arrowsize, stroke, linewidth,
                                            angle)
                            svg += getArrow(obj.ViewObject.ArrowType, p3,
                                            arrowsize, stroke, linewidth,
                                            angle + math.pi)

                    # drawing text
                    svg += getText(stroke, fontsize, obj.ViewObject.FontName,
                                   tangle, tbase, prx.string)

    elif getType(obj) == "AngularDimension":
        if gui:
            if not obj.ViewObject:
                print(
                    "export of dimensions to SVG is only available in GUI mode"
                )
            elif obj.ViewObject.Proxy:
                if hasattr(obj.ViewObject.Proxy, "circle"):
                    prx = obj.ViewObject.Proxy

                    # drawing arc
                    fill = "none"
                    if obj.ViewObject.DisplayMode == "2D":
                        svg += getPath([prx.circle])
                    else:
                        if hasattr(prx, "circle1"):
                            svg += getPath([prx.circle1])
                            svg += getPath([prx.circle2])
                        else:
                            svg += getPath([prx.circle])

                    # drawing arrows
                    if hasattr(obj.ViewObject, "ArrowType"):
                        p2 = getProj(prx.p2, plane)
                        p3 = getProj(prx.p3, plane)
                        arrowsize = obj.ViewObject.ArrowSize.Value / pointratio
                        arrowlength = 4 * obj.ViewObject.ArrowSize.Value
                        u1 = getProj(
                            (prx.circle.valueAt(prx.circle.FirstParameter +
                                                arrowlength)
                             ).sub(
                                 prx.circle.valueAt(
                                     prx.circle.FirstParameter)), plane)
                        u2 = getProj(
                            (prx.circle.valueAt(prx.circle.LastParameter -
                                                arrowlength)
                             ).sub(prx.circle.valueAt(
                                 prx.circle.LastParameter)), plane)
                        angle1 = -DraftVecUtils.angle(u1)
                        angle2 = -DraftVecUtils.angle(u2)
                        if hasattr(obj.ViewObject, "FlipArrows"):
                            if obj.ViewObject.FlipArrows:
                                angle1 = angle1 + math.pi
                                angle2 = angle2 + math.pi
                        svg += getArrow(obj.ViewObject.ArrowType, p2,
                                        arrowsize, stroke, linewidth, angle1)
                        svg += getArrow(obj.ViewObject.ArrowType, p3,
                                        arrowsize, stroke, linewidth, angle2)

                    # drawing text
                    if obj.ViewObject.DisplayMode == "2D":
                        t = prx.circle.tangentAt(prx.circle.FirstParameter +
                                                 (prx.circle.LastParameter -
                                                  prx.circle.FirstParameter) /
                                                 2.0)
                        t = getProj(t, plane)
                        tangle = DraftVecUtils.angle(t)
                        if (tangle <= -math.pi / 2) or (tangle > math.pi / 2):
                            tangle = tangle + math.pi
                        tbase = getProj(
                            prx.circle.valueAt(prx.circle.FirstParameter +
                                               (prx.circle.LastParameter -
                                                prx.circle.FirstParameter) /
                                               2.0), plane)
                        tbase = tbase.add(
                            DraftVecUtils.rotate(Vector(0, 2.0 / scale, 0),
                                                 tangle))
                        #print(tbase)
                    else:
                        tangle = 0
                        tbase = getProj(prx.tbase, plane)
                    svg += getText(stroke, fontsize, obj.ViewObject.FontName,
                                   tangle, tbase, prx.string)

    elif getType(obj) == "Label":
        if getattr(obj.ViewObject, "Line",
                   True):  # some Labels may have no Line property

            def format_point(coords, action='L'):
                return "{action}{x},{y}".format(x=coords.x,
                                                y=coords.y,
                                                action=action)

            # Draw multisegment line
            proj_points = list(map(lambda x: getProj(x, plane), obj.Points))
            path_dir_list = [format_point(proj_points[0], action='M')]
            path_dir_list += map(format_point, proj_points[1:])
            path_dir_str = " ".join(path_dir_list)
            svg_path = '<path fill="none" stroke="{stroke}" stroke-width="{linewidth}" d="{directions}"/>'.format(
                stroke=stroke, linewidth=linewidth, directions=path_dir_str)
            svg += svg_path

            # Draw arrow.
            # We are different here from 3D view
            # if Line is set to 'off', no arrow is drawn
            if hasattr(obj.ViewObject, "ArrowType") and len(obj.Points) >= 2:
                last_segment = FreeCAD.Vector(obj.Points[-1] - obj.Points[-2])
                angle = -DraftVecUtils.angle(getProj(last_segment,
                                                     plane)) + math.pi
                svg += getArrow(arrowtype=obj.ViewObject.ArrowType,
                                point=proj_points[-1],
                                arrowsize=obj.ViewObject.ArrowSize.Value /
                                pointratio,
                                color=stroke,
                                linewidth=linewidth,
                                angle=angle)

        # print text
        if gui:
            if not obj.ViewObject:
                print("export of texts to SVG is only available in GUI mode")
            else:
                fontname = obj.ViewObject.TextFont
                position = getProj(obj.Placement.Base, plane)
                rotation = obj.Placement.Rotation
                justification = obj.ViewObject.TextAlignment
                text = obj.Text
                svg += getText(stroke, fontsize, fontname, rotation, position,
                               text, linespacing, justification)

    elif getType(obj) in ["Annotation", "DraftText"]:
        "returns an svg representation of a document annotation"
        if gui:
            if not obj.ViewObject:
                print("export of texts to SVG is only available in GUI mode")
            else:
                n = obj.ViewObject.FontName
                if getType(obj) == "Annotation":
                    p = getProj(obj.Position, plane)
                    r = obj.ViewObject.Rotation.getValueAs("rad")
                    t = obj.LabelText
                else:  # DraftText
                    p = getProj(obj.Placement.Base, plane)
                    r = obj.Placement.Rotation
                    t = obj.Text
                j = obj.ViewObject.Justification
                svg += getText(stroke, fontsize, n, r, p, t, linespacing, j)

    elif getType(obj) == "Axis":
        "returns the SVG representation of an Arch Axis system"
        if gui:
            if not obj.ViewObject:
                print("export of axes to SVG is only available in GUI mode")
            else:
                vobj = obj.ViewObject
                lorig = lstyle
                fill = 'none'
                rad = vobj.BubbleSize.Value / 2
                n = 0
                for e in obj.Shape.Edges:
                    lstyle = lorig
                    svg += getPath([e])
                    lstyle = "none"
                    pos = ["Start"]
                    if hasattr(vobj, "BubblePosition"):
                        if vobj.BubblePosition == "Both":
                            pos = ["Start", "End"]
                        else:
                            pos = [vobj.BubblePosition]
                    for p in pos:
                        if p == "Start":
                            p1 = e.Vertexes[0].Point
                            p2 = e.Vertexes[1].Point
                        else:
                            p1 = e.Vertexes[1].Point
                            p2 = e.Vertexes[0].Point
                        dv = p2.sub(p1)
                        dv.normalize()
                        center = p2.add(dv.scale(rad, rad, rad))
                        svg += getCircle(Part.makeCircle(rad, center))
                        if hasattr(vobj.Proxy, "bubbletexts"):
                            if len(vobj.Proxy.bubbletexts) >= n:
                                svg += '<text fill="' + stroke + '" '
                                svg += 'font-size="' + str(rad) + '" '
                                svg += 'style="text-anchor:middle;'
                                svg += 'text-align:center;'
                                svg += 'font-family: sans;" '
                                svg += 'transform="translate(' + str(
                                    center.x +
                                    rad / 4.0) + ',' + str(center.y -
                                                           rad / 3.0) + ') '
                                svg += 'scale(1,-1)"> '
                                svg += '<tspan>' + obj.ViewObject.Proxy.bubbletexts[
                                    n].string.getValues()[0] + '</tspan>\n'
                                svg += '</text>\n'
                                n += 1
                lstyle = lorig

    elif getType(obj) == "Pipe":
        fill = stroke
        if obj.Base and obj.Diameter:
            svg += getPath(obj.Base.Shape.Edges)
        for f in obj.Shape.Faces:
            if len(f.Edges) == 1:
                if isinstance(f.Edges[0].Curve, Part.Circle):
                    svg += getCircle(f.Edges[0])

    elif getType(obj) == "Rebar":
        fill = "none"
        if obj.Proxy:
            if not hasattr(obj.Proxy, "wires"):
                obj.Proxy.execute(obj)
            if hasattr(obj.Proxy, "wires"):
                svg += getPath(wires=obj.Proxy.wires)

    elif getType(obj) == "PipeConnector":
        pass

    elif getType(obj) == "Space":
        "returns an SVG fragment for the text of a space"
        if gui:
            if not obj.ViewObject:
                print("export of spaces to SVG is only available in GUI mode")
            else:
                if fillSpaces:
                    if hasattr(obj, "Proxy"):
                        if not hasattr(obj.Proxy, "face"):
                            obj.Proxy.getArea(obj, notouch=True)
                        if hasattr(obj.Proxy, "face"):
                            # setting fill
                            if gui:
                                fill = getrgb(obj.ViewObject.ShapeColor,
                                              testbw=False)
                                fill_opacity = 1 - (
                                    obj.ViewObject.Transparency / 100.0)
                            else:
                                fill = "#888888"
                            svg += getPath(wires=[obj.Proxy.face.OuterWire])
                c = getrgb(obj.ViewObject.TextColor)
                n = obj.ViewObject.FontName
                a = 0
                if rotation != 0:
                    a = math.radians(rotation)
                t1 = obj.ViewObject.Proxy.text1.string.getValues()
                t2 = obj.ViewObject.Proxy.text2.string.getValues()
                scale = obj.ViewObject.FirstLine.Value / obj.ViewObject.FontSize.Value
                f1 = fontsize * scale
                p2 = obj.Placement.multVec(
                    FreeCAD.Vector(obj.ViewObject.Proxy.coords.translation.
                                   getValue().getValue()))
                lspc = FreeCAD.Vector(obj.ViewObject.Proxy.header.translation.
                                      getValue().getValue())
                p1 = p2.add(lspc)
                j = obj.ViewObject.TextAlign
                t3 = getText(c,
                             f1,
                             n,
                             a,
                             getProj(p1, plane),
                             t1,
                             linespacing,
                             j,
                             flip=True)
                svg += t3
                if t2:
                    ofs = FreeCAD.Vector(0, -lspc.Length, 0)
                    if a:
                        ofs = FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1),
                                               -rotation).multVec(ofs)
                    t4 = getText(c,
                                 fontsize,
                                 n,
                                 a,
                                 getProj(p1, plane).add(ofs),
                                 t2,
                                 linespacing,
                                 j,
                                 flip=True)
                    svg += t4

    elif obj.isDerivedFrom('Part::Feature'):
        if obj.Shape.isNull():
            return ''
        # setting fill
        if obj.Shape.Faces:
            if gui:
                try:
                    m = obj.ViewObject.DisplayMode
                except AttributeError:
                    m = None
                if (m != "Wireframe"):
                    if fillstyle == "shape color":
                        fill = getrgb(obj.ViewObject.ShapeColor, testbw=False)
                        fill_opacity = 1 - (obj.ViewObject.Transparency /
                                            100.0)
                    else:
                        fill = 'url(#' + fillstyle + ')'
                        svg += getPattern(fillstyle)
                else:
                    fill = "none"
            else:
                fill = "#888888"
        else:
            fill = 'none'

        if len(obj.Shape.Vertexes) > 1:
            wiredEdges = []
            if obj.Shape.Faces:
                for i, f in enumerate(obj.Shape.Faces):
                    # place outer wire first
                    wires = [f.OuterWire]
                    wires.extend([
                        w for w in f.Wires
                        if w.hashCode() != f.OuterWire.hashCode()
                    ])
                    svg += getPath(wires=f.Wires,pathname='%s_f%04d' % \
                            (obj.Name,i))
                    wiredEdges.extend(f.Edges)
            else:
                for i, w in enumerate(obj.Shape.Wires):
                    svg += getPath(w.Edges,pathname='%s_w%04d' % \
                            (obj.Name,i))
                    wiredEdges.extend(w.Edges)
            if len(wiredEdges) != len(obj.Shape.Edges):
                for i, e in enumerate(obj.Shape.Edges):
                    if (DraftGeomUtils.findEdge(e, wiredEdges) is None):
                        svg += getPath([e],pathname='%s_nwe%04d' % \
                                (obj.Name,i))
        else:
            # closed circle or spline
            if obj.Shape.Edges:
                if isinstance(obj.Shape.Edges[0].Curve, Part.Circle):
                    svg = getCircle(obj.Shape.Edges[0])
                else:
                    svg = getPath(obj.Shape.Edges)
        if FreeCAD.GuiUp:
            if hasattr(obj.ViewObject, "EndArrow") and hasattr(
                    obj.ViewObject,
                    "ArrowType") and (len(obj.Shape.Vertexes) > 1):
                if obj.ViewObject.EndArrow:
                    p1 = getProj(obj.Shape.Vertexes[-1].Point, plane)
                    p2 = getProj(obj.Shape.Vertexes[-2].Point, plane)
                    angle = -DraftVecUtils.angle(p2.sub(p1))
                    arrowsize = obj.ViewObject.ArrowSize.Value / pointratio
                    svg += getArrow(obj.ViewObject.ArrowType, p1, arrowsize,
                                    stroke, linewidth, angle)

    # techdraw expects bottom-to-top coordinates
    if techdraw:
        svg = '<g transform ="scale(1,-1)">\n    ' + svg + '</g>\n'
    return svg
コード例 #21
0
ファイル: gui_mirror.py プロジェクト: yuchuangu85/FreeCAD
    def action(self, arg):
        """Handle the 3D scene events.

        This is installed as an EventCallback in the Inventor view.

        Parameters
        ----------
        arg: dict
            Dictionary with strings that indicates the type of event received
            from the 3D view.
        """
        if arg["Type"] == "SoKeyboardEvent":
            if arg["Key"] == "ESCAPE":
                self.finish()
        elif arg["Type"] == "SoLocation2Event":  # mouse movement detection
            (self.point, ctrlPoint, info) = gui_tool_utils.getPoint(self, arg)
            if len(self.node) > 0:
                last = self.node[-1]
                if self.ghost:
                    if self.point != last:
                        # TODO: the following doesn't work at the moment
                        mu = self.point.sub(last).normalize()
                        # This part used to test for the GUI to obtain
                        # the camera view but this is unnecessary
                        # as this command is always launched in the GUI.
                        _view = Gui.ActiveDocument.ActiveView
                        mv = _view.getViewDirection().negative()
                        mw = mv.cross(mu)
                        _plane = WorkingPlane.plane(u=mu, v=mv, w=mw, pos=last)
                        tm = _plane.getPlacement().toMatrix()
                        m = self.ghost.getMatrix()
                        m = m.multiply(tm.inverse())
                        m.scale(App.Vector(1, 1, -1))
                        m = m.multiply(tm)
                        m.scale(App.Vector(-1, 1, 1))
                        self.ghost.setMatrix(m)
            if self.extendedCopy:
                if not gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT):
                    self.finish()
            gui_tool_utils.redraw3DView()
        elif arg["Type"] == "SoMouseButtonEvent":
            if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
                if self.point:
                    self.ui.redraw()
                    if (self.node == []):
                        self.node.append(self.point)
                        self.ui.isRelative.show()
                        if self.ghost:
                            self.ghost.on()
                        _msg(
                            translate("draft",
                                      "Pick end point of mirror line"))
                        if self.planetrack:
                            self.planetrack.set(self.point)
                    else:
                        last = self.node[0]
                        if (self.ui.isCopy.isChecked()
                                or gui_tool_utils.hasMod(
                                    arg, gui_tool_utils.MODALT)):
                            self.mirror(last, self.point, True)
                        else:
                            self.mirror(last, self.point)
                        if gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT):
                            self.extendedCopy = True
                        else:
                            self.finish(cont=True)
コード例 #22
0
    def renderClassicSVG(self, objs, direction, base=None):
        """returns an svg fragment from a SectionPlane object,
        a direction vector and optionally a base point"""
        def intersection(p1, p2, p3, p4):
            "returns the intersection of line (p1,p2) with plane (p3,p4)"
            # http://paulbourke.net/geometry/planeline/
            dn = p4.dot(p2.sub(p1))
            if dn != 0:
                u = (p4.dot(p3.sub(p1))) / dn
                p = p1.add((p2.sub(p1)).scale(u, u, u))
                return p
            else:
                # line is parallel to normal
                vp = fcvec.project(p3.sub(p1), p2.sub(p1))
                l = vp.Length
                if vp.getAngle(p2.sub(p1)) > 1:
                    l = -l
                return fcvec.scaleTo(p2.sub(p1), l)

        def getFirstIndex(list1, list2):
            "returns the first index from list2 where there is an item of list1"
            for i1 in range(len(list1)):
                for i2 in range(len(list2)):
                    if list1[i1].hashCode() == list2[i2].hashCode():
                        return i2
            return None

        def getLastIndex(list1, list2):
            "returns the last index from list2 where there is an item of list1"
            i = None
            for i1 in range(len(list1)):
                for i2 in range(len(list2)):
                    if list1[i1].hashCode() == list2[i2].hashCode():
                        i = i2
            return i

        def findPrevious(base, dir, faces):
            "returns the highest index in faces that is crossed by the given line"
            for i in range(len(faces) - 1, -1, -1):
                print "p1:", base, " p2: ", base.add(dir)
                obb = faces[i].BoundBox
                print "bo: ", obb
                op = intersection(base, base.add(dir), faces[i].CenterOfMass,
                                  faces[i].normalAt(0, 0))
                print "int:", op
                if obb.isInside(op):
                    dv = op.sub(base)
                    if dv.getAngle(dir) < math.pi / 2:
                        return i
            return None

        def findNext(base, dir, faces):
            "returns the lowest index in faces that is crossed by the given line"
            for i in range(len(faces)):
                obb = faces[i].BoundBox
                op = intersection(base, base.add(dir), faces[i].CenterOfMass,
                                  faces[i].normalAt(0, 0))
                if obb.isInside(op):
                    dv = op.sub(base)
                    if dv.getAngle(dir) > math.pi / 2:
                        return i
            return None

        print "getting representation at ", direction, " =======================================>"

        # using Draft WorkingPlane
        plane = None
        plane = WorkingPlane.plane()
        if direction != Vector(0, 0, 0):
            plane.alignToPointAndAxis(Vector(0, 0, 0), fcvec.neg(direction), 0)
        else:
            direction = Vector(0, 0, -1)
        print "plane:", plane

        sortedFaces = []

        if not base:
            # getting the base point = first point from the bounding box
            bb = FreeCAD.BoundBox()
            for o in objs:
                bb.add(o.Shape.BoundBox)
            rad = bb.DiagonalLength / 2
            rv = bb.Center.add(direction)
            rv = fcvec.scaleTo(rv, rad)
            rv = fcvec.neg(rv)
            base = bb.Center.add(rv)

        print "base:", base

        # getting faces
        unsortedFaces = []
        notFoundFaces = []
        for o in objs:
            unsortedFaces.append(o.Name)
            unsortedFaces.extend(o.Shape.Faces[:])
        print "analyzing ", len(unsortedFaces), " faces"

        for face in unsortedFaces:

            if isinstance(face, str):
                print "OBJECT ", face, " =======================================>"
                continue

            print "testing face ", unsortedFaces.index(face)

            # testing if normal points outwards
            normal = face.normalAt(0, 0)
            if normal.getAngle(direction) <= math.pi / 2:
                print "normal pointing outwards"
                continue

            fprev = 0
            fnext = len(sortedFaces)
            notFound = True

            print "checking ", len(face.Vertexes), " verts"

            for v in face.Vertexes:
                vprev = findPrevious(v.Point, direction, sortedFaces)
                vnext = findNext(v.Point, direction, sortedFaces)
                print "temp indexes:", vprev, vnext
                if (vprev != None):
                    notfound = False
                    if (vprev > fprev):
                        fprev = vprev
                if (vnext != None):
                    notfound = False
                    if (vnext < fnext):
                        fnext = vnext

            print "fprev:", fprev
            print "fnext:", fnext
            print "notFound", notFound

            if fnext < fprev:
                raise "Error, impossible index"
            elif fnext == fprev:
                sortedFaces.insert(fnext, face)
            else:
                sortedFaces.insert(fnext, face)

            print len(sortedFaces), " sorted faces:", sortedFaces

        # building SVG representation in correct order
        svg = ''
        for f in sortedFaces:
            svg += self.getPath(f, plane)

        return svg
コード例 #23
0
ファイル: dxf.py プロジェクト: vishalbelsare/FreeCAD
def get_dxf(obj, direction=None):
    """Return a DXF entity from the given object.

    If direction is given, the object is projected in 2D.
    """
    plane = None
    result = ""
    if (obj.isDerivedFrom("Drawing::View")
            or obj.isDerivedFrom("TechDraw::DrawView")):
        if obj.Source.isDerivedFrom("App::DocumentObjectGroup"):
            for o in obj.Source.Group:
                result += get_dxf(o, obj.Direction)
        else:
            result += get_dxf(obj.Source, obj.Direction)
        return result

    if direction and isinstance(direction, App.Vector):
        if direction != App.Vector(0, 0, 0):
            plane = WorkingPlane.Plane()
            plane.alignToPointAndAxis(App.Vector(0, 0, 0), direction)

    if utils.get_type(obj) in ("Dimension", "LinearDimension"):
        p1 = _get_proj(obj.Start, plane=plane)
        p2 = _get_proj(obj.End, plane=plane)
        p3 = _get_proj(obj.Dimline, plane=plane)
        result += "0\nDIMENSION\n8\n0\n62\n0\n3\nStandard\n70\n1\n"
        result += "10\n" + str(p3.x) + "\n20\n" + str(p3.y) + "\n30\n" + str(
            p3.z) + "\n"
        result += "13\n" + str(p1.x) + "\n23\n" + str(p1.y) + "\n33\n" + str(
            p1.z) + "\n"
        result += "14\n" + str(p2.x) + "\n24\n" + str(p2.y) + "\n34\n" + str(
            p2.z) + "\n"

    elif utils.get_type(obj) == "Annotation":
        # Only for App::Annotation
        p = _get_proj(obj.Position, plane=plane)
        count = 0
        for t in obj.LabeLtext:
            result += "0\nTEXT\n8\n0\n62\n0\n"
            result += "10\n"
            result += str(p.x) + "\n20\n"
            result += str(p.y + count) + "\n30\n"
            result += str(p.z) + "\n"
            result += "40\n1\n"
            result += "1\n" + str(t) + "\n"
            result += "7\nSTANDARD\n"
            count += 1

    elif hasattr(obj, 'Shape'):
        # TODO do this the Draft way, for ex. using polylines and rectangles
        if not direction:
            direction = App.Vector(0, 0, -1)

        if DraftVecUtils.isNull(direction):
            direction = App.Vector(0, 0, -1)

        try:
            d = Drawing.projectToDXF(obj.Shape, direction)
        except Exception:
            # TODO: trap only specific exception.
            # Impossible to generate DXF from Shape? Which exception is throw?
            _wrn("get_dxf: "
                 "unable to project '{}' to {}".format(obj.Label, direction))
        else:
            result += d
    else:
        _wrn("get_dxf: unsupported object, '{}'".format(obj.Label))

    return result
コード例 #24
0
    def onChanged(self, obj, prop):
        if prop in ["Source", "RenderingMode", "ShowCut"]:
            import Part, DraftGeomUtils
            if hasattr(obj, "Source"):
                if obj.Source:
                    if obj.Source.Objects:
                        objs = Draft.getGroupContents(obj.Source.Objects,
                                                      walls=True,
                                                      addgroups=True)
                        objs = Draft.removeHidden(objs)
                        # separate spaces
                        self.spaces = []
                        os = []
                        for o in objs:
                            if Draft.getType(o) == "Space":
                                self.spaces.append(o)
                            else:
                                os.append(o)
                        objs = os
                        self.svg = ''
                        fillpattern = '<pattern id="sectionfill" patternUnits="userSpaceOnUse" patternTransform="matrix(5,0,0,5,0,0)"'
                        fillpattern += ' x="0" y="0" width="10" height="10">'
                        fillpattern += '<g>'
                        fillpattern += '<rect width="10" height="10" style="stroke:none; fill:#ffffff" /><path style="stroke:#000000; stroke-width:1" d="M0,0 l10,10" /></g></pattern>'

                        # generating SVG
                        if obj.RenderingMode == "Solid":
                            # render using the Arch Vector Renderer
                            import ArchVRM, WorkingPlane
                            wp = WorkingPlane.plane()
                            wp.setFromPlacement(obj.Source.Placement)
                            #wp.inverse()
                            render = ArchVRM.Renderer()
                            render.setWorkingPlane(wp)
                            render.addObjects(objs)
                            if hasattr(obj, "ShowCut"):
                                render.cut(obj.Source.Shape, obj.ShowCut)
                            else:
                                render.cut(obj.Source.Shape)
                            self.svg += '<g transform="scale(1,-1)">\n'
                            self.svg += render.getViewSVG(
                                linewidth="LWPlaceholder")
                            self.svg += fillpattern
                            self.svg += render.getSectionSVG(
                                linewidth="SWPlaceholder",
                                fillpattern="sectionfill")
                            if hasattr(obj, "ShowCut"):
                                if obj.ShowCut:
                                    self.svg += render.getHiddenSVG(
                                        linewidth="LWPlaceholder")
                            self.svg += '</g>\n'
                            # print render.info()

                        else:
                            # render using the Drawing module
                            import Drawing, Part
                            shapes = []
                            hshapes = []
                            sshapes = []
                            p = FreeCAD.Placement(obj.Source.Placement)
                            self.direction = p.Rotation.multVec(
                                FreeCAD.Vector(0, 0, 1))
                            for o in objs:
                                if o.isDerivedFrom("Part::Feature"):
                                    if o.Shape.isNull():
                                        pass
                                        #FreeCAD.Console.PrintWarning(translate("Arch","Skipping empty object: ")+o.Name)
                                    elif o.Shape.isValid():
                                        if hasattr(obj.Source, "OnlySolids"):
                                            if obj.Source.OnlySolids:
                                                shapes.extend(o.Shape.Solids)
                                            else:
                                                shapes.append(o.Shape)
                                        else:
                                            shapes.extend(o.Shape.Solids)
                                    else:
                                        FreeCAD.Console.PrintWarning(
                                            translate(
                                                "Arch",
                                                "Skipping invalid object: ") +
                                            o.Name)
                            cutface, cutvolume, invcutvolume = ArchCommands.getCutVolume(
                                obj.Source.Shape.copy(), shapes)
                            if cutvolume:
                                nsh = []
                                for sh in shapes:
                                    for sol in sh.Solids:
                                        if sol.Volume < 0:
                                            sol.reverse()
                                        c = sol.cut(cutvolume)
                                        s = sol.section(cutface)
                                        try:
                                            wires = DraftGeomUtils.findWires(
                                                s.Edges)
                                            for w in wires:
                                                f = Part.Face(w)
                                                sshapes.append(f)
                                            #s = Part.Wire(s.Edges)
                                            #s = Part.Face(s)
                                        except Part.OCCError:
                                            #print "ArchDrawingView: unable to get a face"
                                            sshapes.append(s)
                                        nsh.extend(c.Solids)
                                        #sshapes.append(s)
                                        if hasattr(obj, "ShowCut"):
                                            if obj.ShowCut:
                                                c = sol.cut(invcutvolume)
                                                hshapes.append(c)
                                shapes = nsh
                            if shapes:
                                self.shapes = shapes
                                self.baseshape = Part.makeCompound(shapes)
                                svgf = Drawing.projectToSVG(
                                    self.baseshape, self.direction)
                                if svgf:
                                    svgf = svgf.replace(
                                        'stroke-width="0.35"',
                                        'stroke-width="LWPlaceholder"')
                                    svgf = svgf.replace(
                                        'stroke-width="1"',
                                        'stroke-width="LWPlaceholder"')
                                    svgf = svgf.replace(
                                        'stroke-width:0.01',
                                        'stroke-width:LWPlaceholder')
                                    self.svg += svgf
                            if hshapes:
                                hshapes = Part.makeCompound(hshapes)
                                self.hiddenshape = hshapes
                                svgh = Drawing.projectToSVG(
                                    hshapes, self.direction)
                                if svgh:
                                    svgh = svgh.replace(
                                        'stroke-width="0.35"',
                                        'stroke-width="LWPlaceholder"')
                                    svgh = svgh.replace(
                                        'stroke-width="1"',
                                        'stroke-width="LWPlaceholder"')
                                    svgh = svgh.replace(
                                        'stroke-width:0.01',
                                        'stroke-width:LWPlaceholder')
                                    svgh = svgh.replace(
                                        'fill="none"',
                                        'fill="none"\nstroke-dasharray="DAPlaceholder"'
                                    )
                                    self.svg += svgh
                            if sshapes:
                                svgs = ""
                                if hasattr(obj, "ShowFill"):
                                    if obj.ShowFill:
                                        svgs += fillpattern
                                        svgs += '<g transform="rotate(180)">\n'
                                        for s in sshapes:
                                            if s.Edges:
                                                f = Draft.getSVG(
                                                    s,
                                                    direction=self.direction.
                                                    negative(),
                                                    linewidth=0,
                                                    fillstyle="sectionfill",
                                                    color=(0, 0, 0))
                                                svgs += f
                                        svgs += "</g>\n"
                                sshapes = Part.makeCompound(sshapes)
                                self.sectionshape = sshapes
                                svgs += Drawing.projectToSVG(
                                    sshapes, self.direction)
                                if svgs:
                                    svgs = svgs.replace(
                                        'stroke-width="0.35"',
                                        'stroke-width="SWPlaceholder"')
                                    svgs = svgs.replace(
                                        'stroke-width="1"',
                                        'stroke-width="SWPlaceholder"')
                                    svgs = svgs.replace(
                                        'stroke-width:0.01',
                                        'stroke-width:SWPlaceholder')
                                    svgs = svgs.replace(
                                        'stroke-width="0.35 px"',
                                        'stroke-width="SWPlaceholder"')
                                    svgs = svgs.replace(
                                        'stroke-width:0.35',
                                        'stroke-width:SWPlaceholder')
                                    self.svg += svgs
コード例 #25
0
import draftguitools.gui_trackers as trackers

# The module is used to prevent complaints from code checkers (flake8)
True if Draft_rc.__name__ else False
True if DraftGui.__name__ else False

__title__ = "FreeCAD Draft Workbench GUI Tools"
__author__ = ("Yorik van Havre, Werner Mayer, Martin Burbaum, Ken Cline, "
              "Dmitry Chigrin")
__url__ = "https://www.freecadweb.org"

if not hasattr(FreeCADGui, "Snapper"):
    FreeCADGui.Snapper = gui_snapper.Snapper()

if not hasattr(FreeCAD, "DraftWorkingPlane"):
    FreeCAD.DraftWorkingPlane = WorkingPlane.plane()

# ---------------------------------------------------------------------------
# Commands that have been migrated to their own modules
# ---------------------------------------------------------------------------
import draftguitools.gui_edit
import draftguitools.gui_selectplane
import draftguitools.gui_planeproxy
from draftguitools.gui_lineops import FinishLine
from draftguitools.gui_lineops import CloseLine
from draftguitools.gui_lineops import UndoLine
from draftguitools.gui_togglemodes import ToggleConstructionMode
from draftguitools.gui_togglemodes import ToggleContinueMode
from draftguitools.gui_togglemodes import ToggleDisplayMode
from draftguitools.gui_groups import AddToGroup
from draftguitools.gui_groups import SelectGroup
コード例 #26
0
def getSVG(section,
           allOn=False,
           renderMode="Wireframe",
           showHidden=False,
           showFill=False,
           scale=1,
           linewidth=1,
           fontsize=1,
           techdraw=False,
           rotation=0):
    """getSVG(section,[allOn,renderMode,showHidden,showFill,scale,linewidth,fontsize]) : 
    returns an SVG fragment from an Arch section plane. If
    allOn is True, all cut objects are shown, regardless if they are visible or not.
    renderMode can be Wireframe (default) or Solid to use the Arch solid renderer. If
    showHidden is True, the hidden geometry above the section plane is shown in dashed line.
    If showFill is True, the cut areas get filled with a pattern"""

    if not section.Objects:
        return
    import Part, DraftGeomUtils
    p = FreeCAD.Placement(section.Placement)
    direction = p.Rotation.multVec(FreeCAD.Vector(0, 0, 1))
    objs = Draft.getGroupContents(section.Objects, walls=True, addgroups=True)
    if not allOn:
        objs = Draft.removeHidden(objs)
    # separate spaces and Draft objects
    spaces = []
    nonspaces = []
    drafts = []
    windows = []
    cutface = None
    for o in objs:
        if Draft.getType(o) == "Space":
            spaces.append(o)
        elif Draft.getType(o) in ["Dimension", "Annotation"]:
            drafts.append(o)
        elif o.isDerivedFrom("Part::Part2DObject"):
            drafts.append(o)
        else:
            nonspaces.append(o)
        if Draft.getType(o) == "Window":
            windows.append(o)
    objs = nonspaces
    svg = ''
    fillpattern = '<pattern id="sectionfill" patternUnits="userSpaceOnUse" patternTransform="matrix(5,0,0,5,0,0)"'
    fillpattern += ' x="0" y="0" width="10" height="10">'
    fillpattern += '<g>'
    fillpattern += '<rect width="10" height="10" style="stroke:none; fill:#ffffff" /><path style="stroke:#000000; stroke-width:1" d="M0,0 l10,10" /></g></pattern>'
    # generating SVG
    if renderMode in ["Solid", 1]:
        # render using the Arch Vector Renderer
        import ArchVRM, WorkingPlane
        wp = WorkingPlane.plane()
        wp.setFromPlacement(section.Placement)
        #wp.inverse()
        render = ArchVRM.Renderer()
        render.setWorkingPlane(wp)
        render.addObjects(objs)
        if showHidden:
            render.cut(section.Shape, showHidden)
        else:
            render.cut(section.Shape)
        svg += '<g transform="scale(1,-1)">\n'
        svg += render.getViewSVG(linewidth="LWPlaceholder")
        svg += fillpattern
        svg += render.getSectionSVG(linewidth="SWPlaceholder",
                                    fillpattern="sectionfill")
        if showHidden:
            svg += render.getHiddenSVG(linewidth="LWPlaceholder")
        svg += '</g>\n'
        # print render.info()

    else:
        # render using the Drawing module
        import Drawing, Part
        shapes, hshapes, sshapes, cutface, cutvolume, invcutvolume = getCutShapes(
            objs, section, showHidden)
        if shapes:
            baseshape = Part.makeCompound(shapes)
            svgf = Drawing.projectToSVG(baseshape, direction)
            if svgf:
                svgf = svgf.replace('stroke-width="0.35"',
                                    'stroke-width="LWPlaceholder"')
                svgf = svgf.replace('stroke-width="1"',
                                    'stroke-width="LWPlaceholder"')
                svgf = svgf.replace('stroke-width:0.01',
                                    'stroke-width:LWPlaceholder')
                svg += svgf
        if hshapes:
            hshapes = Part.makeCompound(hshapes)
            svgh = Drawing.projectToSVG(hshapes, direction)
            if svgh:
                svgh = svgh.replace('stroke-width="0.35"',
                                    'stroke-width="LWPlaceholder"')
                svgh = svgh.replace('stroke-width="1"',
                                    'stroke-width="LWPlaceholder"')
                svgh = svgh.replace('stroke-width:0.01',
                                    'stroke-width:LWPlaceholder')
                svgh = svgh.replace(
                    'fill="none"',
                    'fill="none"\nstroke-dasharray="DAPlaceholder"')
                svg += svgh
        if sshapes:
            svgs = ""
            if showFill:
                #svgs += fillpattern
                svgs += '<g transform="rotate(180)">\n'
                for s in sshapes:
                    if s.Edges:
                        #f = Draft.getSVG(s,direction=direction.negative(),linewidth=0,fillstyle="sectionfill",color=(0,0,0))
                        # temporarily disabling fill patterns
                        f = Draft.getSVG(s,
                                         direction=direction.negative(),
                                         linewidth=0,
                                         fillstyle="#aaaaaa",
                                         color=(0, 0, 0))
                        svgs += f
                svgs += "</g>\n"
            sshapes = Part.makeCompound(sshapes)
            svgs += Drawing.projectToSVG(sshapes, direction)
            if svgs:
                svgs = svgs.replace('stroke-width="0.35"',
                                    'stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width="1"',
                                    'stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width:0.01',
                                    'stroke-width:SWPlaceholder')
                svgs = svgs.replace('stroke-width="0.35 px"',
                                    'stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width:0.35',
                                    'stroke-width:SWPlaceholder')
                svg += svgs
    scaledlinewidth = linewidth / scale
    st = FreeCAD.ParamGet(
        "User parameter:BaseApp/Preferences/Mod/Arch").GetFloat(
            "CutLineThickness", 2)
    yt = FreeCAD.ParamGet(
        "User parameter:BaseApp/Preferences/Mod/Arch").GetFloat(
            "SymbolLineThickness", 0.6)
    da = FreeCAD.ParamGet(
        "User parameter:BaseApp/Preferences/Mod/Arch").GetString(
            "archHiddenPattern", "30,10")
    da = da.replace(" ", "")
    svg = svg.replace('LWPlaceholder', str(scaledlinewidth) + 'px')
    svg = svg.replace('SWPlaceholder', str(scaledlinewidth * st) + 'px')
    svg = svg.replace('DAPlaceholder', str(da))
    if drafts:
        if not techdraw:
            svg += '<g transform="scale(1,-1)">'
        for d in drafts:
            svg += Draft.getSVG(d,
                                scale=scale,
                                linewidth=linewidth * yt,
                                fontsize=fontsize,
                                direction=direction,
                                techdraw=techdraw,
                                rotation=rotation)
        if not techdraw:
            svg += '</g>'
    # filter out spaces not cut by the section plane
    if cutface and spaces:
        spaces = [
            s for s in spaces if s.Shape.BoundBox.intersect(cutface.BoundBox)
        ]
    if spaces:
        if not techdraw:
            svg += '<g transform="scale(1,-1)">'
        for s in spaces:
            svg += Draft.getSVG(s,
                                scale=scale,
                                linewidth=linewidth * yt,
                                fontsize=fontsize,
                                direction=direction,
                                techdraw=techdraw,
                                rotation=rotation)
        if not techdraw:
            svg += '</g>'
    # add additional edge symbols from windows
    if cutface and windows:
        cutwindows = [
            w.Name for w in windows
            if w.Shape.BoundBox.intersect(cutface.BoundBox)
        ]
    if windows:
        sh = []
        for w in windows:
            if not hasattr(w.Proxy, "sshapes"):
                w.Proxy.execute(w)
            if hasattr(w.Proxy, "sshapes"):
                if w.Proxy.sshapes and (w.Name in cutwindows):
                    c = Part.makeCompound(w.Proxy.sshapes)
                    c.Placement = w.Placement
                    sh.append(c)
            # buggy for now...
            #if hasattr(w.Proxy,"vshapes"):
            #    if w.Proxy.vshapes:
            #        c = Part.makeCompound(w.Proxy.vshapes)
            #        c.Placement = w.Placement
            #        sh.append(c)
        if sh:
            if not techdraw:
                svg += '<g transform="scale(1,-1)">'
            for s in sh:
                svg += Draft.getSVG(s,
                                    scale=scale,
                                    linewidth=linewidth * yt,
                                    fontsize=fontsize,
                                    fillstyle="none",
                                    direction=direction,
                                    techdraw=techdraw,
                                    rotation=rotation)
            if not techdraw:
                svg += '</g>'

    #print "complete node:",svg
    return svg
コード例 #27
0
def getSVG(section,allOn=False,renderMode="Wireframe",showHidden=False,showFill=False,scale=1,linewidth=1,fontsize=1):
    """getSVG(section,[allOn,renderMode,showHidden,showFill,scale,linewidth,fontsize]) : 
    returns an SVG fragment from an Arch section plane. If
    allOn is True, all cut objects are shown, regardless if they are visible or not.
    renderMode can be Wireframe (default) or Solid to use the Arch solid renderer. If
    showHidden is True, the hidden geometry above the section plane is shown in dashed line.
    If showFill is True, the cut areas get filled with a pattern"""

    if not section.Objects:
        return
    import DraftGeomUtils
    p = FreeCAD.Placement(section.Placement)
    direction = p.Rotation.multVec(FreeCAD.Vector(0,0,1))
    objs = Draft.getGroupContents(section.Objects,walls=True,addgroups=True)
    if not allOn:
            objs = Draft.removeHidden(objs)
    # separate spaces
    spaces = []
    nonspaces = []
    for o in objs:
        if Draft.getType(o) == "Space":
            spaces.append(o)
        else:
            nonspaces.append(o)
    objs = nonspaces
    svg = ''
    fillpattern = '<pattern id="sectionfill" patternUnits="userSpaceOnUse" patternTransform="matrix(5,0,0,5,0,0)"'
    fillpattern += ' x="0" y="0" width="10" height="10">'
    fillpattern += '<g>'
    fillpattern += '<rect width="10" height="10" style="stroke:none; fill:#ffffff" /><path style="stroke:#000000; stroke-width:1" d="M0,0 l10,10" /></g></pattern>'

    # generating SVG
    if renderMode == "Solid":
        # render using the Arch Vector Renderer
        import ArchVRM, WorkingPlane
        wp = WorkingPlane.plane()
        wp.setFromPlacement(section.Placement)
        #wp.inverse()
        render = ArchVRM.Renderer()
        render.setWorkingPlane(wp)
        render.addObjects(objs)
        if showHidden:
            render.cut(section.Shape,showHidden)
        else:
            render.cut(section.Shape)
        svg += '<g transform="scale(1,-1)">\n'
        svg += render.getViewSVG(linewidth="LWPlaceholder")
        svg += fillpattern
        svg += render.getSectionSVG(linewidth="SWPlaceholder",fillpattern="sectionfill")
        if showHidden:
            svg += render.getHiddenSVG(linewidth="LWPlaceholder")
        svg += '</g>\n'
        # print render.info()

    else:
        # render using the Drawing module
        import Drawing, Part
        shapes = []
        hshapes = []
        sshapes = []
        for o in objs:
            if o.isDerivedFrom("Part::Feature"):
                if o.Shape.isNull():
                    pass
                elif o.Shape.isValid():
                    if section.OnlySolids:
                        shapes.extend(o.Shape.Solids)
                    else:
                        shapes.append(o.Shape)
                else:
                    print section.Label,": Skipping invalid object:",o.Label
        cutface,cutvolume,invcutvolume = ArchCommands.getCutVolume(section.Shape.copy(),shapes)
        if cutvolume:
            nsh = []
            for sh in shapes:
                for sol in sh.Solids:
                    if sol.Volume < 0:
                        sol.reverse()
                    c = sol.cut(cutvolume)
                    s = sol.section(cutface)
                    try:
                        wires = DraftGeomUtils.findWires(s.Edges)
                        for w in wires:
                            f = Part.Face(w)
                            sshapes.append(f)
                        #s = Part.Wire(s.Edges)
                        #s = Part.Face(s)
                    except Part.OCCError:
                        #print "ArchDrawingView: unable to get a face"
                        sshapes.append(s)
                    nsh.extend(c.Solids)
                    #sshapes.append(s)
                    if showHidden:
                        c = sol.cut(invcutvolume)
                        hshapes.append(c)
            shapes = nsh
        if shapes:
            baseshape = Part.makeCompound(shapes)
            svgf = Drawing.projectToSVG(baseshape,direction)
            if svgf:
                svgf = svgf.replace('stroke-width="0.35"','stroke-width="LWPlaceholder"')
                svgf = svgf.replace('stroke-width="1"','stroke-width="LWPlaceholder"')
                svgf = svgf.replace('stroke-width:0.01','stroke-width:LWPlaceholder')
                svg += svgf
        if hshapes:
            hshapes = Part.makeCompound(hshapes)
            svgh = Drawing.projectToSVG(hshapes,direction)
            if svgh:
                svgh = svgh.replace('stroke-width="0.35"','stroke-width="LWPlaceholder"')
                svgh = svgh.replace('stroke-width="1"','stroke-width="LWPlaceholder"')
                svgh = svgh.replace('stroke-width:0.01','stroke-width:LWPlaceholder')
                svgh = svgh.replace('fill="none"','fill="none"\nstroke-dasharray="DAPlaceholder"')
                svg += svgh
        if sshapes:
            svgs = ""
            if showFill:
                svgs += fillpattern
                svgs += '<g transform="rotate(180)">\n'
                for s in sshapes:
                    if s.Edges:
                        f = Draft.getSVG(s,direction=direction.negative(),linewidth=0,fillstyle="sectionfill",color=(0,0,0))
                        svgs += f
                svgs += "</g>\n"
            sshapes = Part.makeCompound(sshapes)
            svgs += Drawing.projectToSVG(sshapes,direction)
            if svgs:
                svgs = svgs.replace('stroke-width="0.35"','stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width="1"','stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width:0.01','stroke-width:SWPlaceholder')
                svgs = svgs.replace('stroke-width="0.35 px"','stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width:0.35','stroke-width:SWPlaceholder')
                svg += svgs

    linewidth = linewidth/scale
    st = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetFloat("CutLineThickness",2)
    da = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetString("archHiddenPattern","30,10")
    da = da.replace(" ","")
    svg = svg.replace('LWPlaceholder', str(linewidth) + 'px')
    svg = svg.replace('SWPlaceholder', str(linewidth*st) + 'px')
    svg = svg.replace('DAPlaceholder', str(da))
    if spaces and round(direction.getAngle(FreeCAD.Vector(0,0,1)),Draft.precision()) in [0,round(math.pi,Draft.precision())]:
        svg += '<g transform="scale(1,-1)">'
        for s in spaces:
            svg += Draft.getSVG(s,scale=scale,fontsize=fontsize,direction=direction)
        svg += '</g>'
    # print "complete node:",svg
    return svg
コード例 #28
0
def getSVG(section,
           allOn=False,
           renderMode="Wireframe",
           showHidden=False,
           showFill=False,
           scale=1,
           linewidth=1,
           fontsize=1):
    """getSVG(section,[allOn,renderMode,showHidden,showFill,scale,linewidth,fontsize]) : 
    returns an SVG fragment from an Arch section plane. If
    allOn is True, all cut objects are shown, regardless if they are visible or not.
    renderMode can be Wireframe (default) or Solid to use the Arch solid renderer. If
    showHidden is True, the hidden geometry above the section plane is shown in dashed line.
    If showFill is True, the cut areas get filled with a pattern"""

    if not section.Objects:
        return
    import DraftGeomUtils
    p = FreeCAD.Placement(section.Placement)
    direction = p.Rotation.multVec(FreeCAD.Vector(0, 0, 1))
    objs = Draft.getGroupContents(section.Objects, walls=True, addgroups=True)
    if not allOn:
        objs = Draft.removeHidden(objs)
    # separate spaces
    spaces = []
    nonspaces = []
    for o in objs:
        if Draft.getType(o) == "Space":
            spaces.append(o)
        else:
            nonspaces.append(o)
    objs = nonspaces
    svg = ''
    fillpattern = '<pattern id="sectionfill" patternUnits="userSpaceOnUse" patternTransform="matrix(5,0,0,5,0,0)"'
    fillpattern += ' x="0" y="0" width="10" height="10">'
    fillpattern += '<g>'
    fillpattern += '<rect width="10" height="10" style="stroke:none; fill:#ffffff" /><path style="stroke:#000000; stroke-width:1" d="M0,0 l10,10" /></g></pattern>'

    # generating SVG
    if renderMode == "Solid":
        # render using the Arch Vector Renderer
        import ArchVRM, WorkingPlane
        wp = WorkingPlane.plane()
        wp.setFromPlacement(section.Placement)
        #wp.inverse()
        render = ArchVRM.Renderer()
        render.setWorkingPlane(wp)
        render.addObjects(objs)
        if showHidden:
            render.cut(section.Shape, showHidden)
        else:
            render.cut(section.Shape)
        svg += '<g transform="scale(1,-1)">\n'
        svg += render.getViewSVG(linewidth="LWPlaceholder")
        svg += fillpattern
        svg += render.getSectionSVG(linewidth="SWPlaceholder",
                                    fillpattern="sectionfill")
        if showHidden:
            svg += render.getHiddenSVG(linewidth="LWPlaceholder")
        svg += '</g>\n'
        # print render.info()

    else:
        # render using the Drawing module
        import Drawing, Part
        shapes = []
        hshapes = []
        sshapes = []
        for o in objs:
            if o.isDerivedFrom("Part::Feature"):
                if o.Shape.isNull():
                    pass
                elif o.Shape.isValid():
                    if section.OnlySolids:
                        shapes.extend(o.Shape.Solids)
                    else:
                        shapes.append(o.Shape)
                else:
                    print section.Label, ": Skipping invalid object:", o.Label
        cutface, cutvolume, invcutvolume = ArchCommands.getCutVolume(
            section.Shape.copy(), shapes)
        if cutvolume:
            nsh = []
            for sh in shapes:
                for sol in sh.Solids:
                    if sol.Volume < 0:
                        sol.reverse()
                    c = sol.cut(cutvolume)
                    s = sol.section(cutface)
                    try:
                        wires = DraftGeomUtils.findWires(s.Edges)
                        for w in wires:
                            f = Part.Face(w)
                            sshapes.append(f)
                        #s = Part.Wire(s.Edges)
                        #s = Part.Face(s)
                    except Part.OCCError:
                        #print "ArchDrawingView: unable to get a face"
                        sshapes.append(s)
                    nsh.extend(c.Solids)
                    #sshapes.append(s)
                    if showHidden:
                        c = sol.cut(invcutvolume)
                        hshapes.append(c)
            shapes = nsh
        if shapes:
            baseshape = Part.makeCompound(shapes)
            svgf = Drawing.projectToSVG(baseshape, direction)
            if svgf:
                svgf = svgf.replace('stroke-width="0.35"',
                                    'stroke-width="LWPlaceholder"')
                svgf = svgf.replace('stroke-width="1"',
                                    'stroke-width="LWPlaceholder"')
                svgf = svgf.replace('stroke-width:0.01',
                                    'stroke-width:LWPlaceholder')
                svg += svgf
        if hshapes:
            hshapes = Part.makeCompound(hshapes)
            svgh = Drawing.projectToSVG(hshapes, direction)
            if svgh:
                svgh = svgh.replace('stroke-width="0.35"',
                                    'stroke-width="LWPlaceholder"')
                svgh = svgh.replace('stroke-width="1"',
                                    'stroke-width="LWPlaceholder"')
                svgh = svgh.replace('stroke-width:0.01',
                                    'stroke-width:LWPlaceholder')
                svgh = svgh.replace(
                    'fill="none"',
                    'fill="none"\nstroke-dasharray="DAPlaceholder"')
                svg += svgh
        if sshapes:
            svgs = ""
            if showFill:
                svgs += fillpattern
                svgs += '<g transform="rotate(180)">\n'
                for s in sshapes:
                    if s.Edges:
                        f = Draft.getSVG(s,
                                         direction=direction.negative(),
                                         linewidth=0,
                                         fillstyle="sectionfill",
                                         color=(0, 0, 0))
                        svgs += f
                svgs += "</g>\n"
            sshapes = Part.makeCompound(sshapes)
            svgs += Drawing.projectToSVG(sshapes, direction)
            if svgs:
                svgs = svgs.replace('stroke-width="0.35"',
                                    'stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width="1"',
                                    'stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width:0.01',
                                    'stroke-width:SWPlaceholder')
                svgs = svgs.replace('stroke-width="0.35 px"',
                                    'stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width:0.35',
                                    'stroke-width:SWPlaceholder')
                svg += svgs

    linewidth = linewidth / scale
    st = FreeCAD.ParamGet(
        "User parameter:BaseApp/Preferences/Mod/Arch").GetFloat(
            "CutLineThickness", 2)
    da = FreeCAD.ParamGet(
        "User parameter:BaseApp/Preferences/Mod/Arch").GetString(
            "archHiddenPattern", "30,10")
    da = da.replace(" ", "")
    svg = svg.replace('LWPlaceholder', str(linewidth) + 'px')
    svg = svg.replace('SWPlaceholder', str(linewidth * st) + 'px')
    svg = svg.replace('DAPlaceholder', str(da))
    if spaces and round(
            direction.getAngle(FreeCAD.Vector(0, 0, 1)),
            Draft.precision()) in [0, round(math.pi, Draft.precision())]:
        svg += '<g transform="scale(1,-1)">'
        for s in spaces:
            svg += Draft.getSVG(s,
                                scale=scale,
                                fontsize=fontsize,
                                direction=direction)
        svg += '</g>'
    # print "complete node:",svg
    return svg
コード例 #29
0
ファイル: svg.py プロジェクト: zqsgdnq/FreeCAD
def get_svg(obj,
            scale=1,
            linewidth=0.35,
            fontsize=12,
            fillstyle="shape color",
            direction=None,
            linestyle=None,
            color=None,
            linespacing=None,
            techdraw=False,
            rotation=0,
            fillspaces=False,
            override=True):
    """Return a string containing an SVG representation of the object.

    Paramaeters
    -----------
    scale: float, optional
        It defaults to 1.
        It allows scaling line widths down, so they are resolution-independent.

    linewidth: float, optional
        It defaults to 0.35.

    fontsize: float, optional
        It defaults to 12, which is interpreted as `pt` unit (points).
        It is used if the given object contains any text.

    fillstyle: str, optional
        It defaults to 'shape color'.

    direction: Base::Vector3, optional
        It defaults to `None`.
        It is an arbitrary projection vector or a `WorkingPlane.Plane`
        instance.

    linestyle: optional
        It defaults to `None`.

    color: optional
        It defaults to `None`.

    linespacing: float, optional
        It defaults to `None`.

    techdraw: bool, optional
        It defaults to `False`.
        If it is `True`, it sets some options for generating SVG strings
        for displaying inside TechDraw.

    rotation: float, optional
        It defaults to 0.

    fillspaces: bool, optional
        It defaults to `False`.

    override: bool, optional
        It defaults to `True`.
    """
    # If this is a group, recursively call this function to gather
    # all the SVG strings from the contents of the group
    if hasattr(obj, "isDerivedFrom"):
        if (obj.isDerivedFrom("App::DocumentObjectGroup")
                or utils.get_type(obj) == "Layer"):
            svg = ""
            for child in obj.Group:
                svg += get_svg(child, scale, linewidth, fontsize, fillstyle,
                               direction, linestyle, color, linespacing,
                               techdraw, rotation, fillspaces, override)
            return svg

    pathdata = []
    svg = ""
    linewidth = float(linewidth) / scale
    if not override:
        if hasattr(obj, "ViewObject") and hasattr(obj.ViewObject, "LineWidth"):
            if hasattr(obj.ViewObject.LineWidth, "Value"):
                lw = obj.ViewObject.LineWidth.Value
            else:
                lw = obj.ViewObject.LineWidth
            linewidth = lw * linewidth

    fontsize = (float(fontsize) / scale) / 2
    if linespacing:
        linespacing = float(linespacing) / scale
    else:
        linespacing = 0.5

    # print(obj.Label, "line spacing", linespacing, "scale", scale)

    # The number of times the dots are smaller than the arrow size
    pointratio = 0.75
    plane = None

    if direction:
        if isinstance(direction, App.Vector):
            if direction != App.Vector(0, 0, 0):
                plane = WorkingPlane.plane()
                plane.alignToPointAndAxis_SVG(App.Vector(0, 0, 0),
                                              direction.negative().negative(),
                                              0)
        elif isinstance(direction, WorkingPlane.plane):
            plane = direction

    stroke = "#000000"
    if color and override:
        if "#" in color:
            stroke = color
        else:
            stroke = utils.get_rgb(color)
    elif App.GuiUp:
        if hasattr(obj, "ViewObject"):
            if hasattr(obj.ViewObject, "LineColor"):
                stroke = utils.get_rgb(obj.ViewObject.LineColor)
            elif hasattr(obj.ViewObject, "TextColor"):
                stroke = utils.get_rgb(obj.ViewObject.TextColor)

    lstyle = "none"
    if override:
        lstyle = get_line_style(linestyle, scale)
    else:
        if hasattr(obj, "ViewObject") and hasattr(obj.ViewObject, "DrawStyle"):
            lstyle = get_line_style(obj.ViewObject.DrawStyle, scale)

    if not obj:
        pass

    elif isinstance(obj, Part.Shape):
        svg = _svg_shape(svg, obj, plane, fillstyle, pathdata, stroke,
                         linewidth, lstyle)

    elif utils.get_type(obj) in ["Dimension", "LinearDimension"]:
        svg = _svg_dimension(obj, plane, scale, linewidth, fontsize, stroke,
                             pointratio, techdraw, rotation)

    elif utils.get_type(obj) == "AngularDimension":
        if not App.GuiUp:
            _wrn("Export of dimensions to SVG is only available in GUI mode")

        if App.GuiUp:
            if obj.ViewObject.Proxy:
                if hasattr(obj.ViewObject.Proxy, "circle"):
                    prx = obj.ViewObject.Proxy

                    # drawing arc
                    fill = "none"
                    if obj.ViewObject.DisplayMode == "2D":
                        svg += get_path(obj,
                                        plane,
                                        fill,
                                        pathdata,
                                        stroke,
                                        linewidth,
                                        lstyle,
                                        fill_opacity=None,
                                        edges=[prx.circle])
                    else:
                        if hasattr(prx, "circle1"):
                            svg += get_path(obj,
                                            plane,
                                            fill,
                                            pathdata,
                                            stroke,
                                            linewidth,
                                            lstyle,
                                            fill_opacity=None,
                                            edges=[prx.circle1])
                            svg += get_path(obj,
                                            plane,
                                            fill,
                                            pathdata,
                                            stroke,
                                            linewidth,
                                            lstyle,
                                            fill_opacity=None,
                                            edges=[prx.circle2])
                        else:
                            svg += get_path(obj,
                                            plane,
                                            fill,
                                            pathdata,
                                            stroke,
                                            linewidth,
                                            lstyle,
                                            fill_opacity=None,
                                            edges=[prx.circle])

                    # drawing arrows
                    if hasattr(obj.ViewObject, "ArrowType"):
                        p2 = get_proj(prx.p2, plane)
                        p3 = get_proj(prx.p3, plane)
                        arrowsize = obj.ViewObject.ArrowSize.Value / pointratio
                        arrowlength = 4 * obj.ViewObject.ArrowSize.Value

                        _v1a = prx.circle.valueAt(prx.circle.FirstParameter +
                                                  arrowlength)
                        _v1b = prx.circle.valueAt(prx.circle.FirstParameter)

                        _v2a = prx.circle.valueAt(prx.circle.LastParameter -
                                                  arrowlength)
                        _v2b = prx.circle.valueAt(prx.circle.LastParameter)

                        u1 = get_proj(_v1a - _v1b, plane)
                        u2 = get_proj(_v2a - _v2b, plane)
                        angle1 = -DraftVecUtils.angle(u1)
                        angle2 = -DraftVecUtils.angle(u2)

                        if hasattr(obj.ViewObject, "FlipArrows"):
                            if obj.ViewObject.FlipArrows:
                                angle1 = angle1 + math.pi
                                angle2 = angle2 + math.pi

                        svg += get_arrow(obj, obj.ViewObject.ArrowType, p2,
                                         arrowsize, stroke, linewidth, angle1)
                        svg += get_arrow(obj, obj.ViewObject.ArrowType, p3,
                                         arrowsize, stroke, linewidth, angle2)

                    # drawing text
                    if obj.ViewObject.DisplayMode == "2D":
                        _diff = (prx.circle.LastParameter -
                                 prx.circle.FirstParameter)
                        t = prx.circle.tangentAt(prx.circle.FirstParameter +
                                                 _diff / 2.0)
                        t = get_proj(t, plane)
                        tangle = DraftVecUtils.angle(t)
                        if (tangle <= -math.pi / 2) or (tangle > math.pi / 2):
                            tangle = tangle + math.pi

                        _diff = (prx.circle.LastParameter -
                                 prx.circle.FirstParameter)
                        _va = prx.circle.valueAt(prx.circle.FirstParameter +
                                                 _diff / 2.0)
                        tbase = get_proj(_va, plane)

                        _v = App.Vector(0, 2.0 / scale, 0)
                        tbase = tbase + DraftVecUtils.rotate(_v, tangle)
                        # print(tbase)
                    else:
                        tangle = 0
                        tbase = get_proj(prx.tbase, plane)

                    svg += svgtext.get_text(plane, techdraw, stroke, fontsize,
                                            obj.ViewObject.FontName, tangle,
                                            tbase, prx.string)

    elif utils.get_type(obj) == "Label":
        if getattr(obj.ViewObject, "Line", True):
            # Some Labels may have no Line property
            # Draw multisegment line
            proj_points = list(map(lambda x: get_proj(x, plane), obj.Points))
            path_dir_list = [format_point(proj_points[0], action='M')]
            path_dir_list += map(format_point, proj_points[1:])
            path_dir_str = " ".join(path_dir_list)

            svg_path = '<path '
            svg_path += 'fill="none" '
            svg_path += 'stroke="{}" '.format(stroke)
            svg_path += 'stroke-width="{}" '.format(linewidth)
            svg_path += 'd="{}"'.format(path_dir_str)
            svg_path += '/>'
            svg += svg_path

            # Draw arrow.
            # We are different here from 3D view
            # if Line is set to 'off', no arrow is drawn
            if hasattr(obj.ViewObject, "ArrowType") and len(obj.Points) >= 2:
                last_segment = App.Vector(obj.Points[-1] - obj.Points[-2])
                _v = get_proj(last_segment, plane)
                angle = -DraftVecUtils.angle(_v) + math.pi
                svg += get_arrow(obj, obj.ViewObject.ArrowType,
                                 proj_points[-1],
                                 obj.ViewObject.ArrowSize.Value / pointratio,
                                 stroke, linewidth, angle)

        if not App.GuiUp:
            _wrn("Export of texts to SVG is only available in GUI mode")

        # print text
        if App.GuiUp:
            fontname = obj.ViewObject.TextFont
            position = get_proj(obj.Placement.Base, plane)
            rotation = obj.Placement.Rotation
            justification = obj.ViewObject.TextAlignment
            text = obj.Text
            svg += svgtext.get_text(plane, techdraw, stroke, fontsize,
                                    fontname, rotation, position, text,
                                    linespacing, justification)

    elif utils.get_type(obj) in ["Annotation", "DraftText", "Text"]:
        # returns an svg representation of a document annotation
        if not App.GuiUp:
            _wrn("Export of texts to SVG is only available in GUI mode")

        if App.GuiUp:
            n = obj.ViewObject.FontName
            if utils.get_type(obj) == "Annotation":
                p = get_proj(obj.Position, plane)
                r = obj.ViewObject.Rotation.getValueAs("rad")
                t = obj.LabelText
            else:  # DraftText (old) or Text (new, 0.19)
                p = get_proj(obj.Placement.Base, plane)
                r = obj.Placement.Rotation
                t = obj.Text

            j = obj.ViewObject.Justification
            svg += svgtext.get_text(plane, techdraw, stroke, fontsize, n, r, p,
                                    t, linespacing, j)

    elif utils.get_type(obj) == "Axis":
        # returns the SVG representation of an Arch Axis system
        if not App.GuiUp:
            _wrn("Export of axes to SVG is only available in GUI mode")

        if App.GuiUp:
            vobj = obj.ViewObject
            lorig = lstyle
            fill = 'none'
            rad = vobj.BubbleSize.Value / 2
            n = 0
            for e in obj.Shape.Edges:
                lstyle = lorig
                svg += get_path(obj,
                                plane,
                                fill,
                                pathdata,
                                stroke,
                                linewidth,
                                lstyle,
                                fill_opacity=None,
                                edges=[e])
                lstyle = "none"
                pos = ["Start"]
                if hasattr(vobj, "BubblePosition"):
                    if vobj.BubblePosition == "Both":
                        pos = ["Start", "End"]
                    else:
                        pos = [vobj.BubblePosition]
                for p in pos:
                    if p == "Start":
                        p1 = e.Vertexes[0].Point
                        p2 = e.Vertexes[1].Point
                    else:
                        p1 = e.Vertexes[1].Point
                        p2 = e.Vertexes[0].Point
                    dv = p2.sub(p1)
                    dv.normalize()
                    center = p2.add(dv.scale(rad, rad, rad))
                    svg += get_circle(plane, fill, stroke, linewidth, lstyle,
                                      Part.makeCircle(rad, center))
                    if (hasattr(vobj.Proxy, "bubbletexts")
                            and len(vobj.Proxy.bubbletexts) >= n):
                        bubb = vobj.Proxy.bubbletexts
                        svg += '<text '
                        svg += 'fill="{}" '.format(stroke)
                        svg += 'font-size="{}" '.format(rad)
                        svg += 'style="text-anchor:middle;'
                        svg += 'text-align:center;'
                        svg += 'font-family: sans;" '
                        svg += 'transform="'
                        svg += 'translate({},{}) '.format(
                            center.x + rad / 4.0, center.y - rad / 3.0)
                        svg += 'scale(1,-1)"> '
                        svg += '<tspan>'
                        svg += bubb[n].string.getValues()[0]
                        svg += '</tspan>\n'
                        svg += '</text>\n'
                        n += 1
            lstyle = lorig

    elif utils.get_type(obj) == "Pipe":
        fill = stroke
        if obj.Base and obj.Diameter:
            svg += get_path(obj,
                            plane,
                            fill,
                            pathdata,
                            stroke,
                            linewidth,
                            lstyle,
                            fill_opacity=None,
                            edges=obj.Base.Shape.Edges)
        for f in obj.Shape.Faces:
            if len(f.Edges) == 1:
                if isinstance(f.Edges[0].Curve, Part.Circle):
                    svg += get_circle(plane, fill, stroke, linewidth, lstyle,
                                      f.Edges[0])

    elif utils.get_type(obj) == "Rebar":
        fill = "none"
        basewire = obj.Base.Shape.Wires[0].copy()
        # Not applying rounding because the results are not correct
        # if hasattr(obj, "Rounding") and obj.Rounding:
        #     basewire = DraftGeomUtils.filletWire(
        #         basewire, obj.Rounding * obj.Diameter.Value
        #     )
        wires = []
        for placement in obj.PlacementList:
            wire = basewire.copy()
            wire.Placement = placement.multiply(basewire.Placement)
            wires.append(wire)
        svg += get_path(obj,
                        plane,
                        fill,
                        pathdata,
                        stroke,
                        linewidth,
                        lstyle,
                        fill_opacity=None,
                        wires=wires)

    elif utils.get_type(obj) == "PipeConnector":
        pass

    elif utils.get_type(obj) == "Space":
        fill_opacity = 1

        # returns an SVG fragment for the text of a space
        if not App.GuiUp:
            _wrn("Export of spaces to SVG is only available in GUI mode")

        if App.GuiUp:
            vobj = obj.ViewObject
            if fillspaces and hasattr(obj, "Proxy"):
                if not hasattr(obj.Proxy, "face"):
                    obj.Proxy.getArea(obj, notouch=True)
                if hasattr(obj.Proxy, "face"):
                    # setting fill
                    if App.GuiUp:
                        fill = utils.get_rgb(vobj.ShapeColor, testbw=False)
                        fill_opacity = 1 - vobj.Transparency / 100.0
                    else:
                        fill = "#888888"
                    svg += get_path(obj,
                                    plane,
                                    fill,
                                    pathdata,
                                    stroke,
                                    linewidth,
                                    lstyle,
                                    fill_opacity=fill_opacity,
                                    wires=[obj.Proxy.face.OuterWire])
            c = utils.get_rgb(vobj.TextColor)
            n = vobj.FontName
            a = 0
            if rotation != 0:
                a = math.radians(rotation)

            t1 = vobj.Proxy.text1.string.getValues()
            t2 = vobj.Proxy.text2.string.getValues()
            scale = vobj.FirstLine.Value / vobj.FontSize.Value
            f1 = fontsize * scale

            if round(plane.axis.getAngle(App.Vector(0, 0, 1)),
                     2) not in [0, 3.14]:
                # if not in XY view, place the label at center
                p2 = obj.Shape.CenterOfMass
            else:
                _v = vobj.Proxy.coords.translation.getValue().getValue()
                p2 = obj.Placement.multVec(App.Vector(_v))

            _h = vobj.Proxy.header.translation.getValue().getValue()
            lspc = App.Vector(_h)
            p1 = p2 + lspc
            j = vobj.TextAlign
            t3 = svgtext.get_text(plane,
                                  techdraw,
                                  c,
                                  f1,
                                  n,
                                  a,
                                  get_proj(p1, plane),
                                  t1,
                                  linespacing,
                                  j,
                                  flip=True)
            svg += t3
            if t2:
                ofs = App.Vector(0, -lspc.Length, 0)
                if a:
                    Z = App.Vector(0, 0, 1)
                    ofs = App.Rotation(Z, -rotation).multVec(ofs)
                t4 = svgtext.get_text(plane,
                                      techdraw,
                                      c,
                                      fontsize,
                                      n,
                                      a,
                                      get_proj(p1, plane).add(ofs),
                                      t2,
                                      linespacing,
                                      j,
                                      flip=True)
                svg += t4

    elif hasattr(obj, 'Shape'):
        # In the past we tested for a Part Feature
        # elif obj.isDerivedFrom('Part::Feature'):
        #
        # however, this doesn't work for App::Links; instead we
        # test for a 'Shape'. All Part::Features should have a Shape,
        # and App::Links can have one as well.
        if obj.Shape.isNull():
            return ''

        fill_opacity = 1
        # setting fill
        if obj.Shape.Faces:
            if App.GuiUp:
                try:
                    m = obj.ViewObject.DisplayMode
                except AttributeError:
                    m = None

                vobj = obj.ViewObject
                if m != "Wireframe":
                    if fillstyle == "shape color":
                        fill = utils.get_rgb(vobj.ShapeColor, testbw=False)
                        fill_opacity = 1 - vobj.Transparency / 100.0
                    else:
                        fill = 'url(#' + fillstyle + ')'
                        svg += get_pattern(fillstyle)
                else:
                    fill = "none"
            else:
                fill = "#888888"
        else:
            fill = 'none'

        if len(obj.Shape.Vertexes) > 1:
            wiredEdges = []
            if obj.Shape.Faces:
                for i, f in enumerate(obj.Shape.Faces):
                    # place outer wire first
                    wires = [f.OuterWire]
                    wires.extend([
                        w for w in f.Wires
                        if w.hashCode() != f.OuterWire.hashCode()
                    ])
                    svg += get_path(obj,
                                    plane,
                                    fill,
                                    pathdata,
                                    stroke,
                                    linewidth,
                                    lstyle,
                                    fill_opacity=fill_opacity,
                                    wires=f.Wires,
                                    pathname='%s_f%04d' % (obj.Name, i))
                    wiredEdges.extend(f.Edges)
            else:
                for i, w in enumerate(obj.Shape.Wires):
                    svg += get_path(obj,
                                    plane,
                                    fill,
                                    pathdata,
                                    stroke,
                                    linewidth,
                                    lstyle,
                                    fill_opacity=fill_opacity,
                                    edges=w.Edges,
                                    pathname='%s_w%04d' % (obj.Name, i))
                    wiredEdges.extend(w.Edges)
            if len(wiredEdges) != len(obj.Shape.Edges):
                for i, e in enumerate(obj.Shape.Edges):
                    if DraftGeomUtils.findEdge(e, wiredEdges) is None:
                        svg += get_path(obj,
                                        plane,
                                        fill,
                                        pathdata,
                                        stroke,
                                        linewidth,
                                        lstyle,
                                        fill_opacity=fill_opacity,
                                        edges=[e],
                                        pathname='%s_nwe%04d' % (obj.Name, i))
        else:
            # closed circle or spline
            if obj.Shape.Edges:
                if isinstance(obj.Shape.Edges[0].Curve, Part.Circle):
                    svg = get_circle(plane, fill, stroke, linewidth, lstyle,
                                     obj.Shape.Edges[0])
                else:
                    svg = get_path(obj,
                                   plane,
                                   fill,
                                   pathdata,
                                   stroke,
                                   linewidth,
                                   lstyle,
                                   fill_opacity=fill_opacity,
                                   edges=obj.Shape.Edges)

        if (App.GuiUp and hasattr(obj.ViewObject, "EndArrow")
                and obj.ViewObject.EndArrow
                and hasattr(obj.ViewObject, "ArrowType")
                and len(obj.Shape.Vertexes) > 1):
            p1 = get_proj(obj.Shape.Vertexes[-1].Point, plane)
            p2 = get_proj(obj.Shape.Vertexes[-2].Point, plane)
            angle = -DraftVecUtils.angle(p2 - p1)

            arrowsize = obj.ViewObject.ArrowSize.Value / pointratio
            svg += get_arrow(obj, obj.ViewObject.ArrowType, p1, arrowsize,
                             stroke, linewidth, angle)

    # techdraw expects bottom-to-top coordinates
    if techdraw:
        svg = '<g transform ="scale(1,-1)">\n    ' + svg + '</g>\n'

    return svg
コード例 #30
0
ファイル: ArchSectionPlane.py プロジェクト: wdconinc/FreeCAD
def getSVG(section,
           renderMode="Wireframe",
           allOn=False,
           showHidden=False,
           scale=1,
           rotation=0,
           linewidth=1,
           lineColor=(0.0, 0.0, 0.0),
           fontsize=1,
           showFill=False,
           fillColor=(0.8, 0.8, 0.8),
           techdraw=False):
    """getSVG(section, [renderMode, allOn, showHidden, scale, rotation,
              linewidth, lineColor, fontsize, showFill, fillColor, techdraw]):

    returns an SVG fragment from an Arch section plane. If
    allOn is True, all cut objects are shown, regardless if they are visible or not.
    renderMode can be Wireframe (default) or Solid to use the Arch solid renderer. If
    showHidden is True, the hidden geometry above the section plane is shown in dashed line.
    If showFill is True, the cut areas get filled with a pattern.
    lineColor -- Color of lines for the renderMode "Wireframe".
    fillColor -- If showFill is True and renderMode is "Wireframe",
                 the cut areas are filled with fillColor.
    """

    if not section.Objects:
        return ""
    import Part, DraftGeomUtils
    p = FreeCAD.Placement(section.Placement)
    direction = p.Rotation.multVec(FreeCAD.Vector(0, 0, 1))
    objs = Draft.getGroupContents(section.Objects, walls=True, addgroups=True)
    if not allOn:
        objs = Draft.removeHidden(objs)

    # separate spaces and Draft objects
    spaces = []
    nonspaces = []
    drafts = []
    windows = []
    cutface = None
    for o in objs:
        if Draft.getType(o) == "Space":
            spaces.append(o)
        elif Draft.getType(o) in ["Dimension", "Annotation"]:
            drafts.append(o)
        elif o.isDerivedFrom("Part::Part2DObject"):
            drafts.append(o)
        else:
            nonspaces.append(o)
        if Draft.getType(o) == "Window":
            windows.append(o)
    objs = nonspaces

    archUserParameters = FreeCAD.ParamGet(
        "User parameter:BaseApp/Preferences/Mod/Arch")
    scaledLineWidth = linewidth / scale
    svgLineWidth = str(scaledLineWidth) + 'px'
    st = archUserParameters.GetFloat("CutLineThickness", 2)
    svgCutLineWidth = str(scaledLineWidth * st) + 'px'
    yt = archUserParameters.GetFloat("SymbolLineThickness", 0.6)
    svgSymbolLineWidth = str(linewidth * yt)
    hiddenPattern = archUserParameters.GetString("archHiddenPattern", "30,10")
    svgHiddenPattern = hiddenPattern.replace(" ", "")
    fillpattern = '<pattern id="sectionfill" patternUnits="userSpaceOnUse" patternTransform="matrix(5,0,0,5,0,0)"'
    fillpattern += ' x="0" y="0" width="10" height="10">'
    fillpattern += '<g>'
    fillpattern += '<rect width="10" height="10" style="stroke:none; fill:#ffffff" /><path style="stroke:#000000; stroke-width:1" d="M0,0 l10,10" /></g></pattern>'
    svgLineColor = Draft.getrgb(lineColor)
    svg = ''

    # reading cached version
    svgcache = None
    if hasattr(section.Proxy, "svgcache") and section.Proxy.svgcache:
        svgcache = section.Proxy.svgcache[0]
        if section.Proxy.svgcache[1] != renderMode:
            svgcache = None
        if section.Proxy.svgcache[2] != showHidden:
            svgcache = None
        if section.Proxy.svgcache[3] != showFill:
            svgcache = None

    # generating SVG
    if renderMode in ["Solid", 1]:
        if not svgcache:
            svgcache = ''
            # render using the Arch Vector Renderer
            import ArchVRM, WorkingPlane
            wp = WorkingPlane.plane()
            wp.setFromPlacement(section.Placement)
            #wp.inverse()
            render = ArchVRM.Renderer()
            render.setWorkingPlane(wp)
            render.addObjects(objs)
            if showHidden:
                render.cut(section.Shape, showHidden)
            else:
                render.cut(section.Shape)
            svgcache += '<g transform="scale(1,-1)">\n'
            svgcache += render.getViewSVG(linewidth="SVGLINEWIDTH")
            svgcache += fillpattern
            svgcache += render.getSectionSVG(linewidth="SVGCUTLINEWIDTH",
                                             fillpattern="sectionfill")
            if showHidden:
                svgcache += render.getHiddenSVG(linewidth="SVGLINEWIDTH")
            svgcache += '</g>\n'
            # print(render.info())
            section.Proxy.svgcache = [
                svgcache, renderMode, showHidden, showFill
            ]
    else:
        if not svgcache:
            svgcache = ""
            # render using the Drawing module
            import Drawing, Part
            shapes, hshapes, sshapes, cutface, cutvolume, invcutvolume = getCutShapes(
                objs, section, showHidden)
            if shapes:
                baseshape = Part.makeCompound(shapes)
                style = {
                    'stroke': "SVGLINECOLOR",
                    'stroke-width': "SVGLINEWIDTH"
                }
                svgcache += Drawing.projectToSVG(baseshape,
                                                 direction,
                                                 hStyle=style,
                                                 h0Style=style,
                                                 h1Style=style,
                                                 vStyle=style,
                                                 v0Style=style,
                                                 v1Style=style)
            if hshapes:
                hshapes = Part.makeCompound(hshapes)
                style = {
                    'stroke': "SVGLINECOLOR",
                    'stroke-width': "SVGLINEWIDTH",
                    'stroke-dasharray': "SVGHIDDENPATTERN"
                }
                svgcache += Drawing.projectToSVG(hshapes,
                                                 direction,
                                                 hStyle=style,
                                                 h0Style=style,
                                                 h1Style=style,
                                                 vStyle=style,
                                                 v0Style=style,
                                                 v1Style=style)
            if sshapes:
                if showFill:
                    #svgcache += fillpattern
                    svgcache += '<g transform="rotate(180)">\n'
                    for s in sshapes:
                        if s.Edges:
                            #svg += Draft.getSVG(s,direction=direction.negative(),linewidth=0,fillstyle="sectionfill",color=(0,0,0))
                            # temporarily disabling fill patterns
                            svgcache += Draft.getSVG(
                                s,
                                direction=direction.negative(),
                                linewidth=0,
                                fillstyle=Draft.getrgb(fillColor),
                                color=lineColor)
                    svgcache += "</g>\n"
                sshapes = Part.makeCompound(sshapes)
                style = {
                    'stroke': "SVGLINECOLOR",
                    'stroke-width': "SVGCUTLINEWIDTH"
                }
                svgcache += Drawing.projectToSVG(sshapes,
                                                 direction,
                                                 hStyle=style,
                                                 h0Style=style,
                                                 h1Style=style,
                                                 vStyle=style,
                                                 v0Style=style,
                                                 v1Style=style)
            section.Proxy.svgcache = [
                svgcache, renderMode, showHidden, showFill
            ]
    svgcache = svgcache.replace("SVGLINECOLOR", svgLineColor)
    svgcache = svgcache.replace("SVGLINEWIDTH", svgLineWidth)
    svgcache = svgcache.replace("SVGHIDDENPATTERN", svgHiddenPattern)
    svgcache = svgcache.replace("SVGCUTLINEWIDTH", svgCutLineWidth)
    svg += svgcache

    if drafts:
        if not techdraw:
            svg += '<g transform="scale(1,-1)">'
        for d in drafts:
            svg += Draft.getSVG(d,
                                scale=scale,
                                linewidth=svgSymbolLineWidth,
                                fontsize=fontsize,
                                direction=direction,
                                color=lineColor,
                                techdraw=techdraw,
                                rotation=rotation)
        if not techdraw:
            svg += '</g>'

    # filter out spaces not cut by the section plane
    if cutface and spaces:
        spaces = [
            s for s in spaces if s.Shape.BoundBox.intersect(cutface.BoundBox)
        ]
    if spaces:
        if not techdraw:
            svg += '<g transform="scale(1,-1)">'
        for s in spaces:
            svg += Draft.getSVG(s,
                                scale=scale,
                                linewidth=svgSymbolLineWidth,
                                fontsize=fontsize,
                                direction=direction,
                                color=lineColor,
                                techdraw=techdraw,
                                rotation=rotation)
        if not techdraw:
            svg += '</g>'

    # add additional edge symbols from windows
    cutwindows = []
    if cutface and windows:
        cutwindows = [
            w.Name for w in windows
            if w.Shape.BoundBox.intersect(cutface.BoundBox)
        ]
    if windows:
        sh = []
        for w in windows:
            if not hasattr(w.Proxy, "sshapes"):
                w.Proxy.execute(w)
            if hasattr(w.Proxy, "sshapes"):
                if w.Proxy.sshapes and (w.Name in cutwindows):
                    c = Part.makeCompound(w.Proxy.sshapes)
                    c.Placement = w.Placement
                    sh.append(c)
            # buggy for now...
            #if hasattr(w.Proxy,"vshapes"):
            #    if w.Proxy.vshapes:
            #        c = Part.makeCompound(w.Proxy.vshapes)
            #        c.Placement = w.Placement
            #        sh.append(c)
        if sh:
            if not techdraw:
                svg += '<g transform="scale(1,-1)">'
            for s in sh:
                svg += Draft.getSVG(s,
                                    scale=scale,
                                    linewidth=svgSymbolLineWidth,
                                    fontsize=fontsize,
                                    fillstyle="none",
                                    direction=direction,
                                    color=lineColor,
                                    techdraw=techdraw,
                                    rotation=rotation)
            if not techdraw:
                svg += '</g>'

    return svg
コード例 #31
0
ファイル: DraftSnap.py プロジェクト: msocorcim/FreeCAD
    def isEnabled(self,but):
        "returns true if the given button is turned on"
        for b in self.toolbarButtons:
            if str(b.objectName()) == "SnapButton" + but:
                return (b.isEnabled() and b.isChecked())
        return False

    def show(self):
        "shows the toolbar"
        if not hasattr(self,"toolbar"):
            self.makeSnapToolBar()
        mw = getMainWindow()
        bt = mw.findChild(QtGui.QToolBar,"Draft Snap")
        if not bt:
            mw.addToolBar(self.toolbar)
        self.toolbar.show()

    def setGrid(self):
        "sets the grid, if visible"
        if self.grid:
            if self.grid.Visible:
                self.grid.set()

if not hasattr(FreeCADGui,"Snapper"):
    FreeCADGui.Snapper = Snapper()
if not hasattr(FreeCAD,"DraftWorkingPlane"):
    import WorkingPlane, Draft_rc
    FreeCAD.DraftWorkingPlane = WorkingPlane.plane()
    print FreeCAD.DraftWorkingPlane
    FreeCADGui.addIconPath(":/icons")
コード例 #32
0
ファイル: test_cmd_2.py プロジェクト: luzpaz/freecad.trails
import FreeCAD as App
import FreeCADGui as Gui
from FreeCAD import Vector

import Draft
import DraftGeomUtils
import DraftVecUtils

from DraftTrackers import editTracker, Tracker, lineTracker
from DraftTools import Modifier, Creator, DraftTool
from DraftTools import selectObject, getPoint, redraw3DView

#from .edit_tracker import editTracker

plane = WorkingPlane.plane()


class radiusTracker(Tracker):
    "A tracker that displays a transparent sphere to inicate a radius"

    def __init__(self, position=App.Vector(0, 0, 0), radius=1):
        self.trans = coin.SoTransform()
        self.trans.translation.setValue([position.x, position.y, position.z])
        self.line = coin.SoLineSet()
        self.line.numVertices.setValue(4)
        m = coin.SoMaterial()
        m.transparency.setValue(0.9)
        m.diffuseColor.setValue([0, 1, 0])
        self.coords = coin.SoCoordinate3()
        self.coords.point.set1Value(0, [0.0, 0.0, 0.0])
コード例 #33
0
ファイル: getSVG.py プロジェクト: KimK/FreeCAD
def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direction=None,linestyle=None,color=None,linespacing=None,techdraw=False,rotation=0):
    '''getSVG(object,[scale], [linewidth],[fontsize],[fillstyle],[direction],[linestyle],[color],[linespacing]):
    returns a string containing a SVG representation of the given object,
    with the given linewidth and fontsize (used if the given object contains
    any text). You can also supply an arbitrary projection vector. the
    scale parameter allows to scale linewidths down, so they are resolution-independant.'''

    # if this is a group, gather all the svg views of its children
    if hasattr(obj,"isDerivedFrom"):
        if obj.isDerivedFrom("App::DocumentObjectGroup"):
            svg = ""
            for child in obj.Group:
                svg += getSVG(child,scale,linewidth,fontsize,fillstyle,direction,linestyle,color,linespacing,techdraw)
            return svg

    pathdata = []
    svg = ""
    linewidth = float(linewidth)/scale
    fontsize = (float(fontsize)/scale)/2
    if linespacing:
        linespacing = float(linespacing)/scale
    else:
        linespacing = 0.5
    #print obj.Label," line spacing ",linespacing,"scale ",scale
    pointratio = .75 # the number of times the dots are smaller than the arrow size
    plane = None
    if direction:
        if isinstance(direction,FreeCAD.Vector):
            if direction != Vector(0,0,0):
                plane = WorkingPlane.plane()
                plane.alignToPointAndAxis_SVG(Vector(0,0,0),direction.negative().negative(),0)
        elif isinstance(direction,WorkingPlane.plane):
            plane = direction
    stroke = "#000000"
    if color:
        if "#" in color:
            stroke = color
        else:
            stroke = getrgb(color)
    elif gui:
        if hasattr(obj,"ViewObject"):
            if hasattr(obj.ViewObject,"LineColor"):
                stroke = getrgb(obj.ViewObject.LineColor)


    def getPath(edges=[],wires=[],pathname=None):
        import Part,DraftGeomUtils
        svg = "<path "
        if pathname is None:
            svg += 'id="%s" ' % obj.Name
        elif pathname != "":
            svg += 'id="%s" ' % pathname
        svg += ' d="'
        if not wires:
            egroups = Part.sortEdges(edges)
        else:
            egroups = []
            for w in wires:
                w1=w.copy()
                w1.fixWire()
                egroups.append(Part.__sortEdges__(w1.Edges))
        for egroupindex, edges in enumerate(egroups):
            edata = ""
            vs=() #skipped for the first edge
            for edgeindex,e in enumerate(edges):
                previousvs = vs
                # vertexes of an edge (reversed if needed)
                vs = e.Vertexes
                if previousvs:
                    if (vs[0].Point-previousvs[-1].Point).Length > 1e-6:
                        vs.reverse()
                if edgeindex == 0:
                    v = getProj(vs[0].Point, plane)
                    edata += 'M '+ str(v.x) +' '+ str(v.y) + ' '
                else:
                    if (vs[0].Point-previousvs[-1].Point).Length > 1e-6:
                        raise ValueError('edges not ordered')
                iscircle = DraftGeomUtils.geomType(e) == "Circle"
                isellipse = DraftGeomUtils.geomType(e) == "Ellipse"
                if iscircle or isellipse:
                    import math
                    if hasattr(FreeCAD,"DraftWorkingPlane"):
                        drawing_plane_normal = FreeCAD.DraftWorkingPlane.axis
                    else:
                        drawing_plane_normal = FreeCAD.Vector(0,0,1)
                    if plane: drawing_plane_normal = plane.axis
                    c = e.Curve
                    if round(c.Axis.getAngle(drawing_plane_normal),2) in [0,3.14]:
                        occversion = Part.OCC_VERSION.split(".")
                        done = False
                        if (int(occversion[0]) >= 7) and (int(occversion[1]) >= 1):
                            # if using occ >= 7.1, use HLR algorithm
                            import Drawing
                            snip = Drawing.projectToSVG(e,drawing_plane_normal)
                            if snip:
                                try:
                                    a = "A " + snip.split("path d=\"")[1].split("\"")[0].split("A")[1]
                                except:
                                    pass
                                else:
                                    edata += a
                                    done = True
                        if not done:
                            if len(e.Vertexes) == 1 and iscircle: #complete curve
                                svg = getCircle(e)
                                return svg
                            elif len(e.Vertexes) == 1 and isellipse:
                                #svg = getEllipse(e)
                                #return svg
                                endpoints = (getProj(c.value((c.LastParameter-\
                                        c.FirstParameter)/2.0), plane), \
                                        getProj(vs[-1].Point, plane))
                            else:
                                endpoints = (getProj(vs[-1].Point), plane)
                            # arc
                            if iscircle:
                                rx = ry = c.Radius
                                rot = 0
                            else: #ellipse
                                rx = c.MajorRadius
                                ry = c.MinorRadius
                                rot = math.degrees(c.AngleXU * (c.Axis * \
                                    FreeCAD.Vector(0,0,1)))
                                if rot > 90:
                                    rot -=180
                                if rot < -90:
                                    rot += 180
                                #be careful with the sweep flag
                            flag_large_arc = (((e.ParameterRange[1] - \
                                    e.ParameterRange[0]) / math.pi) % 2) > 1
                            #flag_sweep = (c.Axis * drawing_plane_normal >= 0) \
                            #         == (e.LastParameter > e.FirstParameter)
                            #        == (e.Orientation == "Forward")
                            # other method: check the direction of the angle between tangents
                            t1 = e.tangentAt(e.FirstParameter)
                            t2 = e.tangentAt(e.FirstParameter + (e.LastParameter-e.FirstParameter)/10)
                            flag_sweep = (DraftVecUtils.angle(t1,t2,drawing_plane_normal) < 0)
                            for v in endpoints:
                                edata += 'A %s %s %s %s %s %s %s ' % \
                                        (str(rx),str(ry),str(rot),\
                                        str(int(flag_large_arc)),\
                                        str(int(flag_sweep)),str(v.x),str(v.y))
                    else:
                        edata += getDiscretized(e, plane)
                elif DraftGeomUtils.geomType(e) == "Line":
                    v = getProj(vs[-1].Point, plane)
                    edata += 'L '+ str(v.x) +' '+ str(v.y) + ' '
                else:
                    bspline=e.Curve.toBSpline(e.FirstParameter,e.LastParameter)
                    if bspline.Degree > 3 or bspline.isRational():
                        try:
                            bspline=bspline.approximateBSpline(0.05,50, 3,'C0')
                        except RuntimeError:
                            print("Debug: unable to approximate bspline")
                    if bspline.Degree <= 3 and not bspline.isRational():
                        for bezierseg in bspline.toBezier():
                            if bezierseg.Degree>3: #should not happen
                                raise AssertionError
                            elif bezierseg.Degree==1:
                                edata +='L '
                            elif bezierseg.Degree==2:
                                edata +='Q '
                            elif bezierseg.Degree==3:
                                edata +='C '
                            for pole in bezierseg.getPoles()[1:]:
                                v = getProj(pole, plane)
                                edata += str(v.x) +' '+ str(v.y) + ' '
                    else:
                        print("Debug: one edge (hash ",e.hashCode(),\
                                ") has been discretized with parameter 0.1")
                        for linepoint in bspline.discretize(0.1)[1:]:
                            v = getProj(linepoint, plane)
                            edata += 'L '+ str(v.x) +' '+ str(v.y) + ' '
            if fill != 'none':
                edata += 'Z '
            if edata in pathdata:
                # do not draw a path on another identical path
                return ""
            else:
                svg += edata
                pathdata.append(edata)
        svg += '" '
        svg += 'stroke="' + stroke + '" '
        svg += 'stroke-width="' + str(linewidth) + ' px" '
        svg += 'style="stroke-width:'+ str(linewidth)
        svg += ';stroke-miterlimit:4'
        svg += ';stroke-dasharray:' + lstyle
        svg += ';fill:' + fill
        try:
            svg += ';fill-opacity:' + str(fill_opacity)
        except NameError:
            pass
        svg += ';fill-rule: evenodd "'
        svg += '/>\n'
        return svg

    def getCircle(edge):
        cen = getProj(edge.Curve.Center, plane)
        rad = edge.Curve.Radius
        if hasattr(FreeCAD,"DraftWorkingPlane"):
            drawing_plane_normal = FreeCAD.DraftWorkingPlane.axis
        else:
            drawing_plane_normal = FreeCAD.Vector(0,0,1)
        if plane: drawing_plane_normal = plane.axis
        if round(edge.Curve.Axis.getAngle(drawing_plane_normal),2) == 0:
            # perpendicular projection: circle
            svg = '<circle cx="' + str(cen.x)
            svg += '" cy="' + str(cen.y)
            svg += '" r="' + str(rad)+'" '
        else:
            # any other projection: ellipse
            svg = '<path d="'
            svg += getDiscretized(edge, plane)
            svg += '" '
        svg += 'stroke="' + stroke + '" '
        svg += 'stroke-width="' + str(linewidth) + ' px" '
        svg += 'style="stroke-width:'+ str(linewidth)
        svg += ';stroke-miterlimit:4'
        svg += ';stroke-dasharray:' + lstyle
        svg += ';fill:' + fill + '"'
        svg += '/>\n'
        return svg

    def getEllipse(edge):
        cen = getProj(edge.Curve.Center, plane)
        mir = edge.Curve.MinorRadius
        mar = edge.Curve.MajorRadius
        svg = '<ellipse cx="' + str(cen.x)
        svg += '" cy="' + str(cen.y)
        svg += '" rx="' + str(mar)
        svg += '" ry="' + str(mir)+'" '
        svg += 'stroke="' + stroke + '" '
        svg += 'stroke-width="' + str(linewidth) + ' px" '
        svg += 'style="stroke-width:'+ str(linewidth)
        svg += ';stroke-miterlimit:4'
        svg += ';stroke-dasharray:' + lstyle
        svg += ';fill:' + fill + '"'
        svg += '/>\n'
        return svg

    def getArrow(arrowtype,point,arrowsize,color,linewidth,angle=0):
        svg = ""
        if gui:
            if not obj.ViewObject:
                return svg
            if obj.ViewObject.ArrowType == "Circle":
                svg += '<circle cx="'+str(point.x)+'" cy="'+str(point.y)
                svg += '" r="'+str(arrowsize)+'" '
                svg += 'fill="none" stroke="'+ color + '" '
                svg += 'style="stroke-width:'+ str(linewidth) + ';stroke-miterlimit:4;stroke-dasharray:none" '
                svg += 'freecad:skip="1"'
                svg += '/>\n'
            elif obj.ViewObject.ArrowType == "Dot":
                svg += '<circle cx="'+str(point.x)+'" cy="'+str(point.y)
                svg += '" r="'+str(arrowsize)+'" '
                svg += 'fill="'+ color +'" stroke="none" '
                svg += 'style="stroke-miterlimit:4;stroke-dasharray:none" '
                svg += 'freecad:skip="1"'
                svg += '/>\n'
            elif obj.ViewObject.ArrowType == "Arrow":
                svg += '<path transform="rotate('+str(math.degrees(angle))
                svg += ','+ str(point.x) + ',' + str(point.y) + ') '
                svg += 'translate(' + str(point.x) + ',' + str(point.y) + ') '
                svg += 'scale('+str(arrowsize)+','+str(arrowsize)+')" freecad:skip="1" '
                svg += 'fill="'+ color +'" stroke="none" '
                svg += 'style="stroke-miterlimit:4;stroke-dasharray:none" '
                svg += 'd="M 0 0 L 4 1 L 4 -1 Z"/>\n'
            elif obj.ViewObject.ArrowType == "Tick":
                svg += '<path transform="rotate('+str(math.degrees(angle))
                svg += ','+ str(point.x) + ',' + str(point.y) + ') '
                svg += 'translate(' + str(point.x) + ',' + str(point.y) + ') '
                svg += 'scale('+str(arrowsize)+','+str(arrowsize)+')" freecad:skip="1" '
                svg += 'fill="'+ color +'" stroke="none" '
                svg += 'style="stroke-miterlimit:4;stroke-dasharray:none" '
                svg += 'd="M -1 -2 L 0 2 L 1 2 L 0 -2 Z"/>\n'
            elif obj.ViewObject.ArrowType == "Tick-2":
                svg += '<line transform="rotate('+str(math.degrees(angle)+45)
                svg += ','+ str(point.x) + ',' + str(point.y) + ') '
                svg += 'translate(' + str(point.x) + ',' + str(point.y) + ') '
                svg += '" freecad:skip="1" '
                svg += 'fill="none" stroke="'+ color +'" '
                svg += 'style="stroke-dasharray:none;stroke-linecap:square;'
                svg += 'stroke-width:'+ str(linewidth) +'" '
                svg += 'x1="-'+ str(arrowsize*2) +'" y1="0" '
                svg += 'x2="' + str(arrowsize*2) +'" y2="0" />\n'
            else:
                print("getSVG: arrow type not implemented")
        return svg

    def getOvershoot(point,shootsize,color,linewidth,angle=0):
        svg = '<line transform="rotate('+str(math.degrees(angle))
        svg += ','+ str(point.x) + ',' + str(point.y) + ') '
        svg += 'translate(' + str(point.x) + ',' + str(point.y) + ') '
        svg += '" freecad:skip="1" '
        svg += 'fill="none" stroke="'+ color +'" '
        svg += 'style="stroke-dasharray:none;stroke-linecap:square;'
        svg += 'stroke-width:'+ str(linewidth) +'" '
        svg += 'x1="0" y1="0" '
        svg += 'x2="'+ str(shootsize*-1) +'" y2="0" />\n'
        return svg

    def getText(color,fontsize,fontname,angle,base,text,linespacing=0.5,align="center",flip=True):
        if isinstance(angle,FreeCAD.Rotation):
            if not plane:
                angle = angle.Angle
            else:
                if plane.axis.getAngle(angle.Axis) < 0.001:
                    angle = angle.Angle
                elif abs(plane.axis.getAngle(angle.Axis)-math.pi) < 0.001:
                    return "" # text is perpendicular to view, so it shouldn't appear
                else:
                    angle = 0 #TODO maybe there is something better to do here?
        if not isinstance(text,list):
            text = text.split("\n")
        if align.lower() == "center":
            anchor = "middle"
        elif align.lower() == "left":
            anchor = "start"
        else:
            anchor = "end"
        if techdraw:
            svg = ""
            for i in range(len(text)):
                t = text[i]
                if sys.version_info.major < 3 and (not isinstance(t,unicode)):
                    t = t.decode("utf8")
                # possible workaround if UTF8 is unsupported
                #    import unicodedata
                #    t = u"".join([c for c in unicodedata.normalize("NFKD",t) if not unicodedata.combining(c)]).encode("utf8")
                svg += '<text fill="' + color +'" font-size="' + str(fontsize) + '" '
                svg += 'style="text-anchor:'+anchor+';text-align:'+align.lower()+';'
                svg += 'font-family:'+ fontname +'" '
                svg += 'transform="rotate('+str(math.degrees(angle))
                svg += ','+ str(base.x) + ',' + str(base.y-linespacing*i) + ') '
                svg += 'translate(' + str(base.x) + ',' + str(base.y-linespacing*i) + ') '
                svg += 'scale(1,-1)" '
                #svg += '" freecad:skip="1"'
                svg += '>\n' + t + '</text>\n'
        else:
            svg = '<text fill="'
            svg += color +'" font-size="'
            svg += str(fontsize) + '" '
            svg += 'style="text-anchor:'+anchor+';text-align:'+align.lower()+';'
            svg += 'font-family:'+ fontname +'" '
            svg += 'transform="rotate('+str(math.degrees(angle))
            svg += ','+ str(base.x) + ',' + str(base.y) + ') '
            if flip:
                svg += 'translate(' + str(base.x) + ',' + str(base.y) + ')'
            else:
                svg += 'translate(' + str(base.x) + ',' + str(-base.y) + ')'
            #svg += 'scale('+str(tmod/2000)+',-'+str(tmod/2000)+') '
            if flip:
                svg += ' scale(1,-1) '
            else:
                svg += ' scale(1,1) '
            svg += '" freecad:skip="1"'
            svg += '>\n'
            if len(text) == 1:
                try:
                    svg += text[0]
                except:
                    svg += text[0].decode("utf8")
            else:
                for i in range(len(text)):
                    if i == 0:
                        svg += '<tspan>'
                    else:
                        svg += '<tspan x="0" dy="'+str(linespacing)+'">'
                    try:
                        svg += text[i]
                    except:
                        svg += text[i].decode("utf8")
                    svg += '</tspan>\n'
            svg += '</text>\n'
        return svg


    if not obj:
        pass

    elif isinstance(obj,Part.Shape):
        if "#" in fillstyle:
            fill = fillstyle
        elif fillstyle == "shape color":
            fill = "#888888"
        else:
            fill = 'url(#'+fillstyle+')'
        lstyle = getLineStyle(linestyle, scale)
        svg += getPath(obj.Edges,pathname="")


    elif getType(obj) == "Dimension":
        if gui:
            if not obj.ViewObject:
                print ("export of dimensions to SVG is only available in GUI mode")
            elif obj.ViewObject.Proxy:
                if hasattr(obj.ViewObject.Proxy,"p1"):
                    prx = obj.ViewObject.Proxy
                    ts = (len(prx.string)*obj.ViewObject.FontSize.Value)/4.0
                    rm = ((prx.p3.sub(prx.p2)).Length/2.0)-ts
                    p2a = getProj(prx.p2.add(DraftVecUtils.scaleTo(prx.p3.sub(prx.p2),rm)), plane)
                    p2b = getProj(prx.p3.add(DraftVecUtils.scaleTo(prx.p2.sub(prx.p3),rm)), plane)
                    p1 = getProj(prx.p1, plane)
                    p2 = getProj(prx.p2, plane)
                    p3 = getProj(prx.p3, plane)
                    p4 = getProj(prx.p4, plane)
                    tbase = getProj(prx.tbase, plane)
                    r = prx.textpos.rotation.getValue().getValue()
                    rv = FreeCAD.Rotation(r[0],r[1],r[2],r[3]).multVec(FreeCAD.Vector(1,0,0))
                    angle = -DraftVecUtils.angle(getProj(rv, plane))
                    #angle = -DraftVecUtils.angle(p3.sub(p2))

                    # drawing lines
                    svg = '<path '
                    if obj.ViewObject.DisplayMode == "2D":
                        tangle = angle
                        if tangle > math.pi/2:
                            tangle = tangle-math.pi
                        #elif (tangle <= -math.pi/2) or (tangle > math.pi/2):
                        #    tangle = tangle+math.pi
                        #tbase = tbase.add(DraftVecUtils.rotate(Vector(0,2/scale,0),tangle))
                        if rotation != 0:
                            #print "dim: tangle:",tangle," rot: ",rotation," text: ",prx.string
                            if abs(tangle+math.radians(rotation)) < 0.0001:
                                tangle += math.pi
                                tbase = tbase.add(DraftVecUtils.rotate(Vector(0,2/scale,0),tangle))
                        svg += 'd="M '+str(p1.x)+' '+str(p1.y)+' '
                        svg += 'L '+str(p2.x)+' '+str(p2.y)+' '
                        svg += 'L '+str(p3.x)+' '+str(p3.y)+' '
                        svg += 'L '+str(p4.x)+' '+str(p4.y)+'" '
                    else:
                        tangle = 0
                        if rotation != 0:
                            tangle = -math.radians(rotation)
                        tbase = tbase.add(Vector(0,-2.0/scale,0))
                        svg += 'd="M '+str(p1.x)+' '+str(p1.y)+' '
                        svg += 'L '+str(p2.x)+' '+str(p2.y)+' '
                        svg += 'L '+str(p2a.x)+' '+str(p2a.y)+' '
                        svg += 'M '+str(p2b.x)+' '+str(p2b.y)+' '
                        svg += 'L '+str(p3.x)+' '+str(p3.y)+' '
                        svg += 'L '+str(p4.x)+' '+str(p4.y)+'" '

                    svg += 'fill="none" stroke="'
                    svg += stroke + '" '
                    svg += 'stroke-width="' + str(linewidth) + ' px" '
                    svg += 'style="stroke-width:'+ str(linewidth)
                    svg += ';stroke-miterlimit:4;stroke-dasharray:none" '
                    svg += 'freecad:basepoint1="'+str(p1.x)+' '+str(p1.y)+'" '
                    svg += 'freecad:basepoint2="'+str(p4.x)+' '+str(p4.y)+'" '
                    svg += 'freecad:dimpoint="'+str(p2.x)+' '+str(p2.y)+'"'
                    svg += '/>\n'

                    # drawing dimension and extension lines overshoots
                    if hasattr(obj.ViewObject,"DimOvershoot") and obj.ViewObject.DimOvershoot.Value:
                        shootsize = obj.ViewObject.DimOvershoot.Value/pointratio
                        svg += getOvershoot(p2,shootsize,stroke,linewidth,angle)
                        svg += getOvershoot(p3,shootsize,stroke,linewidth,angle+math.pi)
                    if hasattr(obj.ViewObject,"ExtOvershoot") and obj.ViewObject.ExtOvershoot.Value:
                        shootsize = obj.ViewObject.ExtOvershoot.Value/pointratio
                        shootangle = -DraftVecUtils.angle(p1.sub(p2))
                        svg += getOvershoot(p2,shootsize,stroke,linewidth,shootangle)
                        svg += getOvershoot(p3,shootsize,stroke,linewidth,shootangle)

                    # drawing arrows
                    if hasattr(obj.ViewObject,"ArrowType"):
                        arrowsize = obj.ViewObject.ArrowSize.Value/pointratio
                        if hasattr(obj.ViewObject,"FlipArrows"):
                            if obj.ViewObject.FlipArrows:
                                angle = angle+math.pi
                        svg += getArrow(obj.ViewObject.ArrowType,p2,arrowsize,stroke,linewidth,angle)
                        svg += getArrow(obj.ViewObject.ArrowType,p3,arrowsize,stroke,linewidth,angle+math.pi)

                    # drawing text
                    svg += getText(stroke,fontsize,obj.ViewObject.FontName,tangle,tbase,prx.string)

    elif getType(obj) == "AngularDimension":
        if gui:
            if not obj.ViewObject:
                print ("export of dimensions to SVG is only available in GUI mode")
            elif obj.ViewObject.Proxy:
                if hasattr(obj.ViewObject.Proxy,"circle"):
                    prx = obj.ViewObject.Proxy

                    # drawing arc
                    fill= "none"
                    lstyle = getLineStyle(linestyle, scale)
                    if obj.ViewObject.DisplayMode == "2D":
                        svg += getPath([prx.circle])
                    else:
                        if hasattr(prx,"circle1"):
                            svg += getPath([prx.circle1])
                            svg += getPath([prx.circle2])
                        else:
                            svg += getPath([prx.circle])

                    # drawing arrows
                    if hasattr(obj.ViewObject,"ArrowType"):
                        p2 = getProj(prx.p2, plane)
                        p3 = getProj(prx.p3, plane)
                        arrowsize = obj.ViewObject.ArrowSize.Value/pointratio
                        arrowlength = 4*obj.ViewObject.ArrowSize.Value
                        u1 = getProj((prx.circle.valueAt(prx.circle.FirstParameter+arrowlength)).sub(prx.circle.valueAt(prx.circle.FirstParameter)), plane)
                        u2 = getProj((prx.circle.valueAt(prx.circle.LastParameter-arrowlength)).sub(prx.circle.valueAt(prx.circle.LastParameter)), plane)
                        angle1 = -DraftVecUtils.angle(u1)
                        angle2 = -DraftVecUtils.angle(u2)
                        if hasattr(obj.ViewObject,"FlipArrows"):
                            if obj.ViewObject.FlipArrows:
                                angle1 = angle1+math.pi
                                angle2 = angle2+math.pi
                        svg += getArrow(obj.ViewObject.ArrowType,p2,arrowsize,stroke,linewidth,angle1)
                        svg += getArrow(obj.ViewObject.ArrowType,p3,arrowsize,stroke,linewidth,angle2)

                    # drawing text
                    if obj.ViewObject.DisplayMode == "2D":
                        t = prx.circle.tangentAt(prx.circle.FirstParameter+(prx.circle.LastParameter-prx.circle.FirstParameter)/2.0)
                        t = getProj(t, plane)
                        tangle = DraftVecUtils.angle(t)
                        if (tangle <= -math.pi/2) or (tangle > math.pi/2):
                            tangle = tangle + math.pi
                        tbase = getProj(prx.circle.valueAt(prx.circle.FirstParameter+(prx.circle.LastParameter-prx.circle.FirstParameter)/2.0), plane)
                        tbase = tbase.add(DraftVecUtils.rotate(Vector(0,2.0/scale,0),tangle))
                        #print(tbase)
                    else:
                        tangle = 0
                        tbase = getProj(prx.tbase, plane)
                    svg += getText(stroke,fontsize,obj.ViewObject.FontName,tangle,tbase,prx.string)

    elif getType(obj) == "Label":
        if getattr(obj.ViewObject, "Line", True):  # some Labels may have no Line property
            def format_point(coords, action='L'):
                return "{action}{x},{y}".format(
                    x=coords.x, y=coords.y, action=action
                )

            # Draw multisegment line
            proj_points = list(map(lambda x: getProj(x, plane), obj.Points))
            path_dir_list = [format_point(proj_points[0], action='M')]
            path_dir_list += map(format_point, proj_points[1:])
            path_dir_str = " ".join(path_dir_list)
            svg_path = '<path fill="none" stroke="{stroke}" stroke-width="{linewidth}" d="{directions}"/>'.format(
                stroke=stroke,
                linewidth=linewidth,
                directions=path_dir_str
            )
            svg += svg_path

            # Draw arrow.
            # We are different here from 3D view
            # if Line is set to 'off', no arrow is drawn
            if hasattr(obj.ViewObject, "ArrowType") and len(obj.Points) >= 2:
                last_segment = FreeCAD.Vector(obj.Points[-1] - obj.Points[-2])
                angle = -DraftVecUtils.angle(getProj(last_segment, plane)) + math.pi
                svg += getArrow(
                    arrowtype=obj.ViewObject.ArrowType,
                    point=proj_points[-1],
                    arrowsize=obj.ViewObject.ArrowSize.Value/pointratio,
                    color=stroke,
                    linewidth=linewidth,
                    angle=angle
                )

        # print text
        if gui:
            if not obj.ViewObject:
                print("export of texts to SVG is only available in GUI mode")
            else:
                fontname = obj.ViewObject.TextFont
                position = getProj(obj.Placement.Base, plane)
                rotation = obj.Placement.Rotation
                justification = obj.ViewObject.TextAlignment
                text = obj.Text
                svg += getText(stroke, fontsize, fontname, rotation, position,
                               text, linespacing, justification)

    elif getType(obj) in ["Annotation","DraftText"]:
        "returns an svg representation of a document annotation"
        if gui:
            if not obj.ViewObject:
                print ("export of texts to SVG is only available in GUI mode")
            else:
                n = obj.ViewObject.FontName
                if getType(obj) == "Annotation":
                    p = getProj(obj.Position, plane)
                    r = obj.ViewObject.Rotation.getValueAs("rad")
                    t = obj.LabelText
                else: # DraftText
                    p = getProj(obj.Placement.Base, plane)
                    r = obj.Placement.Rotation
                    t = obj.Text
                j = obj.ViewObject.Justification
                svg += getText(stroke,fontsize,n,r,p,t,linespacing,j)

    elif getType(obj) == "Axis":
        "returns the SVG representation of an Arch Axis system"
        if gui:
            if not obj.ViewObject:
                print ("export of axes to SVG is only available in GUI mode")
            else:
                vobj = obj.ViewObject
                lorig = getLineStyle(linestyle, scale)
                fill = 'none'
                rad = vobj.BubbleSize.Value/2
                n = 0
                for e in obj.Shape.Edges:
                    lstyle = lorig
                    svg += getPath([e])
                    lstyle = "none"
                    pos = ["Start"]
                    if hasattr(vobj,"BubblePosition"):
                        if vobj.BubblePosition == "Both":
                            pos = ["Start","End"]
                        else:
                            pos = [vobj.BubblePosition]
                    for p in pos:
                        if p == "Start":
                            p1 = e.Vertexes[0].Point
                            p2 = e.Vertexes[1].Point
                        else:
                            p1 = e.Vertexes[1].Point
                            p2 = e.Vertexes[0].Point
                        dv = p2.sub(p1)
                        dv.normalize()
                        center = p2.add(dv.scale(rad,rad,rad))
                        svg += getCircle(Part.makeCircle(rad,center))
                        if hasattr(vobj.Proxy,"bubbletexts"):
                            if len (vobj.Proxy.bubbletexts) >= n:
                                svg += '<text fill="' + stroke + '" '
                                svg += 'font-size="' + str(rad) + '" '
                                svg += 'style="text-anchor:middle;'
                                svg += 'text-align:center;'
                                svg += 'font-family: sans;" '
                                svg += 'transform="translate(' + str(center.x+rad/4.0) + ',' + str(center.y-rad/3.0) + ') '
                                svg += 'scale(1,-1)"> '
                                svg += '<tspan>' + obj.ViewObject.Proxy.bubbletexts[n].string.getValues()[0] + '</tspan>\n'
                                svg += '</text>\n'
                                n += 1

    elif getType(obj) == "Pipe":
        fill = stroke
        lstyle = getLineStyle(linestyle, scale)
        if obj.Base and obj.Diameter:
            svg += getPath(obj.Base.Shape.Edges)
        for f in obj.Shape.Faces:
            if len(f.Edges) == 1:
                if isinstance(f.Edges[0].Curve,Part.Circle):
                    svg += getCircle(f.Edges[0])

    elif getType(obj) == "Rebar":
        fill = "none"
        lstyle = getLineStyle(linestyle, scale)
        if obj.Proxy:
            if not hasattr(obj.Proxy,"wires"):
                obj.Proxy.execute(obj)
            if hasattr(obj.Proxy,"wires"):
                svg += getPath(wires=obj.Proxy.wires)

    elif getType(obj) == "PipeConnector":
        pass

    elif getType(obj) == "Space":
        "returns an SVG fragment for the text of a space"
        if gui:
            if not obj.ViewObject:
                print ("export of spaces to SVG is only available in GUI mode")
            else:
                c = getrgb(obj.ViewObject.TextColor)
                n = obj.ViewObject.FontName
                a = 0
                if rotation != 0:
                    a = math.radians(rotation)
                t1 = obj.ViewObject.Proxy.text1.string.getValues()
                t2 = obj.ViewObject.Proxy.text2.string.getValues()
                scale = obj.ViewObject.FirstLine.Value/obj.ViewObject.FontSize.Value
                f1 = fontsize*scale
                p2 = FreeCAD.Vector(obj.ViewObject.Proxy.coords.translation.getValue().getValue())
                lspc = FreeCAD.Vector(obj.ViewObject.Proxy.header.translation.getValue().getValue())
                p1 = p2.add(lspc)
                j = obj.ViewObject.TextAlign
                svg += getText(c,f1,n,a,getProj(p1, plane),t1,linespacing,j,flip=True)
                if t2:
                    ofs = FreeCAD.Vector(0,lspc.Length,0)
                    if a:
                        ofs = FreeCAD.Rotation(FreeCAD.Vector(0,0,1),-rotation).multVec(ofs)
                    svg += getText(c,fontsize,n,a,getProj(p1, plane).add(ofs),t2,linespacing,j,flip=True)

    elif obj.isDerivedFrom('Part::Feature'):
        if obj.Shape.isNull():
            return ''
        # setting fill
        if obj.Shape.Faces:
            if gui:
                try:
                    m = obj.ViewObject.DisplayMode
                except AttributeError:
                    m = None
                if (m != "Wireframe"):
                    if fillstyle == "shape color":
                        fill = getrgb(obj.ViewObject.ShapeColor,testbw=False)
                        fill_opacity = 1 - (obj.ViewObject.Transparency / 100.0)
                    else:
                        fill = 'url(#'+fillstyle+')'
                        svg += getPattern(fillstyle)
                else:
                    fill = "none"
            else:
                fill = "#888888"
        else:
            fill = 'none'
        lstyle = getLineStyle(linestyle, scale)

        if len(obj.Shape.Vertexes) > 1:
            wiredEdges = []
            if obj.Shape.Faces:
                for i,f in enumerate(obj.Shape.Faces):
                    svg += getPath(wires=f.Wires,pathname='%s_f%04d' % \
                            (obj.Name,i))
                    wiredEdges.extend(f.Edges)
            else:
                for i,w in enumerate(obj.Shape.Wires):
                    svg += getPath(w.Edges,pathname='%s_w%04d' % \
                            (obj.Name,i))
                    wiredEdges.extend(w.Edges)
            if len(wiredEdges) != len(obj.Shape.Edges):
                for i,e in enumerate(obj.Shape.Edges):
                    if (DraftGeomUtils.findEdge(e,wiredEdges) == None):
                        svg += getPath([e],pathname='%s_nwe%04d' % \
                                (obj.Name,i))
        else:
            # closed circle or spline
            if obj.Shape.Edges:
                if isinstance(obj.Shape.Edges[0].Curve,Part.Circle):
                    svg = getCircle(obj.Shape.Edges[0])
                else:
                    svg = getPath(obj.Shape.Edges)
        if FreeCAD.GuiUp:
            if hasattr(obj.ViewObject,"EndArrow") and hasattr(obj.ViewObject,"ArrowType") and (len(obj.Shape.Vertexes) > 1):
                if obj.ViewObject.EndArrow:
                    p1 = getProj(obj.Shape.Vertexes[-2].Point, plane)
                    p2 = getProj(obj.Shape.Vertexes[-1].Point, plane)
                    angle = -DraftVecUtils.angle(p2.sub(p1))
                    arrowsize = obj.ViewObject.ArrowSize.Value/pointratio
                    svg += getArrow(obj.ViewObject.ArrowType,p2,arrowsize,stroke,linewidth,angle)

    # techdraw expects bottom-to-top coordinates
    if techdraw:
        svg = '<g transform ="scale(1,-1)">'+svg+'</g>'
    return svg
コード例 #34
0
ファイル: TrackerTools.py プロジェクト: sgnannan/DDA
#*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
#*   USA                                                                   *
#*                                                                         *
#***************************************************************************

import FreeCADGui , WorkingPlane, math, re
from pivy import coin
from FreeCAD import Vector
from drawGui import *
#from draftlibs import fcvec, fcgeo
import fcvec, fcgeo
from functools import partial
import Part
            
# sets the default working plane
plane = WorkingPlane.plane()
FreeCAD.DDADockWidget = plane
plane.alignToPointAndAxis(Vector(0, 0, 0), Vector(0, 0, 1), 0)


#---------------------------------------------------------------------------
# Trackers
#---------------------------------------------------------------------------

class Tracker:
    "A generic Draft Tracker, to be used by other specific trackers"
    # 辅助绘图工具
    def __init__(self, dotted=False, scolor=None, swidth=None, children=[], ontop=False):
        self.ontop = ontop
        color = coin.SoBaseColor()
        color.rgb = scolor or FreeCADGui.DDADockWidget.getDefaultColor("ui")
コード例 #35
0
    def Activated(self):
        b = []
        selection = FreeCADGui.Selection.getSelectionEx()
        if selection:
            if len(selection) == 4:
                base = FreeCAD.ActiveDocument.getObject(
                    (selection[0].ObjectName))
                b = base.WingPanels
                _rootRib = FreeCAD.ActiveDocument.getObject(
                    (selection[1].ObjectName))
                _path = FreeCAD.ActiveDocument.getObject(
                    (selection[2].ObjectName))
                base.WingEdges.append(_path)
                _envelope = FreeCAD.ActiveDocument.getObject(
                    (selection[3].ObjectName))
                base.WingEdges.append(_envelope)
                _leadingedge = FreeCAD.ActiveDocument.getObject(
                    (selection[3].ObjectName))  # A netoyer en doublon
                wingsketch = FreeCAD.ActiveDocument.getObject(
                    (selection[3].ObjectName))
                # Separate leadInEdge & trailingEdge
                edges = Part.sortEdges(
                    wingsketch.Shape.Edges
                )  # Separate, #edges=Part.sortEdges(wingsketch.Shape.Edges) # deprecated ?
                paths = Part.__sortEdges__(_path.Shape.Edges)
                leadInEdges = edges[0]  #id the leading edge
                trailingEdges = edges[1]  #id the trailing edge
                FreeCAD.Console.PrintMessage("Edges number : " +
                                             str(len(edges)) + "\n")
                if len(edges) != 2:
                    FreeCAD.Console.PrintMessage("Edges must be 2 and not " +
                                                 str(len(edges)) + "\n")
                    return

                nbOfPanels = len(leadInEdges)
                FreeCAD.Console.PrintMessage(
                    "-------------------- Wing Panel --------------------" +
                    "\n")
                FreeCAD.Console.PrintMessage("  Rib :" + str(_rootRib.Label) +
                                             "\n")
                FreeCAD.Console.PrintMessage("  Wing :" + str(base.Label) +
                                             "\n")
                FreeCAD.Console.PrintMessage("  Path :" + str(_path.Label) +
                                             "\n")
                FreeCAD.Console.PrintMessage("  envelope :" +
                                             str(_envelope.Label) + "\n")
                FreeCAD.Console.PrintMessage("  envelope placement:" +
                                             str(_envelope.Placement) + "\n")
                FreeCAD.Console.PrintMessage("  Number of Panels :" +
                                             str(nbOfPanels) + "\n")

                pmin = 0
                pmax = 0
                for i in range(0, nbOfPanels):  # for each panel
                    pmin = 0  #pmax
                    pmax = leadInEdges[i].Length
                    param = leadInEdges[i].getParameterByLength(pmin)
                    param2 = leadInEdges[i].getParameterByLength(pmax)
                    direction = leadInEdges[i].tangentAt(param)
                    posvec = leadInEdges[i].valueAt(param)
                    posvec2 = leadInEdges[i].valueAt(param2)

                    #normal = CurvedShapes.getNormal(obj.Base)
                    #rotaxis = normal.cross(direction)
                    #angle = math.degrees(normal.getAngle(direction))
                    bbox = leadInEdges[i].BoundBox
                    bbox2 = trailingEdges[i].BoundBox

                    FreeCAD.Console.PrintMessage("  Panel n° " + str(i) +
                                                 " ------------------------\n")
                    FreeCAD.Console.PrintMessage("  leadInEdges id        :" +
                                                 str(leadInEdges[i]) + "\n")
                    FreeCAD.Console.PrintMessage("  leadInEdges Length    :" +
                                                 str(leadInEdges[i].Length) +
                                                 "\n")
                    FreeCAD.Console.PrintMessage("  trailingEdges id      :" +
                                                 str(trailingEdges[i]) + "\n")
                    FreeCAD.Console.PrintMessage("  trailingEdges Length  :" +
                                                 str(trailingEdges[i].Length) +
                                                 "\n")
                    FreeCAD.Console.PrintMessage("  direction             :" +
                                                 str(direction) + "\n")
                    FreeCAD.Console.PrintMessage("     pmin               : " +
                                                 str(pmin) + "\n")
                    FreeCAD.Console.PrintMessage("     Param              : " +
                                                 str(param) + "\n")
                    FreeCAD.Console.PrintMessage("     Position           : " +
                                                 str(posvec) + "\n")
                    FreeCAD.Console.PrintMessage("     Position2          : " +
                                                 str(posvec2) + "\n")
                    FreeCAD.Console.PrintMessage(
                        "     BoundBox leadInEdges   : " + str(bbox) + "\n")
                    FreeCAD.Console.PrintMessage(
                        "     BoundBox trailingEdges   : " + str(bbox2) + "\n")

                    FreeCADGui.activateWorkbench("DraftWorkbench")
                    plane = WorkingPlane.plane()
                    FreeCAD.DraftWorkingPlane = plane

                    #workplane = WorkingPlane.plane()
                    workplane = FreeCAD.DraftWorkingPlane
                    v1 = FreeCAD.Vector(
                        0, 1,
                        0).normalize()  #paths[i].tangentAt(param).normalize()
                    v2 = FreeCAD.Vector(0, 0, 1).normalize()
                    #workplane.alignToPointAndAxis(v1, v2, 0)

                    #FreeCAD.DraftWorkingPlane.alignToPointAndAxis(v1, v2, 0)
                    #FreeCADGui.Snapper.toggleGrid()

                    FreeCAD.Console.PrintMessage("     V1   : " + str(v1) +
                                                 "\n")
                    FreeCAD.Console.PrintMessage("     V2   : " + str(v2) +
                                                 "\n")

                    # workplane.alignToPointAndAxis( v1, v2, 0)
                    #FreeCADGui.Snapper.toggleGrid()
                    FreeCADGui.activeDocument().activeView(
                    ).setCameraOrientation(_path.Placement.Rotation)

                    #paths[i].

                    FreeCAD.Console.PrintMessage("     pathline   : " +
                                                 str(paths[i]) + "\n")
                    #pathline=Part.Line(paths[i].Geometry)

                    myObj0 = Draft.makeSketch(paths[i], autoconstraints=True)
                    #myObj1=Part.Line(paths[i].Content)
                    myObj0.Label = "path" + str(i)

                    vec = _envelope.Placement.Rotation
                    FreeCADGui.activeDocument().activeView(
                    ).setCameraOrientation(vec)  #(0,0,0,1))
                    myObj1 = Draft.makeSketch(leadInEdges[i],
                                              name="leadInEdges" + str(i),
                                              autoconstraints=True)
                    #myObj1=Part.Line()
                    myObj1.Label = "leadInEdges" + str(i)

                    FreeCADGui.activeDocument().activeView(
                    ).setCameraOrientation(vec)
                    myObj2 = Draft.makeSketch(trailingEdges[i],
                                              autoconstraints=True)
                    myObj2.Label = "trailingEdge" + str(i)

                    obj = FreeCAD.ActiveDocument.addObject(
                        "Part::FeaturePython", "WingPanel" + str(i))

                    WingPanel(obj, _rootRib, myObj0, _envelope, myObj1, myObj2,
                              200, 100, 100, 0, 0)
                    #WingPanel(obj,_rootRib,_path,_envelope,myObj1,myObj2,200,100,100,0,0)
                    #WingPanel(obj,_rootRib,_path,_envelope,leadInEdges[i],trailingEdges[i],200,100,100,0,0)

                    #WingPanel(obj,_rootRib,_path,leadInEdges[i],trailingEdges[i],200,100,100,0,0)
                    ViewProviderPanel(obj.ViewObject)
                    b.append(obj)
                    FreeCAD.ActiveDocument.recompute()
            else:
                #---------------------création des nervures temporaires
                #_rootRib=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","RibRoot_")
                #WingRib(_rootRib,"/Users/fredericnivoix/Library/Preferences/FreeCAD/Mod/AirPlaneDesign/wingribprofil/naca/naca2412.dat",False,0,200,0,0,0,0,0,0)
                #ViewProviderWingRib(_rootRib.ViewObject)

                #_tipRib=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","RibTip_")
                #WingRib(_tipRib,"/Users/fredericnivoix/Library/Preferences/FreeCAD/Mod/AirPlaneDesign/wingribprofil/naca/naca2412.dat",False,0,200,0,500,0,0,0,0)
                #ViewProviderWingRib(_tipRib.ViewObject)

                #----------

                obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",
                                                       "WingPanel")
                WingPanel(obj, None, None, None, None, None, 200, 100, 100, 0,
                          0)
                ViewProviderPanel(obj.ViewObject)

        if selection:  #selection==None :
            try:
                #b=base.WingPanels
                #b.append(obj)
                base.WingPanels = b
            except:
                print("The selection is not a wing")
        FreeCAD.Gui.activeDocument().activeView().viewAxonometric()
        FreeCAD.Gui.SendMsgToActiveView("ViewFit")
コード例 #36
0
    def PointCallback(self, point, snapinfo):

        if not point:
            # cancelled
            if hasattr(FreeCAD, "DraftWorkingPlane"):
                FreeCAD.DraftWorkingPlane.restore()
            FreeCADGui.Snapper.setGrid()
            for c in self.cubetracker:
                c.off()
            return

        if len(self.points) == 0:
            # this is our first clicked point, nothing to do just yet
            FreeCADGui.Snapper.getPoint(last=point,
                                        callback=self.PointCallback,
                                        movecallback=self.MoveCallback,
                                        extradlg=self.taskbox())
        elif len(self.points) == 1:
            # this is our second point
            # we turn on only one of the rectangles
            baseline = point.sub(self.points[0])
            self.cubetracker[0].setPlane(baseline)
            self.cubetracker[0].p1(self.points[0])
            self.cubetracker[0].on()
            FreeCADGui.Snapper.getPoint(last=point,
                                        callback=self.PointCallback,
                                        movecallback=self.MoveCallback,
                                        extradlg=self.taskbox())
        elif len(self.points) == 2:
            # this is our third point
            # we can get the cubes Z axis from our first rectangle
            self.normal = self.cubetracker[0].getNormal()
            # we can therefore define the (u,v) planes of all rectangles
            u = self.cubetracker[0].u
            v = self.cubetracker[0].v
            self.cubetracker[1].setPlane(u, self.normal)
            self.cubetracker[2].setPlane(u, self.normal)
            self.cubetracker[3].setPlane(u, v)
            # and the origin points of the vertical rectangles
            self.cubetracker[1].p1(self.cubetracker[0].p1())
            self.cubetracker[2].p1(self.cubetracker[0].p3())
            # finally we turn all rectangles on
            for r in self.cubetracker:
                r.on()
            if hasattr(FreeCAD, "DraftWorkingPlane"):
                FreeCAD.DraftWorkingPlane.save()
                FreeCAD.DraftWorkingPlane.position = self.cubetracker[0].p3()
                FreeCAD.DraftWorkingPlane.u = (self.cubetracker[0].p4().sub(
                    self.cubetracker[0].p3())).normalize()
                FreeCAD.DraftWorkingPlane.v = FreeCAD.Vector(
                    self.normal).normalize()
                FreeCAD.DraftWorkingPlane.axis = (self.cubetracker[0].p2().sub(
                    self.cubetracker[0].p3())).normalize()
                FreeCADGui.Snapper.setGrid()
            FreeCADGui.Snapper.getPoint(last=self.cubetracker[0].p3(),
                                        callback=self.PointCallback,
                                        movecallback=self.MoveCallback,
                                        extradlg=self.taskbox())
        elif len(self.points) == 3:
            # finally we have all our points. Let's create the actual cube
            cube = FreeCAD.ActiveDocument.addObject("Part::Box", "Cube")
            cube.Length = self.LengthValue
            cube.Width = self.WidthValue
            cube.Height = self.HeightValue
            # we get 3 points that define our cube orientation
            p1 = self.cubetracker[0].p1()
            p2 = self.cubetracker[0].p2()
            p3 = self.cubetracker[0].p4()
            import WorkingPlane
            cube.Placement = WorkingPlane.getPlacementFromPoints([p1, p2, p3])
            if hasattr(FreeCAD, "DraftWorkingPlane"):
                FreeCAD.DraftWorkingPlane.restore()
            FreeCADGui.Snapper.setGrid()
            for c in self.cubetracker:
                c.off()
            FreeCAD.ActiveDocument.recompute()
        self.points.append(point)
コード例 #37
0
def get_DXF(obj, direction=None):
    """getDXF(object,[direction]): returns a DXF entity from the given
    object. If direction is given, the object is projected in 2D."""
    plane = None
    result = ""
    if obj.isDerivedFrom("Drawing::View") or obj.isDerivedFrom(
            "TechDraw::DrawView"):
        if obj.Source.isDerivedFrom("App::DocumentObjectGroup"):
            for o in obj.Source.Group:
                result += getDXF(o, obj.Direction)
        else:
            result += getDXF(obj.Source, obj.Direction)
        return result
    if direction:
        if isinstance(direction, App.Vector):
            import WorkingPlane
            if direction != App.Vector(0, 0, 0):
                plane = WorkingPlane.Plane()
                plane.alignToPointAndAxis(App.Vector(0, 0, 0), direction)

    def getProj(vec):
        if not plane: return vec
        nx = DraftVecUtils.project(vec, plane.u)
        ny = DraftVecUtils.project(vec, plane.v)
        return App.Vector(nx.Length, ny.Length, 0)

    if getType(obj) in ["Dimension", "LinearDimension"]:
        p1 = getProj(obj.Start)
        p2 = getProj(obj.End)
        p3 = getProj(obj.Dimline)
        result += "0\nDIMENSION\n8\n0\n62\n0\n3\nStandard\n70\n1\n"
        result += "10\n" + str(p3.x) + "\n20\n" + str(p3.y) + "\n30\n" + str(
            p3.z) + "\n"
        result += "13\n" + str(p1.x) + "\n23\n" + str(p1.y) + "\n33\n" + str(
            p1.z) + "\n"
        result += "14\n" + str(p2.x) + "\n24\n" + str(p2.y) + "\n34\n" + str(
            p2.z) + "\n"

    elif getType(obj) == "Annotation":
        p = getProj(obj.Position)
        count = 0
        for t in obj.LabeLtext:
            result += "0\nTEXT\n8\n0\n62\n0\n"
            result += "10\n" + str(
                p.x) + "\n20\n" + str(p.y + count) + "\n30\n" + str(p.z) + "\n"
            result += "40\n1\n"
            result += "1\n" + str(t) + "\n"
            result += "7\nSTANDARD\n"
            count += 1

    elif hasattr(obj, 'Shape'):
        # TODO do this the Draft way, for ex. using polylines and rectangles
        import Drawing
        import DraftVecUtils
        if not direction:
            direction = App.Vector(0, 0, -1)
        if DraftVecUtils.isNull(direction):
            direction = App.Vector(0, 0, -1)
        try:
            d = Drawing.projectToDXF(obj.Shape, direction)
        except:
            print("Draft.getDXF: Unable to project ", obj.Label, " to ",
                  direction)
        else:
            result += d

    else:
        print("Draft.getDXF: Unsupported object: ", obj.Label)

    return result
コード例 #38
0
ファイル: ArchSectionPlane.py プロジェクト: 5263/FreeCAD
    def onChanged(self, obj, prop):
        if prop in ["Source","RenderingMode","ShowCut"]:
            import Part, DraftGeomUtils
            if hasattr(obj,"Source"):
                if obj.Source:
                    if obj.Source.Objects:
                        objs = Draft.getGroupContents(obj.Source.Objects,walls=True)
                        objs = Draft.removeHidden(objs)
                        # separate spaces
                        self.spaces = []
                        os = []
                        for o in objs:
                            if Draft.getType(o) == "Space":
                                self.spaces.append(o)
                            else:
                                os.append(o)
                        objs = os
                        self.svg = ''
                        fillpattern = '<pattern id="sectionfill" patternUnits="userSpaceOnUse" patternTransform="matrix(5,0,0,5,0,0)"'
                        fillpattern += ' x="0" y="0" width="10" height="10">'
                        fillpattern += '<g>'
                        fillpattern += '<rect width="10" height="10" style="stroke:none; fill:#ffffff" /><path style="stroke:#000000; stroke-width:1" d="M0,0 l10,10" /></g></pattern>'

                        # generating SVG
                        if obj.RenderingMode == "Solid":
                            # render using the Arch Vector Renderer
                            import ArchVRM, WorkingPlane
                            wp = WorkingPlane.plane()
                            wp.setFromPlacement(obj.Source.Placement)
                            wp.inverse()
                            render = ArchVRM.Renderer()
                            render.setWorkingPlane(wp)
                            render.addObjects(objs)
                            if hasattr(obj,"ShowCut"):
                                render.cut(obj.Source.Shape,obj.ShowCut)
                            else:
                                render.cut(obj.Source.Shape)
                            self.svg += render.getViewSVG(linewidth="LWPlaceholder")
                            self.svg += fillpattern
                            self.svg += render.getSectionSVG(linewidth="SWPlaceholder",fillpattern="sectionfill")
                            if hasattr(obj,"ShowCut"):
                                if obj.ShowCut:
                                    self.svg += render.getHiddenSVG(linewidth="LWPlaceholder")
                            # print render.info()

                        else:
                            # render using the Drawing module
                            import Drawing, Part
                            shapes = []
                            hshapes = []
                            sshapes = []
                            p = FreeCAD.Placement(obj.Source.Placement)
                            self.direction = p.Rotation.multVec(FreeCAD.Vector(0,0,1))
                            for o in objs:
                                if o.isDerivedFrom("Part::Feature"):
                                    if o.Shape.isNull():
                                        pass
                                        #FreeCAD.Console.PrintWarning(translate("Arch","Skipping empty object: ")+o.Name)
                                    elif o.Shape.isValid():
                                        if hasattr(obj.Source,"OnlySolids"):
                                            if obj.Source.OnlySolids:
                                                shapes.extend(o.Shape.Solids)
                                            else:
                                                shapes.append(o.Shape)
                                        else:
                                            shapes.extend(o.Shape.Solids)
                                    else:
                                        FreeCAD.Console.PrintWarning(translate("Arch","Skipping invalid object: ")+o.Name)
                            cutface,cutvolume,invcutvolume = ArchCommands.getCutVolume(obj.Source.Shape.copy(),shapes)
                            if cutvolume:
                                nsh = []
                                for sh in shapes:
                                    for sol in sh.Solids:
                                        if sol.Volume < 0:
                                            sol.reverse()
                                        c = sol.cut(cutvolume)
                                        s = sol.section(cutface)
                                        try:
                                            wires = DraftGeomUtils.findWires(s.Edges)
                                            for w in wires:
                                                f = Part.Face(w)
                                                sshapes.append(f)
                                            #s = Part.Wire(s.Edges)
                                            #s = Part.Face(s)
                                        except Part.OCCError:
                                            #print "ArchDrawingView: unable to get a face"
                                            sshapes.append(s)
                                        nsh.extend(c.Solids)
                                        #sshapes.append(s)
                                        if hasattr(obj,"ShowCut"):
                                            if obj.ShowCut:
                                                c = sol.cut(invcutvolume)
                                                hshapes.append(c)
                                shapes = nsh
                            if shapes:
                                self.shapes = shapes
                                self.baseshape = Part.makeCompound(shapes)
                                svgf = Drawing.projectToSVG(self.baseshape,self.direction)
                                if svgf:
                                    svgf = svgf.replace('stroke-width="0.35"','stroke-width="LWPlaceholder"')
                                    svgf = svgf.replace('stroke-width="1"','stroke-width="LWPlaceholder"')
                                    svgf = svgf.replace('stroke-width:0.01','stroke-width:LWPlaceholder')
                                    self.svg += svgf
                            if hshapes:
                                hshapes = Part.makeCompound(hshapes)
                                self.hiddenshape = hshapes
                                svgh = Drawing.projectToSVG(hshapes,self.direction)
                                if svgh:
                                    svgh = svgh.replace('stroke-width="0.35"','stroke-width="LWPlaceholder"')
                                    svgh = svgh.replace('stroke-width="1"','stroke-width="LWPlaceholder"')
                                    svgh = svgh.replace('stroke-width:0.01','stroke-width:LWPlaceholder')
                                    svgh = svgh.replace('fill="none"','fill="none"\nstroke-dasharray="DAPlaceholder"')
                                    self.svg += svgh
                            if sshapes:
                                svgs = ""
                                if hasattr(obj,"ShowFill"):
                                    if obj.ShowFill:
                                        svgs += fillpattern
                                        svgs += '<g transform="rotate(180)">\n'
                                        for s in sshapes:
                                            if s.Edges:
                                                f = Draft.getSVG(s,direction=self.direction.negative(),linewidth=0,fillstyle="sectionfill",color=(0,0,0))
                                                svgs += f
                                        svgs += "</g>\n"
                                sshapes = Part.makeCompound(sshapes)
                                self.sectionshape = sshapes
                                svgs += Drawing.projectToSVG(sshapes,self.direction)
                                if svgs:
                                    svgs = svgs.replace('stroke-width="0.35"','stroke-width="SWPlaceholder"')
                                    svgs = svgs.replace('stroke-width="1"','stroke-width="SWPlaceholder"')
                                    svgs = svgs.replace('stroke-width:0.01','stroke-width:SWPlaceholder')
                                    svgs = svgs.replace('stroke-width="0.35 px"','stroke-width="SWPlaceholder"')
                                    svgs = svgs.replace('stroke-width:0.35','stroke-width:SWPlaceholder')
                                    self.svg += svgs
コード例 #39
0
    def action(self, arg):
        # 3D scene handler. This function will be called by the 3D view on
        # special events such as keypress or mouse movements. We must take
        # care of treating what we want. All the hard work will be here!
        point, ctrlPoint = draftTools.getPoint(self, arg)
        if arg["Type"] == "SoKeyboardEvent":
            if arg["Key"] == "ESCAPE":
                # important! if ESC is pressed, we cancel everything
                self.finish()
        elif arg["Type"] == "SoLocation2Event":
            # this will be executed in case of mouse movement
            if len(self.points) == 1:
                # this will be executed after we got our first point
                self.linetracker.p2(point)
                self.length = self.linetracker.getLength()
                self.ui.setRadiusValue(self.length)
            elif len(self.points) == 2:
                # now we already have our base line, we update the 1st rectangle
                self.cubetracker[0].p3(point)
                self.width = self.cubetracker[0].getSize()[1]
                self.ui.setRadiusValue(self.width)
            elif len(self.points) == 3:
                # we must first find our height point by projecting on the normal
                w = fcvec.project(point, self.normal)
                # then we update all rectangles
                self.cubetracker[1].p3((self.cubetracker[0].p2()).add(w))
                self.cubetracker[2].p3((self.cubetracker[0].p4()).add(w))
                self.cubetracker[3].p1((self.cubetracker[0].p1()).add(w))
                self.cubetracker[3].p3((self.cubetracker[0].p3()).add(w))
                self.height = w.Length
                self.ui.setRadiusValue(self.height)

        elif arg["Type"] == "SoMouseButtonEvent":
            if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
                # this will be executed in case of mouse button 1 pressed
                print "Got point: ", point
                if len(self.points) == 0:
                    # this is our first clicked point
                    self.linetracker.p1(point)
                    self.linetracker.on()
                    # we set the radius UI, which has only a length input field
                    # but we change the "radius" name
                    self.ui.radiusUi()
                    self.ui.labelRadius.setText("Width")
                elif len(self.points) == 1:
                    # this is our second point
                    # first we turn off our line tracker
                    self.linetracker.off()
                    # then we turn on only one of the rectangles
                    baseline = point.sub(self.points[0])
                    self.cubetracker[0].setPlane(baseline)
                    self.cubetracker[0].p1(self.linetracker.p1())
                    self.cubetracker[0].on()
                    self.ui.labelRadius.setText("Length")
                elif len(self.points) == 2:
                    # this is our third point
                    # we can get the cubes Z axis from our first rectangle
                    self.normal = self.cubetracker[0].getNormal()
                    # we can therefore define the (u,v) planes of all rectangles
                    u = self.cubetracker[0].u
                    v = self.cubetracker[0].v
                    self.cubetracker[1].setPlane(u, self.normal)
                    self.cubetracker[2].setPlane(u, self.normal)
                    self.cubetracker[3].setPlane(u, v)
                    # and the origin points of the vertical rectangles
                    self.cubetracker[1].p1(self.cubetracker[0].p1())
                    self.cubetracker[2].p1(self.cubetracker[0].p3())
                    # finally we turn all rectangles on
                    for r in self.cubetracker:
                        r.on()
                    self.ui.labelRadius.setText("Heigth")
                elif len(self.points) == 3:
                    # finally we have all our points! Let's create the actual cube.
                    cube = self.doc.addObject("Part::Box", "Cube")
                    cube.Length = self.length
                    cube.Width = self.width
                    cube.Height = self.height
                    # we get 3 points that define our cube orientation
                    p1 = self.cubetracker[0].p1()
                    p2 = self.cubetracker[0].p2()
                    p3 = self.cubetracker[0].p4()
                    cube.Placement = WorkingPlane.getPlacementFromPoints(
                        [p1, p2, p3])
                    self.finish()
                self.points.append(point)