Draft: implemented dxf export of techdraw pages
This commit is contained in:
parent
6f4f92019a
commit
945d99f982
|
@ -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 += '<g transform="scale(1,-1)">'
|
||||
|
@ -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):
|
||||
|
|
|
@ -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 getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct
|
|||
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 @@ class _DrawingView(_DraftObject):
|
|||
|
||||
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"
|
||||
|
|
|
@ -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 @@ class dxfcounter:
|
|||
|
||||
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")
|
||||
|
|
Loading…
Reference in New Issue
Block a user