Draft: workaround for exporting DXF with R14+ templates - fixes 2177

- Adapted Drawing algos to export R14+ compatible DXF code
- Added option in DXF prefs to disable groups (not supported in R14+ templates)
This commit is contained in:
Yorik van Havre 2015-12-18 10:47:14 -02:00
parent 45292eb9ee
commit dab7ef4262
4 changed files with 103 additions and 46 deletions

View File

@ -1672,7 +1672,10 @@ def getDXF(obj,direction=None):
elif obj.isDerivedFrom("Part::Feature"):
# TODO do this the Draft way, for ex. using polylines and rectangles
import Drawing
if not direction: direction = FreeCAD.Vector(0,0,-1)
if not direction:
direction = FreeCAD.Vector(0,0,-1)
if DraftVecUtils.isNull(direction):
direction = FreeCAD.Vector(0,0,-1)
result += Drawing.projectToDXF(obj.Shape,direction)
else:
@ -4522,7 +4525,7 @@ class _DrawingView(_DraftObject):
if o.ViewObject.isVisible():
result += getDXF(o,obj.Direction)
else:
result += getDXF(o,obj.Direction)
result += getDXF(obj.Source,obj.Direction)
return result
class _BSpline(_DraftObject):

View File

@ -478,6 +478,29 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_5">
<property name="toolTip">
<string>if this is checked, Drawing Views will be exported as blocks. This might fail for post-R12 templates.</string>
</property>
<property name="text">
<string>Export Drawing Views as blocks</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfExportBlocks</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>

View File

@ -1861,18 +1861,23 @@ def export(objectslist,filename,nospline=False,lwPoly=False):
FreeCAD.Console.PrintMessage("successfully exported "+filename+"\r\n")
else:
errorDXFLib(gui)
class dxfcounter:
def __init__(self):
self.count = 10000 # this leaves 10000 entities for the template...
def incr(self,matchobj):
self.count += 1
#print format(self.count,'02x')
return format(self.count,'02x')
def exportPage(page,filename):
"special export for pages"
template = os.path.splitext(page.Template)[0]+".dxf"
global dxfhandle
dxfhandle = 1
if os.path.exists(template):
f = pythonopen(template,"U")
template = f.read()
f.close()
# find & replace editable texts
import re
f = pythonopen(page.Template,"rb")
svgtemplate = f.read()
f.close()
@ -1886,8 +1891,8 @@ def exportPage(page,filename):
print("DXF version of the template not found. Creating a default empty template.")
template = "999\nFreeCAD DXF exporter v"+FreeCAD.Version()[0]+"."+FreeCAD.Version()[1]+"-"+FreeCAD.Version()[2]+"\n"
template += "0\nSECTION\n2\nHEADER\n9\n$ACADVER\n1\nAC1009\n0\nENDSEC\n"
template += "0\nSECTION\n2\nBLOCKS\n$blocks\n0\nENDSEC\n"
template += "0\nSECTION\n2\nENTITIES\n$entities\n0\nENDSEC\n"
template += "0\nSECTION\n2\nBLOCKS\n999\n$blocks\n0\nENDSEC\n"
template += "0\nSECTION\n2\nENTITIES\n999\n$entities\n0\nENDSEC\n"
template += "0\nEOF"
blocks = ""
entities = ""
@ -1895,18 +1900,23 @@ def exportPage(page,filename):
b,e = getViewDXF(view)
blocks += b
entities += e
result = template.replace("999\n$blocks",blocks[:-1])
result = result.replace("999\n$entities",entities[:-1])
if blocks:
template = template.replace("999\n$blocks",blocks[:-1])
if entities:
template = template.replace("999\n$entities",entities[:-1])
c = dxfcounter()
pat = re.compile("(_handle_)")
template = pat.sub(c.incr,template)
f = pythonopen(filename,"wb")
f.write(result)
f.write(template)
f.close()
def getViewDXF(view):
def getViewDXF(view,blocks=True):
"returns a DXF fragment from a Drawing View"
global dxfhandle
block = ""
insert = ""
blockcount = 1
if view.isDerivedFrom("App::DocumentObjectGroup"):
for child in view.Group:
@ -1918,47 +1928,52 @@ def getViewDXF(view):
if hasattr(view.Proxy,"getDXF"):
r = view.Rotation
if r != 0: r = -r # fix rotation direction
count = 0
block = ""
insert = ""
geom = view.Proxy.getDXF(view)
if not isinstance(geom,list): geom = [geom]
for g in geom: # getDXF returns a list of entities
g = g.replace("sheet_layer\n","0\n6\nBYBLOCK\n62\n0\n") # change layer and set color and ltype to BYBLOCK (0)
block += "0\nBLOCK\n8\n0\n2\n"+view.Name+str(count)+"\n70\n0\n10\n0\n20\n0\n3\n"+view.Name+str(count)+"\n1\n\n"
block += g
block += "0\nENDBLK\n8\n0\n"
insert += "0\nINSERT\n5\naaaa"+hex(dxfhandle)[2:]+"\n8\n0\n6\nBYLAYER\n62\n256\n2\n"+view.Name+str(count)
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"
dxfhandle += 1
count += 1
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
elif view.isDerivedFrom("Drawing::FeatureViewPart"):
r = view.Rotation
if r != 0: r = -r # fix rotation direction
import Drawing
proj = Drawing.projectToDXF(view.Source.Shape,view.Direction)
proj = proj.replace("sheet_layer\n","0\n6\nBYBLOCK\n62\n0\n") # change layer and set color and ltype to BYBLOCK (0)
block = "0\nBLOCK\n8\n0\n2\n"+view.Name+"\n70\n0\n10\n0\n20\n0\n3\n"+view.Name+"\n1\n\n"
block += proj
block += "0\nENDBLK\n8\n0\n"
insert = "0\nINSERT\n5\naaaa"+hex(dxfhandle)[2:]+"\n8\n0\n6\nBYLAYER\n62\n256\n2\n"+view.Name
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"
dxfhandle += 1
if dxfExportBlocks:
proj = proj.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 += proj
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:
proj = proj.replace("sheet_layer\n","0\n5\n_handle_\n")
insert += proj
elif view.isDerivedFrom("Drawing::FeatureViewAnnotation"):
r = view.Rotation
if r != 0: r = -r # fix rotation direction
insert ="0\nTEXT\n5\n"+hex(dxfhandle)[2:]+"\n8\n0"
insert ="0\nTEXT\n5\n_handle_\n8\n0\n100\nAcDbEntity\n100\nAcDbText\n5\n_handle_"
insert += "\n10\n"+str(view.X)+"\n20\n"+str(-view.Y)
insert += "\n30\n0\n40\n"+str(view.Scale/2)
insert += "\n50\n"+str(r)
insert += "\n1\n"+view.Text[0]+"\n"
dxfhandle += 1
else:
print("Unable to get DXF representation from view: ",view.Label)
@ -1979,7 +1994,7 @@ def readPreferences():
global dxfCreatePart, dxfCreateDraft, dxfCreateSketch, dxfDiscretizeCurves, dxfStarBlocks
global dxfMakeBlocks, dxfJoin, dxfRenderPolylineWidth, dxfImportTexts, dxfImportLayouts
global dxfImportPoints, dxfImportHatches, dxfUseStandardSize, dxfGetColors, dxfUseDraftVisGroups
global dxfFillMode, dxfBrightBackground, dxfDefaultColor, dxfUseLegacyImporter
global dxfFillMode, dxfBrightBackground, dxfDefaultColor, dxfUseLegacyImporter, dxfExportBlocks
dxfCreatePart = p.GetBool("dxfCreatePart",True)
dxfCreateDraft = p.GetBool("dxfCreateDraft",False)
dxfCreateSketch = p.GetBool("dxfCreateSketch",False)
@ -1999,3 +2014,4 @@ def readPreferences():
dxfUseLegacyImporter = p.GetBool("dxfUseLegacyImporter",True)
dxfBrightBackground = isBrightBackground()
dxfDefaultColor = getColor()
dxfExportBlocks = p.GetBool("dxfExportBlocks",True)

