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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user