bugfix and updates for DXF-Importer/Exporter scripts
[blender.git] / release / scripts / export_dxf.py
1 #!BPY
2
3 """
4  Name: 'Autodesk DXF (.dxf)'
5  Blender: 249
6  Group: 'Export'
7  Tooltip: 'Export geometry to DXF/DWG-r12 (Drawing eXchange Format).'
8 """
9
10 __version__ = "1.34 - 2009.06.02"
11 __author__  = "Remigiusz Fiedler (AKA migius)"
12 __license__ = "GPL"
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.
15
16 Version %s
17 Copyright %s
18 License %s
19
20 extern dependances: dxfLibrary.py, (optionaly: DConvertCon.exe)
21
22 CONTRIBUTORS:
23 Remigiusz Fiedler (AKA migius)
24 Alexandros Sigalas (AKA alxarch)
25 Stani Michiels (AKA stani)
26
27 See the homepage for documentation.
28 url: %s
29
30 IDEAs:
31 - HPGL output, especially usefull for correct scaled printing of 2d drawings
32                 
33 TODO:
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
41
42 History
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__)
102
103 # --------------------------------------------------------------------------
104 # Script copyright (C) 2008 Remigiusz Fiedler (AKA migius)
105 # --------------------------------------------------------------------------
106 # ***** BEGIN GPL LICENSE BLOCK *****
107 #
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.
112 #
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.
117 #
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.
121 #
122 # ***** END GPL LICENCE BLOCK *****
123
124
125 import Blender
126 from Blender import Mathutils, Window, Scene, Draw, Camera, BezTriple
127 from Blender import Registry, Object, Mesh, Curve
128 import os
129 import subprocess
130
131 import dxfLibrary as DXF
132 #reload(DXF)
133 #reload(dxfLibrary)
134 #from dxfLibrary import *
135
136 import math
137 from math import atan, atan2, log10, sin, cos
138
139 #pi = math.pi
140 #pi = 3.14159265359
141 r2d = 180.0 / math.pi
142 d2r = math.pi / 180.0
143 #note: d2r * angle == math.radians(angle)
144
145 print '\n\n\n'
146 print 'DXF-Exporter v%s *** start ***' %(__version__)   #---------------------
147
148 #DEBUG = True #activets debug mode
149
150
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
160 APPLY_MODIFIERS = 1
161 INCLUDE_DUPLIS = 0
162 OUTPUT_DWG = 0 #optional save to DWG with extern converter
163
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
167
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
174
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
184 E_M = 0
185 LAB = "scroll MMB/WHEEL           . wip   .. todo" #"*) parts under construction"
186 M_OBJ = 0
187
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'
194
195 SCENE = None
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))
200
201 AUTO = BezTriple.HandleTypes.AUTO
202 FREE = BezTriple.HandleTypes.FREE
203 VECT = BezTriple.HandleTypes.VECT
204 ALIGN = BezTriple.HandleTypes.ALIGN
205
206
207 #-------- DWG support ------------------------------------------
208 extCONV_OK = True
209 extCONV = 'DConvertCon.exe'
210 extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV)
211 if not os.path.isfile(extCONV_PATH):
212         extCONV_OK = False
213         extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\
214 Copy first %s into Blender script directory.|\
215 More details in online Help.' %extCONV
216 else:
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
221                 else: 
222                         extCONV_OK = False
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
227
228
229 #----------------------------------------------
230 def updateMenuCAMERA():
231         global CAMERAS
232         global MenuCAMERA
233         global MenuLIGHT
234
235         scn = Scene.GetCurrent()
236         objs = scn.getChildren()
237         currcam = scn.getCurrentCamera()
238         if currcam: currcam = currcam.getName()
239         maincams = []
240         MenuCAMERA = "Select Camera%t"
241         for cam in objs:
242                 if cam.getType() == 'Camera':
243                         if cam.getName()[0:4] != "Temp":
244                                 maincams.append(cam.getName())
245         maincams.sort()
246         maincams.reverse() 
247         CAMERAS = maincams
248         for i, cam in enumerate(CAMERAS):
249                 if cam==currcam:
250                         MenuCAMERA += "|* " + cam
251                 else: MenuCAMERA += "| " + cam
252         MenuCAMERA += "|current 3d-View"                        
253         MenuLIGHT = "Select Sun%t| *todo"                       
254
255
256 #----------------------------------------------
257 def updateCAMERA():
258         global CAMERA, GUI_A
259         #CAMERA = 1
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
266
267 #----------------------------------------------
268 def gotoCAMERA():
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.")
273         else:
274                 scn = Scene.getCurrent()   
275                 scn.setCurrentCamera(cam)
276                 Window.CameraView(0)
277                 Window.Redraw()
278                 updateMenuCAMERA()
279
280
281 #------- Duplicats support ----------------------------------------------
282 def dupTest(object):
283         """
284         Checks objects for duplicates enabled (any type)
285         object: Blender Object.
286         Returns: Boolean - True if object has any kind of duplicates enabled.
287         """
288         if (object.enableDupFrames or \
289                 object.enableDupGroup or \
290                 object.enableDupVerts):
291                 return True
292         else:
293                 return False
294
295 def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False):
296         """
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.
306         """
307
308         result = []
309         for ob in oblist:
310                 if INCLUDE_DUPLIS and dupTest(ob):
311                         dup_obs=ob.DupObjects
312                         if len(dup_obs):
313                                 for dup_ob, dup_mx in dup_obs:
314                                         if MATRICES:
315                                                 result.append((dup_ob,dup_mx))
316                                         else:
317                                                 result.append(dup_ob)
318                 else:
319                         if HACK:
320                                 if ob.getName()[0:4] != "dpl_":
321                                         if MATRICES:
322                                                 mx = ob.mat
323                                                 result.append((ob,mx))
324                                         else:
325                                                 result.append(ob)
326                         else:
327                                 if MATRICES:
328                                         mx = ob.mat
329                                         result.append((ob,mx))
330                                 else:
331                                         result.append(ob)
332         return result
333
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'
338         front_faces = []
339         front_edges = []
340         for f in faces:
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
347                 vec_normal *= mx_n
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' #------------------
352
353                 
354                 frontFace = False
355                 if not PERSPECTIVE: #for ortho mode ----------
356                         # normal must point the Z direction-hemisphere
357                         if vec_normal[2] > 0.00001:
358                                 frontFace = True
359                 else:
360                         v = f.verts[0]
361                         vert = Mathutils.Vector(v.co) * mx
362                         if Mathutils.DotVecs(vert, vec_normal) < 0.00001:
363                                 frontFace = True
364
365                 if frontFace:
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)
371
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
377
378
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()
384         co[3] = 1.0
385         sc = co * mw
386         #print 'deb: viewprojection=', sc #---------
387         return [sc[0],sc[1],0.0]
388
389
390 #--------not used---------------------------------------------
391 def flatten(points, mw):
392         for i,v in enumerate(points):
393                 v = projected_co(v, mw)
394                 points[i]=v
395         #print 'deb: flatten points=', points #---------
396         return points
397
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
405 else:
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
410         
411
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]]
417         if AZaxis[2]==1.0:
418                 Extrusion = None
419                 AXaxis = matrix[0].copy().resize3D() # = ArbitraryZvector
420         else:
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)
425                 else:
426                         AXaxis = M_CrossVecs(WORLDZ,AZaxis)
427
428         #print 'deb:\n' #-------------
429         #print 'deb:getExtrusion()  Extrusion=', Extrusion #---------
430         return Extrusion, AXaxis.normalize() 
431
432 #-----------------------------------------------------
433 def     getZRotation(AXaxis, rot_matrix_invert):
434         #ZRotation = Mathutils.AngleBetweenVecs(WORLDX,AXaxis) #output in degrees
435
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
440
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
450
451         #print 'deb:ZRotation()  ZRotation=', ZRotation*r2d #---------
452         return ZRotation
453
454
455 #------------------------------------------
456 def normalizeMat(matrix):
457         mat12 = matrix.copy()
458         mat12 = [Mathutils.Vector(v).normalize() for v in mat12]
459         if len(mat12)>3:
460                 matr12 = Mathutils.Matrix(mat12[0],mat12[1],mat12[2],mat12[3])
461         else:
462                 matr12 = Mathutils.Matrix(mat12[0],mat12[1],mat12[2])
463         return matr12
464
465
466 #-----------------------------------------------------
467 def projected_co(verts, mx):
468         # converts world coordinates of points to screen coordinates
469         temp_verts = []
470         for v in verts:
471                 #temp_verts.append(Blender.Mesh.MVert(v.co))
472                 temp_verts.append(Mesh.MVert(v))
473         #print 'deb: temp_verts=', temp_verts #---------
474         for v in temp_verts:
475                 v.co *= mx
476
477         if GUI_A['Z_force_on'].val: locZ = GUI_A['Z_elev'].val
478         else: locZ = 0.0
479
480         if PROJECTION:
481                 if PERSPECTIVE:
482                         clipStart = 10.0
483                         for v in temp_verts:
484                                 coef = - clipStart / v.co[2]
485                                 v.co[0] *= coef
486                                 v.co[1] *= coef
487                                 v.co[2] = locZ
488                 for v in temp_verts:
489                         v.co[2] = locZ
490         temp_verts = [v.co[:3] for v in temp_verts]
491         return temp_verts
492
493
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
501         return 0
502
503
504 #-----------------------------------------------------
505 def     exportMesh(ob, mx, mx_n, me=None, **common):
506         global APPLY_MODIFIERS
507         entities = []
508         #print 'deb:exportMesh() common=', common #---------
509         if me is None: # me means mesh
510                 me = ob.getData(mesh=1)
511         else:
512                 me.getFromObject(ob)
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?
518         if me.verts:
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
523                         for p in allpoints:
524                                 p[0] += G_ORIGIN[0]
525                                 p[1] += G_ORIGIN[1]
526                                 p[2] += G_ORIGIN[2]
527                 faces=[]
528                 edges=[]
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]
533                 else:
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
543                         for f in faces:
544                                 f.reverse()
545                                 #f = [f[-1]] + f[:-1] #TODO: might be needed
546                 #print 'deb: faces=\n', faces #---------
547
548                 c = mesh_as_list[GUI_A['mesh_as'].val]
549                 if 'POINTs'==c: # export Mesh as multiple POINTs
550                         for p in allpoints:
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
556                                 for e in edges:
557                                         points = [allpoints[e[0]], allpoints[e[1]]]
558                                         dxfLINE = DXF.Line(points, **common)
559                                         entities.append(dxfLINE)
560                 elif faces:
561                         if c in ('POLYFACE','POLYLINE'):
562                                 if allpoints:
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)
570                         elif '3DFACEs'==c:
571                                 if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene
572                                 for f in faces:
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)
579                                         
580         return entities
581
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)
586         me = Mesh.New(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)
593         if flatten:
594                 for v in me.verts: v.co.z = 0.0
595         ob.link(me)
596         if link:
597                 sce = Scene.getCurrent()
598                 sce.objects.link(ob)
599                 #me.triangleToQuad()
600                 if AT_CUR:
601                         cur_loc = Window.GetCursorPos()
602                         ob.setLocation(cur_loc)
603                 Blender.Redraw()
604         #return ob
605
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)
610         cu = Curve.New(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))
615         for point in curve:
616                 #point.handleTypes = [VECT, VECT]
617                 point.handleTypes = [FREE, FREE]
618                 point.radius = 1.0
619         curve.flagU = closed # 0 sets the curve not cyclic=open
620         cu.setResolu(6)
621         cu.update() #important for handles calculation
622         if flatten:
623                 for v in cu.verts: v.co.z = 0.0
624         ob.link(cu)
625         if link:
626                 sce = Scene.getCurrent()
627                 sce.objects.link(ob)
628                 #me.triangleToQuad()
629                 if AT_CUR:
630                         cur_loc = Window.GetCursorPos()
631                         ob.setLocation(cur_loc)
632                 elif org_point:
633                         cur_loc=org_point
634                         ob.setLocation(cur_loc)
635                 Blender.Redraw()
636         #return ob
637
638
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
645                 p[0] += G_ORIGIN[0]
646                 p[1] += G_ORIGIN[1]
647                 p[2] += G_ORIGIN[2]
648
649         entities = []
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)
654         return entities
655
656
657 #-----------------------------------------------------
658 def exportCurve(ob, mx, mw, **common):
659         entities = []
660         curve = ob.getData()
661         Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
662         if not PROJECTION:
663                 #Extrusion, ZRotation, Elevation = getExtrusion(mx)
664                 Extrusion, AXaxis = getExtrusion(mx)
665
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 #---------
669
670         sizeX = ob.SizeX
671         sizeY = ob.SizeY
672         sizeZ = ob.SizeZ
673         rotZ  = ob.RotZ
674         #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
675
676         #print 'deb: curve.ext1=', curve.ext1 #---------
677         if curve.ext1: Thickness = curve.ext1 * sizeZ
678
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 #---------
690                 ZRotation = rotZ
691                 if Extrusion!=None:
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])
697
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!
706
707         for cur in curve:
708                 #print 'deb: START cur=', cur #--------------
709                 points = []
710                 if cur.isNurb():
711                         for point in cur:
712                                 #print 'deb:isNurb point=', point #---------
713                                 vec = point[0:3]
714                                 #print 'deb: vec=', vec #---------
715                                 pkt = Mathutils.Vector(vec)
716                                 #print 'deb: pkt=', pkt #---------
717                                 points.append(pkt)
718                 else:
719                         for point in cur:
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 #---------
725                                 points.append(pkt)
726
727                 #print 'deb: points', points #--------------
728                 if len(points)>1:
729                         c = curve_as_list[GUI_A['curve_as'].val]
730
731                         if c=="POLYLINE": # export Curve as POLYLINE
732                                 for p in points: # vectors4d
733                                         p[0] *= sizeX
734                                         p[1] *= sizeY
735                                         p2 = p * Zrotmatrix
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 #--------------
740
741                                 if cur.isCyclic(): closed = 1
742                                 else: closed = 0
743                                 if GUI_A['g_origin_on'].val: #TODO: scale and object orientation
744                                         for p in points:
745                                                 p[0] += G_ORIGIN[0]
746                                                 p[1] += G_ORIGIN[1]
747                                                 p[2] += G_ORIGIN[2]
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 #------------------
754
755                                 if 0: #DEBUG
756                                         linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]]
757                                         dxfLINE = DXF.Line(linepoints,**common)
758                                         entities.append(dxfLINE)
759
760                                 dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common)
761                                 entities.append(dxfPLINE)
762                                 if Thickness:
763                                         common['thickness']= -Thickness
764                                         dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common)
765                                         entities.append(dxfPLINE)
766
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
772                                         for p in points:
773                                                 p[0] += G_ORIGIN[0]
774                                                 p[1] += G_ORIGIN[1]
775                                                 p[2] += G_ORIGIN[2]
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)
785                                 if Thickness:
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)
791
792                         elif c=="POINTs": # export Curve as multiple POINTs
793                                 for p in points:
794                                         dxfPOINT = DXF.Point(points=[p],**common)
795                                         entities.append(dxfPOINT)
796
797         return entities
798
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 #------------------
808
809         clip1_Z = - camera.clipStart
810         clip2_Z = - camera.clipEnd
811         #print 'deb: clip Start=', camera.clipStart #------------------
812         #print 'deb: clip   End=', camera.clipEnd #------------------
813
814         if camera.type=='ortho':
815                 scale = camera.scale
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
823                 clip2_X = clip1_X
824                 clip2_Y = clip1_Y
825
826                 near = clip1_Z
827                 far = clip2_Z
828                 right, left = clip1_X, -clip1_X
829                 top, bottom = clip1_Y, -clip1_Y
830
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)
837                 
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])
842
843         elif camera.type=='persp': 
844                 #viewpoint = [0.0, 0.0, 0.0] #camera's coordinate system, hehe
845                 #lens = camera.lens
846                 angle = camera.angle
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
860                 if ratioXY > 1.0:
861                         clip1_Y /= ratioXY
862                         clip2_Y /= ratioXY
863                 else:
864                         clip1_X *= ratioXY
865                         clip2_X *= ratioXY
866
867                 near = clip1_Z
868                 far = clip2_Z
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])
879
880
881         clip_box = [
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,
886                 clip1_Z, clip2_Z]
887         #print 'deb: clip_box=\n', clip_box #------------------
888         #drawClipBox(clip_box)
889         return clip_box, matr
890
891
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
897         verts = []
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]]
907         nme = Mesh.New()
908         nme.verts.extend(verts)
909         nme.faces.extend(faces)
910         
911         plan = Object.New('Mesh','clip_box')
912         plan.link(nme)
913         sce = Scene.GetCurrent()
914         sce.objects.link(plan)
915         plan.setMatrix(sce.objects.camera.matrix)
916
917
918 #-------------------------------------------------
919 def getCommons(ob):
920         #set up common attributes for output style:
921         # color=None
922         # extrusion=None
923         # layer='0',
924         # lineType=None
925         # lineTypeScale=None
926         # lineWeight=None
927         # thickness=None
928         # parent=None
929
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 #--------------
933
934         materials = ob.getMaterials()
935         if materials:
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 #--------------
940
941         data = ob.getData()
942         data_materials = ob.getMaterials()
943         if data_materials:
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 #--------------
948         
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
958         elif c=="obj.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"
966
967         entitycolor = ENTITYCOLOR_DEF
968         c = entitycolor_from_list[GUI_A['entitycolor_from'].val]
969         if c=="default_COLOR":
970                 entitycolor = LAYERCOLOR_DEF
971         elif c=="BYLAYER":
972                 entitycolor = BYLAYER
973         elif c=="BYBLOCK":
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
984
985         entityltype = ENTITYLTYPE_DEF
986         c = entityltype_from_list[GUI_A['entityltype_from'].val]
987         if c=="default_LTYPE":
988                 entityltype = LAYERLTYPE_DEF
989         elif c=="BYLAYER":
990                 entityltype = BYLAYER
991         elif c=="BYBLOCK":
992                 entityltype = BYBLOCK
993         elif c:
994                 entityltype = c
995
996         return entitylayer,entitycolor,entityltype
997
998
999 #-----------------------------------------------------
1000 def do_export(export_list, filepath):
1001         global PERSPECTIVE
1002         Window.WaitCursor(1)
1003         t = Blender.sys.time()
1004
1005         #init Drawing ---------------------
1006         d=DXF.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
1012
1013         #add Entities --------------------
1014         something_ready = 0
1015         sce = Scene.GetCurrent()
1016
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])
1021         if PROJECTION:
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 #------------------
1029                         if 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)
1037         
1038                                 #mcp = getPerspMatrix(camera)
1039                                 mw = mc0.copy().invert()
1040         
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        #---------
1052                         #mw0 = mwp
1053                         #clip_box = getClipBox(camera, context)
1054                         mw = mw0.copy()
1055         
1056         #print 'deb: ViewMatrix=\n', mw #------------------
1057         
1058         if APPLY_MODIFIERS: tmp_me = Mesh.New('tmp')
1059         else: tmp_me = None
1060
1061         layernames = []
1062         for ob,mx in export_list:
1063                 entities = []
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
1071                 mx *= mw
1072                 
1073                 #mx_inv = mx.copy().invert()
1074                 #print 'deb: mx =\n', mx         #---------
1075                 #print 'deb: mx_inv=\n', mx_inv #---------
1076
1077                 if ob.type in ('Mesh', 'Curve', 'Empty'):
1078                         if GUI_A['paper_space_on'].val==1: espace=1
1079                         else: espace=None
1080                         elayer,ecolor,eltype = getCommons(ob)
1081                         #print 'deb: elayer,ecolor,eltype =', elayer,ecolor,eltype #--------------
1082
1083                         if elayer!=None:
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))
1089
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)
1099         
1100                 for e in entities:
1101                         d.append(e)
1102                         something_ready += 1
1103
1104         if something_ready:
1105                 if not GUI_A['outputDWG_on'].val:
1106                         print 'exporting to %s' % filepath
1107                         try:
1108                                 d.saveas(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)))
1113                         except IOError:
1114                                 Window.WaitCursor(0)
1115                                 Draw.PupMenu('DXF Exporter: Write Error:     Permission denied:| %s' %filepath)
1116                                 
1117                 else:
1118                         if not extCONV_OK:
1119                                 Draw.PupMenu(extCONV_TEXT)
1120                                 Window.WaitCursor(False)
1121                         else:
1122                                 print 'temp. exporting to %s' % filepath
1123                                 d.saveas(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))
1130                                 #os.chdir(cwd)
1131                                 os.remove(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)))
1135         else:
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!')
1139
1140
1141 #------------------------------------------------------
1142 """
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])
1152 del v, i
1153 """
1154 #TODO: validDXFr14 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.'
1155 validDXFr12 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'
1156
1157 #------------------------------------------------------
1158 def cleanName(name,valid):
1159         validname = ''
1160         for ch in name:
1161                 if ch not in valid:     ch = '_'
1162                 validname += ch
1163         return validname
1164
1165 #------------------------------------------------------
1166 def validDXFr12name(str_name):
1167         dxfname = str(str_name)
1168         dxfname = dxfname[:MAX_NAMELENGTH].upper()
1169         dxfname = cleanName(dxfname,validDXFr12)
1170         return dxfname
1171
1172 #print cleanName('dumka',validDXFr12)
1173 #print validDXFr12name('dum 15%ka')
1174
1175 #------------------------------------------------------
1176 def col2RGB(color):
1177         return [int(floor(255*color[0])),
1178                         int(floor(255*color[1])),
1179                         int(floor(255*color[2]))]
1180
1181 global dxfColors
1182 dxfColors=None
1183
1184 #------------------------------------------------------
1185 def col2DXF(rgbcolor):
1186         global dxfColors
1187         if dxfColors is None:
1188                 from dxfColorMap import color_map
1189                 dxfColors = [(tuple(color),idx) for idx, color in color_map.iteritems()]
1190                 dxfColors.sort()
1191         entry = (tuple(rgbcolor), -1)
1192         dxfColors.append(entry)
1193         dxfColors.sort()
1194         i = dxfColors.index(entry)
1195         dxfColors.pop(i)
1196         return dxfColors[i-1][1]
1197
1198
1199
1200 # NEW UI -----#################################################-----------------
1201 # ------------#################################################-----------------
1202
1203 class Settings:  #-----------------------------------------------------------------
1204         """A container for all the import settings and objects used by the draw functions.
1205
1206         This is like a collection of globally accessable persistant properties and functions.
1207         """
1208         # Optimization constants
1209         MIN = 0
1210         MID = 1
1211         PRO = 2
1212         MAX = 3
1213
1214         def __init__(self, keywords, drawTypes):
1215                 """initialize all the important settings used by the draw functions.
1216                 """
1217                 self.obj_number = 1 #global object_number for progress_bar
1218
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
1221
1222                 self.var['colorFilter_on'] = False   #deb:remi------------
1223                 self.acceptedColors = [0,2,3,4,5,6,7,8,9,
1224                                                            10 ]
1225
1226                 self.var['materialFilter_on'] = False   #deb:remi------------
1227                 self.acceptedLayers = ['3',
1228                                                    '0'
1229                                                   ]
1230
1231                 self.var['groupFilter_on'] = False   #deb:remi------------
1232                 self.acceptedLayers = ['3',
1233                                                    '0'
1234                                                   ]
1235
1236                 #self.var['objectFilter_on'] = 0   #deb:remi------------
1237                 self.acceptedBlocks = ['WALL_1871',
1238                                                    'BOX02'
1239                                                   ]
1240                 self.unwantedBlocks = ['BOX05',
1241                                                    'BOX04'
1242                                                   ]
1243
1244
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
1248                 """
1249
1250                 for k, v in keywords.iteritems():
1251                         self.var[k] = v
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]) #--------------
1256
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']
1263
1264                 #print 'deb:self.drawTypes', self.drawTypes #---------------
1265
1266
1267         def validate(self, drawing):
1268                 """Given the drawing, build dictionaries of Layers, Colors and Blocks.
1269                 """
1270                 global oblist
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'])
1275
1276
1277         def write(self, text, newline=True):
1278                 """Wraps the built-in print command in a optimization check.
1279                 """
1280                 if self.var['optimization'] <= self.MID:
1281                         if newline:
1282                                 print text
1283                         else:
1284                                 print text,
1285
1286
1287         def redraw(self):
1288                 """Update Blender if optimization level is low enough.
1289                 """
1290                 if self.var['optimization'] <= self.MIN:
1291                         Blender.Redraw()
1292
1293
1294         def progress(self, done, text):
1295                 """Wrapper for Blender.Window.DrawProgressBar.
1296                 """
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  #-----------------------
1301
1302
1303
1304 # GUI STUFF -----#################################################-----------------
1305 from Blender.BGL import *
1306
1307 EVENT_NONE = 1
1308 EVENT_START = 2
1309 EVENT_REDRAW = 3
1310 EVENT_LOAD_INI = 4
1311 EVENT_SAVE_INI = 5
1312 EVENT_RESET = 6
1313 EVENT_CHOOSE_INI = 7
1314 EVENT_CHOOSE_DXF = 8
1315 EVENT_HELP = 9
1316 EVENT_CAMERA = 10
1317 EVENT_LIGHT =11
1318 EVENT_DXF_DIR = 12
1319 EVENT_setCAMERA = 13
1320 EVENT_LIST = 14
1321 EVENT_ORIGIN = 15
1322 EVENT_SCALE = 16
1323 EVENT_PRESET2D = 20
1324 EVENT_PRESET3D = 21
1325 EVENT_PRESETPLINE = 22
1326 EVENT_PRESETS = 23
1327 EVENT_EXIT = 100
1328 GUI_EVENT = EVENT_NONE
1329
1330 GUI_A = {}  # GUI-buttons dictionary for parameter
1331 GUI_B = {}  # GUI-buttons dictionary for drawingTypes
1332
1333 # settings default, initialize ------------------------
1334
1335 #-----------------------------------------------
1336 def prepareMenu(title,list):
1337         menu = title    
1338         for i, item in enumerate(list):
1339                 menu += '|'+ item + ' %x' + str(i)
1340         return menu
1341
1342 #-----------------------------------------------
1343 mesh_as_list  = ["3DFACEs","POLYFACE","POLYLINE","LINEs","POINTs"]
1344 mesh_as_menu = prepareMenu("export to: %t", mesh_as_list) 
1345
1346 curve_as_list  = ["LINEs","POLYLINE","..LWPOLYLINE r14","..SPLINE r14","POINTs"]
1347 curve_as_menu = prepareMenu("export to: %t", curve_as_list) 
1348
1349 surface_as_list   = ["..3DFACEs","..POLYFACE","..POINTs","..NURBS"]
1350 surface_as_menu = prepareMenu("export to: %t", surface_as_list) 
1351
1352 meta_as_list  = ["..3DFACEs","..POLYFACE","..3DSOLID"]
1353 meta_as_menu = prepareMenu("export to: %t", meta_as_list) 
1354
1355 text_as_list   = ["..TEXT","..MTEXT","..ATTRIBUTs"]
1356 text_as_menu = prepareMenu("export to: %t", text_as_list) 
1357
1358 empty_as_list  = ["POINT","..INSERT","..XREF"]
1359 empty_as_menu = prepareMenu("export to: %t|", empty_as_list) 
1360
1361 group_as_list  = ["..GROUP","..BLOCK","..ungroup"]
1362 group_as_menu = prepareMenu("export to: %t", group_as_list) 
1363
1364 parent_as_list = ["..BLOCK","..ungroup"]
1365 parent_as_menu = prepareMenu("export to: %t", parent_as_list) 
1366
1367 proxy_as_list = ["..BLOCK","..XREF","..ungroup","..POINT"]
1368 proxy_as_menu = prepareMenu("export to: %t", proxy_as_list) 
1369
1370 camera_as_list = ["..BLOCK","..A_CAMERA","..VPORT","..VIEW","..POINT"]
1371 camera_as_menu = prepareMenu("export to: %t", camera_as_list) 
1372         
1373 lamp_as_list  = ["..BLOCK","..A_LAMP","..POINT"]
1374 lamp_as_menu = prepareMenu("export to: %t", lamp_as_list) 
1375         
1376 material_to_list= ["COLOR","LAYER","..LINESTYLE","..BLOCK","..XDATA","..INI-File"]
1377 material_to_menu = prepareMenu("export to: %t", material_to_list) 
1378
1379 ltype_map_list= ["object_rgb","material_rgb","..map_table"]
1380 ltype_map_menu = prepareMenu("export to: %t", ltype_map_list) 
1381
1382
1383
1384 layername_from_list = [LAYERNAME_DEF,"drawing_name","scene_name"]
1385 layername_from_menu = prepareMenu("defaultLAYER: %t", layername_from_list)
1386
1387 layerltype_def_list = ["CONTINUOUS","DOT","DASH","DASH-DOT"]
1388 layerltype_def_menu = prepareMenu("LINETYPE set to: %t",layerltype_def_list)
1389
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 #--------------
1393         
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)
1396
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)
1399
1400 #dxf-LINE,ARC,CIRCLE,ELLIPSE
1401
1402 g_scale_list    = ''.join((
1403         'scale factor: %t',
1404         '|user def. %x12',
1405         '|yard to m %x8',
1406         '|feet to m %x7',
1407         '|inch to m %x6',
1408         '|  x  100000 %x5',
1409         '|  x  10000 %x4',
1410         '|  x  1000 %x3',
1411         '|  x  100 %x2',
1412         '|  x  10 %x1',
1413         '|  x  1 %x0',
1414         '|  x  0.1 %x-1',
1415         '|  x  0.01 %x-2',
1416         '|  x  0.001 %x-3',
1417         '|  x  0.0001 %x-4',
1418         '|  x  0.00001 %x-5'))
1419
1420 #print 'deb:  g_scale_list', g_scale_list #-----------
1421
1422 dxfFileName = Draw.Create("")
1423 iniFileName = Draw.Create(INIFILE_DEFAULT_NAME + INIFILE_EXTENSION)
1424 user_preset = 0
1425 config_UI = Draw.Create(0)   #switch_on/off extended config_UI
1426 g_scale_as = Draw.Create(int(log10(G_SCALE)))
1427
1428
1429 keywords_org = {
1430         'optimization': 2,
1431         'dummy_on' : 0,
1432
1433         'xref_on' : 1,
1434         'block_nn': 0,
1435
1436         'paper_space_on': 0,
1437         'layFrozen_on': 0,
1438         'objectFilter_on': 0,
1439         'materialFilter_on': 0,
1440         'colorFilter_on': 0,
1441         'groupFilter_on': 0,
1442
1443         'only_selected_on': ONLYSELECTED,
1444         'projection_on' : PROJECTION,
1445         'hidden_lines_on': HIDDEN_LINES,
1446         'shadows_on'  : SHADOWS,
1447         'light_on'  : 1,
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,
1454
1455         'g_originX'   : G_ORIGIN[0],
1456         'g_originY'   : G_ORIGIN[1],
1457         'g_originZ'   : G_ORIGIN[2],
1458         'g_origin_on': 0,
1459         'g_scale'   : float(G_SCALE),
1460 #   'g_scale_as': int(log10(G_SCALE)), #   0,
1461         'g_scale_on': 0,
1462         'Z_force_on': 0,
1463         'Z_elev': float(ELEVATION),
1464
1465
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,
1473
1474         'material_on': 1,
1475         'material_to': 2,
1476         'fill_on'   : 1,
1477
1478         'mesh_as'  : 1,
1479         'curve_as' : 1,
1480         'surface_as' : 1,
1481         'meta_as'  : 1,
1482         'text_as' : 0,
1483         'empty_as' : 0,
1484         'group_as' : 0,
1485         'parent_as' : 0,
1486         'proxy_as' : 0,
1487         'camera_as': 1,
1488         'lamp_as' : 1,
1489         }
1490
1491 drawTypes_org = {
1492         'bmesh' : 1,
1493         'bcurve': 1,
1494         'surface': 0,
1495         'bmeta' : 0,
1496         'text'  : 0,
1497         'empty' : 1,
1498         'group' : 1,
1499         'parent': 1,
1500         'proxy' : 0,
1501         'camera': 0,
1502         'lamp'  : 0,
1503
1504 #   'view' : 0,
1505         }
1506
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 #---------------
1516
1517 model_space_on = Draw.Create(1)
1518
1519 # initialize settings-object controls how dxf entities are drawn
1520 settings = Settings(keywords_org, drawTypes_org)
1521
1522
1523 def update_RegistryKey(key, item): #
1524         """updates key in Blender.Registry
1525         """
1526         cache = True # data is also saved to a file
1527         rdict = Registry.GetKey('DXF_Exporter', cache)
1528         if not rdict: rdict = {}
1529         if item:
1530                 rdict[key] = item
1531                 Registry.SetKey('DXF_Exporter', rdict, cache)
1532                 #print  'deb:update_RegistryKey rdict', rdict #---------------
1533
1534
1535 def check_RegistryKey(key):
1536         """ check if the key is already there (saved on a previous execution of this script)
1537         """
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
1542                 try:
1543                         item = rdict[key]
1544                         return item
1545                 except:
1546                         #update_RegistryKey() # if data isn't valid rewrite it
1547                         pass
1548
1549 def saveConfig():  #--todo-----------------------------------------------
1550         """Save settings/config/materials from GUI to INI-file.
1551
1552         Write all config data to INI-file.
1553         """
1554         global iniFileName
1555
1556         iniFile = iniFileName.val
1557         #print 'deb:saveConfig inifFile: ', inifFile #----------------------
1558         if iniFile.lower().endswith(INIFILE_EXTENSION):
1559
1560                 #--todo-- sort key.list for output
1561                 #key_list = GUI_A.keys().val
1562                 #key_list.sort()
1563                 #for key in key_list:
1564                 #   l_name, l_data = key, GUI_A[key].val
1565                 #   list_A
1566
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!')
1570                 else:
1571                         if Blender.sys.exists(iniFile):
1572                                 f = file(iniFile, 'r')
1573                                 header_str = f.readline()
1574                                 f.close()
1575                                 if header_str.startswith(INIFILE_HEADER[0:13]):
1576                                         if Draw.PupMenu('  OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile) == 1:
1577                                                 save_ok = True
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:
1581                                         save_ok = True
1582                                 else: save_ok = False
1583                         else: save_ok = True
1584
1585                         if save_ok:
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('{'))
1592                                 try:
1593                                         f = file(iniFile, 'w')
1594                                         f.write(INIFILE_HEADER + '\n# this is a comment line\n')
1595                                         f.write(output_str)
1596                                         f.close()
1597                                         #Draw.PupMenu('DXF-Exporter: INI-file: Done!%t|config-data saved in ' + '\'%s\'' %iniFile)
1598                                 except:
1599                                         Draw.PupMenu('DXF-Exporter: INI-file: Error!%t|failure by writing to ' + '\'%s\'|no config-data saved!' %iniFile)
1600
1601         else:
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."
1604                 if not iniFile:
1605                         if dxfFileName.val.lower().endswith('.dxf'):
1606                                 iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
1607
1608
1609 def loadConfig():  #remi--todo-----------------------------------------------
1610         """Load settings/config/materials from INI-file.
1611
1612         Read material-assignements from config-file.
1613         """
1614         #070724 buggy Window.FileSelector(loadConfigFile, 'Load config data from INI-file', inifilename)
1615         global iniFileName, GUI_A, GUI_B
1616
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):
1624                         data_str = f.read()
1625                         f.close()
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)
1634                 else:
1635                         f.close()
1636                         Draw.PupMenu('DXF-Exporter: INI-file:  Alert!%t|no valid header in INI-file: ' + '\'%s\'' %iniFile)
1637         else:
1638                 Draw.PupMenu('DXF-Exporter: INI-file:  Alert!%t|no valid INI-file selected!')
1639                 print "DXF-Exporter: Alert!: no valid INI-file selected."
1640                 if not iniFileName:
1641                         if dxfFileName.val.lower().endswith('.dxf'):
1642                                 iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
1643
1644
1645
1646 def updateConfig(keywords, drawTypes):  #-----------------------------------------------
1647         """updates GUI_settings with given dictionaries
1648
1649         """
1650         global GUI_A, GUI_B
1651         #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
1652         for k, v in keywords.iteritems():
1653                 GUI_A[k].val = v
1654         for k, v in drawTypes.iteritems():
1655                 GUI_B[k].val = v
1656
1657 def resetDefaultConfig():  #-----------------------------------------------
1658         """Resets settings/config/materials to defaults.
1659
1660         """
1661         #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
1662         updateConfig(keywords_org, drawTypes_org)
1663
1664
1665 def presetConfig_polyline(activate):  #-----------------------------------------------
1666         """Sets settings/config for polygon representation: POLYLINE(FACE) or LINEs/3DFACEs.
1667
1668         """
1669         global GUI_A
1670         if activate:
1671                 GUI_A['to_polyline_on'].val = 1
1672                 GUI_A['mesh_as'].val = 1
1673                 GUI_A['curve_as'].val = 1
1674         else:
1675                 GUI_A['to_polyline_on'].val = 0
1676                 GUI_A['mesh_as'].val = 0
1677                 GUI_A['curve_as'].val = 0
1678         
1679 def resetDefaultConfig_2D():  #-----------------------------------------------
1680         """Sets settings/config/materials to defaults 2D.
1681
1682         """
1683         keywords2d = {
1684                 'projection_on' : 1,
1685                 'fill_on' : 1,
1686                 'text_as' : 0,
1687                 'group_as' : 0,
1688                 }
1689
1690         drawTypes2d = {
1691                 'bmesh' : 1,
1692                 'bcurve': 1,
1693                 'surface':0,
1694                 'bmeta' : 0,
1695                 'text'  : 1,
1696                 'empty' : 1,
1697                 'group' : 1,
1698                 'parent' : 1,
1699                 #'proxy' : 0,
1700                 #'camera': 0,
1701                 #'lamp'  : 0,
1702
1703                 }
1704         presetConfig_polyline(1)
1705         updateConfig(keywords2d, drawTypes2d)
1706
1707 def resetDefaultConfig_3D():  #-----------------------------------------------
1708         """Sets settings/config/materials to defaults 3D.
1709
1710         """
1711         keywords3d = {
1712                 'projection_on' : 0,
1713                 'fill_on' : 0,
1714                 #'text_as' : 0,
1715                 'group_as' : 0,
1716                 }
1717
1718         drawTypes3d = {
1719                 'bmesh' : 1,
1720                 'bcurve': 1,
1721                 'surface':0,
1722                 'bmeta' : 0,
1723                 'text'  : 0,
1724                 'empty' : 1,
1725                 'group' : 1,
1726                 'parent' : 1,
1727                 #'proxy' : 0,
1728                 'camera': 1,
1729                 'lamp'  : 1,
1730                 }
1731         presetConfig_polyline(1)
1732         updateConfig(keywords3d, drawTypes3d)
1733
1734
1735 def inputGlobalScale():
1736         """Pop-up UI-Block for global scale factor
1737         """
1738         global GUI_A
1739         #print 'deb:inputGlobalScale ##########' #------------
1740         x_scale = Draw.Create(GUI_A['g_scale'].val)
1741         block = []
1742         #block.append("global translation vector:")
1743         block.append(("", x_scale, 0.0, 10000000.0))
1744
1745         retval = Draw.PupBlock("set global scale factor:", block)
1746
1747         GUI_A['g_scale'].val = float(x_scale.val)
1748
1749         
1750 def inputOriginVector():
1751         """Pop-up UI-Block for global translation vector
1752         """
1753         global GUI_A
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)
1758         block = []
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))
1763
1764         retval = Draw.PupBlock("set global translation vector:", block)
1765
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
1769
1770
1771 def update_globals():  #-----------------------------------------------------------------
1772         """ update globals if GUI_A changed
1773         """
1774         global  ONLYSELECTED, DEBUG,\
1775         PROJECTION, HIDDEN_LINES,       CAMERA, \
1776         G_SCALE, G_ORIGIN,\
1777         PREFIX, LAYERNAME_DEF, LAYERCOLOR_DEF, LAYERLTYPE_DEF,\
1778         APPLY_MODIFIERS, INCLUDE_DUPLIS,\
1779         OUTPUT_DWG
1780         #global POLYLINES
1781         
1782         ONLYSELECTED = GUI_A['only_selected_on'].val
1783         """
1784         POLYLINES = GUI_A['to_polyline_on'].val
1785         if GUI_A['curve_as'].val==1: POLYLINES=1
1786         else: POLYLINES=0
1787         """
1788         
1789         if GUI_A['optimization'].val==0: DEBUG = 1
1790         else: DEBUG = 0
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
1803
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]
1808
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 #---------------
1815
1816
1817 def draw_UI():  #-----------------------------------------------------------------
1818         """ Draw startUI and setup Settings.
1819         """
1820         global GUI_A, GUI_B #__version__
1821         global user_preset, iniFileName, dxfFileName, config_UI, g_scale_as
1822         global model_space_on
1823         global SCROLL
1824
1825         global mPAN_X, menu_orgX, mPAN_Xmax
1826         global mPAN_Y, menu_orgY, mPAN_Ymax
1827         global menu__Area, headerArea, screenArea, scrollArea
1828
1829         size=Buffer(GL_FLOAT, 4)
1830         glGetFloatv(GL_SCISSOR_BOX, size) #window X,Y,sizeX,sizeY
1831         size= size.list
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]]
1837
1838         menu_orgX = -mPAN_X
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
1843
1844         menu_orgY = -mPAN_Y
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
1848
1849
1850         menu_margin = 10
1851         butt_margin = 10
1852         common_column = int((window_Area[2] - (3 * butt_margin) - (2 * menu_margin)-30) / 4.0)
1853         common_column = 70
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
1860
1861         simple_menu_h = 240
1862         extend_menu_h = 345
1863         menu_h = simple_menu_h          # y is menu upper.y
1864         if config_UI.val:
1865                 menu_h += extend_menu_h
1866
1867         mPAN_Xmax = menu_w-window_Area[2]+50
1868         mPAN_Ymax = menu_h-window_Area[3]+30
1869
1870         y = menu_h
1871         x = 0 #menu left.x
1872         x +=menu_orgX+20
1873         y +=menu_orgY+20
1874
1875
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
1881
1882         # Here starts menu -----------------------------------------------------
1883         #glClear(GL_COLOR_BUFFER_BIT)
1884         #glRasterPos2d(8, 125)
1885
1886
1887         ui_box(x, y, x+menu_w+menu_margin*2, y-menu_h)
1888         y -= 20
1889         Draw.Label("DXF(r12)-Exporter  v" + __version__, but0c, y, menu_w, 20)
1890
1891         if config_UI.val:
1892                 b0, b0_ = but0c, but_0c-20 + butt_margin
1893                 b1, b1_ = but1c-20, but_1c+20
1894                 y_top = y
1895
1896                 y -= 10
1897                 y -= 20
1898                 Draw.BeginAlign()
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")
1902                 Draw.EndAlign()
1903
1904                 y -= 20
1905                 Draw.BeginAlign()
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")
1909                 Draw.EndAlign()
1910
1911                 y -= 20
1912                 Draw.BeginAlign()
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")
1916                 Draw.EndAlign()
1917
1918                 y -= 20
1919                 Draw.BeginAlign()
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")
1925                 Draw.EndAlign()
1926
1927                 y -= 20
1928                 Draw.BeginAlign()
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")
1933                 Draw.EndAlign()
1934
1935                 y -= 20
1936                 Draw.BeginAlign()
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)
1941                 Draw.EndAlign()
1942
1943                 y_down = y
1944                 # -----------------------------------------------
1945
1946                 y = y_top
1947                 b0, b0_ = but2c, but_2c-20 + butt_margin
1948                 b1, b1_ = but3c-20, but_3c+20
1949
1950                 y -= 10
1951                 y -= 20
1952                 Draw.BeginAlign()
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")
1959                 Draw.EndAlign()
1960
1961                 y -= 20
1962                 Draw.BeginAlign()
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")
1966                 Draw.EndAlign()
1967
1968                 y -= 20
1969                 Draw.BeginAlign()
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")
1973                 Draw.EndAlign()
1974
1975                 y -= 20
1976                 Draw.BeginAlign()
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")
1980                 Draw.EndAlign()
1981
1982                 y -= 20
1983                 Draw.BeginAlign()
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")
1987                 Draw.EndAlign()
1988
1989
1990                 if y < y_down: y_down = y
1991                 # -----end supported objects--------------------------------------
1992
1993                 y_top = y_down
1994                 y = y_top
1995                 y -= 10
1996                 y -= 20
1997                 but_ = menu_w / 6
1998                 b0 = but0c + (menu_w - but_*6)/2
1999                 Draw.BeginAlign()
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")
2007                 Draw.EndAlign()
2008
2009                 # -----end filters--------------------------------------
2010
2011                 b0, b0_ = but0c, but_0c + butt_margin
2012                 b1, b1_ = but1c, but_1c
2013
2014                 y -= 10
2015                 y -= 20
2016                 Draw.BeginAlign()
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
2024                                 )
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")
2027                 Draw.EndAlign()
2028
2029                 y -= 20
2030                 Draw.BeginAlign()
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:
2035                                 pass
2036                         else:
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
2043                                 else:
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
2048                         else:   
2049                                 scale_str = ' = %.6f' % GUI_A['g_scale'].val
2050                         Draw.Label(scale_str, b1+45, y, 200, 20)
2051                 Draw.EndAlign()
2052
2053                 y -= 20
2054                 Draw.BeginAlign()
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)")
2058                 Draw.EndAlign()
2059
2060                 """
2061                 y -= 30
2062                 Draw.BeginAlign()
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?")
2066                 Draw.EndAlign()
2067                 """
2068
2069                 #b0, b0_ = but0c, but_0c + butt_margin
2070                 b0, b0_ = but0c, 50
2071                 b1, b1_ = b0+b0_, but_0c-b0_+ but_1c + butt_margin
2072                 b2, b2_ = but2c, but_2c
2073                 b3, b3_ = but3c, but_3c
2074
2075                 y -= 30
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)
2081
2082                 y -= 20
2083                 Draw.BeginAlign()
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")
2088                 Draw.EndAlign()
2089
2090                 y -= 25
2091                 Draw.Label('Style:', b0, y, b0_, 20)
2092                 Draw.BeginAlign()
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")
2096                 Draw.EndAlign()
2097                 
2098                 y -= 10
2099
2100                 y_down = y
2101                 # -----end material,translate,scale------------------------------------------
2102
2103                 """
2104                 b0, b0_ = but0c, but_0c + butt_margin
2105                 b1, b1_ = but1c, but_1c
2106
2107                 y_top = y_down
2108                 y = y_top
2109                 y -= 10
2110
2111                 y -= 20
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")
2113
2114                 y_down = y
2115                 # -----------------------------------------------
2116
2117                 b0, b0_ = but2c, but_2c + butt_margin
2118                 b1, b1_ = but3c, but_3c
2119
2120                 y = y_top
2121                 y -= 10
2122                 y -= 20
2123
2124
2125                 if y < y_down: y_down = y
2126                 # -----end options --------------------------------------
2127                 """
2128
2129
2130                 #--------------------------------------
2131                 y_top = y_down
2132                 y = y_top
2133                 #GUI_A['dummy_on'] = Draw.Toggle(' - ', EVENT_NONE, but0c, y, but_0c, 20, GUI_A['dummy_on'].val, "reserved")
2134                 y -= 30
2135                 Draw.BeginAlign()
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")
2138                 but = but4c-60
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)
2142                 Draw.EndAlign()
2143
2144         bm = butt_margin/2
2145
2146         y -= 10
2147         y -= 20
2148         Draw.BeginAlign()
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")
2151         Draw.EndAlign()
2152
2153         y -= 30
2154         config_UI = Draw.Toggle('CONFIG', EVENT_REDRAW, but0c, y, but_0c+bm, 20, config_UI.val, 'Advanced configuration   on/off' )
2155         Draw.BeginAlign()
2156         but, but_ = but1c, but_1c+bm
2157         but_ /= 3
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')
2161         Draw.EndAlign()
2162
2163
2164         y -= 30
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
2168
2169         y -= 20
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
2173         Draw.BeginAlign()
2174
2175         #y -=20
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')           
2184         Draw.EndAlign()
2185
2186         y -= 20
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)")
2191
2192         y -= 20
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
2196         
2197         
2198         y -= 50
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")
2203
2204         Draw.BeginAlign()
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')
2207         Draw.EndAlign()
2208
2209         y -= 20
2210         #Draw.BeginAlign()
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)
2215         #Draw.EndAlign()
2216
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)
2219
2220
2221
2222
2223 #-- END GUI Stuf-----------------------------------------------------
2224
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]
2232 c7=[0.6,0.6,0.6,0]
2233 c8=[1.0,0.0,0.0,0]
2234 c9=[0.7,0.0,0.0,0]
2235 c10=[0.64,0.81,0.81,0]
2236 c11=[0.57,0.71,0.71,0]
2237 c_nor= c5[:3]
2238 c_act= c10[:3]
2239 c_sel= c11[:3]
2240 c_tx = c0[:3]
2241 c_fg = c2[:3]
2242 c_bg = c5[:3]
2243
2244 def ui_rect(coords,color):
2245         [X1,Y1,X2,Y2],[r,g,b] = coords,color
2246         glColor3f(r,g,b)
2247         glRecti(X1,Y1,X2,Y2)
2248 def ui_rectA(coords,color):
2249         [X1,Y1,X2,Y2],[r,g,b,a] = coords,color
2250         glColor4f(r,g,b,a)
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
2255         glColor3f(r,g,b)
2256         glBegin(GL_LINES)
2257         glVertex2i(X1,Y1)
2258         glVertex2i(X2,Y2)
2259         glEnd()
2260 def ui_panel(posX,posY,L,H,color):
2261         [r,g,b] = 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)
2274
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
2279         AreaH = P2X-P1X
2280         if PanelH > AreaH:
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)
2286
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
2291         AreaH = P2Y-P1Y
2292         if PanelH > AreaH:
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)
2299
2300
2301 #------------------------------------------------------------
2302 def dxf_callback(input_filename):
2303         global dxfFileName
2304         dxfFileName.val=input_filename
2305 #   dirname == Blender.sys.dirname(Blender.Get('filename'))
2306 #   update_RegistryKey('DirName', dirname)
2307 #   update_RegistryKey('dxfFileName', input_filename)
2308         
2309 def ini_callback(input_filename):
2310         global iniFileName
2311         iniFileName.val=input_filename
2312
2313 #------------------------------------------------------------
2314 def getSpaceRect():
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]))
2319
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])
2324         return None
2325
2326
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]:
2330                 return True
2331         else:
2332                 return False
2333
2334
2335
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
2355
2356 PAN_X,PAN_Y = 0,0 # pan coordinates in characters
2357 mPAN_X,mPAN_Y = 0,0 # manu pan coordinates in characters
2358 menu_orgX = 0
2359 menu_orgY = 0
2360 mPAN_Xmax = 800
2361 mPAN_Ymax = 800
2362
2363
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
2370
2371         #if Blender.event:
2372         #       print 'Blender.event:%s, evt:%s' %(Blender.event, evt) #------------
2373
2374         if evt in (Draw.QKEY, Draw.ESCKEY) and not val:
2375                 print 'DXF-Exporter  *** end ***'   #---------------------
2376                 Draw.Exit()
2377
2378         elif val:
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):
2385                                         menu_pan = True
2386                                         mPAN_X0 = mPAN_X
2387                                         mPAN_Y0 = mPAN_Y
2388                                         mco = mco2
2389                 elif evt == Draw.MOUSEY or evt == Draw.MOUSEX:
2390                         if menu_pan:
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 #--------------------
2397                                 Draw.Redraw()
2398                 elif evt == Draw.WHEELDOWNMOUSE:
2399                         mPAN_Y -= 80
2400                         Draw.Redraw()
2401                 elif evt == Draw.WHEELUPMOUSE:
2402                         mPAN_Y += 80
2403                         Draw.Redraw()
2404         else: # = if val==False:
2405                 if evt==Draw.LEFTMOUSE:
2406                         scroll_pan = False
2407                 elif evt==Draw.MIDDLEMOUSE:
2408                         menu_pan = False
2409
2410 def bevent(evt):
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
2414
2415         ######### Manages GUI events
2416         if (evt==EVENT_EXIT):
2417                 Draw.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):
2422                 Draw.Redraw()
2423         elif (evt==EVENT_RESET):
2424                 resetDefaultConfig()
2425                 Draw.Redraw()
2426         elif (evt==EVENT_PRESET2D):
2427                 resetDefaultConfig_2D()
2428                 Draw.Redraw()
2429         elif (evt==EVENT_PRESET3D):
2430                 resetDefaultConfig_3D()
2431                 Draw.Redraw()
2432         elif evt in (EVENT_CAMERA,EVENT_LIGHT):
2433                 CAMERA = GUI_A['camera_on'].val
2434                 if CAMERA==len(CAMERAS)+1:
2435                         doAllCameras = True
2436                 else:
2437                         print 'deb: CAMERAS=',CAMERAS #----------------
2438                 Draw.Redraw()
2439         elif (evt==EVENT_setCAMERA):
2440                 if CAMERA<len(CAMERAS)+1:
2441                         gotoCAMERA()
2442
2443         elif (evt==EVENT_SCALE):
2444                 if g_scale_as.val == 12:
2445                         inputGlobalScale()
2446                 if GUI_A['g_scale'].val < 0.00000001:
2447                         GUI_A['g_scale'].val = 0.00000001
2448                 Draw.Redraw()
2449         elif (evt==EVENT_ORIGIN):
2450                 inputOriginVector()
2451                 Draw.Redraw()
2452         elif (evt==EVENT_PRESETPLINE):
2453                 presetConfig_polyline(GUI_A['to_polyline_on'].val)
2454                 Draw.Redraw()
2455         elif (evt==EVENT_PRESETS):
2456                 user_preset += 1
2457                 index = str(user_preset)
2458                 if user_preset > 5: user_preset = 0; index = ''
2459                 iniFileName.val = INIFILE_DEFAULT_NAME + index + INIFILE_EXTENSION
2460                 Draw.Redraw()
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):
2465                         analyzeDXF(dxfFile)
2466                 else:
2467                         Draw.PupMenu('DXF-Exporter:  Alert!%t|no valid DXF-file selected!')
2468                         print "DXF-Exporter: error, no valid DXF-file selected! try again"
2469                 Draw.Redraw()
2470         elif (evt==EVENT_HELP):
2471                 try:
2472                         import webbrowser
2473                         webbrowser.open('http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf')
2474                 except:
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')
2477                 Draw.Redraw()
2478         elif (evt==EVENT_LOAD_INI):
2479                 loadConfig()
2480                 Draw.Redraw()
2481         elif (evt==EVENT_SAVE_INI):
2482                 saveConfig()
2483                 Draw.Redraw()
2484         elif (evt==EVENT_DXF_DIR):
2485                 dxfFile = dxfFileName.val
2486                 dxfPathName = ''
2487                 if '/' in dxfFile:
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
2496                 Draw.Redraw()
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)
2506                 update_globals()
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:
2509                                 global UI_MODE
2510                                 UI_MODE = False
2511                                 #multi_import(dxfFile[:-5])  # cut last 5 characters '*.dxf'
2512                                 Draw.Redraw()
2513                                 #Draw.Exit()
2514                         else:
2515                                 Draw.Redraw()
2516                 elif dxfFile.lower()[-4:] in ('.dxf','.dwg'): # and Blender.sys.exists(dxfFile):
2517                         print '\nStandard Mode: active'
2518                         filepath = dxfFile
2519                         sce = Scene.GetCurrent()
2520                         if ONLYSELECTED: sel_group = sce.objects.selected
2521                         else: sel_group = sce.objects
2522                         
2523                         export_list = getObjectsAndDuplis(sel_group,MATRICES=True)
2524                 
2525                         if export_list: do_export(export_list, filepath)
2526                         else:
2527                                 print "Abort: selection was empty, no object to export!"
2528                                 Draw.PupMenu('DXF Exporter:   nothing exported!|empty selection!')
2529                 else:
2530                         Draw.PupMenu('DXF-Exporter:  Alert!%t|no valid DXF-file selected!')
2531                         print "DXF-Exporter: error, no valid DXF-file selected! try again"
2532                         Draw.Redraw()
2533
2534
2535
2536
2537 def multi_import(DIR):
2538         """Imports all DXF-files from directory DIR.
2539         
2540         """
2541         global SCENE
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
2546         files = \
2547                 [Blender.sys.join(DIR, f) for f in os.listdir(DIR) if f.lower().endswith('.dxf')] 
2548         if not files:
2549                 print '...None DXF-files found. Abort!'
2550                 return
2551         
2552         i = 0
2553         for dxfFile in files:
2554                 i += 1
2555                 print '\nDXF-file', i, 'of', len(files) #,'\nImporting', dxfFile
2556                 if ONLYSELECTED:
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)
2561                         SCENE.makeCurrent()
2562                         #or so? Blender.Scene.makeCurrent(_dxf_file)
2563                         #sce = bpy.data.scenes.new(_dxf_file)
2564                         #bpy.data.scenes.active = sce
2565                 else:
2566                         SCENE = Blender.Scene.GetCurrent()
2567                         SCENE.objects.selected = [] # deselect all
2568                 main(dxfFile)
2569                 #Blender.Redraw()
2570
2571         print 'TOTAL TIME: %.6f' % (Blender.sys.time() - batchTIME)
2572         print '\a\r', # beep when done
2573
2574
2575 #-----------------------------------------------------
2576 if __name__=='__main__':
2577
2578         if not DXF.copy:
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
2585         else:
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
2591
2592         updateMenuCAMERA()
2593         updateCAMERA()
2594
2595         Draw.Register(draw_UI, event, bevent)
2596         
2597