4 Name: 'Autodesk DXF (.dxf)'
7 Tooltip: 'Export geometry to DXF/DWG-r12 (Drawing eXchange Format).'
10 __version__ = "1.34 - 2009.06.02"
11 __author__ = "Remigiusz Fiedler (AKA migius)"
13 __url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf"
14 __bpydoc__ ="""The script exports Blender geometry to DXF format r12 version.
20 extern dependances: dxfLibrary.py, (optionaly: DConvertCon.exe)
23 Remigiusz Fiedler (AKA migius)
24 Alexandros Sigalas (AKA alxarch)
25 Stani Michiels (AKA stani)
27 See the homepage for documentation.
31 - HPGL output, especially usefull for correct scaled printing of 2d drawings
34 - export dupligroups and dupliverts as blocks (option for the user to decide)
35 - optimize POLYFACE routine: remove double-vertices
36 - optimize POLYFACE routine: remove loose vertices
37 - support any-oriented mirrored curves(to POLYLINEs): fix blender negative-matrix.invert()
38 - support hierarchies: groups, instances, parented structures
39 - write drawing extends for automatic view positioning in CAD
40 - mapping materials to DXF-styles
43 v1.34 - 2009.06.02 by migius
44 - support XYmirrored 2d-curves to POLYLINEs: works correct only for rotX,rotY==0.0
45 - support thickness and elevation for curve-objects
46 - fix extrusion 210-code (3d orientation vector)
47 - fix POLYFACE export, synchronized with dxfLibrary.py
48 - changed to the new 2.49 method Vector.cross()
49 - output style manager (first try)
50 v1.33 - 2009.05.25 by migius
51 - bugfix flipping normals in mirrored mesh-objects
52 - added UI-Button for future Shadow Generator
53 - support curve objects in projection-2d mode
54 - UI stuff: camera selector/manager
55 v1.32 - 2009.05.22 by migius
56 - debug mode for curve-objects: output pass to Blender
57 - wip support 210-code(extrusion) calculation
58 - default settings for 2D and 3D export
59 v1.31 - 2009.05.18 by migius
60 - globals translated to GUI_A/B dictionary
61 - optimizing back-faces removal for "hidden-lines" mode
62 - presets for global location and scale (architecture)
63 - UI layout: scrollbars, pan with MMB/WHEEL, dynamic width
64 - new GUI with Draw.Register() from DXF-importer.py
65 v1.30 - 2008.12.14 by migius
66 - started work on GUI with Draw.Register()
67 v1.29 - 2009.04.11 by stani
68 - added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter
69 v1.28 - 2009.02.05 by Alexandros Sigalas (alxarch)
70 - added option to apply modifiers on exported meshes
71 - added option to also export duplicates (from dupliverts etc)
72 v1.28 - 2008.10.22 by migius
73 - workaround for PVert-bug on ubuntu (reported by Yorik)
74 - add support for FGons - ignore invisible_tagged edges
75 - add support for camera: ortho and perspective
76 v1.27 - 2008.10.07 by migius
77 - exclude Stani's DXF-Library to extern module
78 v1.26 - 2008.10.05 by migius
79 - add "hidden mode" substitut: back-faces removal
80 - add support for mesh ->POLYFACE
81 - optimized code for "Flat" procedure
82 v1.25 - 2008.09.28 by migius
83 - modif FACE class for r12
84 - add mesh-polygon -> Bezier-curve converter (Yorik's code)
85 - add support for curves ->POLYLINEs
86 - add "3d-View to Flat" - geometry projection to XY-plane
87 v1.24 - 2008.09.27 by migius
88 - add start UI with preferences
89 - modif POLYLINE class for r12
90 - changing output format from r9 to r12(AC1009)
91 v1.23 - 2008.09.26 by migius
92 - add finish message-box
93 v1.22 - 2008.09.26 by migius
94 - add support for curves ->LINEs
95 - add support for mesh-edges ->LINEs
96 v1.21 - 2008.06.04 by migius
97 - initial adaptation for Blender
98 v1.1 (20/6/2005) by Stani Michiels www.stani.be/python/sdxf
99 - Python library to generate dxf drawings
100 ______________________________________________________________
101 """ % (__author__,__version__,__license__,__url__)
103 # --------------------------------------------------------------------------
104 # Script copyright (C) 2008 Remigiusz Fiedler (AKA migius)
105 # --------------------------------------------------------------------------
106 # ***** BEGIN GPL LICENSE BLOCK *****
108 # This program is free software; you can redistribute it and/or
109 # modify it under the terms of the GNU General Public License
110 # as published by the Free Software Foundation; either version 2
111 # of the License, or (at your option) any later version.
113 # This program is distributed in the hope that it will be useful,
114 # but WITHOUT ANY WARRANTY; without even the implied warranty of
115 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
116 # GNU General Public License for more details.
118 # You should have received a copy of the GNU General Public License
119 # along with this program; if not, write to the Free Software Foundation,
120 # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
122 # ***** END GPL LICENCE BLOCK *****
126 from Blender import Mathutils, Window, Scene, Draw, Camera, BezTriple
127 from Blender import Registry, Object, Mesh, Curve
131 import dxfLibrary as DXF
134 #from dxfLibrary import *
137 from math import atan, atan2, log10, sin, cos
141 r2d = 180.0 / math.pi
142 d2r = math.pi / 180.0
143 #note: d2r * angle == math.radians(angle)
146 print 'DXF-Exporter v%s *** start ***' %(__version__) #---------------------
148 #DEBUG = True #activets debug mode
151 #----globals------------------------------------------
152 ONLYSELECTED = 1 # 0/1 = False/True
153 POLYLINES = 1 # prefer POLYLINEs not LINEs
154 POLYFACES = 1 # prefer POLYFACEs not 3DFACEs
155 PROJECTION = 0 # flatten output geometry to Z = 0.0
156 HIDDEN_LINES = 0 #filter out hidden geometry
157 SHADOWS = 0 # sun/shadows simulation
158 CAMERA = 1 # view from active camera or from 3d-view
159 PERSPECTIVE = 0 #perspective camera
162 OUTPUT_DWG = 0 #optional save to DWG with extern converter
164 G_SCALE = 1.0 #(0.0001-1000) global scaling factor for output dxf data
165 G_ORIGIN = [0.0,0.0,0.0] #global translation-vector (x,y,z) in Blender units
166 ELEVATION = 0.0 #standard elevation = coordinate Z value in Blender units
168 MIN_DIST = 0.001 #cut-off value for sort out short-distance polyline-"duoble_vertex"
169 CURV_RESOLUTION = 12 #(1-128) Bezier curves U-resolution
170 CURVARC_RESOLUTION = 4 #(3-32) resolution of circle represented as Bezier curve
171 THIN_RESOLUTION = 8 #(4-64) thin_cylinder arc_resolution - number of segments
172 MIN_THICK = MIN_DIST * 10.0 #minimal thickness by forced thickness
173 MIN_WIDTH = MIN_DIST * 10.0 #minimal width by forced width
175 BYBLOCK = 0 #DXF-attribute: assign property to BLOCK defaults
176 BYLAYER = None #256 #DXF-attribute: assign property to LAYER defaults
177 PREFIX = 'BF_' #used as prefix for DXF names
178 LAYERNAME_DEF = '' #default layer name
179 LAYERCOLOR_DEF = 7 #default layer color index
180 LAYERLTYPE_DEF = 0 #'CONTINUOUS' - default layer lineType
181 ENTITYLAYER_DEF = LAYERNAME_DEF #default entity color index
182 ENTITYCOLOR_DEF = BYLAYER #default entity color index
183 ENTITYLTYPE_DEF = BYLAYER #default entity lineType
185 LAB = "scroll MMB/WHEEL . wip .. todo" #"*) parts under construction"
188 FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE)
189 MAX_NAMELENGTH = 17 #max_effective_obnamelength in blender =21=17+(.001)
190 INIFILE_DEFAULT_NAME = 'exportDXF'
191 INIFILE_EXTENSION = '.ini'
192 INIFILE_HEADER = '#ExportDXF.py ver.1.0 config data'
193 INFFILE_HEADER = '#ExportDXF.py ver.1.0 analyze of DXF-data'
196 WORLDX = Mathutils.Vector((1,0,0))
197 #TODO: a bug? WORLDY = Mathutils.Vector((1,1,0))
198 WORLDY = Mathutils.Vector((0,1,0))
199 WORLDZ = Mathutils.Vector((0,0,1))
201 AUTO = BezTriple.HandleTypes.AUTO
202 FREE = BezTriple.HandleTypes.FREE
203 VECT = BezTriple.HandleTypes.VECT
204 ALIGN = BezTriple.HandleTypes.ALIGN
207 #-------- DWG support ------------------------------------------
209 extCONV = 'DConvertCon.exe'
210 extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV)
211 if not os.path.isfile(extCONV_PATH):
213 extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\
214 Copy first %s into Blender script directory.|\
215 More details in online Help.' %extCONV
217 if not os.sys.platform.startswith('win'):
218 # check if Wine installed:
219 if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip():
220 extCONV_PATH = 'wine %s'%extCONV_PATH
223 extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\
224 The external DWG-converter (%s) needs Wine installed on your system.|\
225 More details in online Help.' %extCONV
226 #print 'extCONV_PATH = ', extCONV_PATH
229 #----------------------------------------------
230 def updateMenuCAMERA():
235 scn = Scene.GetCurrent()
236 objs = scn.getChildren()
237 currcam = scn.getCurrentCamera()
238 if currcam: currcam = currcam.getName()
240 MenuCAMERA = "Select Camera%t"
242 if cam.getType() == 'Camera':
243 if cam.getName()[0:4] != "Temp":
244 maincams.append(cam.getName())
248 for i, cam in enumerate(CAMERAS):
250 MenuCAMERA += "|* " + cam
251 else: MenuCAMERA += "| " + cam
252 MenuCAMERA += "|current 3d-View"
253 MenuLIGHT = "Select Sun%t| *todo"
256 #----------------------------------------------
260 scn = Scene.GetCurrent()
261 currcam = scn.getCurrentCamera()
262 if currcam: currcam = currcam.getName()
263 if currcam in CAMERAS:
264 CAMERA = CAMERAS.index(currcam)+1
265 GUI_A['camera_on'].val = CAMERA
267 #----------------------------------------------
269 cam = Object.Get(CAMERAS[CAMERA-1])
270 print 'deb: CAMERA, cam',CAMERA, cam
271 if cam.getType() != 'Camera':
272 sure = Draw.PupMenu("Info: %t| It is not a Camera Object.")
274 scn = Scene.getCurrent()
275 scn.setCurrentCamera(cam)
281 #------- Duplicats support ----------------------------------------------
284 Checks objects for duplicates enabled (any type)
285 object: Blender Object.
286 Returns: Boolean - True if object has any kind of duplicates enabled.
288 if (object.enableDupFrames or \
289 object.enableDupGroup or \
290 object.enableDupVerts):
295 def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False):
297 Return a list of real objects and duplicates and optionally their matrices
298 oblist: List of Blender Objects
299 MATRICES: Boolean - Check to also get the objects matrices default=False
300 HACK: Boolean - See note default=False
301 Returns: List of objects or
302 List of tuples of the form:(ob,matrix) if MATRICES is set to True
303 NOTE: There is an ugly hack here that excludes all objects whose name
304 starts with "dpl_" to exclude objects that are parented to a duplicating
305 object, User must name objects properly if hack is used.
310 if INCLUDE_DUPLIS and dupTest(ob):
311 dup_obs=ob.DupObjects
313 for dup_ob, dup_mx in dup_obs:
315 result.append((dup_ob,dup_mx))
317 result.append(dup_ob)
320 if ob.getName()[0:4] != "dpl_":
323 result.append((ob,mx))
329 result.append((ob,mx))
334 #-----------------------------------------------------
335 def hidden_status(faces, mx, mx_n):
336 # sort out back-faces = with normals pointed away from camera
337 print 'HIDDEN_LINES: caution! not full implemented yet'
341 #print 'deb: face=', f #---------
342 #print 'deb: dir(face)=', dir(f) #---------
343 # get its normal-vector in localCS
344 vec_normal = f.no.copy()
345 #print 'deb: vec_normal=', vec_normal #------------------
346 # must be transfered to camera/view-CS
348 #vec_normal *= mb.rotationPart()
349 #print 'deb:2vec_normal=', vec_normal #------------------
350 #vec_normal *= mw0.rotationPart()
351 #print 'deb:3vec_normal=', vec_normal, '\n' #------------------
355 if not PERSPECTIVE: #for ortho mode ----------
356 # normal must point the Z direction-hemisphere
357 if vec_normal[2] > 0.00001:
361 vert = Mathutils.Vector(v.co) * mx
362 if Mathutils.DotVecs(vert, vec_normal) < 0.00001:
366 front_faces.append(f.index)
367 for key in f.edge_keys:
368 #this test can be done faster with set()
369 if key not in front_edges:
370 front_edges.append(key)
372 #print 'deb: amount of visible faces=', len(front_faces) #---------
373 #print 'deb: visible faces=', front_faces #---------
374 #print 'deb: amount of visible edges=', len(front_edges) #---------
375 #print 'deb: visible edges=', front_edges #---------
376 return front_faces, front_edges
379 #--------not used-------------------------------------
380 def projected_co0(vec, mw):
381 # convert the world coordinates of vector to screen coordinates
382 #co = vec.co.copy().resize4D()
383 co = vec.copy().resize4D()
386 #print 'deb: viewprojection=', sc #---------
387 return [sc[0],sc[1],0.0]
390 #--------not used---------------------------------------------
391 def flatten(points, mw):
392 for i,v in enumerate(points):
393 v = projected_co(v, mw)
395 #print 'deb: flatten points=', points #---------
398 #---- migration to 2.49-------------------------------------------------
399 if 'cross' in dir(Mathutils.Vector()):
400 #Draw.PupMenu('DXF exporter: Abort%t|This script version works for Blender up 2.49 only!')
401 def M_CrossVecs(v1,v2):
402 return v1.cross(v2) #for up2.49
403 def M_DotVecs(v1,v2):
404 return v1.dot(v2) #for up2.49
406 def M_CrossVecs(v1,v2):
407 return Mathutils.CrossVecs(v1,v2) #for pre2.49
408 def M_DotVecs(v1,v2):
409 return Mathutils.DotVecs(v1,v2) #for pre2.49
412 #-----------------------------------------------------
413 def getExtrusion(matrix):
414 #print 'deb:getExtrusion() given matrix=\n', matrix #---------
415 AZaxis = matrix[2].copy().resize3D().normalize() # = ArbitraryZvector
416 Extrusion = [AZaxis[0],AZaxis[1],AZaxis[2]]
419 AXaxis = matrix[0].copy().resize3D() # = ArbitraryZvector
421 threshold = 1.0 / 64.0
422 if abs(AZaxis[0]) < threshold or abs(AZaxis[1]) < threshold:
423 # AXaxis is the intersection WorldPlane and ExtrusionPlane
424 AXaxis = M_CrossVecs(WORLDY,AZaxis)
426 AXaxis = M_CrossVecs(WORLDZ,AZaxis)
428 #print 'deb:\n' #-------------
429 #print 'deb:getExtrusion() Extrusion=', Extrusion #---------
430 return Extrusion, AXaxis.normalize()
432 #-----------------------------------------------------
433 def getZRotation(AXaxis, rot_matrix_invert):
434 #ZRotation = Mathutils.AngleBetweenVecs(WORLDX,AXaxis) #output in degrees
436 # this works: Xaxis is the obj.matrix Xaxis vector
437 #Xaxis = matrix[0].copy().resize3D() # = ArbitraryXvector
438 ##Xaxis.normalize() # = ArbitraryXvector
439 #ZRotation = - d2r * Mathutils.AngleBetweenVecs(Xaxis,AXaxis) #output in degrees
441 # this works too, maybe faster
442 # transform AXaxis into OCS:Object-Coord-System
443 #rot_matrix = normalizeMat(matrix.rotationPart())
444 #rot_matrix_invert = rot_matrix.invert()
445 vec = AXaxis * rot_matrix_invert
446 ##vec = AXaxis * matrix.copy().invert()
447 ##vec.normalize() # not needed for atan2()
448 ##print '\ndeb:getExtrusion() vec=', vec #---------
449 ZRotation = - atan2(vec[1],vec[0]) #output in radians
451 #print 'deb:ZRotation() ZRotation=', ZRotation*r2d #---------
455 #------------------------------------------
456 def normalizeMat(matrix):
457 mat12 = matrix.copy()
458 mat12 = [Mathutils.Vector(v).normalize() for v in mat12]
460 matr12 = Mathutils.Matrix(mat12[0],mat12[1],mat12[2],mat12[3])
462 matr12 = Mathutils.Matrix(mat12[0],mat12[1],mat12[2])
466 #-----------------------------------------------------
467 def projected_co(verts, mx):
468 # converts world coordinates of points to screen coordinates
471 #temp_verts.append(Blender.Mesh.MVert(v.co))
472 temp_verts.append(Mesh.MVert(v))
473 #print 'deb: temp_verts=', temp_verts #---------
477 if GUI_A['Z_force_on'].val: locZ = GUI_A['Z_elev'].val
484 coef = - clipStart / v.co[2]
490 temp_verts = [v.co[:3] for v in temp_verts]
494 #-----------------------------------------------------
495 def isLeftHand(matrix):
496 #Is the matrix a left-hand-system, or not?
497 ma = matrix.rotationPart()
498 crossXY = M_CrossVecs(ma[0], ma[1])
499 check = M_DotVecs(ma[2], crossXY)
500 if check < 0.00001: return 1
504 #-----------------------------------------------------
505 def exportMesh(ob, mx, mx_n, me=None, **common):
506 global APPLY_MODIFIERS
508 #print 'deb:exportMesh() common=', common #---------
509 if me is None: # me means mesh
510 me = ob.getData(mesh=1)
513 # me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state
514 # above is eventualy faster, but bad, cause
515 # invasive: directly transforms origin geometry and write back rounding errors
516 #we dont want to manipulate origin data
517 #temp_verts = me.verts[:] #doesn't work on ubuntu(Yorik), bug?
519 #print 'deb:exportMesh() started' #---------
520 allpoints = [v.co for v in me.verts]
521 allpoints = projected_co(allpoints, mx)
522 if GUI_A['g_origin_on'].val: #TODO: scale and object orientation
529 if me.faces and HIDDEN_LINES:
530 if DEBUG: print 'deb:exportMesh HIDDEN_LINES mode' #---------
531 faces, edges = hidden_status(me.faces, mx, mx_n)
532 faces = [[v.index for v in me.faces[f_nr].verts] for f_nr in faces]
534 if DEBUG: print 'deb:exportMesh STANDARD mode' #---------
535 for e in me.edges: edges.append(e.key)
536 #faces = [f.index for f in me.faces]
537 faces = [[v.index for v in f.verts] for f in me.faces]
538 #faces = [[allpoints[v.index] for v in f.verts] for f in me.faces]
539 #print 'deb: allpoints=\n', allpoints #---------
540 #print 'deb: edges=\n', edges #---------
541 #print 'deb: faces=\n', faces #---------
542 if isLeftHand(mx): # then change vertex-order in every face
545 #f = [f[-1]] + f[:-1] #TODO: might be needed
546 #print 'deb: faces=\n', faces #---------
548 c = mesh_as_list[GUI_A['mesh_as'].val]
549 if 'POINTs'==c: # export Mesh as multiple POINTs
551 dxfPOINT = DXF.Point(points=[p],**common)
552 entities.append(dxfPOINT)
553 elif 'LINEs'==c or (not faces):
554 if edges and allpoints:
555 if DEBUG: mesh_drawBlender(allpoints, edges, None) #deb: draw to blender scene
557 points = [allpoints[e[0]], allpoints[e[1]]]
558 dxfLINE = DXF.Line(points, **common)
559 entities.append(dxfLINE)
561 if c in ('POLYFACE','POLYLINE'):
563 #TODO: purge allpoints: left only vertices used by faces
564 if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene
565 faces = [[v+1 for v in f] for f in faces]
566 dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag=64, **common)
567 #dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag=64)
568 #print '\n deb: dxfPOLYFACE=',dxfPOLYFACE #-------------
569 entities.append(dxfPOLYFACE)
571 if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene
573 #print 'deb: face=', f #---------
574 points = [allpoints[key] for key in f]
575 #points = [p.co[:3] for p in points]
576 #print 'deb: pointsXX=\n', points #---------
577 dxfFACE = DXF.Face(points, **common)
578 entities.append(dxfFACE)
582 #-----------------------------------------------------
583 def mesh_drawBlender(vertList, edgeList, faceList, name="dxfMesh", flatten=False, AT_CUR=True, link=True):
584 #print 'deb:mesh_drawBlender started XXXXXXXXXXXXXXXXXX' #---------
585 ob = Object.New("Mesh",name)
587 #print 'deb: vertList=\n', vertList #---------
588 #print 'deb: edgeList=\n', edgeList #---------
589 #print 'deb: faceList=\n', faceList #---------
590 me.verts.extend(vertList)
591 if edgeList: me.edges.extend(edgeList)
592 if faceList: me.faces.extend(faceList)
594 for v in me.verts: v.co.z = 0.0
597 sce = Scene.getCurrent()
601 cur_loc = Window.GetCursorPos()
602 ob.setLocation(cur_loc)
606 #-----------------------------------------------------
607 def curve_drawBlender(vertList, org_point=[0.0,0.0,0.0], closed=0, name="dxfCurve", flatten=False, AT_CUR=True, link=True):
608 #print 'deb:curve_drawBlender started XXXXXXXXXXXXXXXXXX' #---------
609 ob = Object.New("Curve",name)
611 #print 'deb: vertList=\n', vertList #---------
612 curve = cu.appendNurb(BezTriple.New(vertList[0]))
613 for p in vertList[1:]:
614 curve.append(BezTriple.New(p))
616 #point.handleTypes = [VECT, VECT]
617 point.handleTypes = [FREE, FREE]
619 curve.flagU = closed # 0 sets the curve not cyclic=open
621 cu.update() #important for handles calculation
623 for v in cu.verts: v.co.z = 0.0
626 sce = Scene.getCurrent()
630 cur_loc = Window.GetCursorPos()
631 ob.setLocation(cur_loc)
634 ob.setLocation(cur_loc)
639 #-----------------------------------------------------
640 def exportEmpty(ob, mx, mw, **common):
641 p = Mathutils.Vector(ob.loc)
642 print 'is it a vector?:', p
643 [p] = projected_co([p], mx)
644 if GUI_A['g_origin_on'].val: #TODO: scale and object orientation
650 c = empty_as_list[GUI_A['empty_as'].val]
651 if c=="POINT": # export Empty as POINT
652 dxfPOINT = DXF.Point(points=[p],**common)
653 entities.append(dxfPOINT)
657 #-----------------------------------------------------
658 def exportCurve(ob, mx, mw, **common):
661 Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
663 #Extrusion, ZRotation, Elevation = getExtrusion(mx)
664 Extrusion, AXaxis = getExtrusion(mx)
666 WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
667 #WCS_loc = [0.0,0.0,0.0]
668 #print 'deb: WCS_loc=', WCS_loc #---------
674 #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
676 #print 'deb: curve.ext1=', curve.ext1 #---------
677 if curve.ext1: Thickness = curve.ext1 * sizeZ
679 if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE
680 rot_matrix = normalizeMat(mx.rotationPart())
681 #TODO: workaround for blender negative-matrix.invert()
682 # partially done: works only for rotX,rotY==0.0
683 if sizeX<0.0: rot_matrix[0] *= -1
684 if sizeY<0.0: rot_matrix[1] *= -1
685 #if sizeZ<0.0: rot_matrix[2] *= -1
686 rot_matrix_invert = rot_matrix.invert()
687 OCS_origin = Mathutils.Vector(WCS_loc) * rot_matrix_invert
688 # OCS_origin is global origin in ObjectCoordSystem
689 #print 'deb: OCS_origin=', OCS_origin #---------
692 ZRotation = getZRotation(AXaxis,rot_matrix_invert)
693 #print 'deb: ZRotation=', ZRotation * r2d #--------------
694 #Zrotmatrix = Mathutils.RotationMatrix(-ZRotation, 3, "Z")
695 rs, rc = sin(ZRotation), cos(ZRotation)
696 Zrotmatrix = Mathutils.Matrix([rc, rs,0.0],[-rs,rc,0.0],[0.0,0.0,1.0])
698 ECS_origin = OCS_origin.copy()
699 #if sizeX<0.0: ECS_origin[0] *= -1
700 #if sizeY<0.0: ECS_origin[1] *= -1
701 #if sizeZ<0.0: ECS_origin[2] *= -1
702 ECS_origin = ECS_origin * Zrotmatrix
703 #print 'deb: ECS_origin=', ECS_origin #---------
704 # ECS_origin is global origin in EntityCoordSystem
705 #TODO: it doesnt work yet for negative scaled curve-objects!
708 #print 'deb: START cur=', cur #--------------
712 #print 'deb:isNurb point=', point #---------
714 #print 'deb: vec=', vec #---------
715 pkt = Mathutils.Vector(vec)
716 #print 'deb: pkt=', pkt #---------
720 #print 'deb:isBezier point=', point.getTriple() #---------
721 vec = point.getTriple()[1]
722 #print 'deb: vec=', vec #---------
723 pkt = Mathutils.Vector(vec)
724 #print 'deb: pkt=', pkt #---------
727 #print 'deb: points', points #--------------
729 c = curve_as_list[GUI_A['curve_as'].val]
731 if c=="POLYLINE": # export Curve as POLYLINE
732 for p in points: # vectors4d
736 p2[0] += ECS_origin[0]
737 p2[1] += ECS_origin[1]
738 p[0],p[1] = p2[0],p2[1]
739 #print 'deb:points', points #--------------
741 if cur.isCyclic(): closed = 1
743 if GUI_A['g_origin_on'].val: #TODO: scale and object orientation
748 if DEBUG: curve_drawBlender(points,OCS_origin,closed) #deb: draw to scene
749 common['extrusion']= Extrusion
750 #common['rotation']= ZRotation
751 #common['elevation']= Elevation
752 common['thickness']= Thickness
753 #print 'deb: common=', common #------------------
756 linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]]
757 dxfLINE = DXF.Line(linepoints,**common)
758 entities.append(dxfLINE)
760 dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common)
761 entities.append(dxfPLINE)
763 common['thickness']= -Thickness
764 dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common)
765 entities.append(dxfPLINE)
767 elif c=="LINEs": # export Curve as multiple LINEs
768 points = projected_co(points, mx)
769 if cur.isCyclic(): points.append(points[0])
770 #print 'deb: points', points #--------------
771 if GUI_A['g_origin_on'].val: #TODO: scale and object orientation
776 if DEBUG: curve_drawBlender(points,WCS_loc,closed) #deb: draw to scene
777 common['extrusion']= Extrusion
778 common['elevation']= Elevation
779 common['thickness']= Thickness
780 #print 'deb: common=', common #------------------
781 for i in range(len(points)-1):
782 linepoints = [points[i], points[i+1]]
783 dxfLINE = DXF.Line(linepoints,**common)
784 entities.append(dxfLINE)
786 common['thickness']= -Thickness
787 for i in range(len(points)-1):
788 linepoints = [points[i], points[i+1]]
789 dxfLINE = DXF.Line(linepoints,**common)
790 entities.append(dxfLINE)
792 elif c=="POINTs": # export Curve as multiple POINTs
794 dxfPOINT = DXF.Point(points=[p],**common)
795 entities.append(dxfPOINT)
799 #-----------------------------------------------------
800 def getClipBox(camera):
801 sce = Scene.GetCurrent()
802 context = sce.getRenderingContext()
803 #print 'deb: context=\n', context #------------------
804 sizeX = context.sizeX
805 sizeY = context.sizeY
806 ratioXY = sizeX/float(sizeY)
807 #print 'deb: size X,Y, ratio=', sizeX, sizeY, ratioXY #------------------
809 clip1_Z = - camera.clipStart
810 clip2_Z = - camera.clipEnd
811 #print 'deb: clip Start=', camera.clipStart #------------------
812 #print 'deb: clip End=', camera.clipEnd #------------------
814 if camera.type=='ortho':
816 #print 'deb: camscale=', scale #------------------
817 clip1shiftX = clip2shiftX = camera.shiftX * scale
818 clip1shiftY = clip2shiftY = camera.shiftY * scale
819 clip1_X = scale * 0.5
820 clip1_Y = scale * 0.5
821 if ratioXY > 1.0: clip1_Y /= ratioXY
822 else: clip1_X *= ratioXY
828 right, left = clip1_X, -clip1_X
829 top, bottom = clip1_Y, -clip1_Y
831 scaleX = 2.0/float(right - left)
832 x3 = -float(right + left)/float(right - left)
833 scaleY = 2.0/float(top - bottom)
834 y3 = -float(top + bottom)/float(top - bottom)
835 scaleZ = 1.0/float(far - near)
836 z3 = -float(near)/float(far - near)
838 matr = Mathutils.Matrix( [scaleX, 0.0, 0.0, x3],
839 [0.0, scaleY, 0.0, y3],
840 [0.0, 0.0, scaleZ, z3],
841 [0.0, 0.0, 0.0, 1.0])
843 elif camera.type=='persp':
844 #viewpoint = [0.0, 0.0, 0.0] #camera's coordinate system, hehe
847 #print 'deb: cam angle=', angle #------------------
848 shiftX = camera.shiftX
849 shiftY = camera.shiftY
850 fov_coef = atan(angle * d2r)
851 fov_coef *= 1.3 #incl. passpartou
852 clip1_k = clip1_Z * fov_coef
853 clip2_k = clip2_Z * fov_coef
854 clip1shiftX = - camera.shiftX * clip1_k
855 clip2shiftX = - camera.shiftX * clip2_k
856 clip1shiftY = - camera.shiftY * clip1_k
857 clip2shiftY = - camera.shiftY * clip2_k
858 clip1_X = clip1_Y = clip1_k * 0.5
859 clip2_X = clip2_Y = clip2_k * 0.5
869 right, left = clip1_X, -clip1_X
870 top, bottom = clip1_Y, -clip1_Y
871 #return Matrix( [scaleX, 0.0, x2, 0.0],
872 #[0.0, scaleY, y2, 0.0],
873 #[0.0, 0.0, scaleZ, wZ],
874 #[0.0, 0.0, -1.0, 0.0])
875 matr = Mathutils.Matrix( [(2.0 * near)/float(right - left), 0.0, float(right + left)/float(right - left), 0.0],
876 [0.0, (2.0 * near)/float(top - bottom), float(top + bottom)/float(top - bottom), 0.0],
877 [0.0, 0.0, -float(far + near)/float(far - near), -(2.0 * far * near)/float(far - near)],
878 [0.0, 0.0, -1.0, 0.0])
882 -clip1_X + clip1shiftX, clip1_X + clip1shiftX,
883 -clip1_Y + clip1shiftY, clip1_Y + clip1shiftY,
884 -clip2_X + clip2shiftX, clip2_X + clip2shiftX,
885 -clip2_Y + clip2shiftY, clip2_Y + clip2shiftY,
887 #print 'deb: clip_box=\n', clip_box #------------------
888 #drawClipBox(clip_box)
889 return clip_box, matr
892 #-----------------------------------------------------
893 def drawClipBox(clip_box):
894 min_X1, max_X1, min_Y1, max_Y1,\
895 min_X2, max_X2, min_Y2, max_Y2,\
896 min_Z, max_Z = clip_box
898 verts.append([min_X1, min_Y1, min_Z])
899 verts.append([max_X1, min_Y1, min_Z])
900 verts.append([max_X1, max_Y1, min_Z])
901 verts.append([min_X1, max_Y1, min_Z])
902 verts.append([min_X2, min_Y2, max_Z])
903 verts.append([max_X2, min_Y2, max_Z])
904 verts.append([max_X2, max_Y2, max_Z])
905 verts.append([min_X2, max_Y2, max_Z])
906 faces = [[0,1,2,3],[4,5,6,7]]
908 nme.verts.extend(verts)
909 nme.faces.extend(faces)
911 plan = Object.New('Mesh','clip_box')
913 sce = Scene.GetCurrent()
914 sce.objects.link(plan)
915 plan.setMatrix(sce.objects.camera.matrix)
918 #-------------------------------------------------
920 #set up common attributes for output style:
930 layers = ob.layers #gives a list e.g.[1,5,19]
931 if layers: ob_layer_nr = layers[0]
932 #print 'ob_layer_nr=', ob_layer_nr #--------------
934 materials = ob.getMaterials()
936 ob_material = materials[0]
937 ob_mat_color = ob_material.rgbCol
938 else: ob_mat_color, ob_material = None, None
939 #print 'ob_mat_color, ob_material=', ob_mat_color, ob_material #--------------
942 data_materials = ob.getMaterials()
944 data_material = data_materials[0]
945 data_mat_color = data_material.rgbCol
946 else: data_mat_color, data_material = None, None
947 #print 'data_mat_color, data_material=', data_mat_color, data_material #--------------
949 entitylayer = ENTITYLAYER_DEF
950 c = entitylayer_from_list[GUI_A['entitylayer_from'].val]
951 #["default_LAYER","obj.name","obj.layer","obj.material","obj.data.name","obj.data.material","..vertexgroup","..group","..map_table"]
952 if c=="default_LAYER":
953 entitylayer = LAYERNAME_DEF
954 elif c=="obj.layer" and ob_layer_nr:
955 entitylayer = 'LAYER'+ str(ob_layer_nr)
956 elif c=="obj.material" and ob_material:
957 entitylayer = ob_material.name
959 entitylayer = ob.name
960 elif c=="obj.data.material" and ob_material:
961 entitylayer = data_material.name
962 elif c=="obj.data.name":
963 entitylayer = data.name
964 entitylayer = validDXFr12name(PREFIX+entitylayer)
965 if entitylayer=="": entitylayer = "BF_0"
967 entitycolor = ENTITYCOLOR_DEF
968 c = entitycolor_from_list[GUI_A['entitycolor_from'].val]
969 if c=="default_COLOR":
970 entitycolor = LAYERCOLOR_DEF
972 entitycolor = BYLAYER
974 entitycolor = BYBLOCK
975 elif c=="obj.layer" and ob_layer_nr:
976 entitycolor = ob_layer_nr
977 elif c=="obj.color" and ob.color:
978 entitycolor = col2DXF(ob.color)
979 elif c=="obj.material" and ob_mat_color:
980 entitycolor = col2DXF(ob_mat_color)
981 elif c=="obj.data.material" and data_mat_color:
982 entitycolor = col2DXF(data_mat_color)
983 #if entitycolor!=None: layercolor = entitycolor
985 entityltype = ENTITYLTYPE_DEF
986 c = entityltype_from_list[GUI_A['entityltype_from'].val]
987 if c=="default_LTYPE":
988 entityltype = LAYERLTYPE_DEF
990 entityltype = BYLAYER
992 entityltype = BYBLOCK
996 return entitylayer,entitycolor,entityltype
999 #-----------------------------------------------------
1000 def do_export(export_list, filepath):
1002 Window.WaitCursor(1)
1003 t = Blender.sys.time()
1005 #init Drawing ---------------------
1007 #add Tables -----------------
1008 #d.blocks.append(b) #table blocks
1009 #goes automatic: d.styles.append(DXF.Style()) #table styles
1010 #d.views.append(DXF.View('Normal')) #table view
1011 d.views.append(DXF.ViewByWindow('BF_TOPVIEW',leftBottom=(-10,-6),rightTop=(10,6))) #idem
1013 #add Entities --------------------
1015 sce = Scene.GetCurrent()
1017 mw = Mathutils.Matrix( [1.0, 0.0, 0.0, 0.0],
1018 [0.0, 1.0, 0.0, 0.0],
1019 [0.0, 0.0, 1.0, 0.0],
1020 [0.0, 0.0, 0.0, 1.0])
1022 if CAMERA<len(CAMERAS)+1: #the biggest number is the current view
1023 act_camera = Object.Get(CAMERAS[CAMERA-1])
1024 context = sce.getRenderingContext()
1025 #print 'deb: context=\n', context #------------------
1026 #print 'deb: context=\n', dir(context) #------------------
1027 #act_camera = sce.objects.camera
1028 #print 'deb: act_camera=', act_camera #------------------
1030 mc0 = act_camera.matrix.copy()
1031 #print 'deb: camera.Matrix=\n', mc0 #------------------
1032 camera = Camera.Get(act_camera.getData(name_only=True))
1033 #print 'deb: camera=', dir(camera) #------------------
1034 if camera.type=='persp': PERSPECTIVE = 1
1035 elif camera.type=='ortho': PERSPECTIVE = 0
1036 clip_box, mcp = getClipBox(camera)
1038 #mcp = getPerspMatrix(camera)
1039 mw = mc0.copy().invert()
1041 else: # get 3D-View instead of camera
1042 #ViewVector = Mathutils.Vector(Window.GetViewVector())
1043 #print 'deb: ViewVector=\n', ViewVector #------------------
1044 #TODO: for what is Window.GetViewOffset() ??
1045 #print 'deb: Window.GetViewOffset():', Window.GetViewOffset() #---------
1046 #Window.SetViewOffset([0,0,0])
1047 #print 'deb: Window.GetViewOffset():', Window.GetViewOffset() #---------
1048 mw0 = Window.GetViewMatrix()
1049 #print 'deb: mwOrtho =\n', mw0 #---------
1050 mwp = Window.GetPerspMatrix() #TODO: how get it working?
1051 #print 'deb: mwPersp =\n', mwp #---------
1053 #clip_box = getClipBox(camera, context)
1056 #print 'deb: ViewMatrix=\n', mw #------------------
1058 if APPLY_MODIFIERS: tmp_me = Mesh.New('tmp')
1062 for ob,mx in export_list:
1064 #mx = ob.matrix.copy()
1065 #print 'deb: ob =', ob #---------
1066 #print 'deb: mx =\n', mx #---------
1067 #print 'deb: mw0 =\n', mw0 #---------
1068 #mx_n is trans-matrix for normal_vectors for front-side faces
1069 mx_n = mx.rotationPart() * mw.rotationPart()
1070 if G_SCALE!=1.0: mx *= G_SCALE
1073 #mx_inv = mx.copy().invert()
1074 #print 'deb: mx =\n', mx #---------
1075 #print 'deb: mx_inv=\n', mx_inv #---------
1077 if ob.type in ('Mesh', 'Curve', 'Empty'):
1078 if GUI_A['paper_space_on'].val==1: espace=1
1080 elayer,ecolor,eltype = getCommons(ob)
1081 #print 'deb: elayer,ecolor,eltype =', elayer,ecolor,eltype #--------------
1084 if elayer not in layernames:
1085 layernames.append(elayer)
1086 if ecolor!=None: tempcolor = ecolor
1087 else: tempcolor = LAYERCOLOR_DEF
1088 d.layers.append(DXF.Layer(color=tempcolor, name=elayer))
1090 if (ob.type == 'Mesh') and GUI_B['bmesh'].val:
1091 entities = exportMesh(ob, mx, mx_n, tmp_me,\
1092 paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
1093 elif (ob.type == 'Curve') and GUI_B['bcurve'].val:
1094 entities = exportCurve(ob, mx, mw, \
1095 paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
1096 elif (ob.type == 'Empty') and GUI_B['empty'].val:
1097 entities = exportEmpty(ob, mx, mw, \
1098 paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
1102 something_ready += 1
1105 if not GUI_A['outputDWG_on'].val:
1106 print 'exporting to %s' % filepath
1109 Window.WaitCursor(0)
1110 #print '%s objects exported to %s' %(something_ready,filepath)
1111 print '%s objects exported in %.2f seconds. -----DONE-----' %(something_ready,(Blender.sys.time()-t))
1112 Draw.PupMenu('DXF Exporter: job finished!| %s objects exported in %.2f sek.' %(something_ready, (Blender.sys.time()-t)))
1114 Window.WaitCursor(0)
1115 Draw.PupMenu('DXF Exporter: Write Error: Permission denied:| %s' %filepath)
1119 Draw.PupMenu(extCONV_TEXT)
1120 Window.WaitCursor(False)
1122 print 'temp. exporting to %s' % filepath
1124 #Draw.PupMenu('DXF Exporter: job finished')
1125 #print 'exported to %s' % filepath
1126 #print 'finished in %.2f seconds' % (Blender.sys.time()-t)
1127 filedwg = filepath[:-3]+'dwg'
1128 print 'exporting to %s' % filedwg
1129 os.system('%s %s -acad13 -dwg' %(extCONV_PATH,filepath))
1132 Window.WaitCursor(0)
1133 print ' finished in %.2f seconds. -----DONE-----' % (Blender.sys.time()-t)
1134 Draw.PupMenu('DWG Exporter: job finished!| %s objects exported in %.2f sek.' %(something_ready, (Blender.sys.time()-t)))
1136 Window.WaitCursor(0)
1137 print "Abort: selected objects dont match choosen export option, nothing exported!"
1138 Draw.PupMenu('DXF Exporter: nothing exported!|selected objects dont match choosen export option!')
1141 #------------------------------------------------------
1143 v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\
1144 28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,58,59,60,61,62,63,64,91,92,93,94,96,\
1145 123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,\
1146 151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,\
1147 171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,\
1148 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,\
1149 211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,\
1150 231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254]
1151 invalid = ''.join([chr(i) for i in v])
1154 #TODO: validDXFr14 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.'
1155 validDXFr12 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'
1157 #------------------------------------------------------
1158 def cleanName(name,valid):
1161 if ch not in valid: ch = '_'
1165 #------------------------------------------------------
1166 def validDXFr12name(str_name):
1167 dxfname = str(str_name)
1168 dxfname = dxfname[:MAX_NAMELENGTH].upper()
1169 dxfname = cleanName(dxfname,validDXFr12)
1172 #print cleanName('dumka',validDXFr12)
1173 #print validDXFr12name('dum 15%ka')
1175 #------------------------------------------------------
1177 return [int(floor(255*color[0])),
1178 int(floor(255*color[1])),
1179 int(floor(255*color[2]))]
1184 #------------------------------------------------------
1185 def col2DXF(rgbcolor):
1187 if dxfColors is None:
1188 from dxfColorMap import color_map
1189 dxfColors = [(tuple(color),idx) for idx, color in color_map.iteritems()]
1191 entry = (tuple(rgbcolor), -1)
1192 dxfColors.append(entry)
1194 i = dxfColors.index(entry)
1196 return dxfColors[i-1][1]
1200 # NEW UI -----#################################################-----------------
1201 # ------------#################################################-----------------
1203 class Settings: #-----------------------------------------------------------------
1204 """A container for all the import settings and objects used by the draw functions.
1206 This is like a collection of globally accessable persistant properties and functions.
1208 # Optimization constants
1214 def __init__(self, keywords, drawTypes):
1215 """initialize all the important settings used by the draw functions.
1217 self.obj_number = 1 #global object_number for progress_bar
1219 self.var = dict(keywords) #a dictionary of (key_variable:Value) control parameter
1220 self.drawTypes = dict(drawTypes) #a dictionary of (entity_type:True/False) = import on/off for this entity_type
1222 self.var['colorFilter_on'] = False #deb:remi------------
1223 self.acceptedColors = [0,2,3,4,5,6,7,8,9,
1226 self.var['materialFilter_on'] = False #deb:remi------------
1227 self.acceptedLayers = ['3',
1231 self.var['groupFilter_on'] = False #deb:remi------------
1232 self.acceptedLayers = ['3',
1236 #self.var['objectFilter_on'] = 0 #deb:remi------------
1237 self.acceptedBlocks = ['WALL_1871',
1240 self.unwantedBlocks = ['BOX05',
1245 def update(self, keywords, drawTypes):
1246 """update all the important settings used by the draw functions.
1247 mostly used after loading parameters from INI-file
1250 for k, v in keywords.iteritems():
1252 #print 'deb:settings_update var %s= %s' %(k, self.var[k]) #--------------
1253 for t, v in drawTypes.iteritems():
1254 self.drawTypes[t] = v
1255 #print 'deb:settings_update drawType %s= %s' %(t, self.drawTypes[t]) #--------------
1257 self.drawTypes['arc'] = self.drawTypes['surface']
1258 self.drawTypes['circle'] = self.drawTypes['surface']
1259 self.drawTypes['ellipse'] = self.drawTypes['surface']
1260 self.drawTypes['trace'] = self.drawTypes['solid']
1261 self.drawTypes['insert'] = self.drawTypes['group']
1262 #self.drawTypes['vport'] = self.drawTypes['view']
1264 #print 'deb:self.drawTypes', self.drawTypes #---------------
1267 def validate(self, drawing):
1268 """Given the drawing, build dictionaries of Layers, Colors and Blocks.
1271 #adjust the distance parameter to globalScale
1272 if self.var['g_scale'] != 1.0:
1273 self.var['dist_min'] = self.var['dist_min'] / self.var['g_scale']
1274 self.g_origin = Mathutils.Vector(self.var['g_originX'], self.var['g_originY'], self.var['g_originZ'])
1277 def write(self, text, newline=True):
1278 """Wraps the built-in print command in a optimization check.
1280 if self.var['optimization'] <= self.MID:
1288 """Update Blender if optimization level is low enough.
1290 if self.var['optimization'] <= self.MIN:
1294 def progress(self, done, text):
1295 """Wrapper for Blender.Window.DrawProgressBar.
1297 if self.var['optimization'] <= self.PRO:
1298 progressbar = done * self.obj_number
1299 Window.DrawProgressBar(progressbar, text)
1300 #print 'deb:drawer done, progressbar: ', done, progressbar #-----------------------
1304 # GUI STUFF -----#################################################-----------------
1305 from Blender.BGL import *
1313 EVENT_CHOOSE_INI = 7
1314 EVENT_CHOOSE_DXF = 8
1319 EVENT_setCAMERA = 13
1325 EVENT_PRESETPLINE = 22
1328 GUI_EVENT = EVENT_NONE
1330 GUI_A = {} # GUI-buttons dictionary for parameter
1331 GUI_B = {} # GUI-buttons dictionary for drawingTypes
1333 # settings default, initialize ------------------------
1335 #-----------------------------------------------
1336 def prepareMenu(title,list):
1338 for i, item in enumerate(list):
1339 menu += '|'+ item + ' %x' + str(i)
1342 #-----------------------------------------------
1343 mesh_as_list = ["3DFACEs","POLYFACE","POLYLINE","LINEs","POINTs"]
1344 mesh_as_menu = prepareMenu("export to: %t", mesh_as_list)
1346 curve_as_list = ["LINEs","POLYLINE","..LWPOLYLINE r14","..SPLINE r14","POINTs"]
1347 curve_as_menu = prepareMenu("export to: %t", curve_as_list)
1349 surface_as_list = ["..3DFACEs","..POLYFACE","..POINTs","..NURBS"]
1350 surface_as_menu = prepareMenu("export to: %t", surface_as_list)
1352 meta_as_list = ["..3DFACEs","..POLYFACE","..3DSOLID"]
1353 meta_as_menu = prepareMenu("export to: %t", meta_as_list)
1355 text_as_list = ["..TEXT","..MTEXT","..ATTRIBUTs"]
1356 text_as_menu = prepareMenu("export to: %t", text_as_list)
1358 empty_as_list = ["POINT","..INSERT","..XREF"]
1359 empty_as_menu = prepareMenu("export to: %t|", empty_as_list)
1361 group_as_list = ["..GROUP","..BLOCK","..ungroup"]
1362 group_as_menu = prepareMenu("export to: %t", group_as_list)
1364 parent_as_list = ["..BLOCK","..ungroup"]
1365 parent_as_menu = prepareMenu("export to: %t", parent_as_list)
1367 proxy_as_list = ["..BLOCK","..XREF","..ungroup","..POINT"]
1368 proxy_as_menu = prepareMenu("export to: %t", proxy_as_list)
1370 camera_as_list = ["..BLOCK","..A_CAMERA","..VPORT","..VIEW","..POINT"]
1371 camera_as_menu = prepareMenu("export to: %t", camera_as_list)
1373 lamp_as_list = ["..BLOCK","..A_LAMP","..POINT"]
1374 lamp_as_menu = prepareMenu("export to: %t", lamp_as_list)
1376 material_to_list= ["COLOR","LAYER","..LINESTYLE","..BLOCK","..XDATA","..INI-File"]
1377 material_to_menu = prepareMenu("export to: %t", material_to_list)
1379 ltype_map_list= ["object_rgb","material_rgb","..map_table"]
1380 ltype_map_menu = prepareMenu("export to: %t", ltype_map_list)
1384 layername_from_list = [LAYERNAME_DEF,"drawing_name","scene_name"]
1385 layername_from_menu = prepareMenu("defaultLAYER: %t", layername_from_list)
1387 layerltype_def_list = ["CONTINUOUS","DOT","DASH","DASH-DOT"]
1388 layerltype_def_menu = prepareMenu("LINETYPE set to: %t",layerltype_def_list)
1390 entitylayer_from_list = ["default_LAYER","obj.name","obj.layer","obj.material","obj.data.name","obj.data.material","..vertexgroup","..group","..map_table"]
1391 entitylayer_from_menu = prepareMenu("entityLAYER from: %t", entitylayer_from_list)
1392 #print 'deb: entitylayer_from_menu=', entitylayer_from_menu #--------------
1394 entitycolor_from_list = ["default_COLOR","BYLAYER","BYBLOCK","obj.layer","obj.color","obj.material","obj.data.material","..map_table"]
1395 entitycolor_from_menu = prepareMenu("entityCOLOR set to: %t",entitycolor_from_list)
1397 entityltype_from_list = ["default_LTYPE","BYLAYER","BYBLOCK","CONTINUOUS","..DOT","..DASHED","..DASHDOT","..BORDER","..HIDDEN"]
1398 entityltype_from_menu = prepareMenu("entityCOLOR set to: %t",entityltype_from_list)
1400 #dxf-LINE,ARC,CIRCLE,ELLIPSE
1402 g_scale_list = ''.join((
1418 '| x 0.00001 %x-5'))
1420 #print 'deb: g_scale_list', g_scale_list #-----------
1422 dxfFileName = Draw.Create("")
1423 iniFileName = Draw.Create(INIFILE_DEFAULT_NAME + INIFILE_EXTENSION)
1425 config_UI = Draw.Create(0) #switch_on/off extended config_UI
1426 g_scale_as = Draw.Create(int(log10(G_SCALE)))
1436 'paper_space_on': 0,
1438 'objectFilter_on': 0,
1439 'materialFilter_on': 0,
1440 'colorFilter_on': 0,
1441 'groupFilter_on': 0,
1443 'only_selected_on': ONLYSELECTED,
1444 'projection_on' : PROJECTION,
1445 'hidden_lines_on': HIDDEN_LINES,
1446 'shadows_on' : SHADOWS,
1448 'outputDWG_on' : OUTPUT_DWG,
1449 'to_polyline_on': POLYLINES,
1450 'to_polyface_on': POLYFACES,
1451 'apply_modifiers_on': APPLY_MODIFIERS,
1452 'include_duplis_on': INCLUDE_DUPLIS,
1453 'camera_on': CAMERA,
1455 'g_originX' : G_ORIGIN[0],
1456 'g_originY' : G_ORIGIN[1],
1457 'g_originZ' : G_ORIGIN[2],
1459 'g_scale' : float(G_SCALE),
1460 # 'g_scale_as': int(log10(G_SCALE)), # 0,
1463 'Z_elev': float(ELEVATION),
1466 'prefix_def' : PREFIX,
1467 'layername_def' : LAYERNAME_DEF,
1468 'layercolor_def': LAYERCOLOR_DEF,
1469 'layerltype_def': LAYERLTYPE_DEF,
1470 'entitylayer_from': 5,
1471 'entitycolor_from': 1,
1472 'entityltype_from' : 1,
1507 # creating of GUI-buttons
1508 # GUI_A - GUI-buttons dictionary for parameter
1509 # GUI_B - GUI-buttons dictionary for drawingTypes
1510 for k, v in keywords_org.iteritems():
1511 GUI_A[k] = Draw.Create(v)
1512 for k, v in drawTypes_org.iteritems():
1513 GUI_B[k] = Draw.Create(v)
1514 #print 'deb:init GUI_A: ', GUI_A #---------------
1515 #print 'deb:init GUI_B: ', GUI_B #---------------
1517 model_space_on = Draw.Create(1)
1519 # initialize settings-object controls how dxf entities are drawn
1520 settings = Settings(keywords_org, drawTypes_org)
1523 def update_RegistryKey(key, item): #
1524 """updates key in Blender.Registry
1526 cache = True # data is also saved to a file
1527 rdict = Registry.GetKey('DXF_Exporter', cache)
1528 if not rdict: rdict = {}
1531 Registry.SetKey('DXF_Exporter', rdict, cache)
1532 #print 'deb:update_RegistryKey rdict', rdict #---------------
1535 def check_RegistryKey(key):
1536 """ check if the key is already there (saved on a previous execution of this script)
1538 cache = True # data is also saved to a file
1539 rdict = Registry.GetKey('DXF_Exporter', cache)
1540 #print 'deb:check_RegistryKey rdict:', rdict #----------------
1541 if rdict: # if found, get the values saved there
1546 #update_RegistryKey() # if data isn't valid rewrite it
1549 def saveConfig(): #--todo-----------------------------------------------
1550 """Save settings/config/materials from GUI to INI-file.
1552 Write all config data to INI-file.
1556 iniFile = iniFileName.val
1557 #print 'deb:saveConfig inifFile: ', inifFile #----------------------
1558 if iniFile.lower().endswith(INIFILE_EXTENSION):
1560 #--todo-- sort key.list for output
1561 #key_list = GUI_A.keys().val
1563 #for key in key_list:
1564 # l_name, l_data = key, GUI_A[key].val
1567 output_str = '[%s,%s]' %(GUI_A, GUI_B)
1568 if output_str =='None':
1569 Draw.PupMenu('DXF-Exporter: INI-file: Alert!%t|no config-data present to save!')
1571 if Blender.sys.exists(iniFile):
1572 f = file(iniFile, 'r')
1573 header_str = f.readline()
1575 if header_str.startswith(INIFILE_HEADER[0:13]):
1576 if Draw.PupMenu(' OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile) == 1:
1578 else: save_ok = False
1579 elif Draw.PupMenu(' OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile +
1580 '|Alert: this file has no valid ImportDXF-header| ! it may belong to another aplication !') == 1:
1582 else: save_ok = False
1583 else: save_ok = True
1586 # replace: ',' -> ',\n'
1587 # replace: '{' -> '\n{\n'
1588 # replace: '}' -> '\n}\n'
1589 output_str = ',\n'.join(output_str.split(','))
1590 output_str = '\n}'.join(output_str.split('}'))
1591 output_str = '{\n'.join(output_str.split('{'))
1593 f = file(iniFile, 'w')
1594 f.write(INIFILE_HEADER + '\n# this is a comment line\n')
1597 #Draw.PupMenu('DXF-Exporter: INI-file: Done!%t|config-data saved in ' + '\'%s\'' %iniFile)
1599 Draw.PupMenu('DXF-Exporter: INI-file: Error!%t|failure by writing to ' + '\'%s\'|no config-data saved!' %iniFile)
1602 Draw.PupMenu('DXF-Exporter: INI-file: Alert!%t|no valid name/extension for INI-file selected!')
1603 print "DXF-Exporter: Alert!: no valid INI-file selected."
1605 if dxfFileName.val.lower().endswith('.dxf'):
1606 iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
1609 def loadConfig(): #remi--todo-----------------------------------------------
1610 """Load settings/config/materials from INI-file.
1612 Read material-assignements from config-file.
1614 #070724 buggy Window.FileSelector(loadConfigFile, 'Load config data from INI-file', inifilename)
1615 global iniFileName, GUI_A, GUI_B
1617 iniFile = iniFileName.val
1618 update_RegistryKey('iniFileName', iniFile)
1619 #print 'deb:loadConfig iniFile: ', iniFile #----------------------
1620 if iniFile.lower().endswith(INIFILE_EXTENSION) and Blender.sys.exists(iniFile):
1621 f = file(iniFile, 'r')
1622 header_str = f.readline()
1623 if header_str.startswith(INIFILE_HEADER):
1626 #print 'deb:loadConfig data_str from %s: \n' %iniFile , data_str #-----------------
1627 data = eval(data_str)
1628 for k, v in data[0].iteritems():
1629 try: GUI_A[k].val = v
1630 except: GUI_A[k] = Draw.Create(v)
1631 for k, v in data[1].iteritems():
1632 try: GUI_B[k].val = v
1633 except: GUI_B[k] = Draw.Create(v)
1636 Draw.PupMenu('DXF-Exporter: INI-file: Alert!%t|no valid header in INI-file: ' + '\'%s\'' %iniFile)
1638 Draw.PupMenu('DXF-Exporter: INI-file: Alert!%t|no valid INI-file selected!')
1639 print "DXF-Exporter: Alert!: no valid INI-file selected."
1641 if dxfFileName.val.lower().endswith('.dxf'):
1642 iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
1646 def updateConfig(keywords, drawTypes): #-----------------------------------------------
1647 """updates GUI_settings with given dictionaries
1651 #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
1652 for k, v in keywords.iteritems():
1654 for k, v in drawTypes.iteritems():
1657 def resetDefaultConfig(): #-----------------------------------------------
1658 """Resets settings/config/materials to defaults.
1661 #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
1662 updateConfig(keywords_org, drawTypes_org)
1665 def presetConfig_polyline(activate): #-----------------------------------------------
1666 """Sets settings/config for polygon representation: POLYLINE(FACE) or LINEs/3DFACEs.
1671 GUI_A['to_polyline_on'].val = 1
1672 GUI_A['mesh_as'].val = 1
1673 GUI_A['curve_as'].val = 1
1675 GUI_A['to_polyline_on'].val = 0
1676 GUI_A['mesh_as'].val = 0
1677 GUI_A['curve_as'].val = 0
1679 def resetDefaultConfig_2D(): #-----------------------------------------------
1680 """Sets settings/config/materials to defaults 2D.
1684 'projection_on' : 1,
1704 presetConfig_polyline(1)
1705 updateConfig(keywords2d, drawTypes2d)
1707 def resetDefaultConfig_3D(): #-----------------------------------------------
1708 """Sets settings/config/materials to defaults 3D.
1712 'projection_on' : 0,
1731 presetConfig_polyline(1)
1732 updateConfig(keywords3d, drawTypes3d)
1735 def inputGlobalScale():
1736 """Pop-up UI-Block for global scale factor
1739 #print 'deb:inputGlobalScale ##########' #------------
1740 x_scale = Draw.Create(GUI_A['g_scale'].val)
1742 #block.append("global translation vector:")
1743 block.append(("", x_scale, 0.0, 10000000.0))
1745 retval = Draw.PupBlock("set global scale factor:", block)
1747 GUI_A['g_scale'].val = float(x_scale.val)
1750 def inputOriginVector():
1751 """Pop-up UI-Block for global translation vector
1754 #print 'deb:inputOriginVector ##########' #------------
1755 x_origin = Draw.Create(GUI_A['g_originX'].val)
1756 y_origin = Draw.Create(GUI_A['g_originY'].val)
1757 z_origin = Draw.Create(GUI_A['g_originZ'].val)
1759 #block.append("global translation vector:")
1760 block.append(("X: ", x_origin, -100000000.0, 100000000.0))
1761 block.append(("Y: ", y_origin, -100000000.0, 100000000.0))
1762 block.append(("Z: ", z_origin, -100000000.0, 100000000.0))
1764 retval = Draw.PupBlock("set global translation vector:", block)
1766 GUI_A['g_originX'].val = x_origin.val
1767 GUI_A['g_originY'].val = y_origin.val
1768 GUI_A['g_originZ'].val = z_origin.val
1771 def update_globals(): #-----------------------------------------------------------------
1772 """ update globals if GUI_A changed
1774 global ONLYSELECTED, DEBUG,\
1775 PROJECTION, HIDDEN_LINES, CAMERA, \
1777 PREFIX, LAYERNAME_DEF, LAYERCOLOR_DEF, LAYERLTYPE_DEF,\
1778 APPLY_MODIFIERS, INCLUDE_DUPLIS,\
1782 ONLYSELECTED = GUI_A['only_selected_on'].val
1784 POLYLINES = GUI_A['to_polyline_on'].val
1785 if GUI_A['curve_as'].val==1: POLYLINES=1
1789 if GUI_A['optimization'].val==0: DEBUG = 1
1791 PROJECTION = GUI_A['projection_on'].val
1792 HIDDEN_LINES = GUI_A['hidden_lines_on'].val
1793 CAMERA = GUI_A['camera_on'].val
1794 G_SCALE = GUI_A['g_scale'].val
1795 if GUI_A['g_origin_on'].val: #TODO: scale and object orientation
1796 G_ORIGIN[0] = GUI_A['g_originX'].val
1797 G_ORIGIN[1] = GUI_A['g_originY'].val
1798 G_ORIGIN[2] = GUI_A['g_originZ'].val
1799 if GUI_A['g_scale_on'].val:
1800 G_ORIGIN[0] *= G_SCALE
1801 G_ORIGIN[1] *= G_SCALE
1802 G_ORIGIN[2] *= G_SCALE
1804 PREFIX = GUI_A['prefix_def'].val
1805 LAYERNAME_DEF = GUI_A['layername_def'].val
1806 LAYERCOLOR_DEF = GUI_A['layercolor_def'].val
1807 LAYERLTYPE_DEF = layerltype_def_list[GUI_A['layerltype_def'].val]
1809 APPLY_MODIFIERS = GUI_A['apply_modifiers_on'].val
1810 INCLUDE_DUPLIS = GUI_A['include_duplis_on'].val
1811 OUTPUT_DWG = GUI_A['outputDWG_on'].val
1812 #print 'deb: GUI HIDDEN_LINES=', HIDDEN_LINES #---------
1813 #print 'deb: GUI GUI_A: ', GUI_A['hidden_lines_on'].val #---------------
1814 #print 'deb: GUI GUI_B: ', GUI_B #---------------
1817 def draw_UI(): #-----------------------------------------------------------------
1818 """ Draw startUI and setup Settings.
1820 global GUI_A, GUI_B #__version__
1821 global user_preset, iniFileName, dxfFileName, config_UI, g_scale_as
1822 global model_space_on
1825 global mPAN_X, menu_orgX, mPAN_Xmax
1826 global mPAN_Y, menu_orgY, mPAN_Ymax
1827 global menu__Area, headerArea, screenArea, scrollArea
1829 size=Buffer(GL_FLOAT, 4)
1830 glGetFloatv(GL_SCISSOR_BOX, size) #window X,Y,sizeX,sizeY
1832 #print '-------------size:', size #--------------------------
1833 for s in [0,1,2,3]: size[s]=int(size[s])
1834 window_Area = [0,0,size[2],size[3]-2]
1835 scrollXArea = [0,0,window_Area[2],15]
1836 scrollYArea = [0,0,15,window_Area[3]]
1839 #menu_orgX = 0 #scrollW
1840 #if menu_pan: menu_orgX -= mPAN_X
1841 if menu_orgX < -mPAN_Xmax: menu_orgX, mPAN_X = -mPAN_Xmax,mPAN_Xmax
1842 if menu_orgX > 0: menu_orgX, mPAN_X = 0,0
1845 #if menu_pan: menu_orgY -= mPAN_Y
1846 if menu_orgY < -mPAN_Ymax: menu_orgY, mPAN_Y = -mPAN_Ymax,mPAN_Ymax
1847 if menu_orgY > 0: menu_orgY, mPAN_Y = 0,0
1852 common_column = int((window_Area[2] - (3 * butt_margin) - (2 * menu_margin)-30) / 4.0)
1854 # This is for easy layout changes
1855 but_0c = common_column #button 1.column width
1856 but_1c = common_column #button 1.column width
1857 but_2c = common_column #button 2.column
1858 but_3c = common_column #button 3.column
1859 menu_w = (3 * butt_margin) + but_0c + but_1c + but_2c + but_3c #menu width
1863 menu_h = simple_menu_h # y is menu upper.y
1865 menu_h += extend_menu_h
1867 mPAN_Xmax = menu_w-window_Area[2]+50
1868 mPAN_Ymax = menu_h-window_Area[3]+30
1876 but0c = x + menu_margin #buttons 0.column position.x
1877 but1c = but0c + but_0c + butt_margin
1878 but2c = but1c + but_1c + butt_margin
1879 but3c = but2c + but_2c + butt_margin
1880 but4c = but3c + but_3c
1882 # Here starts menu -----------------------------------------------------
1883 #glClear(GL_COLOR_BUFFER_BIT)
1884 #glRasterPos2d(8, 125)
1887 ui_box(x, y, x+menu_w+menu_margin*2, y-menu_h)
1889 Draw.Label("DXF(r12)-Exporter v" + __version__, but0c, y, menu_w, 20)
1892 b0, b0_ = but0c, but_0c-20 + butt_margin
1893 b1, b1_ = but1c-20, but_1c+20
1899 GUI_B['bmesh'] = Draw.Toggle('Mesh', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['bmesh'].val, "Export Mesh-Objects on/off")
1900 if GUI_B['bmesh'].val:
1901 GUI_A['mesh_as'] = Draw.Menu(mesh_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['mesh_as'].val, "Select target DXF-object")
1906 GUI_B['bcurve'] = Draw.Toggle('Curve', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['bcurve'].val, "Export Curve-Objects on/off")
1907 if GUI_B['bcurve'].val:
1908 GUI_A['curve_as'] = Draw.Menu(curve_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['curve_as'].val, "Select target DXF-object")
1913 GUI_B['surface'] = Draw.Toggle('..Surface', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['surface'].val, "(*todo) Export Surface-Objects on/off")
1914 if GUI_B['surface'].val:
1915 GUI_A['surface_as'] = Draw.Menu(surface_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['surface_as'].val, "Select target DXF-object")
1920 GUI_B['bmeta'] = Draw.Toggle('..Meta', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['bmeta'].val, "(*todo) Export Meta-Objects on/off")
1921 if GUI_B['bmeta'].val:
1922 GUI_A['meta_as'] = Draw.Menu(meta_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['meta_as'].val, "Select target DXF-object")
1923 #GUI_A['plmesh_flip'] = Draw.Toggle('N', EVENT_NONE, b1+b1_-40, y, 20, 20, GUI_A['plmesh_flip'].val, "flip DXF normals on/off")
1924 #GUI_A['normals_out'] = Draw.Toggle('N', EVENT_NONE, b1+b1_-20, y, 20, 20, GUI_A['normals_out'].val, "force Blender normals to outside on/off")
1929 GUI_B['text'] = Draw.Toggle('..Text', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['text'].val, "(*todo) Export Text-Objects on/off")
1930 #GUI_B['mtext'] = Draw.Toggle('..MTEXT', EVENT_NONE, b1, y, b1_, 20, GUI_B['mtext'].val, "(*todo) support dxf-MTEXT on/off")
1931 if GUI_B['text'].val:
1932 GUI_A['text_as'] = Draw.Menu(text_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['text_as'].val, "Select target DXF-object")
1937 GUI_B['empty'] = Draw.Toggle('Empty', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['empty'].val, "Export Empty-Objects on/off")
1938 if GUI_B['empty'].val:
1939 GUI_A['empty_as'] = Draw.Menu(empty_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['empty_as'].val, "Select target DXF-object")
1940 # Draw.Label('-->', but2c, y, but_2c, 20)
1944 # -----------------------------------------------
1947 b0, b0_ = but2c, but_2c-20 + butt_margin
1948 b1, b1_ = but3c-20, but_3c+20
1953 GUI_B['group'] = Draw.Toggle('..Group', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['group'].val, "(*todo) Export Group-Relationships on/off")
1954 #GUI_B['insert'].val = GUI_B['group'].val
1955 if GUI_B['group'].val:
1956 #GUI_A['block_nn'] = Draw.Toggle('n', EVENT_NONE, b1-30, y, 15, 20, GUI_A['block_nn'].val, "Export hatch/noname BLOCKs *X... on/off")
1957 #GUI_A['xref_on'] = Draw.Toggle('Xref', EVENT_NONE, b1-15, y, 35, 20, GUI_A['xref_on'].val, "Export for XREF-BLOCKs (place holders) on/off")
1958 GUI_A['group_as'] = Draw.Menu(group_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['group_as'].val, "Select target DXF-object")
1963 GUI_B['parent'] = Draw.Toggle('..Parent', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['parent'].val, "(*todo) Export Parent-Relationships on/off")
1964 if GUI_B['parent'].val:
1965 GUI_A['parent_as'] = Draw.Menu(parent_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['parent_as'].val, "Select target DXF-object")
1970 GUI_B['proxy'] = Draw.Toggle('..Proxy', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['proxy'].val, "(*todo) Export Proxy-Objects on/off")
1971 if GUI_B['proxy'].val:
1972 GUI_A['proxy_as'] = Draw.Menu(proxy_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['proxy_as'].val, "Select target DXF-object")
1977 GUI_B['camera'] = Draw.Toggle('..Camera', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['camera'].val, "(*todo) Export Camera-Objects on/off")
1978 if GUI_B['camera'].val:
1979 GUI_A['camera_as'] = Draw.Menu(camera_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['camera_as'].val, "Select target DXF-object")
1984 GUI_B['lamp'] = Draw.Toggle('..Lamp', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['lamp'].val, "(*todo) Export Lamp-Objects on/off")
1985 if GUI_B['lamp'].val:
1986 GUI_A['lamp_as'] = Draw.Menu(lamp_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['lamp_as'].val, "Select target DXF-object")
1990 if y < y_down: y_down = y
1991 # -----end supported objects--------------------------------------
1998 b0 = but0c + (menu_w - but_*6)/2
2000 GUI_A['paper_space_on'] = Draw.Toggle('paper', EVENT_NONE, b0+but_*0, y, but_, 20, GUI_A['paper_space_on'].val, "Export to Paper-Space, otherwise to Model-Space on/off")
2001 GUI_A['layFrozen_on'] = Draw.Toggle ('..frozen', EVENT_NONE, b0+but_*1, y, but_, 20, GUI_A['layFrozen_on'].val, "(*todo) Support LAYER.frozen status on/off")
2002 GUI_A['materialFilter_on'] = Draw.Toggle('..material', EVENT_NONE, b0+but_*2, y, but_, 20, GUI_A['materialFilter_on'].val, "(*todo) Material filtering on/off")
2003 GUI_A['colorFilter_on'] = Draw.Toggle('..color', EVENT_NONE, b0+but_*3, y, but_, 20, GUI_A['colorFilter_on'].val, "(*todo) Color filtering on/off")
2004 GUI_A['groupFilter_on'] = Draw.Toggle('..group', EVENT_NONE, b0+but_*4, y, but_, 20, GUI_A['groupFilter_on'].val, "(*todo) Group filtering on/off")
2005 GUI_A['objectFilter_on'] = Draw.Toggle('..object', EVENT_NONE, b0+but_*5, y, but_, 20, GUI_A['objectFilter_on'].val, "(*todo) Object filtering on/off")
2006 #GUI_A['dummy_on'] = Draw.Toggle('-', EVENT_NONE, but3c, y, but_3c, 20, GUI_A['dummy_on'].val, "dummy on/off")
2009 # -----end filters--------------------------------------
2011 b0, b0_ = but0c, but_0c + butt_margin
2012 b1, b1_ = but1c, but_1c
2017 GUI_A['g_origin_on'] = Draw.Toggle('Location', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_origin_on'].val, "Global relocate all objects on/off")
2018 if GUI_A['g_origin_on'].val:
2019 tmp = Draw.PushButton('=', EVENT_ORIGIN, b1, y, 20, 20, "Edit relocation-vector (x,y,z in DXF units)")
2020 origin_str = '(%.4f, %.4f, %.4f)' % (
2021 GUI_A['g_originX'].val,
2022 GUI_A['g_originY'].val,
2023 GUI_A['g_originZ'].val
2025 tmp = Draw.Label(origin_str, b1+20, y, 300, 20)
2026 #GUI_A['g_origin'] = Draw.String('', EVENT_ORIGIN, b1, y, b1_, 20, GUI_A['g_origin'].val, "Global translation-vector (x,y,z) in DXF units")
2031 GUI_A['g_scale_on'] = Draw.Toggle('Scale', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_scale_on'].val, "Global scale all objects on/off")
2032 if GUI_A['g_scale_on'].val:
2033 g_scale_as = Draw.Menu(g_scale_list, EVENT_SCALE, b1, y, 45, 20, g_scale_as.val, "Factor for scaling the DXFdata")
2034 if g_scale_as.val == 12:
2037 if g_scale_as.val == 6: #scale inches to meters
2038 GUI_A['g_scale'].val = 0.0254000
2039 elif g_scale_as.val == 7: #scale feets to meters
2040 GUI_A['g_scale'].val = 0.3048000
2041 elif g_scale_as.val == 8: #scale yards to meters
2042 GUI_A['g_scale'].val = 0.9144000
2044 GUI_A['g_scale'].val = 10.0 ** int(g_scale_as.val)
2045 scale_float = GUI_A['g_scale'].val
2046 if scale_float < 0.000001 or scale_float > 1000000:
2047 scale_str = ' = %s' % GUI_A['g_scale'].val
2049 scale_str = ' = %.6f' % GUI_A['g_scale'].val
2050 Draw.Label(scale_str, b1+45, y, 200, 20)
2055 GUI_A['Z_force_on'] = Draw.Toggle('Elevation', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['Z_force_on'].val, "Overwrite Z-coordinates (flatten geometry) on/off")
2056 if GUI_A['Z_force_on'].val:
2057 GUI_A['Z_elev'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['Z_elev'].val, -1000, 1000, "Set value for default Z-coordinate (in DXF units)")
2063 GUI_A['material_on'] = Draw.Toggle('.material', EVENT_REDRAW, b0, y, b0_-20, 20, GUI_A['material_on'].val, "Support for material assignment on/off")
2064 if GUI_A['material_on'].val:
2065 GUI_A['material_to'] = Draw.Menu(material_to_menu, EVENT_NONE, b1-20, y, b1_+20, 20, GUI_A['material_to'].val, "Material assigned to?")
2069 #b0, b0_ = but0c, but_0c + butt_margin
2071 b1, b1_ = b0+b0_, but_0c-b0_+ but_1c + butt_margin
2072 b2, b2_ = but2c, but_2c
2073 b3, b3_ = but3c, but_3c
2076 Draw.Label('Output:', b0, y, b0_, 20)
2077 Draw.Label('LAYER:', b1, y, b1_, 20)
2078 Draw.Label('COLOR:', b2, y, b2_, 20)
2079 Draw.Label('LINETYPE:', b3, y, b3_, 20)
2080 #Draw.Label('LINESIZE:', b4, y, b4_, 20)
2084 GUI_A['prefix_def'] = Draw.String('', EVENT_NONE, b0, y, b0_, 20, GUI_A['prefix_def'].val, 10, "Type Prefix for LAYERs")
2085 GUI_A['layername_def'] = Draw.String('', EVENT_NONE, b1, y, b1_, 20, GUI_A['layername_def'].val, 10, "Type default LAYER name")
2086 GUI_A['layercolor_def'] = Draw.Number('', EVENT_NONE, b2, y, b2_, 20, GUI_A['layercolor_def'].val, 1, 255, "Set default COLOR. (0=BYBLOCK,256=BYLAYER)")
2087 GUI_A['layerltype_def'] = Draw.Menu(layerltype_def_menu, EVENT_NONE, b3, y, b3_, 20, GUI_A['layerltype_def'].val, "Set default LINETYPE")
2091 Draw.Label('Style:', b0, y, b0_, 20)
2093 GUI_A['entitylayer_from'] = Draw.Menu(entitylayer_from_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['entitylayer_from'].val, "entity LAYER assigned to?")
2094 GUI_A['entitycolor_from'] = Draw.Menu(entitycolor_from_menu, EVENT_NONE, b2, y, b2_, 20, GUI_A['entitycolor_from'].val, "entity COLOR assigned to?")
2095 GUI_A['entityltype_from'] = Draw.Menu(entityltype_from_menu, EVENT_NONE, b3, y, b3_, 20, GUI_A['entityltype_from'].val, "Set entity LINETYPE")
2101 # -----end material,translate,scale------------------------------------------
2104 b0, b0_ = but0c, but_0c + butt_margin
2105 b1, b1_ = but1c, but_1c
2112 GUI_A['group_bylayer_on'] = Draw.Toggle('Layer', EVENT_NONE, b0, y, 30, 20, GUI_A['group_bylayer_on'].val, "DXF-entities group by layer on/off")
2115 # -----------------------------------------------
2117 b0, b0_ = but2c, but_2c + butt_margin
2118 b1, b1_ = but3c, but_3c
2125 if y < y_down: y_down = y
2126 # -----end options --------------------------------------
2130 #--------------------------------------
2133 #GUI_A['dummy_on'] = Draw.Toggle(' - ', EVENT_NONE, but0c, y, but_0c, 20, GUI_A['dummy_on'].val, "reserved")
2136 Draw.PushButton('INI file >', EVENT_CHOOSE_INI, but0c, y, but_0c, 20, 'Select INI-file with file selector')
2137 iniFileName = Draw.String(' :', EVENT_NONE, but1c, y, menu_w-but_1c-60, 20, iniFileName.val, FILENAME_MAX, "Write here the name of the INI-file")
2139 Draw.PushButton('#', EVENT_PRESETS, but, y, 20, 20, "Toggle Preset-INI-files")
2140 Draw.PushButton('L', EVENT_LOAD_INI, but+20, y, 20, 20, 'Loads configuration from selected ini-file: %s' % iniFileName.val)
2141 Draw.PushButton('S', EVENT_SAVE_INI, but+40, y, 20, 20, 'Saves configuration to selected ini-file: %s' % iniFileName.val)
2149 Draw.PushButton('DXFfile >', EVENT_CHOOSE_DXF, but0c, y, but_0c, 20, 'Select DXF-file with file selector')
2150 dxfFileName = Draw.String(' :', EVENT_NONE, but1c, y, menu_w-but_0c-menu_margin, 20, dxfFileName.val, FILENAME_MAX, "Type path/name of output DXF-file")
2154 config_UI = Draw.Toggle('CONFIG', EVENT_REDRAW, but0c, y, but_0c+bm, 20, config_UI.val, 'Advanced configuration on/off' )
2156 but, but_ = but1c, but_1c+bm
2158 Draw.PushButton('X', EVENT_RESET, but, y, 15, 20, "Reset configuration to defaults")
2159 Draw.PushButton('2D', EVENT_PRESET2D, but+but_, y, but_, 20, 'Set to standard configuration for 2D export')
2160 Draw.PushButton('3D', EVENT_PRESET3D, but+(but_*2), y, but_, 20, 'Set to standard configuration for 3D import')
2165 b0, b0_ = but0c, but_0c + butt_margin +but_1c
2166 GUI_A['only_selected_on'] = Draw.Toggle('Export Selection', EVENT_NONE, b0, y, b0_, 20, GUI_A['only_selected_on'].val, "Export only selected geometry on/off")
2167 b0, b0_ = but2c, but_2c + butt_margin + but_3c
2170 b0, b0_ = but0c, but_0c + butt_margin +but_1c
2171 GUI_A['to_polyline_on'] = Draw.Toggle('POLYLINE', EVENT_PRESETPLINE, b0, y, b0_, 20, GUI_A['to_polyline_on'].val, "Export to POLYLINEs, otherwise to LINEs/3DFACEs on/off")
2172 b0, b0_ = but2c, but_2c + butt_margin + but_3c
2176 GUI_A['projection_on'] = Draw.Toggle('Projection 2d', EVENT_REDRAW, b0, y+20, b0_, 20, GUI_A['projection_on'].val, "Export a 2d Projection according 3dView or Camera on/off")
2177 if GUI_A['projection_on'].val:
2178 #GUI_A['camera_on'] = Draw.Toggle('Camera / 3dView', EVENT_NONE, b0, y, b0_, 20, GUI_A['camera_on'].val, "get Projection from current Camera, otherwise from 3dView on/off")
2179 GUI_A['camera_on'] = Draw.Menu(MenuCAMERA, EVENT_CAMERA, b0, y, b0_-20, 20, GUI_A['camera_on'].val, 'Choose the camera to be rendered')
2180 Draw.PushButton('>', EVENT_setCAMERA, b0+b0_-20, y, 20, 20, 'switch to selected Camera - make it active')
2181 GUI_A['hidden_lines_on'] = Draw.Toggle('.Hidden Lines', EVENT_NONE, b0, y-20, b0_, 20, GUI_A['hidden_lines_on'].val, "Filter out hidden lines on/off")
2182 #GUI_A['shadows_on'] = Draw.Toggle('..Shadows', EVENT_REDRAW, b0, y-40, but_2c, 20, GUI_A['shadows_on'].val, "(*todo) Shadow tracing on/off")
2183 #GUI_A['light_on'] = Draw.Menu(MenuLIGHT, EVENT_LIGHT, but3c, y-40, but_3c, 20, GUI_A['light_on'].val, '(*todo) Choose the light source(sun) to be rendered')
2187 b0, b0_ = but0c, but_0c + butt_margin +but_1c
2188 GUI_A['apply_modifiers_on'] = Draw.Toggle('Apply Modifiers', EVENT_NONE, b0, y, b0_, 20, GUI_A['apply_modifiers_on'].val, "Apply modifier stack to mesh objects before export on/off")
2189 b0, b0_ = but2c, but_2c + butt_margin + but_3c
2190 #GUI_A['target_layer'] = Draw.Number('layer', EVENT_NONE, but3c, y, but_3c, 20, GUI_A['target_layer'].val, 1, 18, "target Blender-layer (<19> reserved for block_definitions)")
2193 b0, b0_ = but0c, but_0c + butt_margin +but_1c
2194 GUI_A['include_duplis_on'] = Draw.Toggle('Include Duplis', EVENT_NONE, b0, y, b0_, 20, GUI_A['include_duplis_on'].val, "Export Duplicates (dupliverts, dupliframes, dupligroups) on/off")
2195 b0, b0_ = but2c, but_2c + butt_margin + but_3c
2199 Draw.PushButton('EXIT', EVENT_EXIT, but0c, y, but_0c+bm, 20, '' )
2200 Draw.PushButton('HELP', EVENT_HELP, but1c, y, but_1c+bm, 20, 'goes to online-Manual on wiki.blender.org')
2201 GUI_A['optimization'] = Draw.Number('', EVENT_NONE, but2c, y, 40, 20, GUI_A['optimization'].val, 0, 3, "Optimization Level: 0=Debug/Draw-in, 1=Verbose, 2=ProgressBar, 3=SilentMode")
2202 GUI_A['outputDWG_on'] = Draw.Toggle('DWG*', EVENT_NONE, but2c, y+20, 40, 20, GUI_A['outputDWG_on'].val, "converts DXF to DWG (needs external converter) on/off")
2205 #Draw.PushButton('TEST', EVENT_LIST, but2c, y, 40, 20, 'DXF-Analyze-Tool: reads data from selected dxf file and writes report in project_directory/dxf_blendname.INF')
2206 Draw.PushButton('START EXPORT', EVENT_START, but2c+40, y, but_2c-40+but_3c+butt_margin, 40, 'Start the export process. For Cancel go to console and hit Ctrl-C')
2211 #Draw.Label(' ', but0c-menu_margin, y, menu_margin, 20)
2212 #Draw.Label(LAB, but0c, y, menu_w, 20)
2213 Draw.Label(LAB, 30, y, menu_w, 20)
2214 #Draw.Label(' ', but0c+menu_w, y, menu_margin, 20)
2217 ui_scrollbarX(menu_orgX, menu_w+50, scrollXArea, c_fg, c_bg)
2218 ui_scrollbarY(menu_orgY, menu_h+30, scrollYArea, c_fg, c_bg)
2223 #-- END GUI Stuf-----------------------------------------------------
2225 c0=[0.2,0.2,0.2,0.0]
2226 c1=[0.7,0.7,0.9,0.0]
2227 c2=[0.71,0.71,0.71,0.0]
2228 c3=[0.4,0.4,0.4,0.0]
2229 c4=[0.95,0.95,0.9,0.0]
2230 c5=[0.64,0.64,0.64,0]
2231 c6=[0.75,0.75,0.75,0]
2235 c10=[0.64,0.81,0.81,0]
2236 c11=[0.57,0.71,0.71,0]
2244 def ui_rect(coords,color):
2245 [X1,Y1,X2,Y2],[r,g,b] = coords,color
2247 glRecti(X1,Y1,X2,Y2)
2248 def ui_rectA(coords,color):
2249 [X1,Y1,X2,Y2],[r,g,b,a] = coords,color
2251 glRecti(X1,Y1,X2,Y2) #integer coords
2252 #glRectf(X1,Y1,X2,Y2) #floating coords
2253 def ui_line(coords,color):
2254 [X1,Y1,X2,Y2],[r,g,b] = coords,color
2260 def ui_panel(posX,posY,L,H,color):
2262 ui_rect([posX+4,posY-4,posX+L+4,posY-H-4],[.55,.55,.55]) #1st shadow
2263 ui_rect([posX+3,posY-3,posX+L+3,posY-H-3],[.45,.45,.45])
2264 ui_rect([posX+3,posY-3,posX+L+2,posY-H-2],[.30,.30,.30]) #2nd shadow
2265 ui_rect([posX,posY-H,posX+L,posY],[r,g,b]) #Main
2266 ui_rect([posX+3,posY-19,posX+L-3,posY-2],[.75*r,.75*g,.75*b]) #Titlebar
2267 ui_line([posX+3,posY-19,posX+3,posY-2],[.25,.25,.25])
2268 ui_line([posX+4,posY-19,posX+4,posY-2],[(r+.75)/4,(g+.75)/4,(b+.75)/4])
2269 ui_line([posX+4,posY-2,posX+L-3,posY-2],[(r+.75)/4,(g+.75)/4,(b+.75)/4])
2270 def ui_box(x,y,xright,bottom):
2271 color = [0.75, 0.75, 0.75]
2272 coords = x+1,y+1,xright-1,bottom-1
2273 ui_rect(coords,color)
2275 def ui_scrollbarX(Focus,PanelH,Area, color_fg, color_bg):
2276 # Area = ScrollBarArea
2277 # point1=down/left, point2=top/right
2278 P1X,P1Y,P2X,P2Y = Area
2281 Slider = int(AreaH * (AreaH / float(PanelH)))
2282 if Slider<3: Slider = 3 #minimal slider heigh
2283 posX = -int(AreaH * (Focus / float(PanelH)))
2284 ui_rect([P1X,P1Y,P2X,P2Y], color_bg)
2285 ui_rect([P1X+posX,P1Y+3,P1X+posX+Slider,P2Y-3], color_fg)
2287 def ui_scrollbarY(Focus,PanelH,Area, color_fg, color_bg):
2288 # Area = ScrollBarArea
2289 # point1=down/left, point2=top/right
2290 P1X,P1Y,P2X,P2Y = Area
2293 Slider = int(AreaH * (AreaH / float(PanelH)))
2294 if Slider<3: Slider = 3 #minimal slider heigh
2295 posY = -int(AreaH * (Focus / float(PanelH)))
2296 ui_rect([P1X,P1Y,P2X-1,P2Y], color_bg)
2297 #ui_rect([P1X+3,P2Y-posY,P2X-4,P2Y-posY-Slider], color_fg)
2298 ui_rect([P1X+3,P1Y+posY,P2X-4,P1Y+posY+Slider], color_fg)
2301 #------------------------------------------------------------
2302 def dxf_callback(input_filename):
2304 dxfFileName.val=input_filename
2305 # dirname == Blender.sys.dirname(Blender.Get('filename'))
2306 # update_RegistryKey('DirName', dirname)
2307 # update_RegistryKey('dxfFileName', input_filename)
2309 def ini_callback(input_filename):
2311 iniFileName.val=input_filename
2313 #------------------------------------------------------------
2315 __UI_RECT__ = Buffer(GL_FLOAT, 4)
2316 glGetFloatv(GL_SCISSOR_BOX, __UI_RECT__)
2317 __UI_RECT__ = __UI_RECT__.list
2318 return (int(__UI_RECT__[0]), int(__UI_RECT__[1]), int(__UI_RECT__[2]), int(__UI_RECT__[3]))
2320 def getRelMousePos(mco, winRect):
2321 # mco = Blender.Window.GetMouseCoords()
2322 if pointInRect(mco, winRect):
2323 return (mco[0] - winRect[0], mco[1] - winRect[1])
2327 def pointInRect(pt, rect):
2328 if rect[0] < pt[0] < rect[0]+rect[2] and\
2329 rect[1] < pt[1] < rect[1]+rect[3]:
2336 #--- variables UI menu ---------------------------
2337 mco = [0,0] # mouse coordinaten
2338 mbX, mbY = 0,0 # mouse buffer coordinaten
2339 scrollW = 20 # width of scrollbar
2340 rowH = 20 # height of menu raw
2341 menu__H = 2 * rowH +5 # height of menu bar
2342 headerH = 1 * rowH # height of column header bar
2343 scroll_left = True # position of scrollbar
2344 menu_bottom = False # position of menu
2345 edit_mode = False # indicator/activator
2346 iconlib_mode = False # indicator/activator
2347 icon_maps = [] #[['blenderbuttons.png',12,25,20,21],
2348 #['referenceicons.png',12,25,20,21]]
2349 help_text = False # indicator/activator
2350 menu_pan = False # indicator/activator
2351 compact_DESIGN = True # toggle UI
2352 showLINK = True # toggle Links
2353 filterList=[-1,-1,-1,-1,-1]
2354 dubbleclik_delay = 0.25
2356 PAN_X,PAN_Y = 0,0 # pan coordinates in characters
2357 mPAN_X,mPAN_Y = 0,0 # manu pan coordinates in characters
2364 #------------------------------------------------------------
2365 def event(evt, val):
2366 global mbX, mbY, UP, UP0, scroll_pan, FOCUS_fix
2367 global menu_bottom, scroll_left, mco
2368 global PAN_X, PAN_Y, PAN_X0, PAN_Y0
2369 global mPAN_X, mPAN_Y, mPAN_X0, mPAN_Y0, menu_pan
2372 # print 'Blender.event:%s, evt:%s' %(Blender.event, evt) #------------
2374 if evt in (Draw.QKEY, Draw.ESCKEY) and not val:
2375 print 'DXF-Exporter *** end ***' #---------------------
2379 if evt==Draw.MIDDLEMOUSE:
2380 mco2 = Window.GetMouseCoords()
2381 relativeMouseCo = getRelMousePos(mco2, getSpaceRect())
2382 if relativeMouseCo != None:
2383 #rect = [menu__X1,menu__Y1,menu__X2,menu__Y2]
2384 if 1: #pointInRect(relativeMouseCo, menu__Area):
2389 elif evt == Draw.MOUSEY or evt == Draw.MOUSEX:
2391 mco2 = Window.GetMouseCoords()
2392 mbX = mco2[0]-mco[0]
2393 mbY = mco2[1]-mco[1]
2394 mPAN_X = mPAN_X0 - mbX
2395 mPAN_Y = mPAN_Y0 - mbY
2396 #print mbX, mbY #--------------------
2398 elif evt == Draw.WHEELDOWNMOUSE:
2401 elif evt == Draw.WHEELUPMOUSE:
2404 else: # = if val==False:
2405 if evt==Draw.LEFTMOUSE:
2407 elif evt==Draw.MIDDLEMOUSE:
2411 # global EVENT_NONE,EVENT_LOAD_DXF,EVENT_LOAD_INI,EVENT_SAVE_INI,EVENT_EXIT
2412 global config_UI, user_preset
2413 global CAMERA, GUI_A
2415 ######### Manages GUI events
2416 if (evt==EVENT_EXIT):
2418 print 'DXF-Exporter *** end ***' #---------------------
2419 elif (evt==EVENT_CHOOSE_INI):
2420 Window.FileSelector(ini_callback, "INI-file Selection", '*.ini')
2421 elif (evt==EVENT_REDRAW):
2423 elif (evt==EVENT_RESET):
2424 resetDefaultConfig()
2426 elif (evt==EVENT_PRESET2D):
2427 resetDefaultConfig_2D()
2429 elif (evt==EVENT_PRESET3D):
2430 resetDefaultConfig_3D()
2432 elif evt in (EVENT_CAMERA,EVENT_LIGHT):
2433 CAMERA = GUI_A['camera_on'].val
2434 if CAMERA==len(CAMERAS)+1:
2437 print 'deb: CAMERAS=',CAMERAS #----------------
2439 elif (evt==EVENT_setCAMERA):
2440 if CAMERA<len(CAMERAS)+1:
2443 elif (evt==EVENT_SCALE):
2444 if g_scale_as.val == 12:
2446 if GUI_A['g_scale'].val < 0.00000001:
2447 GUI_A['g_scale'].val = 0.00000001
2449 elif (evt==EVENT_ORIGIN):
2452 elif (evt==EVENT_PRESETPLINE):
2453 presetConfig_polyline(GUI_A['to_polyline_on'].val)
2455 elif (evt==EVENT_PRESETS):
2457 index = str(user_preset)
2458 if user_preset > 5: user_preset = 0; index = ''
2459 iniFileName.val = INIFILE_DEFAULT_NAME + index + INIFILE_EXTENSION
2461 elif (evt==EVENT_LIST):
2462 dxfFile = dxfFileName.val
2463 update_RegistryKey('dxfFileName', dxfFileName.val)
2464 if dxfFile.lower().endswith('.dxf') and Blender.sys.exists(dxfFile):
2467 Draw.PupMenu('DXF-Exporter: Alert!%t|no valid DXF-file selected!')
2468 print "DXF-Exporter: error, no valid DXF-file selected! try again"
2470 elif (evt==EVENT_HELP):
2473 webbrowser.open('http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf')
2475 Draw.PupMenu('DXF-Exporter: HELP Alert!%t|no connection to manual-page on Blender-Wiki! try:|\
2476 http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf')
2478 elif (evt==EVENT_LOAD_INI):
2481 elif (evt==EVENT_SAVE_INI):
2484 elif (evt==EVENT_DXF_DIR):
2485 dxfFile = dxfFileName.val
2488 dxfPathName = '/'.join(dxfFile.split('/')[:-1]) + '/'
2489 elif '\\' in dxfFile:
2490 dxfPathName = '\\'.join(dxfFile.split('\\')[:-1]) + '\\'
2491 dxfFileName.val = dxfPathName + '*.dxf'
2492 # dirname == Blender.sys.dirname(Blender.Get('filename'))
2493 # update_RegistryKey('DirName', dirname)
2494 # update_RegistryKey('dxfFileName', dxfFileName.val)
2495 GUI_A['only_selected_on'].val = 1
2497 elif (evt==EVENT_CHOOSE_DXF):
2498 filename = '' # '*.dxf'
2499 if dxfFileName.val: filename = dxfFileName.val
2500 Window.FileSelector(dxf_callback, "DXF-file Selection", filename)
2501 elif (evt==EVENT_START):
2502 dxfFile = dxfFileName.val
2503 #print 'deb: dxfFile file: ', dxfFile #----------------------
2504 if E_M: dxfFileName.val, dxfFile = e_mode(dxfFile) #evaluation mode
2505 update_RegistryKey('dxfFileName', dxfFileName.val)
2507 if dxfFile.lower().endswith('*.dxf'):
2508 if Draw.PupMenu('DXF-Exporter: OK?|will write multiple DXF-files, one for each Scene, in:|%s' % dxfFile) == 1:
2511 #multi_import(dxfFile[:-5]) # cut last 5 characters '*.dxf'
2516 elif dxfFile.lower()[-4:] in ('.dxf','.dwg'): # and Blender.sys.exists(dxfFile):
2517 print '\nStandard Mode: active'
2519 sce = Scene.GetCurrent()
2520 if ONLYSELECTED: sel_group = sce.objects.selected
2521 else: sel_group = sce.objects
2523 export_list = getObjectsAndDuplis(sel_group,MATRICES=True)
2525 if export_list: do_export(export_list, filepath)
2527 print "Abort: selection was empty, no object to export!"
2528 Draw.PupMenu('DXF Exporter: nothing exported!|empty selection!')
2530 Draw.PupMenu('DXF-Exporter: Alert!%t|no valid DXF-file selected!')
2531 print "DXF-Exporter: error, no valid DXF-file selected! try again"
2537 def multi_import(DIR):
2538 """Imports all DXF-files from directory DIR.
2542 batchTIME = Blender.sys.time()
2543 #if #DIR == "": DIR = os.path.curdir
2544 if DIR == "": DIR = Blender.sys.dirname(Blender.Get('filename'))
2545 print 'Multifiles Import from %s' %DIR
2547 [Blender.sys.join(DIR, f) for f in os.listdir(DIR) if f.lower().endswith('.dxf')]
2549 print '...None DXF-files found. Abort!'
2553 for dxfFile in files:
2555 print '\nDXF-file', i, 'of', len(files) #,'\nImporting', dxfFile
2557 _dxf_file = dxfFile.split('/')[-1].split('\\')[-1]
2558 _dxf_file = _dxf_file[:-4] # cut last char:'.dxf'
2559 _dxf_file = _dxf_file[:MAX_NAMELENGTH] #? [-MAX_NAMELENGTH:])
2560 SCENE = Blender.Scene.New(_dxf_file)
2562 #or so? Blender.Scene.makeCurrent(_dxf_file)
2563 #sce = bpy.data.scenes.new(_dxf_file)
2564 #bpy.data.scenes.active = sce
2566 SCENE = Blender.Scene.GetCurrent()
2567 SCENE.objects.selected = [] # deselect all
2571 print 'TOTAL TIME: %.6f' % (Blender.sys.time() - batchTIME)
2572 print '\a\r', # beep when done
2575 #-----------------------------------------------------
2576 if __name__=='__main__':
2579 Draw.PupMenu('Error%t|The dxfLibrary.py script requires a full python install')
2580 #Window.FileSelector(dxf_export_ui, 'EXPORT DXF', Blender.sys.makename(ext='.dxf'))
2581 # recall last used DXF-file and INI-file names
2582 dxffilename = check_RegistryKey('dxfFileName')
2583 #print 'deb:start dxffilename:', dxffilename #----------------
2584 if dxffilename: dxfFileName.val = dxffilename
2586 dirname = Blender.sys.dirname(Blender.Get('filename'))
2587 #print 'deb:start dirname:', dirname #----------------
2588 dxfFileName.val = Blender.sys.join(dirname, '')
2589 inifilename = check_RegistryKey('iniFileName')
2590 if inifilename: iniFileName.val = inifilename
2595 Draw.Register(draw_UI, event, bevent)