diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 29cafb7233..d0096db24a 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -1960,7 +1960,6 @@ def getDXF(obj,direction=None): return result - 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, @@ -2261,50 +2260,51 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct def getArrow(arrowtype,point,arrowsize,color,linewidth,angle=0): svg = "" - if not obj.ViewObject: - return svg - if obj.ViewObject.ArrowType == "Circle": - svg += '\n' - else: - print("getSVG: arrow type not implemented") + if gui: + if not obj.ViewObject: + return svg + if obj.ViewObject.ArrowType == "Circle": + svg += '\n' + else: + print("getSVG: arrow type not implemented") return svg def getOvershoot(point,shootsize,color,linewidth,angle=0): @@ -2410,199 +2410,203 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct elif getType(obj) == "Dimension": - 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))) - p2b = getProj(prx.p3.add(DraftVecUtils.scaleTo(prx.p2.sub(prx.p3),rm))) - p1 = getProj(prx.p1) - p2 = getProj(prx.p2) - p3 = getProj(prx.p3) - p4 = getProj(prx.p4) - tbase = getProj(prx.tbase) - 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)) - #angle = -DraftVecUtils.angle(p3.sub(p2)) - - # drawing lines - svg = ' 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 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() - 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"): + 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))) + p2b = getProj(prx.p3.add(DraftVecUtils.scaleTo(prx.p2.sub(prx.p3),rm))) + p1 = getProj(prx.p1) p2 = getProj(prx.p2) p3 = getProj(prx.p3) - 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))) - u2 = getProj((prx.circle.valueAt(prx.circle.LastParameter-arrowlength)).sub(prx.circle.valueAt(prx.circle.LastParameter))) - 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) - 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)) - tbase = tbase.add(DraftVecUtils.rotate(Vector(0,2.0/scale,0),tangle)) - #print(tbase) - else: - tangle = 0 + p4 = getProj(prx.p4) tbase = getProj(prx.tbase) - svg += getText(stroke,fontsize,obj.ViewObject.FontName,tangle,tbase,prx.string) + 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)) + #angle = -DraftVecUtils.angle(p3.sub(p2)) + + # drawing lines + svg = ' 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() + 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) + p3 = getProj(prx.p3) + 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))) + u2 = getProj((prx.circle.valueAt(prx.circle.LastParameter-arrowlength)).sub(prx.circle.valueAt(prx.circle.LastParameter))) + 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) + 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)) + tbase = tbase.add(DraftVecUtils.rotate(Vector(0,2.0/scale,0),tangle)) + #print(tbase) + else: + tangle = 0 + tbase = getProj(prx.tbase) + svg += getText(stroke,fontsize,obj.ViewObject.FontName,tangle,tbase,prx.string) elif getType(obj) in ["Annotation","DraftText"]: "returns an svg representation of a document annotation" - 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) - r = obj.ViewObject.Rotation.getValueAs("rad") - t = obj.LabelText - else: # DraftText - p = getProj(obj.Placement.Base) - r = obj.Placement.Rotation - t = obj.Text - j = obj.ViewObject.Justification - svg += getText(stroke,fontsize,n,r,p,t,linespacing,j) + 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) + r = obj.ViewObject.Rotation.getValueAs("rad") + t = obj.LabelText + else: # DraftText + p = getProj(obj.Placement.Base) + 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 not obj.ViewObject: - print ("export of axes to SVG is only available in GUI mode") - else: - vobj = obj.ViewObject - lorig = getLineStyle() - 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 += '\n' - svg += '\n' - n += 1 + if gui: + if not obj.ViewObject: + print ("export of axes to SVG is only available in GUI mode") + else: + vobj = obj.ViewObject + lorig = getLineStyle() + 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 += '\n' + svg += '\n' + n += 1 elif getType(obj) == "Pipe": fill = stroke @@ -2628,28 +2632,29 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct elif getType(obj) == "Space": "returns an SVG fragment for the text of a space" - 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),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).add(ofs),t2,linespacing,j,flip=True) + 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),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).add(ofs),t2,linespacing,j,flip=True) elif obj.isDerivedFrom('Part::Feature'): if obj.Shape.isNull(): @@ -4159,8 +4164,9 @@ class _Dimension(_DraftObject): n2 = int(lsub2[0][6:])-1 obj.Start = lobj1.Shape.Vertexes[n1].Point obj.End = lobj2.Shape.Vertexes[n2].Point - if obj.ViewObject: - obj.ViewObject.update() + if gui: + if obj.ViewObject: + obj.ViewObject.update() class _ViewProviderDimension(_ViewProviderDraft):