#!BPY """ Name: 'Profiles12 (.dxf .svg)' Blender: 247 Group: 'Export' Tooltip: 'Exports flat shapes to DXF or SVG.' """ __author__ = ["Yorik van Havre","Migius"] __url__ = ("blender", "blenderartists", "http://yorik.orgfree.com") __version__ = "0.1.5" __bpydoc__ = """ This script has been made for exporting flat shapes (such as cross sections of a mesh) to a dxf file containing polylines or to a svg file. For the script to produce the expected result, the selected shapes must be: - horizontal, everything will be flattened on the ground (z=0) - linear, no vertex can have more than 3 adjacent edges (so, no faces) I also advice you to do a remove doubles before using... History: v0.1.5 - 2008.09.26 modif by yorik - fixed createIslands() or getOrderedVert() that generated plenty of double-verts v0.1.4 - 2008.09.25 modif by migius: - remove header, because DXF-r12 doesn't need it - changed export from LWPOLYLINE to POLYLINE v0.1.3 - 2008.09.22 by Yorik """ # ***** 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 ***** import Blender from Blender import Window, Scene, sys, Draw LAYER = 0 DXFHEADER='''0 SECTION 2 ENTITIES ''' def createIslands(mesh): islands=[[]] edges=[] for e in mesh.edges: edges.append(e) #turn it into a popable python list currentIsland=islands[0] currentIsland.append(edges.pop(0)) while (len(edges)>0): #get list of vectors in our island currentverts=[] for e in currentIsland: if not e.v1 in currentverts: currentverts.append(e.v1) if not e.v2 in currentverts: currentverts.append(e.v2) #scan remaining edges if they contain one of these vectors. basket=[] for i,e in enumerate(edges): for v in currentverts: if (e.v1 == v) or (e.v2 == v): basket.append(edges.pop(i)) break if (len(basket) > 0): currentIsland.extend(basket) else: currentIsland=[] currentIsland.append(edges.pop(0)) islands.append(currentIsland) return islands def getOrderedVertices(edgeslist,mx): #checking if closed currentverts=[] for e in edgeslist: if not e.v1 in currentverts: currentverts.append(e.v1) if not e.v2 in currentverts: currentverts.append(e.v2) if (len (edgeslist) == len (currentverts)): closed = 1 print "closing polyline" else: closed = 0 #ordering vertices edges=[] for e in edgeslist: edges.append(e) #turn it into a popable python list e1=edges.pop(0) verts=[e1.v1,e1.v2] forward=True while forward: forward=False last=verts[-1] for i,e in enumerate(edges): if (e.v1 == verts[-1]): verts.append(e.v2) edges.pop(i) forward=True break elif (e.v2 == verts[-1]): verts.append(e.v1) edges.pop(i) forward=True break backward=True while backward: backward=False last=verts[-1] for i,e in enumerate(edges): if (e.v1 == verts[0]): verts.insert(0,e.v2) edges.pop(i) backward=True break elif (e.v2 == verts[0]): verts.insert(0,e.v1) edges.pop(i) backward=True break vertslist=[] for v in verts: vm = v.co * mx vertslist.append([vm[0],vm[1],vm[2]]) if closed: vertslist.pop() return vertslist,closed def dxfexport(filepath): sce = Scene.GetCurrent() sel_group = sce.objects.selected if sel_group: Window.WaitCursor(1) t = sys.time() fl=open(filepath,'wb') fl.write(DXFHEADER) for ob in sel_group: if (ob.type == 'Mesh'): me = ob.getData(mesh=1) mx = ob.matrix islands=createIslands(me) print "total ",len(islands)," islands" for island in islands: print "one island with ",len(island)," edges" verts,closed=getOrderedVertices(island,mx) if len(verts) > 1: fl.write("0\nPOLYLINE\n") fl.write("8\n%s\n" %LAYER) fl.write("66\n1\n") #verts_len = str(len(verts)) #fl.write("90\n%s\n" %verts_len) if closed: fl.write("70\n1\n") else: fl.write("70\n0\n") fl.write(" 10\n0.0\n 20\n0.0\n 30\n0.0\n") for v in verts: fl.write("0\nVERTEX\n8\n%s\n" %LAYER) fl.write("10\n"+str(v[0])+"\n") fl.write("20\n"+str(v[1])+"\n") fl.write("0\nSEQEND\n8\n0\n") fl.write("0\nENDSEC\n0\nEOF") fl.close() else: print "selection is empty, no object to export!" # Timing the script is a good way to be aware on any speed hits when scripting print 'Export finished in %.2f seconds' % (sys.time()-t) Window.WaitCursor(0) def svgexport(filepath): sce = Scene.GetCurrent() sel_group = sce.objects.selected if sel_group: Window.WaitCursor(1) t = sys.time() fl=open(filepath,'wb') fl.write('\r\n\r\n') fl.write('\r\n') for ob in sel_group: if (ob.type == 'Mesh'): me = ob.getData(mesh=1) mx = ob.matrix islands=createIslands(me) for island in islands: verts,closed=getOrderedVertices(island,mx) fl.write('\r\n') fl.write('') fl.close() if __name__=='__main__': exportMode = Draw.PupMenu("Which format?|DXF|SVG",2) if (exportMode == 3): Blender.Window.FileSelector(svgexport, 'EXPORT SVG', sys.makename(ext='.svg')) else: Blender.Window.FileSelector(dxfexport, 'EXPORT DXF', sys.makename(ext='.dxf'))