#!BPY """ Name: 'FreeCAD (.fcstd)...' Blender: 248 Group: 'Import' Tooltip: 'Imports a FreeCAD file' """ __author__ = ["Yorik van Havre"] __url__ = ("blender", "blenderartists", "http://yorik.orgfree.com", "http://free-cad.sourceforge.net") __version__ = "0.1.0" __bpydoc__ = "This scripts imports the contents of a FreeCAD file in Blender." # History # 0.0.1 - first version # 0.1.0 - added Mesh support # ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # ***** END GPL LICENCE BLOCK ***** # ***** CONFIG ***** FREECADPATH = '/home/yorik/Apps/FreeCAD/lib' # path to your FreeCAD.la file ARCSEGMENTS = 16 # number of segments to use for drawing arcs # ***** END CONFIG ***** from Blender import Scene, Mesh, Object, Draw, Window, Mathutils, Text3d import Blender, BPyMessages, sys, math from import_dxf import calcArc # using the arc segmentation code from Migius sys.path.append(FREECADPATH) def import_fcstd(filename): "main loop through FreeCAD objects" try: import FreeCAD except ValueError: Draw.PupMenu('Error%t|FreeCAD library not found.') else: sce = Scene.GetCurrent() import Part from draftlibs import fcvec Window.WaitCursor(1) t = Blender.sys.time() doc = FreeCAD.open(filename) objects = doc.Objects for ob in objects: meshdata={} meshdata['name']=ob.Name meshdata['verts']=[] meshdata['edges']=[] meshdata['faces']=[] if ob.Type[:4] == 'Part': shape = ob.Shape if shape.Faces: rawdata = shape.tessellate(1) for v in rawdata[0]: meshdata['verts'].append((v.x,v.y,v.z)) for f in rawdata[1]: meshdata['faces'].append(f) elif shape.Edges: verts = [] for v in shape.Vertexes: verts.append(v.Point) meshdata['verts'].append((v.X,v.Y,v.Z)) for e in shape.Edges: if isinstance(e.Curve,Part.Line): i1 = fcvec.find(e.Vertexes[0].Point,verts) i2 = fcvec.find(e.Vertexes[-1].Point,verts) if (i1 != None) and (i2 != None): meshdata['edges'].append((i1,i2)) elif isinstance(e.Curve,Part.Circle): # provisorily, if we found an arc, we'll draw it as a new object cen = e.Curve.Center rad = e.Curve.Radius if len(e.Vertexes) > 1: sta = -math.degrees(fcvec.angle(e.Vertexes[0].Point.sub(cen))) end = -math.degrees(fcvec.angle(e.Vertexes[-1].Point.sub(cen))) else: sta = 0 end = 360 center=(cen.x,cen.y,cen.z) arcverts = calcArc(center, rad, sta, end, ARCSEGMENTS, None) arcdata={} arcdata['name']="Arc" arcdata['verts']=arcverts arcdata['edges']=[] for i in range(len(arcverts)-1): arcdata['edges'].append((i,i+1)) arcdata['faces']=[] drawmesh(arcdata,sce) drawmesh(meshdata,sce) elif ob.Type[:4] == 'Mesh': facets = ob.Mesh.Facets verts = [] faces = [] for f in facets: index = [] for p in f.Points: v = FreeCAD.Vector(p[0],p[1],p[2]) id = fcvec.find(v,verts) if id != None: index.append(id) else: verts.append(v) index.append(len(verts)-1) faces.append(index) for v in verts: meshdata['verts'].append((v.x,v.y,v.z)) meshdata['faces'] = faces drawmesh(meshdata,sce) elif ob.Type == 'App::Annotation': pos = (ob.Position.x,ob.Position.y,ob.Position.z) str = '' for l in ob.LabelText: if str: str += "\n" str += l txt = Text3d.New() txt.setSize(.5) txt.setText(str) obj = sce.objects.new(txt,ob.Name) obj.loc = pos # Timing the script is a good way to be aware on any speed hits when scripting print 'Import finished in %.2f seconds' % (Blender.sys.time()-t) Window.WaitCursor(0) Blender.Redraw() def drawmesh(meshdata,sce): "draws meshes in blender" mes = Mesh.New() mes.verts.extend(meshdata['verts']) if meshdata['edges']: mes.edges.extend(meshdata['edges']) if meshdata['faces']: mes.faces.extend(meshdata['faces']) sce.objects.new(mes,meshdata['name']) def main(): Window.FileSelector(import_fcstd, 'IMPORT FCSTD', Blender.sys.makename(ext='.fcstd')) # This lets you import the script without running it if __name__=='__main__': main()