0001042: Draft DXF export with projection direction

The DXF exporter now features an option in Draft preferences
to project the selected objects along the current view direction
on export.
This commit is contained in:
Yorik van Havre
2013-04-11 14:20:50 -03:00
parent 9d067e5e88
commit 6dbf66b2a9
5 changed files with 394 additions and 293 deletions

View File

@@ -1190,13 +1190,27 @@ def insert(filename,docname):
# EXPORT ########################################################################
def projectShape(shape,direction):
import Drawing
edges = []
try:
groups = Drawing.projectEx(shape,direction)
except:
print "unable to project shape"
return shape
else:
for g in groups[0:5]:
if g:
edges.append(g)
return DraftGeomUtils.cleanProjection(Part.makeCompound(edges))
def getArcData(edge):
"returns center, radius, start and end angles of a circle-based edge"
ce = edge.Curve.Center
radius = edge.Curve.Radius
if len(edge.Vertexes) == 1:
# closed circle
return ce, radius, 0, 0
return DraftVecUtils.tup(ce), radius, 0, 0
else:
# find direction of arc
tang1 = edge.Curve.tangent(edge.ParameterRange[0])
@@ -1218,7 +1232,15 @@ def getArcData(edge):
ang2 = -math.degrees(DraftVecUtils.angle(ve2.sub(ce)))
ve3 = DraftGeomUtils.findMidpoint(edge)
ang3 = -math.degrees(DraftVecUtils.angle(ve3.sub(ce)))
print "edge ",edge.hashCode()," data ",ang1, " , ",ang2," , ", ang3
if (ang3 < ang1) and (ang2 < ang3):
print "inverting, case1"
ang1, ang2 = ang2, ang1
elif (ang3 > ang1) and (ang3 > ang2):
print "inverting, case2"
ang1, ang2 = ang2, ang1
elif (ang3 < ang1) and (ang3 < ang2):
print "inverting, case3"
ang1, ang2 = ang2, ang1
return DraftVecUtils.tup(ce), radius, ang1, ang2
@@ -1246,6 +1268,7 @@ def getWire(wire,nospline=False):
"returns an array of dxf-ready points and bulges from a wire"
edges = DraftGeomUtils.sortEdges(wire.Edges)
points = []
# print "processing wire ",wire.Edges
for edge in edges:
v1 = edge.Vertexes[0].Point
if len(edge.Vertexes) < 2:
@@ -1256,7 +1279,8 @@ def getWire(wire,nospline=False):
c = edge.Curve.Center
angle = abs(DraftVecUtils.angle(v1.sub(c),v2.sub(c)))
if DraftGeomUtils.isWideAngle(edge):
angle = math.pi*2 - angle
if angle < math.pi:
angle = math.pi*2 - angle
# if (DraftVecUtils.angle(v2.sub(c)) < DraftVecUtils.angle(v1.sub(c))):
# angle = -angle
# polyline bulge -> negative makes the arc go clockwise
@@ -1293,16 +1317,16 @@ def getWire(wire,nospline=False):
# print "wire verts: ",points
return points
def getBlock(obj):
def getBlock(sh,obj):
"returns a dxf block with the contents of the object"
block = dxfLibrary.Block(name=obj.Name,layer=getGroup(obj,exportList))
writeShape(obj,block)
writeShape(sh,obj,block)
return block
def writeShape(ob,dxfobject,nospline=False):
def writeShape(sh,ob,dxfobject,nospline=False):
"writes the object's shape contents in the given dxf object"
processededges = []
for wire in ob.Shape.Wires: # polylines
for wire in sh.Wires: # polylines
for e in wire.Edges:
processededges.append(e.hashCode())
if (len(wire.Edges) == 1) and (DraftGeomUtils.geomType(wire.Edges[0]) == "Circle"):
@@ -1319,22 +1343,32 @@ def writeShape(ob,dxfobject,nospline=False):
dxfobject.append(dxfLibrary.PolyLine(getWire(wire,nospline), [0.0,0.0,0.0],
int(DraftGeomUtils.isReallyClosed(wire)), color=getACI(ob),
layer=getGroup(ob,exportList)))
if len(processededges) < len(ob.Shape.Edges): # lone edges
if len(processededges) < len(sh.Edges): # lone edges
loneedges = []
for e in ob.Shape.Edges:
for e in sh.Edges:
if not(e.hashCode() in processededges): loneedges.append(e)
# print "lone edges ",loneedges
for edge in loneedges:
if (DraftGeomUtils.geomType(edge) == "BSplineCurve") and ((not nospline) or (len(edge.Vertexes) == 1)): # splines
points = []
spline = getSplineSegs(edge)
for p in spline:
points.append((p.x,p.y,p.z,None,None,0.0))
dxfobject.append(dxfLibrary.PolyLine(points, [0.0,0.0,0.0],
0, color=getACI(ob),
layer=getGroup(ob,exportList)))
if (len(edge.Vertexes) == 1) and (edge.Curve.isClosed()):
# special case: 1-vert closed spline, approximate as a circle
c = DraftGeomUtils.getCircleFromSpline(edge)
if c:
dxfobject.append(dxfLibrary.Circle(DraftVecUtils.tup(c.Curve.Center), c.Curve.Radius,
color=getACI(ob),
layer=getGroup(ob,exportList)))
else:
points = []
spline = getSplineSegs(edge)
for p in spline:
points.append((p.x,p.y,p.z,None,None,0.0))
dxfobject.append(dxfLibrary.PolyLine(points, [0.0,0.0,0.0],
0, color=getACI(ob),
layer=getGroup(ob,exportList)))
elif DraftGeomUtils.geomType(edge) == "Circle": # curves
center, radius, ang1, ang2 = getArcData(edge)
if not isinstance(center,tuple):
center = DraftVecUtils.tup(center)
if len(edge.Vertexes) == 1: # circles
dxfobject.append(dxfLibrary.Circle(center, radius,
color=getACI(ob),
@@ -1389,27 +1423,37 @@ def export(objectslist,filename,nospline=False):
for ob in exportList:
print "processing ",ob.Name
if ob.isDerivedFrom("Part::Feature"):
if not ob.Shape.isNull():
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetBool("dxfmesh"):
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetBool("dxfmesh"):
sh = None
if not ob.Shape.isNull():
writeMesh(ob,dxf)
elif FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetBool("dxfproject"):
direction = FreeCADGui.ActiveDocument.ActiveView.getViewDirection()
sh = projectShape(ob.Shape,direction)
else:
if ob.Shape.Volume > 0:
sh = projectShape(ob.Shape,Vector(0,0,1))
else:
if ob.Shape.ShapeType == 'Compound':
if (len(ob.Shape.Wires) == 1):
sh = ob.Shape
if sh:
if not sh.isNull():
if sh.ShapeType == 'Compound':
if (len(sh.Wires) == 1):
# only one wire in this compound, no lone edge -> polyline
if (len(ob.Shape.Wires[0].Edges) == len(ob.Shape.Edges)):
writeShape(ob,dxf,nospline)
if (len(sh.Wires[0].Edges) == len(sh.Edges)):
writeShape(sh,ob,dxf,nospline)
else:
# 1 wire + lone edges -> block
block = getBlock(ob)
block = getBlock(sh,ob)
dxf.blocks.append(block)
dxf.append(dxfLibrary.Insert(name=ob.Name.upper()))
else:
# all other cases: block
block = getBlock(ob)
block = getBlock(sh,ob)
dxf.blocks.append(block)
dxf.append(dxfLibrary.Insert(name=ob.Name.upper()))
else:
writeShape(ob,dxf,nospline)
writeShape(sh,ob,dxf,nospline)
elif Draft.getType(ob) == "Annotation":
# texts