From 2e149d05c79a7e74f935c59501882182be0f33dc Mon Sep 17 00:00:00 2001 From: yorikvanhavre Date: Fri, 28 Oct 2011 15:23:35 +0000 Subject: [PATCH] + fixed indentation in Draft DXF importer git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5078 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Draft/importDXF.py | 1891 ++++++++++++++++++------------------ 1 file changed, 944 insertions(+), 947 deletions(-) diff --git a/src/Mod/Draft/importDXF.py b/src/Mod/Draft/importDXF.py index 8e531434f..ae87fb702 100644 --- a/src/Mod/Draft/importDXF.py +++ b/src/Mod/Draft/importDXF.py @@ -56,1041 +56,1038 @@ pythonopen = open # to distinguish python built-in open function from the one de prec = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetInt("precision") def decodeName(name): - "decodes encoded strings" - try: - decodedName = (name.decode("utf8")) - except UnicodeDecodeError: - try: - decodedName = (name.decode("latin1")) - except UnicodeDecodeError: - print "dxf: error: couldn't determine character encoding" - decodedName = name - return decodedName + "decodes encoded strings" + try: + decodedName = (name.decode("utf8")) + except UnicodeDecodeError: + try: + decodedName = (name.decode("latin1")) + except UnicodeDecodeError: + print "dxf: error: couldn't determine character encoding" + decodedName = name + return decodedName def locateLayer(wantedLayer): - "returns layer group and creates it if needed" - wantedLayerName = decodeName(wantedLayer) - for l in layers: - if wantedLayerName==l.Label: - return l - newLayer = doc.addObject("App::DocumentObjectGroup",wantedLayer) - newLayer.Label = wantedLayerName - layers.append(newLayer) - return newLayer + "returns layer group and creates it if needed" + wantedLayerName = decodeName(wantedLayer) + for l in layers: + if wantedLayerName==l.Label: + return l + newLayer = doc.addObject("App::DocumentObjectGroup",wantedLayer) + newLayer.Label = wantedLayerName + layers.append(newLayer) + return newLayer def calcBulge(v1,bulge,v2): - ''' - calculates intermediary vertex for curved segments. - algorithm from http://www.afralisp.net/lisp/Bulges1.htm - ''' - chord = v2.sub(v1) - sagitta = (bulge * chord.Length)/2 - startpoint = v1.add(fcvec.scale(chord,0.5)) - perp = chord.cross(Vector(0,0,1)) - if not fcvec.isNull(perp): perp.normalize() - endpoint = fcvec.scale(perp,sagitta) - return startpoint.add(endpoint) + ''' + calculates intermediary vertex for curved segments. + algorithm from http://www.afralisp.net/lisp/Bulges1.htm + ''' + chord = v2.sub(v1) + sagitta = (bulge * chord.Length)/2 + startpoint = v1.add(fcvec.scale(chord,0.5)) + perp = chord.cross(Vector(0,0,1)) + if not fcvec.isNull(perp): perp.normalize() + endpoint = fcvec.scale(perp,sagitta) + return startpoint.add(endpoint) def getGroup(ob,exportList): - "checks if the object is part of a group" - for i in exportList: - if (i.Type == "App::DocumentObjectGroup"): - for j in i.Group: - if (j == ob): - return i.Label - return "0" + "checks if the object is part of a group" + for i in exportList: + if (i.Type == "App::DocumentObjectGroup"): + for j in i.Group: + if (j == ob): + return i.Label + return "0" def getACI(ob,text=False): - "gets the ACI color closest to the objects color" - if not gui: return 0 - else: - if text: - col=ob.ViewObject.TextColor - else: - col=ob.ViewObject.LineColor - aci=[0,442] - for i in range (255,-1,-1): - ref=dxfColorMap.color_map[i] - dist=((ref[0]-col[0])**2 + (ref[1]-col[1])**2 + (ref[2]-col[2])**2) - if (dist <= aci[1]): aci=[i,dist] - return aci[0] + "gets the ACI color closest to the objects color" + if not gui: return 0 + else: + if text: + col=ob.ViewObject.TextColor + else: + col=ob.ViewObject.LineColor + aci=[0,442] + for i in range (255,-1,-1): + ref=dxfColorMap.color_map[i] + dist=((ref[0]-col[0])**2 + (ref[1]-col[1])**2 + (ref[2]-col[2])**2) + if (dist <= aci[1]): aci=[i,dist] + return aci[0] def rawValue(entity,code): - "returns the value of a DXF code in an entity section" - value = None - for pair in entity.data: - if pair[0] == code: - value = pair[1] - return value + "returns the value of a DXF code in an entity section" + value = None + for pair in entity.data: + if pair[0] == code: + value = pair[1] + return value class fcformat: - "this contains everything related to color/lineweight formatting" - def __init__(self,drawing): - self.dxf = drawing - params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") - self.paramtext = params.GetBool("dxftext") - self.paramstarblocks = params.GetBool("dxfstarblocks") - self.dxflayout = params.GetBool("dxflayouts") - self.paramstyle = params.GetInt("dxfstyle") - self.join = params.GetBool("joingeometry") - self.makeBlocks = params.GetBool("groupLayers") - bparams = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/View") + "this contains everything related to color/lineweight formatting" + def __init__(self,drawing): + self.dxf = drawing + params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") + self.paramtext = params.GetBool("dxftext") + self.paramstarblocks = params.GetBool("dxfstarblocks") + self.dxflayout = params.GetBool("dxflayouts") + self.paramstyle = params.GetInt("dxfstyle") + self.join = params.GetBool("joingeometry") + self.makeBlocks = params.GetBool("groupLayers") + bparams = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/View") - if self.paramstyle > 1: - # checking if FreeCAD background is dark or bright - if bparams.GetBool("Gradient"): - c1 = bparams.GetUnsigned("BackgroundColor2") - c2 = bparams.GetUnsigned("BackgroundColor3") - r1 = float((c1>>24)&0xFF) - g1 = float((c1>>16)&0xFF) - b1 = float((c1>>8)&0xFF) - r2 = float((c2>>24)&0xFF) - g2 = float((c2>>16)&0xFF) - b2 = float((c2>>8)&0xFF) - v1 = FreeCAD.Vector(r1,g1,b1) - v2 = FreeCAD.Vector(r2,g2,b2) - v = v2.sub(v1) - v = fcvec.scale(v,0.5) - cv = v1.add(v) - else: - c1 = bparams.GetUnsigned("BackgroundColor") - r1 = float((c1>>24)&0xFF) - g1 = float((c1>>16)&0xFF) - b1 = float((c1>>8)&0xFF) - cv = FreeCAD.Vector(r1,g1,b1) - value = cv.x*.3 + cv.y*.59 + cv.z*.11 - if value < 128: self.brightbg = False - else: - self.brightbg = True + if self.paramstyle > 1: + # checking if FreeCAD background is dark or bright + if bparams.GetBool("Gradient"): + c1 = bparams.GetUnsigned("BackgroundColor2") + c2 = bparams.GetUnsigned("BackgroundColor3") + r1 = float((c1>>24)&0xFF) + g1 = float((c1>>16)&0xFF) + b1 = float((c1>>8)&0xFF) + r2 = float((c2>>24)&0xFF) + g2 = float((c2>>16)&0xFF) + b2 = float((c2>>8)&0xFF) + v1 = FreeCAD.Vector(r1,g1,b1) + v2 = FreeCAD.Vector(r2,g2,b2) + v = v2.sub(v1) + v = fcvec.scale(v,0.5) + cv = v1.add(v) + else: + c1 = bparams.GetUnsigned("BackgroundColor") + r1 = float((c1>>24)&0xFF) + g1 = float((c1>>16)&0xFF) + b1 = float((c1>>8)&0xFF) + cv = FreeCAD.Vector(r1,g1,b1) + value = cv.x*.3 + cv.y*.59 + cv.z*.11 + if value < 128: self.brightbg = False + else: + self.brightbg = True - if gui and draftui: - r = float(draftui.color.red()/255.0) - g = float(draftui.color.green()/255.0) - b = float(draftui.color.blue()/255.0) - self.lw = float(draftui.linewidth) - else: - self.lw = float(params.GetInt("linewidth")) - c = params.GetUnsigned("color") - r = float(((c>>24)&0xFF)/255) - g = float(((c>>16)&0xFF)/255) - b = float(((c>>8)&0xFF)/255) - self.col = (r,g,b,0.0) + if gui and draftui: + r = float(draftui.color.red()/255.0) + g = float(draftui.color.green()/255.0) + b = float(draftui.color.blue()/255.0) + self.lw = float(draftui.linewidth) + else: + self.lw = float(params.GetInt("linewidth")) + c = params.GetUnsigned("color") + r = float(((c>>24)&0xFF)/255) + g = float(((c>>16)&0xFF)/255) + b = float(((c>>8)&0xFF)/255) + self.col = (r,g,b,0.0) - if self.paramstyle == 3: - parammappingfile = params.GetString("dxfmappingfile") - self.table = self.buildTable(parammappingfile) + if self.paramstyle == 3: + parammappingfile = params.GetString("dxfmappingfile") + self.table = self.buildTable(parammappingfile) - def buildTable(self,tablefile): - "builds a table for converting colors into linewidths" - try: f = pythonopen(tablefile) - except ValueError: + def buildTable(self,tablefile): + "builds a table for converting colors into linewidths" + try: f = pythonopen(tablefile) + except ValueError: print "error: ",tablefile, " not found" return None - table = {} - header = len(f.readline().split("\t")) - if header == 15: - for l in f: - s = l.split("\t") - if "Color_" in s[0]: - index = int(s[0].split("_")[1]) - if s[1] == "(Object)": color = "object" - else: - c = s[2].split(",") - color = [float(c[0])/255,float(c[1])/255,float(c[2])/255] - if (color == [0.0,0.0,0.0]) and (not self.brightbg): - color = [1.0,1.0,1.0] - if s[2] == "(Object)": width = "object" - else: width = float(s[10])*10 - table[index]=[color,width] - elif header == 3: - for l in f: - s = l.split("\t") - index = int(s[0]) - c = string.replace(s[1],'"','') - c = c.split(",") - color = [float(c[0])/255,float(c[1])/255,float(c[2])/255] - width = float(s[2]) - table[index]=[color,width] - for i in range(256): - if not i in table.keys(): - table[i]=["object","object"] - else: - print "error building mapping table: file format not recognized" - table = None - print table - return table + table = {} + header = len(f.readline().split("\t")) + if header == 15: + for l in f: + s = l.split("\t") + if "Color_" in s[0]: + index = int(s[0].split("_")[1]) + if s[1] == "(Object)": color = "object" + else: + c = s[2].split(",") + color = [float(c[0])/255,float(c[1])/255,float(c[2])/255] + if (color == [0.0,0.0,0.0]) and (not self.brightbg): + color = [1.0,1.0,1.0] + if s[2] == "(Object)": width = "object" + else: width = float(s[10])*10 + table[index]=[color,width] + elif header == 3: + for l in f: + s = l.split("\t") + index = int(s[0]) + c = string.replace(s[1],'"','') + c = c.split(",") + color = [float(c[0])/255,float(c[1])/255,float(c[2])/255] + width = float(s[2]) + table[index]=[color,width] + for i in range(256): + if not i in table.keys(): + table[i]=["object","object"] + else: + print "error building mapping table: file format not recognized" + table = None + print table + return table - def formatObject(self,obj,dxfobj,textmode=False): - "applies color and linetype to objects" - if self.paramstyle == 1: - if textmode: - obj.ViewObject.TextColor = (0.0,0.0,0.0) - else: - obj.ViewObject.LineColor = self.col - obj.ViewObject.LineWidth = self.lw - - elif self.paramstyle == 2: - if textmode: - if dxfobj.color_index == 256: cm = self.getGroupColor(dxfobj)[:3] - else: cm = dxfColorMap.color_map[dxfobj.color_index] - obj.ViewObject.TextColor = (cm[0],cm[1],cm[2]) - else: - if dxfobj.color_index == 256: cm = self.getGroupColor(dxfobj) - elif (dxfobj.color_index == 7) and self.brightbg: cm = [0.0,0.0,0.0] - else: cm = dxfColorMap.color_map[dxfobj.color_index] - obj.ViewObject.LineColor = (cm[0],cm[1],cm[2],0.0) - obj.ViewObject.LineWidth = self.lw - elif self.paramstyle == 3: - if textmode: - cm = table[dxfobj.color_index][0] - wm = table[dxfobj.color_index][1] - obj.ViewObject.TextColor = (cm[0],cm[1],cm[2]) - else: - if dxfobj.color_index == 256: - cm = self.table[self.getGroupColor(dxfobj,index=True)][0] - wm = self.table[self.getGroupColor(dxfobj,index=True)][1] - else: - cm = self.table[dxfobj.color_index][0] - wm = self.table[dxfobj.color_index][1] - if cm == "object": cm = self.getGroupColor(dxfobj) - else: obj.ViewObject.LineColor = (cm[0],cm[1],cm[2],0.0) - if wm == "object": wm = self.lw - else: obj.ViewObject.LineWidth = wm + def formatObject(self,obj,dxfobj,textmode=False): + "applies color and linetype to objects" + if self.paramstyle == 1: + if textmode: + obj.ViewObject.TextColor = (0.0,0.0,0.0) + else: + obj.ViewObject.LineColor = self.col + obj.ViewObject.LineWidth = self.lw + elif self.paramstyle == 2: + if textmode: + if dxfobj.color_index == 256: cm = self.getGroupColor(dxfobj)[:3] + else: cm = dxfColorMap.color_map[dxfobj.color_index] + obj.ViewObject.TextColor = (cm[0],cm[1],cm[2]) + else: + if dxfobj.color_index == 256: cm = self.getGroupColor(dxfobj) + elif (dxfobj.color_index == 7) and self.brightbg: cm = [0.0,0.0,0.0] + else: cm = dxfColorMap.color_map[dxfobj.color_index] + obj.ViewObject.LineColor = (cm[0],cm[1],cm[2],0.0) + obj.ViewObject.LineWidth = self.lw + elif self.paramstyle == 3: + if textmode: + cm = table[dxfobj.color_index][0] + wm = table[dxfobj.color_index][1] + obj.ViewObject.TextColor = (cm[0],cm[1],cm[2]) + else: + if dxfobj.color_index == 256: + cm = self.table[self.getGroupColor(dxfobj,index=True)][0] + wm = self.table[self.getGroupColor(dxfobj,index=True)][1] + else: + cm = self.table[dxfobj.color_index][0] + wm = self.table[dxfobj.color_index][1] + if cm == "object": cm = self.getGroupColor(dxfobj) + else: obj.ViewObject.LineColor = (cm[0],cm[1],cm[2],0.0) + if wm == "object": wm = self.lw + else: obj.ViewObject.LineWidth = wm - def getGroupColor(self,dxfobj,index=False): - "get color of bylayer stuff" - name = dxfobj.layer - for table in self.dxf.tables.get_type("table"): - if table.name == "layer": - for l in table.get_type("layer"): - if l.name == name: - if index: return l.color - else: - if (l.color == 7) and self.brightbg: return [0.0,0.0,0.0] - else: return dxfColorMap.color_map[l.color] + def getGroupColor(self,dxfobj,index=False): + "get color of bylayer stuff" + name = dxfobj.layer + for table in self.dxf.tables.get_type("table"): + if table.name == "layer": + for l in table.get_type("layer"): + if l.name == name: + if index: return l.color + else: + if (l.color == 7) and self.brightbg: return [0.0,0.0,0.0] + else: return dxfColorMap.color_map[l.color] def vec(pt): - "returns a rounded Vector from a dxf point" - return FreeCAD.Vector(round(pt[0],prec),round(pt[1],prec),round(pt[2],prec)) + "returns a rounded Vector from a dxf point" + return FreeCAD.Vector(round(pt[0],prec),round(pt[1],prec),round(pt[2],prec)) def drawLine(line,shapemode=False): - "returns a Part shape from a dxf line" - if (len(line.points) > 1): - v1=vec(line.points[0]) - v2=vec(line.points[1]) - if not fcvec.equals(v1,v2): - try: - if (fmt.paramstyle == 4) and (not fmt.makeBlocks) and (not shapemode): - return Draft.makeWire([v1,v2]) - else: - return Part.Line(v1,v2).toShape() - except: - warn(line) - return None + "returns a Part shape from a dxf line" + if (len(line.points) > 1): + v1=vec(line.points[0]) + v2=vec(line.points[1]) + if not fcvec.equals(v1,v2): + try: + if (fmt.paramstyle == 4) and (not fmt.makeBlocks) and (not shapemode): + return Draft.makeWire([v1,v2]) + else: + return Part.Line(v1,v2).toShape() + except: + warn(line) + return None def drawPolyline(polyline,shapemode=False): - "returns a Part shape from a dxf polyline" - if (len(polyline.points) > 1): - edges = [] - curves = False - verts = [] - for p in range(len(polyline.points)-1): - p1 = polyline.points[p] - p2 = polyline.points[p+1] - v1 = FreeCAD.Vector(round(p1[0],prec),round(p1[1],prec),round(p2[2],prec)) - v2 = FreeCAD.Vector(round(p2[0],prec),round(p2[1],prec),round(p2[2],prec)) - verts.append(v1) - if not fcvec.equals(v1,v2): - if polyline.points[p].bulge: - curves = True - cv = calcBulge(v1,polyline.points[p].bulge,v2) - if fcvec.isColinear([v1,cv,v2]): - try: edges.append(Part.Line(v1,v2).toShape()) - except: warn(polyline) - else: - try: edges.append(Part.Arc(v1,cv,v2).toShape()) - except: warn(polyline) - else: - try: edges.append(Part.Line(v1,v2).toShape()) - except: warn(polyline) - verts.append(v2) - if polyline.closed: - p1 = polyline.points[len(polyline.points)-1] - p2 = polyline.points[0] - v1 = FreeCAD.Vector(round(p1[0],prec),round(p1[1],prec),round(p2[2],prec)) - v2 = FreeCAD.Vector(round(p2[0],prec),round(p2[1],prec),round(p2[2],prec)) - if not fcvec.equals(v1,v2): - try: edges.append(Part.Line(v1,v2).toShape()) - except: warn(polyline) - if edges: - try: - if (fmt.paramstyle == 4) and (not curves) and (not fmt.makeBlocks) and (not shapemode): - ob = Draft.makeWire(verts) - ob.Closed = polyline.closed - return ob - else: - if polyline.closed: - w = Part.Wire(edges) - return(Part.Face(w)) - else: - return Part.Wire(edges) - except: - warn(polyline) - return None + "returns a Part shape from a dxf polyline" + if (len(polyline.points) > 1): + edges = [] + curves = False + verts = [] + for p in range(len(polyline.points)-1): + p1 = polyline.points[p] + p2 = polyline.points[p+1] + v1 = FreeCAD.Vector(round(p1[0],prec),round(p1[1],prec),round(p2[2],prec)) + v2 = FreeCAD.Vector(round(p2[0],prec),round(p2[1],prec),round(p2[2],prec)) + verts.append(v1) + if not fcvec.equals(v1,v2): + if polyline.points[p].bulge: + curves = True + cv = calcBulge(v1,polyline.points[p].bulge,v2) + if fcvec.isColinear([v1,cv,v2]): + try: edges.append(Part.Line(v1,v2).toShape()) + except: warn(polyline) + else: + try: edges.append(Part.Arc(v1,cv,v2).toShape()) + except: warn(polyline) + else: + try: edges.append(Part.Line(v1,v2).toShape()) + except: warn(polyline) + verts.append(v2) + if polyline.closed: + p1 = polyline.points[len(polyline.points)-1] + p2 = polyline.points[0] + v1 = FreeCAD.Vector(round(p1[0],prec),round(p1[1],prec),round(p2[2],prec)) + v2 = FreeCAD.Vector(round(p2[0],prec),round(p2[1],prec),round(p2[2],prec)) + if not fcvec.equals(v1,v2): + try: edges.append(Part.Line(v1,v2).toShape()) + except: warn(polyline) + if edges: + try: + if (fmt.paramstyle == 4) and (not curves) and (not fmt.makeBlocks) and (not shapemode): + ob = Draft.makeWire(verts) + ob.Closed = polyline.closed + return ob + else: + if polyline.closed: + w = Part.Wire(edges) + return(Part.Face(w)) + else: + return Part.Wire(edges) + except: + warn(polyline) + return None def drawArc(arc,shapemode=False): - "returns a Part shape from a dxf arc" - v=vec(arc.loc) - firstangle=round(arc.start_angle,prec) - lastangle=round(arc.end_angle,prec) - circle=Part.Circle() - circle.Center=v - circle.Radius=round(arc.radius,prec) - try: - if (fmt.paramstyle == 4) and (not fmt.makeBlocks) and (not shapemode): - pl = FreeCAD.Placement() - pl.move(v) - return Draft.makeCircle(arc.radius,pl,False,firstangle,lastangle) - else: - return circle.toShape(math.radians(firstangle),math.radians(lastangle)) - except: - warn(arc) - return None + "returns a Part shape from a dxf arc" + v=vec(arc.loc) + firstangle=round(arc.start_angle,prec) + lastangle=round(arc.end_angle,prec) + circle=Part.Circle() + circle.Center=v + circle.Radius=round(arc.radius,prec) + try: + if (fmt.paramstyle == 4) and (not fmt.makeBlocks) and (not shapemode): + pl = FreeCAD.Placement() + pl.move(v) + return Draft.makeCircle(arc.radius,pl,False,firstangle,lastangle) + else: + return circle.toShape(math.radians(firstangle),math.radians(lastangle)) + except: + warn(arc) + return None def drawCircle(circle,shapemode=False): - "returns a Part shape from a dxf circle" - v = vec(circle.loc) - curve = Part.Circle() - curve.Radius = round(circle.radius,prec) - curve.Center = v - try: - if (fmt.paramstyle == 4) and (not fmt.makeBlocks) and (not shapemode): - pl = FreeCAD.Placement() - pl.move(v) - return Draft.makeCircle(circle.radius,pl) - else: - return curve.toShape() - except: - warn(circle) - return None + "returns a Part shape from a dxf circle" + v = vec(circle.loc) + curve = Part.Circle() + curve.Radius = round(circle.radius,prec) + curve.Center = v + try: + if (fmt.paramstyle == 4) and (not fmt.makeBlocks) and (not shapemode): + pl = FreeCAD.Placement() + pl.move(v) + return Draft.makeCircle(circle.radius,pl) + else: + return curve.toShape() + except: + warn(circle) + return None def drawFace(face): - "returns a Part face from a list of points" - pl = [] - for p in face.points: - pl.append(vec(p)) - p1 = face.points[0] - pl.append(vec(p1)) - try: - pol = Part.makePolygon(pl) - return Part.Face(pol) - except: - warn(face) - return None + "returns a Part face from a list of points" + pl = [] + for p in face.points: + pl.append(vec(p)) + p1 = face.points[0] + pl.append(vec(p1)) + try: + pol = Part.makePolygon(pl) + return Part.Face(pol) + except: + warn(face) + return None def drawMesh(mesh): - "returns a Mesh from a dxf mesh" - md = [] - if mesh.flags == 16: - pts = mesh.points - udim = rawValue(mesh,71) - vdim = rawValue(mesh,72) - for u in range(udim-1): - for v in range(vdim-1): - b = u+v*udim - p1 = pts[b] - p2 = pts[b+1] - p3 = pts[b+udim] - p4 = pts[b+udim+1] - md.append([p1,p2,p4]) - md.append([p1,p4,p3]) - elif mesh.flags == 64: - pts = [] - fcs = [] - for p in mesh.points: - if p.flags == 192: - pts.append(p) - elif p.flags == 128: - fcs.append(p) - for f in fcs: - p1 = pts[rawValue(f,71)-1] - p2 = pts[rawValue(f,72)-1] - p3 = pts[rawValue(f,73)-1] - md.append([p1,p2,p3]) - if rawValue(f,74) != None: - p4 = pts[rawValue(f,74)-1] - md.append([p1,p3,p4]) - try: - return Mesh.Mesh(md) - except: - warn(mesh) - return None + "returns a Mesh from a dxf mesh" + md = [] + if mesh.flags == 16: + pts = mesh.points + udim = rawValue(mesh,71) + vdim = rawValue(mesh,72) + for u in range(udim-1): + for v in range(vdim-1): + b = u+v*udim + p1 = pts[b] + p2 = pts[b+1] + p3 = pts[b+udim] + p4 = pts[b+udim+1] + md.append([p1,p2,p4]) + md.append([p1,p4,p3]) + elif mesh.flags == 64: + pts = [] + fcs = [] + for p in mesh.points: + if p.flags == 192: + pts.append(p) + elif p.flags == 128: + fcs.append(p) + for f in fcs: + p1 = pts[rawValue(f,71)-1] + p2 = pts[rawValue(f,72)-1] + p3 = pts[rawValue(f,73)-1] + md.append([p1,p2,p3]) + if rawValue(f,74) != None: + p4 = pts[rawValue(f,74)-1] + md.append([p1,p3,p4]) + try: + return Mesh.Mesh(md) + except: + warn(mesh) + return None def drawSolid(solid): - "returns a Part shape from a dxf solid" - p4 = None - p1x = rawValue(solid,10) - p1y = rawValue(solid,20) - p1z = rawValue(solid,30) or 0 - p2x = rawValue(solid,11) - p2y = rawValue(solid,21) - p2z = rawValue(solid,31) or p1z - p3x = rawValue(solid,12) - p3y = rawValue(solid,22) - p3z = rawValue(solid,32) or p1z - p4x = rawValue(solid,13) - p4y = rawValue(solid,23) - p4z = rawValue(solid,33) or p1z - p1 = FreeCAD.Vector(p1x,p1y,p1z) - p2 = FreeCAD.Vector(p2x,p2y,p2z) - p3 = FreeCAD.Vector(p3x,p3y,p3z) - if p4x != None: p4 = FreeCAD.Vector(p4x,p4y,p4z) - if p4 and (p4 != p3) and (p4 != p2) and (p4 != p1): - try: - return Part.Face(Part.makePolygon([p1,p2,p3,p4,p1])) - except: - warn(solid) - else: - try: - return Part.Face(Part.makePolygon([p1,p2,p3,p1])) - except: - warn(solid) - return None + "returns a Part shape from a dxf solid" + p4 = None + p1x = rawValue(solid,10) + p1y = rawValue(solid,20) + p1z = rawValue(solid,30) or 0 + p2x = rawValue(solid,11) + p2y = rawValue(solid,21) + p2z = rawValue(solid,31) or p1z + p3x = rawValue(solid,12) + p3y = rawValue(solid,22) + p3z = rawValue(solid,32) or p1z + p4x = rawValue(solid,13) + p4y = rawValue(solid,23) + p4z = rawValue(solid,33) or p1z + p1 = FreeCAD.Vector(p1x,p1y,p1z) + p2 = FreeCAD.Vector(p2x,p2y,p2z) + p3 = FreeCAD.Vector(p3x,p3y,p3z) + if p4x != None: p4 = FreeCAD.Vector(p4x,p4y,p4z) + if p4 and (p4 != p3) and (p4 != p2) and (p4 != p1): + try: + return Part.Face(Part.makePolygon([p1,p2,p3,p4,p1])) + except: + warn(solid) + else: + try: + return Part.Face(Part.makePolygon([p1,p2,p3,p1])) + except: + warn(solid) + return None def drawBlock(blockref): - "returns a shape from a dxf block reference" - shapes = [] - for line in blockref.entities.get_type('line'): - s = drawLine(line,shapemode=True) - if s: shapes.append(s) - for polyline in blockref.entities.get_type('polyline'): - s = drawPolyline(polyline,shapemode=True) - if s: shapes.append(s) - for polyline in blockref.entities.get_type('lwpolyline'): - s = drawPolyline(polyline,shapemode=True) - if s: shapes.append(s) - for arc in blockref.entities.get_type('arc'): - s = drawArc(arc,shapemode=True) - if s: shapes.append(s) - for circle in blockref.entities.get_type('circle'): - s = drawCircle(circle,shapemode=True) - if s: shapes.append(s) - for insert in blockref.entities.get_type('insert'): - s = drawInsert(insert) - if s: shapes.append(s) - for solid in blockref.entities.get_type('solid'): - s = drawSolid(solid) - if s: shapes.append(s) - for text in blockref.entities.get_type('text'): - if fmt.dxflayout or (not rawValue(text,67)): - addText(text) - for text in blockref.entities.get_type('mtext'): - if fmt.dxflayout or (not rawValue(text,67)): - addText(text) - try: shape = Part.makeCompound(shapes) - except: warn(blockref) - if shape: - blockshapes[blockref.name]=shape - return shape - return None + "returns a shape from a dxf block reference" + shapes = [] + for line in blockref.entities.get_type('line'): + s = drawLine(line,shapemode=True) + if s: shapes.append(s) + for polyline in blockref.entities.get_type('polyline'): + s = drawPolyline(polyline,shapemode=True) + if s: shapes.append(s) + for polyline in blockref.entities.get_type('lwpolyline'): + s = drawPolyline(polyline,shapemode=True) + if s: shapes.append(s) + for arc in blockref.entities.get_type('arc'): + s = drawArc(arc,shapemode=True) + if s: shapes.append(s) + for circle in blockref.entities.get_type('circle'): + s = drawCircle(circle,shapemode=True) + if s: shapes.append(s) + for insert in blockref.entities.get_type('insert'): + s = drawInsert(insert) + if s: shapes.append(s) + for solid in blockref.entities.get_type('solid'): + s = drawSolid(solid) + if s: shapes.append(s) + for text in blockref.entities.get_type('text'): + if fmt.dxflayout or (not rawValue(text,67)): + addText(text) + for text in blockref.entities.get_type('mtext'): + if fmt.dxflayout or (not rawValue(text,67)): + addText(text) + try: shape = Part.makeCompound(shapes) + except: warn(blockref) + if shape: + blockshapes[blockref.name]=shape + return shape + return None def drawInsert(insert): - if blockshapes.has_key(insert): - shape = blockshapes[insert.block] - else: - shape = None - for b in drawing.blocks.data: - if b.name == insert.block: - shape = drawBlock(b) - if fmt.paramtext: - attrs = attribs(insert) - for a in attrs: - addText(a,attrib=True) - if shape: - pos = vec(insert.loc) - rot = math.radians(insert.rotation) - scale = insert.scale - tsf = FreeCAD.Matrix() - tsf.scale(vec(scale)) - tsf.rotateZ(rot) - shape = shape.transformGeometry(tsf) - shape.translate(pos) - return shape - return None + if blockshapes.has_key(insert): + shape = blockshapes[insert.block] + else: + shape = None + for b in drawing.blocks.data: + if b.name == insert.block: + shape = drawBlock(b) + if fmt.paramtext: + attrs = attribs(insert) + for a in attrs: + addText(a,attrib=True) + if shape: + pos = vec(insert.loc) + rot = math.radians(insert.rotation) + scale = insert.scale + tsf = FreeCAD.Matrix() + tsf.scale(vec(scale)) + tsf.rotateZ(rot) + shape = shape.transformGeometry(tsf) + shape.translate(pos) + return shape + return None def drawLayerBlock(shapeslist): - "draws a compound with the given shapes" - shape = None - try: - shape = Part.makeCompound(shapeslist) - except: - pass - return shape + "draws a compound with the given shapes" + shape = None + try: + shape = Part.makeCompound(shapeslist) + except: + pass + return shape def attribs(insert): - "checks if an insert has attributes, and returns the values if yes" - atts = [] - if rawValue(insert,66) != 1: return [] - index = None - for i in range(len(drawing.entities.data)): - if drawing.entities.data[i] == insert: - index = i - break - if index == None: return [] - j = index+1 - while True: - ent = drawing.entities.data[j] - print str(ent) - if str(ent) == 'seqend': - return atts - elif str(ent) == 'attrib': - atts.append(ent) - j += 1 + "checks if an insert has attributes, and returns the values if yes" + atts = [] + if rawValue(insert,66) != 1: return [] + index = None + for i in range(len(drawing.entities.data)): + if drawing.entities.data[i] == insert: + index = i + break + if index == None: return [] + j = index+1 + while True: + ent = drawing.entities.data[j] + print str(ent) + if str(ent) == 'seqend': + return atts + elif str(ent) == 'attrib': + atts.append(ent) + j += 1 def addObject(shape,name="Shape",layer=None): - "adds a new object to the document with passed arguments" - if isinstance(shape,Part.Shape): - newob=doc.addObject("Part::Feature",name) - newob.Shape = shape - else: - newob = shape - if layer: - lay=locateLayer(layer) - lay.addObject(newob) - return newob + "adds a new object to the document with passed arguments" + if isinstance(shape,Part.Shape): + newob=doc.addObject("Part::Feature",name) + newob.Shape = shape + else: + newob = shape + if layer: + lay=locateLayer(layer) + lay.addObject(newob) + return newob def addText(text,attrib=False): - "adds a new text to the document" - if attrib: - lay = locateLayer(rawValue(text,8)) - val = rawValue(text,1) - pos = FreeCAD.Vector(rawValue(text,10),rawValue(text,20),rawValue(text,30)) - hgt = rawValue(text,40) - else: - lay = locateLayer(text.layer) - val = text.value - pos = FreeCAD.Vector(text.loc[0],text.loc[1],text.loc[2]) - hgt = text.height - if val: - newob=doc.addObject("App::Annotation","Text") - lay.addObject(newob) - val = re.sub('{([^!}]([^}]|\n)*)}', '', val) - val = re.sub('%%d','°',val) - val = re.sub('%%c','Ø',val) - val = val.decode("Latin1").encode("Latin1") - newob.LabelText = val - newob.Position = pos - if gui: - newob.ViewObject.FontSize=float(hgt) - newob.ViewObject.DisplayMode = "World" - fmt.formatObject(newob,text,textmode=True) + "adds a new text to the document" + if attrib: + lay = locateLayer(rawValue(text,8)) + val = rawValue(text,1) + pos = FreeCAD.Vector(rawValue(text,10),rawValue(text,20),rawValue(text,30)) + hgt = rawValue(text,40) + else: + lay = locateLayer(text.layer) + val = text.value + pos = FreeCAD.Vector(text.loc[0],text.loc[1],text.loc[2]) + hgt = text.height + if val: + newob=doc.addObject("App::Annotation","Text") + lay.addObject(newob) + val = re.sub('{([^!}]([^}]|\n)*)}', '', val) + val = re.sub('%%d','°',val) + val = re.sub('%%c','Ø',val) + val = val.decode("Latin1").encode("Latin1") + newob.LabelText = val + newob.Position = pos + if gui: + newob.ViewObject.FontSize=float(hgt) + newob.ViewObject.DisplayMode = "World" + fmt.formatObject(newob,text,textmode=True) def addToBlock(shape,layer): - "adds given shape to the layer dict" - if layer in layerBlocks: - layerBlocks[layer].append(shape) - else: - layerBlocks[layer] = [shape] + "adds given shape to the layer dict" + if layer in layerBlocks: + layerBlocks[layer].append(shape) + else: + layerBlocks[layer] = [shape] def processdxf(document,filename): - "this does the translation of the dxf contents into FreeCAD Part objects" - global drawing # for debugging - so drawing is still accessible to python after the script - FreeCAD.Console.PrintMessage("opening "+filename+"...\n") - drawing = readDXF(filename) - global layers - layers = [] - global doc - doc = document - global blockshapes - blockshapes = {} - global badobjects - badobjects = [] - global layerBlocks - layerBlocks = {} + "this does the translation of the dxf contents into FreeCAD Part objects" + global drawing # for debugging - so drawing is still accessible to python after the script + FreeCAD.Console.PrintMessage("opening "+filename+"...\n") + drawing = readDXF(filename) + global layers + layers = [] + global doc + doc = document + global blockshapes + blockshapes = {} + global badobjects + badobjects = [] + global layerBlocks + layerBlocks = {} + + # getting config parameters + + global fmt + fmt = fcformat(drawing) + shapes = [] - # getting config parameters + # drawing lines - global fmt - fmt = fcformat(drawing) - shapes = [] - - # drawing lines - - lines = drawing.entities.get_type("line") - if lines: FreeCAD.Console.PrintMessage("drawing "+str(len(lines))+" lines...\n") - for line in lines: - if fmt.dxflayout or (not rawValue(line,67)): - shape = drawLine(line) - if shape: - if fmt.join: - if isinstance(shape,Part.Shape): - shapes.append(shape) - else: - shapes.append(shape.Shape) - elif fmt.makeBlocks: - if isinstance(shape,Part.Shape): - addToBlock(shape,line.layer) - else: - addToBlock(shape.Shape,line.layer) - else: - newob = addObject(shape,"Line",line.layer) - if gui: fmt.formatObject(newob,line) - - # drawing polylines - - pls = drawing.entities.get_type("lwpolyline") - pls.extend(drawing.entities.get_type("polyline")) - polylines = [] - meshes = [] - for p in pls: - if hasattr(p,"flags"): - if p.flags in [16,64]: - meshes.append(p) - else: - polylines.append(p) + lines = drawing.entities.get_type("line") + if lines: FreeCAD.Console.PrintMessage("drawing "+str(len(lines))+" lines...\n") + for line in lines: + if fmt.dxflayout or (not rawValue(line,67)): + shape = drawLine(line) + if shape: + if fmt.join: + if isinstance(shape,Part.Shape): + shapes.append(shape) + else: + shapes.append(shape.Shape) + elif fmt.makeBlocks: + if isinstance(shape,Part.Shape): + addToBlock(shape,line.layer) + else: + addToBlock(shape.Shape,line.layer) else: - polylines.append(p) - if polylines: FreeCAD.Console.PrintMessage("drawing "+str(len(polylines))+" polylines...\n") - for polyline in polylines: - if fmt.dxflayout or (not rawValue(polyline,67)): - shape = drawPolyline(polyline) - if shape: - if fmt.join: - if isinstance(shape,Part.Shape): - shapes.append(shape) - else: - shapes.append(shape.Shape) - elif fmt.makeBlocks: - if isinstance(shape,Part.Shape): - addToBlock(shape,polyline.layer) - else: - addToBlock(shape.Shape,polyline.layer) - else: - newob = addObject(shape,"Polyline",polyline.layer) - if gui: fmt.formatObject(newob,polyline) - - # drawing arcs - - arcs = drawing.entities.get_type("arc") - if arcs: FreeCAD.Console.PrintMessage("drawing "+str(len(arcs))+" arcs...\n") - for arc in arcs: - if fmt.dxflayout or (not rawValue(arc,67)): - shape = drawArc(arc) - if shape: - if fmt.join: - if isinstance(shape,Part.Shape): - shapes.append(shape) - else: - shapes.append(shape.Shape) - elif fmt.makeBlocks: - if isinstance(shape,Part.Shape): - addToBlock(shape,arc.layer) - else: - addToBlock(shape.Shape,arc.layer) - else: - newob = addObject(shape,"Arc",arc.layer) - if gui: fmt.formatObject(newob,arc) - - # joining lines, polylines and arcs if needed - - if fmt.join and shapes: - FreeCAD.Console.PrintMessage("Joining geometry...\n") - edges = [] - for s in shapes: - edges.extend(s.Edges) - shapes = fcgeo.findWires(edges) - for s in shapes: - newob = addObject(s) - - # drawing circles - - circles = drawing.entities.get_type("circle") - if circles: FreeCAD.Console.PrintMessage("drawing "+str(len(circles))+" circles...\n") - for circle in circles: - if fmt.dxflayout or (not rawValue(circle,67)): - shape = drawCircle(circle) - if shape: - if fmt.makeBlocks: - if isinstance(shape,Part.Shape): - addToBlock(shape,circle.layer) - else: - addToBlock(shape.Shape,circle.layer) - else: - newob = addObject(shape,"Circle",circle.layer) - if gui: fmt.formatObject(newob,circle) - - # drawing solids - - solids = drawing.entities.get_type("solid") - if solids: FreeCAD.Console.PrintMessage("drawing "+str(len(circles))+" solids...\n") - for solid in solids: - lay = rawValue(solid,8) - if fmt.dxflayout or (not rawValue(solid,67)): - shape = drawSolid(solid) - if shape: - if fmt.makeBlocks: - if isinstance(shape,Part.Shape): - addToBlock(shape,lay) - else: - addToBlock(shape.Shape,lay) - else: - newob = addObject(shape,"Solid",lay) - if gui: fmt.formatObject(newob,solid) - - # drawing texts - - if fmt.paramtext: - texts = drawing.entities.get_type("mtext") - texts.extend(drawing.entities.get_type("text")) - if texts: FreeCAD.Console.PrintMessage("drawing "+str(len(texts))+" texts...\n") - for text in texts: - if fmt.dxflayout or (not rawValue(text,67)): - addText(text) - - else: FreeCAD.Console.PrintMessage("skipping texts...\n") - - # drawing 3D objects - - faces3d = drawing.entities.get_type("3dface") - if faces3d: FreeCAD.Console.PrintMessage("drawing "+str(len(faces3d))+" 3dfaces...\n") - for face3d in faces3d: - shape = drawFace(face3d) - if shape: - newob = addObject(shape,"Face",face3d.layer) - if gui: fmt.formatObject(newob,face3d) - if meshes: FreeCAD.Console.PrintMessage("drawing "+str(len(meshes))+" 3dmeshes...\n") - for mesh in meshes: - me = drawMesh(mesh) - if me: - newob = doc.addObject("Mesh::Feature","Mesh") - lay = locateLayer(rawValue(mesh,8)) - lay.addObject(newob) - newob.Mesh = me - if gui: fmt.formatObject(newob,mesh) - - # drawing dims - - if fmt.paramtext: - dims = drawing.entities.get_type("dimension") - FreeCAD.Console.PrintMessage("drawing "+str(len(dims))+" dimensions...\n") - for dim in dims: - if fmt.dxflayout or (not rawValue(dim,67)): - try: - layer = rawValue(dim,8) - x1 = float(rawValue(dim,10)) - y1 = float(rawValue(dim,20)) - z1 = float(rawValue(dim,30)) - x2 = float(rawValue(dim,13)) - y2 = float(rawValue(dim,23)) - z2 = float(rawValue(dim,33)) - x3 = float(rawValue(dim,14)) - y3 = float(rawValue(dim,24)) - z3 = float(rawValue(dim,34)) - d = rawValue(dim,70) - if d: align = int(d) - else: align = 0 - d = rawValue(dim,50) - if d: angle = float(d) - else: angle = 0 - except: - warn(dim) - else: - lay=locateLayer(layer) - pt = FreeCAD.Vector(x1,y1,z1) - p1 = FreeCAD.Vector(x2,y2,z2) - p2 = FreeCAD.Vector(x3,y3,z3) - if align == 0: - if angle == 0: - p2 = FreeCAD.Vector(x3,y2,z2) - else: - p2 = FreeCAD.Vector(x2,y3,z2) - - newob = doc.addObject("App::FeaturePython","Dimension") - lay.addObject(newob) - Dimension(newob) - ViewProviderDimension(newob.ViewObject) - newob.Start = p1 - newob.End = p2 - newob.Dimline = pt - if gui: - dim.layer = layer - dim.color_index = 256 - fmt.formatObject (newob,dim) + newob = addObject(shape,"Line",line.layer) + if gui: fmt.formatObject(newob,line) - else: FreeCAD.Console.PrintMessage("skipping dimensions...\n") + # drawing polylines - # drawing blocks + pls = drawing.entities.get_type("lwpolyline") + pls.extend(drawing.entities.get_type("polyline")) + polylines = [] + meshes = [] + for p in pls: + if hasattr(p,"flags"): + if p.flags in [16,64]: + meshes.append(p) + else: + polylines.append(p) + else: + polylines.append(p) + if polylines: FreeCAD.Console.PrintMessage("drawing "+str(len(polylines))+" polylines...\n") + for polyline in polylines: + if fmt.dxflayout or (not rawValue(polyline,67)): + shape = drawPolyline(polyline) + if shape: + if fmt.join: + if isinstance(shape,Part.Shape): + shapes.append(shape) + else: + shapes.append(shape.Shape) + elif fmt.makeBlocks: + if isinstance(shape,Part.Shape): + addToBlock(shape,polyline.layer) + else: + addToBlock(shape.Shape,polyline.layer) + else: + newob = addObject(shape,"Polyline",polyline.layer) + if gui: fmt.formatObject(newob,polyline) + + # drawing arcs - inserts = drawing.entities.get_type("insert") - if not fmt.paramstarblocks: - FreeCAD.Console.PrintMessage("skipping *blocks...\n") - newinserts = [] - for i in inserts: - if fmt.dxflayout or (not rawValue(i,67)): - if i.block[0] != '*': - newinserts.append(i) - inserts = newinserts - if inserts: - FreeCAD.Console.PrintMessage("drawing "+str(len(inserts))+" blocks...\n") - blockrefs = drawing.blocks.data - for ref in blockrefs: - drawBlock(ref) - for insert in inserts: - shape = drawInsert(insert) - if shape: - if fmt.makeBlocks: - if isinstance(shape,Part.Shape): - addToBlock(shape,block.layer) - else: - addToBlock(shape.Shape,block.layer) - else: - newob = addObject(shape,"Block."+insert.block,insert.layer) - if gui: fmt.formatObject(newob,insert) + arcs = drawing.entities.get_type("arc") + if arcs: FreeCAD.Console.PrintMessage("drawing "+str(len(arcs))+" arcs...\n") + for arc in arcs: + if fmt.dxflayout or (not rawValue(arc,67)): + shape = drawArc(arc) + if shape: + if fmt.join: + if isinstance(shape,Part.Shape): + shapes.append(shape) + else: + shapes.append(shape.Shape) + elif fmt.makeBlocks: + if isinstance(shape,Part.Shape): + addToBlock(shape,arc.layer) + else: + addToBlock(shape.Shape,arc.layer) + else: + newob = addObject(shape,"Arc",arc.layer) + if gui: fmt.formatObject(newob,arc) - # make blocks, if any + # joining lines, polylines and arcs if needed - if fmt.makeBlocks: - for k,l in layerBlocks.iteritems(): - shape = drawLayerBlock(l) - if shape: - newob = addObject(shape,k) - del layerBlocks + if fmt.join and shapes: + FreeCAD.Console.PrintMessage("Joining geometry...\n") + edges = [] + for s in shapes: + edges.extend(s.Edges) + shapes = fcgeo.findWires(edges) + for s in shapes: + newob = addObject(s) + + # drawing circles + + circles = drawing.entities.get_type("circle") + if circles: FreeCAD.Console.PrintMessage("drawing "+str(len(circles))+" circles...\n") + for circle in circles: + if fmt.dxflayout or (not rawValue(circle,67)): + shape = drawCircle(circle) + if shape: + if fmt.makeBlocks: + if isinstance(shape,Part.Shape): + addToBlock(shape,circle.layer) + else: + addToBlock(shape.Shape,circle.layer) + else: + newob = addObject(shape,"Circle",circle.layer) + if gui: fmt.formatObject(newob,circle) + + # drawing solids + + solids = drawing.entities.get_type("solid") + if solids: FreeCAD.Console.PrintMessage("drawing "+str(len(circles))+" solids...\n") + for solid in solids: + lay = rawValue(solid,8) + if fmt.dxflayout or (not rawValue(solid,67)): + shape = drawSolid(solid) + if shape: + if fmt.makeBlocks: + if isinstance(shape,Part.Shape): + addToBlock(shape,lay) + else: + addToBlock(shape.Shape,lay) + else: + newob = addObject(shape,"Solid",lay) + if gui: fmt.formatObject(newob,solid) + + # drawing texts + + if fmt.paramtext: + texts = drawing.entities.get_type("mtext") + texts.extend(drawing.entities.get_type("text")) + if texts: FreeCAD.Console.PrintMessage("drawing "+str(len(texts))+" texts...\n") + for text in texts: + if fmt.dxflayout or (not rawValue(text,67)): + addText(text) + + else: FreeCAD.Console.PrintMessage("skipping texts...\n") + + # drawing 3D objects + + faces3d = drawing.entities.get_type("3dface") + if faces3d: FreeCAD.Console.PrintMessage("drawing "+str(len(faces3d))+" 3dfaces...\n") + for face3d in faces3d: + shape = drawFace(face3d) + if shape: + newob = addObject(shape,"Face",face3d.layer) + if gui: fmt.formatObject(newob,face3d) + if meshes: FreeCAD.Console.PrintMessage("drawing "+str(len(meshes))+" 3dmeshes...\n") + for mesh in meshes: + me = drawMesh(mesh) + if me: + newob = doc.addObject("Mesh::Feature","Mesh") + lay = locateLayer(rawValue(mesh,8)) + lay.addObject(newob) + newob.Mesh = me + if gui: fmt.formatObject(newob,mesh) + + # drawing dims + + if fmt.paramtext: + dims = drawing.entities.get_type("dimension") + FreeCAD.Console.PrintMessage("drawing "+str(len(dims))+" dimensions...\n") + for dim in dims: + if fmt.dxflayout or (not rawValue(dim,67)): + try: + layer = rawValue(dim,8) + x1 = float(rawValue(dim,10)) + y1 = float(rawValue(dim,20)) + z1 = float(rawValue(dim,30)) + x2 = float(rawValue(dim,13)) + y2 = float(rawValue(dim,23)) + z2 = float(rawValue(dim,33)) + x3 = float(rawValue(dim,14)) + y3 = float(rawValue(dim,24)) + z3 = float(rawValue(dim,34)) + d = rawValue(dim,70) + if d: align = int(d) + else: align = 0 + d = rawValue(dim,50) + if d: angle = float(d) + else: angle = 0 + except: + warn(dim) + else: + lay=locateLayer(layer) + pt = FreeCAD.Vector(x1,y1,z1) + p1 = FreeCAD.Vector(x2,y2,z2) + p2 = FreeCAD.Vector(x3,y3,z3) + if align == 0: + if angle == 0: + p2 = FreeCAD.Vector(x3,y2,z2) + else: + p2 = FreeCAD.Vector(x2,y3,z2) + newob = doc.addObject("App::FeaturePython","Dimension") + lay.addObject(newob) + Dimension(newob) + ViewProviderDimension(newob.ViewObject) + newob.Start = p1 + newob.End = p2 + newob.Dimline = pt + if gui: + dim.layer = layer + dim.color_index = 256 + fmt.formatObject (newob,dim) + + else: FreeCAD.Console.PrintMessage("skipping dimensions...\n") + + # drawing blocks + + inserts = drawing.entities.get_type("insert") + if not fmt.paramstarblocks: + FreeCAD.Console.PrintMessage("skipping *blocks...\n") + newinserts = [] + for i in inserts: + if fmt.dxflayout or (not rawValue(i,67)): + if i.block[0] != '*': + newinserts.append(i) + inserts = newinserts + if inserts: + FreeCAD.Console.PrintMessage("drawing "+str(len(inserts))+" blocks...\n") + blockrefs = drawing.blocks.data + for ref in blockrefs: + drawBlock(ref) + for insert in inserts: + shape = drawInsert(insert) + if shape: + if fmt.makeBlocks: + if isinstance(shape,Part.Shape): + addToBlock(shape,block.layer) + else: + addToBlock(shape.Shape,block.layer) + else: + newob = addObject(shape,"Block."+insert.block,insert.layer) + if gui: fmt.formatObject(newob,insert) + + # make blocks, if any + + if fmt.makeBlocks: + for k,l in layerBlocks.iteritems(): + shape = drawLayerBlock(l) + if shape: + newob = addObject(shape,k) + del layerBlocks - # finishing + # finishing - doc.recompute() - FreeCAD.Console.PrintMessage("successfully imported "+filename+"\n") - if badobjects: print "dxf: ",len(badobjects)," objects were not imported" - del fmt - del doc - del blockshapes + doc.recompute() + FreeCAD.Console.PrintMessage("successfully imported "+filename+"\n") + if badobjects: print "dxf: ",len(badobjects)," objects were not imported" + del fmt + del doc + del blockshapes def warn(dxfobject): - "outputs a warning if a dxf object couldn't be imported" - print "dxf: couldn't import", dxfobject - badobjects.append(dxfobject) + "outputs a warning if a dxf object couldn't be imported" + print "dxf: couldn't import", dxfobject + badobjects.append(dxfobject) def open(filename): - "called when freecad opens a file." - docname = os.path.splitext(os.path.basename(filename))[0] - doc = FreeCAD.newDocument(docname) - doc.Label = decodeName(docname) - processdxf(doc,filename) - return doc + "called when freecad opens a file." + docname = os.path.splitext(os.path.basename(filename))[0] + doc = FreeCAD.newDocument(docname) + doc.Label = decodeName(docname) + processdxf(doc,filename) + return doc def insert(filename,docname): - "called when freecad imports a file" - groupname = os.path.splitext(os.path.basename(filename))[0] - try: - doc=FreeCAD.getDocument(docname) - except: - doc=FreeCAD.newDocument(docname) - importgroup = doc.addObject("App::DocumentObjectGroup",groupname) - importgroup.Label = decodeName(groupname) - processdxf(doc,filename) - for l in layers: - importgroup.addObject(l) + "called when freecad imports a file" + groupname = os.path.splitext(os.path.basename(filename))[0] + try: + doc=FreeCAD.getDocument(docname) + except: + doc=FreeCAD.newDocument(docname) + importgroup = doc.addObject("App::DocumentObjectGroup",groupname) + importgroup.Label = decodeName(groupname) + processdxf(doc,filename) + for l in layers: + importgroup.addObject(l) # EXPORT ######################################################################## def getSplineSegs(edge): - "returns an array of vectors from a bSpline edge" - params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") - seglength = params.GetInt("maxsplinesegment") - points = [] - if seglength == 0: - points.append(edge.Vertexes[0].Point) - points.append(edge.Vertexes[-1].Point) - else: - l = edge.Length - points.append(edge.valueAt(0)) - if l > seglength: - nbsegs = int(math.ceil(l/seglength)) - step = l/nbsegs - for nv in range(1,nbsegs): - v = edge.valueAt(nv*step) - points.append(v) - points.append(edge.valueAt(edge.Length)) - return points + "returns an array of vectors from a bSpline edge" + params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") + seglength = params.GetInt("maxsplinesegment") + points = [] + if seglength == 0: + points.append(edge.Vertexes[0].Point) + points.append(edge.Vertexes[-1].Point) + else: + l = edge.Length + points.append(edge.valueAt(0)) + if l > seglength: + nbsegs = int(math.ceil(l/seglength)) + step = l/nbsegs + for nv in range(1,nbsegs): + v = edge.valueAt(nv*step) + points.append(v) + points.append(edge.valueAt(edge.Length)) + return points def getWire(wire,nospline=False): - "returns an array of dxf-ready points and bulges from a wire" - edges = fcgeo.sortEdges(wire.Edges) - points = [] - for edge in edges: - v1 = edge.Vertexes[0].Point - if (isinstance(edge.Curve,Part.Circle)): - v2 = edge.Vertexes[-1].Point - c = edge.Curve.Center - angle = abs(fcvec.angle(v1.sub(c),v2.sub(c))) - if (fcvec.angle(v2.sub(c)) < fcvec.angle(v1.sub(c))): - angle = -angle - bul = math.tan(angle/4) - points.append((v1.x,v1.y,v1.z,None,None,bul)) - elif (isinstance(edge.Curve,Part.BSplineCurve)) and (not nospline): - bul = 0.0 - spline = getSplineSegs(edge) - spline.pop() - for p in spline: - points.append((p.x,p.y,p.z,None,None,bul)) - else: - bul = 0.0 - points.append((v1.x,v1.y,v1.z,None,None,bul)) - if not fcgeo.isReallyClosed(wire): - v = edges[-1].Vertexes[-1].Point - points.append(fcvec.tup(v)) - # print "wire verts: ",points - return points + "returns an array of dxf-ready points and bulges from a wire" + edges = fcgeo.sortEdges(wire.Edges) + points = [] + for edge in edges: + v1 = edge.Vertexes[0].Point + if (isinstance(edge.Curve,Part.Circle)): + v2 = edge.Vertexes[-1].Point + c = edge.Curve.Center + angle = abs(fcvec.angle(v1.sub(c),v2.sub(c))) + if (fcvec.angle(v2.sub(c)) < fcvec.angle(v1.sub(c))): + angle = -angle + bul = math.tan(angle/4) + points.append((v1.x,v1.y,v1.z,None,None,bul)) + elif (isinstance(edge.Curve,Part.BSplineCurve)) and (not nospline): + bul = 0.0 + spline = getSplineSegs(edge) + spline.pop() + for p in spline: + points.append((p.x,p.y,p.z,None,None,bul)) + else: + bul = 0.0 + points.append((v1.x,v1.y,v1.z,None,None,bul)) + if not fcgeo.isReallyClosed(wire): + v = edges[-1].Vertexes[-1].Point + points.append(fcvec.tup(v)) + # print "wire verts: ",points + return points def getBlock(obj): - "returns a dxf block with the contents of the object" - block = dxfLibrary.Block(name=obj.Name,layer=getGroup(obj,exportList)) - writeShape(obj,block) - return block + "returns a dxf block with the contents of the object" + block = dxfLibrary.Block(name=obj.Name,layer=getGroup(obj,exportList)) + writeShape(obj,block) + return block def writeShape(ob,dxfobject,nospline=False): - "writes the object's shape contents in the given dxf object" - processededges = [] - for wire in ob.Shape.Wires: # polylines - for e in wire.Edges: processededges.append(e.hashCode()) - if (len(wire.Edges) == 1) and isinstance(wire.Edges[0].Curve,Part.Circle): - center = fcvec.tup(wire.Edges[0].Curve.Center) - radius = wire.Edges[0].Curve.Radius - dxfobject.append(dxfLibrary.Circle(center, radius, - color=getACI(ob), - layer=getGroup(ob,exportList))) - else: - dxfobject.append(dxfLibrary.PolyLine(getWire(wire,nospline), [0.0,0.0,0.0], - int(fcgeo.isReallyClosed(wire)), color=getACI(ob), - layer=getGroup(ob,exportList))) - if len(processededges) < len(ob.Shape.Edges): # lone edges - loneedges = [] - for e in ob.Shape.Edges: - if not(e.hashCode() in processededges): loneedges.append(e) - # print "lone edges ",loneedges - for edge in loneedges: - if (isinstance(edge.Curve,Part.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))) - elif (len(edge.Vertexes) == 1) and (isinstance(edge.Curve,Part.Circle)): # circles - center = fcvec.tup(edge.Curve.Center) - radius = ob.Shape.Edges[0].Curve.Radius - dxfobject.append(dxfLibrary.Circle(center, radius, - color=getACI(ob), - layer=getGroup(ob,exportList))) - elif (len(edge.Vertexes) == 3) or (isinstance (edge.Curve,Part.Circle)): # arcs - ce = ob.Shape.Edges[0].Curve.Center - radius = ob.Shape.Edges[0].Curve.Radius - ve1 = edge.Vertexes[0].Point - ve2 = edge.Vertexes[-1].Point - ang1=-math.degrees(fcvec.angle(ve1.sub(ce))) - ang2=-math.degrees(fcvec.angle(ve2.sub(ce))) - dxfobject.append(dxfLibrary.Arc(fcvec.tup(ce), radius, - ang1, ang2, color=getACI(ob), - layer=getGroup(ob,exportList))) - else: # anything else is treated as lines - # if (len(edge.Vertexes) == 2) and (isinstance (edge.Curve,Part.Line)): # lines - ve1=edge.Vertexes[0].Point - ve2=edge.Vertexes[1].Point - dxfobject.append(dxfLibrary.Line([fcvec.tup(ve1), fcvec.tup(ve2)], - color=getACI(ob), - layer=getGroup(ob,exportList))) + "writes the object's shape contents in the given dxf object" + processededges = [] + for wire in ob.Shape.Wires: # polylines + for e in wire.Edges: processededges.append(e.hashCode()) + if (len(wire.Edges) == 1) and isinstance(wire.Edges[0].Curve,Part.Circle): + center = fcvec.tup(wire.Edges[0].Curve.Center) + radius = wire.Edges[0].Curve.Radius + dxfobject.append(dxfLibrary.Circle(center, radius, + color=getACI(ob), + layer=getGroup(ob,exportList))) + else: + dxfobject.append(dxfLibrary.PolyLine(getWire(wire,nospline), [0.0,0.0,0.0], + int(fcgeo.isReallyClosed(wire)), color=getACI(ob), + layer=getGroup(ob,exportList))) + if len(processededges) < len(ob.Shape.Edges): # lone edges + loneedges = [] + for e in ob.Shape.Edges: + if not(e.hashCode() in processededges): loneedges.append(e) + # print "lone edges ",loneedges + for edge in loneedges: + if (isinstance(edge.Curve,Part.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))) + elif (len(edge.Vertexes) == 1) and (isinstance(edge.Curve,Part.Circle)): # circles + center = fcvec.tup(edge.Curve.Center) + radius = ob.Shape.Edges[0].Curve.Radius + dxfobject.append(dxfLibrary.Circle(center, radius, + color=getACI(ob), + layer=getGroup(ob,exportList))) + elif (len(edge.Vertexes) == 3) or (isinstance (edge.Curve,Part.Circle)): # arcs + ce = ob.Shape.Edges[0].Curve.Center + radius = ob.Shape.Edges[0].Curve.Radius + ve1 = edge.Vertexes[0].Point + ve2 = edge.Vertexes[-1].Point + ang1=-math.degrees(fcvec.angle(ve1.sub(ce))) + ang2=-math.degrees(fcvec.angle(ve2.sub(ce))) + dxfobject.append(dxfLibrary.Arc(fcvec.tup(ce), radius, + ang1, ang2, color=getACI(ob), + layer=getGroup(ob,exportList))) + else: # anything else is treated as lines + # if (len(edge.Vertexes) == 2) and (isinstance (edge.Curve,Part.Line)): # lines + ve1=edge.Vertexes[0].Point + ve2=edge.Vertexes[1].Point + dxfobject.append(dxfLibrary.Line([fcvec.tup(ve1), fcvec.tup(ve2)], + color=getACI(ob), + layer=getGroup(ob,exportList))) def writeMesh(ob,dxfobject): - "export a shape as a polyface mesh" - meshdata = ob.Shape.tessellate(0.5) - # print meshdata - points = [] - faces = [] - for p in meshdata[0]: - points.append([p.x,p.y,p.z]) - for f in meshdata[1]: - faces.append([f[0]+1,f[1]+1,f[2]+1]) - # print len(points),len(faces) - dxfobject.append(dxfLibrary.PolyLine([points,faces], [0.0,0.0,0.0], - 64, color=getACI(ob), - layer=getGroup(ob,exportList))) + "export a shape as a polyface mesh" + meshdata = ob.Shape.tessellate(0.5) + # print meshdata + points = [] + faces = [] + for p in meshdata[0]: + points.append([p.x,p.y,p.z]) + for f in meshdata[1]: + faces.append([f[0]+1,f[1]+1,f[2]+1]) + # print len(points),len(faces) + dxfobject.append(dxfLibrary.PolyLine([points,faces], [0.0,0.0,0.0], + 64, color=getACI(ob), + layer=getGroup(ob,exportList))) - def export(objectslist,filename,nospline=False): - "called when freecad exports a file. If nospline=True, bsplines are exported as straight segs" - global exportList - exportList = objectslist - dxf = dxfLibrary.Drawing() - if (len(exportList) == 1) and (exportList[0].isDerivedFrom("Drawing::FeaturePage")): - exportPage(exportList[0],filename) - return - 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"): - writeMesh(ob,dxf) - else: - if ob.Shape.ShapeType == 'Compound': - if (len(ob.Shape.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) - else: - # 1 wire + lone edges -> block - block = getBlock(ob) - dxf.blocks.append(block) - dxf.append(dxfLibrary.Insert(name=ob.Name.upper())) - else: - # all other cases: block - block = getBlock(ob) - dxf.blocks.append(block) - dxf.append(dxfLibrary.Insert(name=ob.Name.upper())) - else: - writeShape(ob,dxf,nospline) - - elif (ob.Type == "App::Annotation"): - - # texts - - # temporary - as dxfLibrary doesn't support mtexts well, we use several single-line texts - # well, anyway, at the moment, Draft only writes single-line texts, so... - for text in ob.LabelText: - point = fcvec.tup(FreeCAD.Vector(ob.Position.x, - ob.Position.y-ob.LabelText.index(text), - ob.Position.z)) - if gui: height = float(ob.ViewObject.FontSize) - else: height = 1 - dxf.append(dxfLibrary.Text(text,point,height=height, - color=getACI(ob,text=True), - style='STANDARD', - layer=getGroup(ob,exportList))) - - elif 'Dimline' in ob.PropertiesList: - p1 = fcvec.tup(ob.Start) - p2 = fcvec.tup(ob.End) - base = Part.Line(ob.Start,ob.End).toShape() - proj = fcgeo.findDistance(ob.Dimline,base) - if not proj: - pbase = fcvec.tup(ob.End) + "called when freecad exports a file. If nospline=True, bsplines are exported as straight segs" + global exportList + exportList = objectslist + dxf = dxfLibrary.Drawing() + if (len(exportList) == 1) and (exportList[0].isDerivedFrom("Drawing::FeaturePage")): + exportPage(exportList[0],filename) + return + 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"): + writeMesh(ob,dxf) + else: + if ob.Shape.ShapeType == 'Compound': + if (len(ob.Shape.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) + else: + # 1 wire + lone edges -> block + block = getBlock(ob) + dxf.blocks.append(block) + dxf.append(dxfLibrary.Insert(name=ob.Name.upper())) else: - pbase = fcvec.tup(ob.End.add(fcvec.neg(proj))) - dxf.append(dxfLibrary.Dimension(pbase,p1,p2,color=getACI(ob), - layer=getGroup(ob,exportList))) + # all other cases: block + block = getBlock(ob) + dxf.blocks.append(block) + dxf.append(dxfLibrary.Insert(name=ob.Name.upper())) + else: + writeShape(ob,dxf,nospline) + + elif (ob.Type == "App::Annotation"): + + # texts + + # temporary - as dxfLibrary doesn't support mtexts well, we use several single-line texts + # well, anyway, at the moment, Draft only writes single-line texts, so... + for text in ob.LabelText: + point = fcvec.tup(FreeCAD.Vector(ob.Position.x, + ob.Position.y-ob.LabelText.index(text), + ob.Position.z)) + if gui: height = float(ob.ViewObject.FontSize) + else: height = 1 + dxf.append(dxfLibrary.Text(text,point,height=height, + color=getACI(ob,text=True), + style='STANDARD', + layer=getGroup(ob,exportList))) + + elif 'Dimline' in ob.PropertiesList: + p1 = fcvec.tup(ob.Start) + p2 = fcvec.tup(ob.End) + base = Part.Line(ob.Start,ob.End).toShape() + proj = fcgeo.findDistance(ob.Dimline,base) + if not proj: + pbase = fcvec.tup(ob.End) + else: + pbase = fcvec.tup(ob.End.add(fcvec.neg(proj))) + dxf.append(dxfLibrary.Dimension(pbase,p1,p2,color=getACI(ob), + layer=getGroup(ob,exportList))) - dxf.saveas(filename) - FreeCAD.Console.PrintMessage("successfully exported "+filename+"\r\n") + dxf.saveas(filename) + FreeCAD.Console.PrintMessage("successfully exported "+filename+"\r\n") def exportPage(page,filename): - "special export for pages" - import importSVG - tempdoc = importSVG.open(page.PageResult) - tempobj = tempdoc.Objects - export(tempobj,filename,nospline=True) - FreeCAD.closeDocument(tempdoc.Name) + "special export for pages" + import importSVG + tempdoc = importSVG.open(page.PageResult) + tempobj = tempdoc.Objects + export(tempobj,filename,nospline=True) + FreeCAD.closeDocument(tempdoc.Name)