diff --git a/src/Mod/Arch/ArchSectionPlane.py b/src/Mod/Arch/ArchSectionPlane.py index c527a6754b0f..8bded9a667ec 100644 --- a/src/Mod/Arch/ArchSectionPlane.py +++ b/src/Mod/Arch/ArchSectionPlane.py @@ -75,6 +75,50 @@ def makeSectionView(section,name="View"): return view +def getCutShapes(objs,section,showHidden): + import Part,DraftGeomUtils + shapes = [] + hshapes = [] + sshapes = [] + for o in objs: + if o.isDerivedFrom("Part::Feature"): + if o.Shape.isNull(): + pass + elif section.OnlySolids: + if o.Shape.isValid(): + shapes.extend(o.Shape.Solids) + else: + print section.Label,": Skipping invalid object:",o.Label + else: + shapes.append(o.Shape) + 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 + return shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume + + 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 @@ -140,45 +184,7 @@ def getSVG(section,allOn=False,renderMode="Wireframe",showHidden=False,showFill= 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 + shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume = getCutShapes(objs,section,showHidden) if shapes: baseshape = Part.makeCompound(shapes) svgf = Drawing.projectToSVG(baseshape,direction) @@ -255,11 +261,12 @@ def getSVG(section,allOn=False,renderMode="Wireframe",showHidden=False,showFill= c = Part.makeCompound(w.Proxy.sshapes) c.Placement = w.Placement sh.append(c) - if hasattr(w.Proxy,"vshapes"): - if w.Proxy.vshapes: - c = Part.makeCompound(w.Proxy.vshapes) - 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 += '' @@ -272,6 +279,45 @@ def getSVG(section,allOn=False,renderMode="Wireframe",showHidden=False,showFill= return svg +def getDXF(obj): + "returns a DXF representation from a TechDraw/Drawing view" + allOn = True + if hasattr(obj,"AllOn"): + allOn = obj.AllOn + elif hasattr(obj,"AlwaysOn"): + allOn = obj.AlwaysOn + showHidden = False + if hasattr(obj,"showCut"): + showHidden = obj.showCut + elif hasattr(obj,"showHidden"): + showHidden = obj.showHidden + result = [] + import Drawing,Part + if not obj.Source: + return result + section = obj.Source + if not section.Objects: + return result + 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 = [] + objs = [o for o in objs if ((not(Draft.getType(o) in ["Space","Dimension","Annotation"])) and (not (o.isDerivedFrom("Part::Part2DObject"))))] + shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume = getCutShapes(objs,section,showHidden) + if shapes: + result.append(Drawing.projectToDXF(Part.makeCompound(shapes),direction)) + if sshapes: + result.append(Drawing.projectToDXF(Part.makeCompound(sshapes),direction)) + if hshapes: + result.append(Drawing.projectToDXF(Part.makeCompound(hshapes),direction)) + return result + + class _CommandSectionPlane: "the Arch SectionPlane command definition" def GetResources(self): diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index c2c04776dc80..032607697652 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -1671,6 +1671,13 @@ def getDXF(obj,direction=None): 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,FreeCAD.Vector): if direction != Vector(0,0,0): @@ -1846,52 +1853,57 @@ def getPath(edges=[],wires=[],pathname=None): isellipse = DraftGeomUtils.geomType(e) == "Ellipse" if iscircle or isellipse: import math - c = e.Curve - 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)), \ - getProj(vs[-1].Point)) - else: - endpoints = (getProj(vs[-1].Point),) - - # 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 carefull with the sweep flag 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 - 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)) + c = e.Curve + if round(c.Axis.getAngle(drawing_plane_normal),2) == 1.57: + # arc is perpendicular to view direction: represent as a line + v = getProj(vs[-1].Point) + edata += 'L '+ str(v.x) +' '+ str(v.y) + ' ' + else: + 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)), \ + getProj(vs[-1].Point)) + else: + endpoints = (getProj(vs[-1].Point),) + + # 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 carefull 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)) elif DraftGeomUtils.geomType(e) == "Line": v = getProj(vs[-1].Point) edata += 'L '+ str(v.x) +' '+ str(v.y) + ' ' @@ -4773,14 +4785,7 @@ def execute(self, obj): def getDXF(self,obj): "returns a DXF fragment" - result = "" - if obj.Source.isDerivedFrom("App::DocumentObjectGroup"): - for o in obj.Source.Group: - if o.ViewObject.isVisible(): - result += getDXF(o,obj.Direction) - else: - result += getDXF(obj.Source,obj.Direction) - return result + return getDXF(obj) class _BSpline(_DraftObject): "The BSpline object" diff --git a/src/Mod/Draft/importDXF.py b/src/Mod/Draft/importDXF.py index d1aeb5f64514..4b5943fd08ce 100644 --- a/src/Mod/Draft/importDXF.py +++ b/src/Mod/Draft/importDXF.py @@ -1813,6 +1813,10 @@ def export(objectslist,filename,nospline=False,lwPoly=False): # page: special hack-export! (see below) exportPage(exportList[0],filename) + elif (len(exportList) == 1) and (exportList[0].isDerivedFrom("TechDraw::DrawPage")): + # page: special hack-export! (see below) + exportPage(exportList[0],filename) + else: # other cases, treat edges dxf = dxfLibrary.Drawing() @@ -1900,7 +1904,12 @@ def incr(self,matchobj): def exportPage(page,filename): "special export for pages" - template = os.path.splitext(page.Template)[0]+".dxf" + if hasattr(page.Template,"Template"): #techdraw + template="" # not supported for now... + views = page.Views + else: #drawing + template = os.path.splitext(page.Template)[0]+".dxf" + views = page.Group if os.path.exists(template): f = pythonopen(template,"U") template = f.read() @@ -1930,7 +1939,7 @@ def exportPage(page,filename): # at the moment this is not used. TODO: if r12, do not print ellipses or splines if ver[0].upper() in ["AC1009","AC1010","AC1011","AC1012","AC1013"]: r12 = True - for view in page.Group: + for view in views: b,e = getViewDXF(view) blocks += b entities += e @@ -1945,6 +1954,28 @@ def exportPage(page,filename): f.write(template) f.close() +def getBlock(geom,view,blockcount): + insert = "" + block = "" + r = view.Rotation + if r != 0: r = -r # fix rotation direction + if not isinstance(geom,list): geom = [geom] + for g in geom: # getDXF returns a list of entities + if dxfExportBlocks: + g = g.replace("sheet_layer\n","0\n6\nBYBLOCK\n62\n0\n5\n_handle_\n") # change layer and set color and ltype to BYBLOCK (0) + block += "0\nBLOCK\n5\n_handle_\n100\nAcDbEntity\n8\n0\n100\nAcDbBlockBegin\n2\n"+view.Name+str(blockcount)+"\n70\n0\n10\n0\n20\n0\n3\n"+view.Name+str(blockcount)+"\n1\n\n" + block += g + block += "0\nENDBLK\n5\n_handle_\n100\nAcDbEntity\n8\n0\n100\nAcDbBlockEnd\n" + insert += "0\nINSERT\n5\n_handle_\n8\n0\n6\nBYLAYER\n62\n256\n2\n"+view.Name+str(blockcount) + insert += "\n10\n"+str(view.X)+"\n20\n"+str(-view.Y) + insert += "\n30\n0\n41\n"+str(view.Scale)+"\n42\n"+str(view.Scale)+"\n43\n"+str(view.Scale) + insert += "\n50\n"+str(r)+"\n" + blockcount += 1 + else: + g = g.replace("sheet_layer\n","0\n5\n_handle_\n") # change layer, add handle + insert += g + return block,insert,blockcount + def getViewDXF(view,blocks=True): "returns a DXF fragment from a Drawing View" @@ -1960,26 +1991,17 @@ def getViewDXF(view,blocks=True): elif view.isDerivedFrom("Drawing::FeatureViewPython"): if hasattr(view.Proxy,"getDXF"): - r = view.Rotation - if r != 0: r = -r # fix rotation direction - block = "" - insert = "" geom = view.Proxy.getDXF(view) - if not isinstance(geom,list): geom = [geom] - for g in geom: # getDXF returns a list of entities - if dxfExportBlocks: - g = g.replace("sheet_layer\n","0\n6\nBYBLOCK\n62\n0\n5\n_handle_\n") # change layer and set color and ltype to BYBLOCK (0) - block += "0\nBLOCK\n5\n_handle_\n100\nAcDbEntity\n8\n0\n100\nAcDbBlockBegin\n2\n"+view.Name+str(blockcount)+"\n70\n0\n10\n0\n20\n0\n3\n"+view.Name+str(blockcount)+"\n1\n\n" - block += g - block += "0\nENDBLK\n5\n_handle_\n100\nAcDbEntity\n8\n0\n100\nAcDbBlockEnd\n" - insert += "0\nINSERT\n5\n_handle_\n8\n0\n6\nBYLAYER\n62\n256\n2\n"+view.Name+str(blockcount) - insert += "\n10\n"+str(view.X)+"\n20\n"+str(-view.Y) - insert += "\n30\n0\n41\n"+str(view.Scale)+"\n42\n"+str(view.Scale)+"\n43\n"+str(view.Scale) - insert += "\n50\n"+str(r)+"\n" - blockcount += 1 - else: - g = g.replace("sheet_layer\n","0\n5\n_handle_\n") # change layer, add handle - insert += g + block,insert,blockcount = getBlock(geom,view,blockcount) + + elif view.isDerivedFrom("TechDraw::DrawViewDraft"): + geom = Draft.getDXF(view) + block,insert,blockcount = getBlock(geom,view,blockcount) + + elif view.isDerivedFrom("TechDraw::DrawViewArch"): + import ArchSectionPlane + geom = ArchSectionPlane.getDXF(view) + block,insert,blockcount = getBlock(geom,view,blockcount) elif view.isDerivedFrom("Drawing::FeatureViewPart"): r = view.Rotation @@ -2022,6 +2044,7 @@ def exportPageLegacy(page,filename): export(tempobj,filename,nospline=True,lwPoly=False) FreeCAD.closeDocument(tempdoc.Name) + def readPreferences(): # reading parameters p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")