View File

@ -495,6 +495,10 @@ void DXFOutput::printCircle(const BRepAdaptor_Curve& c, std::ostream& out)
out << "CIRCLE" << endl;
out << 8 << endl; // Group code for layer name
out << "sheet_layer" << endl; // Layer number
out << "100" << endl;
out << "AcDbEntity" << endl;
out << "100" << endl;
out << "AcDbCircle" << endl;
out << 10 << endl; // Centre X
out << p.X() << endl; // X in WCS coordinates
out << 20 << endl;
@ -534,6 +538,10 @@ void DXFOutput::printCircle(const BRepAdaptor_Curve& c, std::ostream& out)
out << "ARC" << endl;
out << 8 << endl; // Group code for layer name
out << "sheet_layer" << endl; // Layer number
out << "100" << endl;
out << "AcDbEntity" << endl;
out << "100" << endl;
out << "AcDbCircle" << endl;
out << 10 << endl; // Centre X
out << p.X() << endl; // X in WCS coordinates
out << 20 << endl;
@ -542,6 +550,8 @@ void DXFOutput::printCircle(const BRepAdaptor_Curve& c, std::ostream& out)
out << 0 << endl; // Z in WCS coordinates
out << 40 << endl; //
out << r << endl; // Radius
out << "100" << endl;
out << "AcDbArc" << endl;
out << 50 << endl;
out << start_angle << endl; // Start angle
out << 51 << endl;
@ -601,6 +611,10 @@ void DXFOutput::printEllipse(const BRepAdaptor_Curve& c, int id, std::ostream& o
out << "ELLIPSE" << endl;
out << 8 << endl; // Group code for layer name
out << "sheet_layer" << endl; // Layer number
out << "100" << endl;
out << "AcDbEntity" << endl;
out << "100" << endl;
out << "AcDbEllipse" << endl;
out << 10 << endl; // Centre X
out << p.X() << endl; // X in WCS coordinates
out << 20 << endl;
@ -657,17 +671,14 @@ void DXFOutput::printBSpline(const BRepAdaptor_Curve& c, int id, std::ostream& o
str << 0 << endl
<< "SECTION" << endl
<< 2 << endl
<< "ENTITIES" << endl
<< 0 << endl
<< "SPLINE" << endl;
//<< 8 << endl
//<< 0 << endl
//<< 66 << endl
//<< 1 << endl
//<< 0 << endl;
str << 70 << endl
<< "SPLINE" << endl
<< 8 << endl // Group code for layer name
<< "sheet_layer" << endl // Layer name
<< "100" << endl
<< "AcDbEntity" << endl
<< "100" << endl
<< "AcDbSpline" << endl
<< 70 << endl
<< spline->IsRational()*4 << endl //flags
<< 71 << endl << spline->Degree() << endl
<< 72 << endl << knotsequence.Length() << endl
@ -711,6 +722,10 @@ void DXFOutput::printGeneric(const BRepAdaptor_Curve& c, int id, std::ostream& o
out << "LINE" << endl;
out << "8" << endl; // Group code for layer name
out << "sheet_layer" << endl; // Layer name
out << "100" << endl;
out << "AcDbEntity" << endl;
out << "100" << endl;
out << "AcDbLine" << endl;
out << "10" << endl; // Start point of line
out << PS.X() << endl; // X in WCS coordinates
out << "20" << endl;