DXF-Exporter script update
[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.07"
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 - stable support X,Y-rotated 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 - wip: corrected text-objects in persp-projection
42 - wip: fix filter out objects from inactive(off) layers
43
44 History
45 v1.34 - 2009.06.07 by migius
46 - cleaning code
47 - fix nasty bug in getExtrusion()
48 - support text-objects, also in ortho/persp-projection
49 - support XYmirrored 2d-curves to 2dPOLYLINEs
50 - support thickness and elevation for curve-objects
51 - fix extrusion 210-code (3d orientation vector)
52 - fix POLYFACE export, synchronized with dxfLibrary.py
53 - changed to the new 2.49 method Vector.cross()
54 - output style manager (first try)
55 v1.33 - 2009.05.25 by migius
56 - bugfix flipping normals in mirrored mesh-objects
57 - added UI-Button for future Shadow Generator
58 - support curve objects in projection-2d mode
59 - UI stuff: camera selector/manager
60 v1.32 - 2009.05.22 by migius
61 - debug mode for curve-objects: output pass to Blender
62 - wip support 210-code(extrusion) calculation
63 - default settings for 2D and 3D export
64 v1.31 - 2009.05.18 by migius
65 - globals translated to GUI_A/B dictionary
66 - optimizing back-faces removal for "hidden-lines" mode
67 - presets for global location and scale (architecture)
68 - UI layout: scrollbars, pan with MMB/WHEEL, dynamic width
69 - new GUI with Draw.Register() from DXF-importer.py
70 v1.30 - 2008.12.14 by migius
71 - started work on GUI with Draw.Register()
72 v1.29 - 2009.04.11 by stani
73 - added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter 
74 v1.28 - 2009.02.05 by Alexandros Sigalas (alxarch)
75 - added option to apply modifiers on exported meshes
76 - added option to also export duplicates (from dupliverts etc)
77 v1.28 - 2008.10.22 by migius
78 - workaround for PVert-bug on ubuntu (reported by Yorik)
79 - add support for FGons - ignore invisible_tagged edges
80 - add support for camera: ortho and perspective
81 v1.27 - 2008.10.07 by migius
82 - exclude Stani's DXF-Library to extern module
83 v1.26 - 2008.10.05 by migius
84 - add "hidden mode" substitut: back-faces removal
85 - add support for mesh ->POLYFACE
86 - optimized code for "Flat" procedure
87 v1.25 - 2008.09.28 by migius
88 - modif FACE class for r12
89 - add mesh-polygon -> Bezier-curve converter (Yorik's code)
90 - add support for curves ->POLYLINEs
91 - add "3d-View to Flat" - geometry projection to XY-plane
92 v1.24 - 2008.09.27 by migius
93 - add start UI with preferences
94 - modif POLYLINE class for r12
95 - changing output format from r9 to r12(AC1009)
96 v1.23 - 2008.09.26 by migius
97 - add finish message-box
98 v1.22 - 2008.09.26 by migius
99 - add support for curves ->LINEs
100 - add support for mesh-edges ->LINEs
101 v1.21 - 2008.06.04 by migius
102 - initial adaptation for Blender
103 v1.1 (20/6/2005) by Stani Michiels www.stani.be/python/sdxf
104 - Python library to generate dxf drawings
105 ______________________________________________________________
106 """ % (__author__,__version__,__license__,__url__)
107
108 # --------------------------------------------------------------------------
109 # Script copyright (C) 2008 Remigiusz Fiedler (AKA migius)
110 # --------------------------------------------------------------------------
111 # ***** BEGIN GPL LICENSE BLOCK *****
112 #
113 # This program is free software; you can redistribute it and/or
114 # modify it under the terms of the GNU General Public License
115 # as published by the Free Software Foundation; either version 2
116 # of the License, or (at your option) any later version.
117 #
118 # This program is distributed in the hope that it will be useful,
119 # but WITHOUT ANY WARRANTY; without even the implied warranty of
120 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
121 # GNU General Public License for more details.
122 #
123 # You should have received a copy of the GNU General Public License
124 # along with this program; if not, write to the Free Software Foundation,
125 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
126 #
127 # ***** END GPL LICENCE BLOCK *****
128
129
130 import Blender
131 from Blender import Mathutils, Window, Scene, Draw, Camera, BezTriple
132 from Blender import Registry, Object, Mesh, Curve
133 import os
134 import subprocess
135
136 import dxfLibrary as DXF
137 #reload(DXF)
138 #reload(dxfLibrary)
139 #from dxfLibrary import *
140
141 import math
142 from math import atan, atan2, log10, sin, cos
143
144 #pi = math.pi
145 #pi = 3.14159265359
146 r2d = 180.0 / math.pi
147 d2r = math.pi / 180.0
148 #note: d2r * angle == math.radians(angle)
149
150 print '\n\n\n'
151 print 'DXF-Exporter v%s *** start ***' %(__version__)   #---------------------
152
153 #DEBUG = True #activets debug mode
154
155
156 #----globals------------------------------------------
157 ONLYSELECTED = 1 # 0/1 = False/True
158 POLYLINES = 1 # prefer POLYLINEs not LINEs
159 POLYFACES = 1 # prefer POLYFACEs not 3DFACEs
160 PROJECTION = 0 # flatten output geometry to Z = 0.0
161 HIDDEN_LINES = 0 #filter out hidden geometry
162 SHADOWS = 0 # sun/shadows simulation
163 CAMERA = 1 # view from active camera or from 3d-view
164 PERSPECTIVE = 0 #perspective camera
165 APPLY_MODIFIERS = 1
166 INCLUDE_DUPLIS = 0
167 OUTPUT_DWG = 0 #optional save to DWG with extern converter
168
169 G_SCALE = 1.0     #(0.0001-1000) global scaling factor for output dxf data
170 G_ORIGIN = [0.0,0.0,0.0]   #global translation-vector (x,y,z) in Blender units
171 ELEVATION = 0.0 #standard elevation = coordinate Z value in Blender units
172
173 MIN_DIST = 0.001        #cut-off value for sort out short-distance polyline-"duoble_vertex"
174 CURV_RESOLUTION = 12 #(1-128) Bezier curves U-resolution
175 CURVARC_RESOLUTION = 4 #(3-32) resolution of circle represented as Bezier curve 
176 THIN_RESOLUTION = 8   #(4-64) thin_cylinder arc_resolution - number of segments
177 MIN_THICK = MIN_DIST * 10.0  #minimal thickness by forced thickness
178 MIN_WIDTH = MIN_DIST * 10.0  #minimal width by forced width
179
180 BYBLOCK = 0 #DXF-attribute: assign property to BLOCK defaults
181 BYLAYER = None #256 #DXF-attribute: assign property to LAYER defaults
182 PREFIX = 'BF_' #used as prefix for DXF names
183 LAYERNAME_DEF = '' #default layer name
184 LAYERCOLOR_DEF = 7 #default layer color index
185 LAYERLTYPE_DEF = 0 #'CONTINUOUS' - default layer lineType
186 ENTITYLAYER_DEF = LAYERNAME_DEF #default entity color index
187 ENTITYCOLOR_DEF = BYLAYER #default entity color index
188 ENTITYLTYPE_DEF = BYLAYER #default entity lineType
189 E_M = 0
190 LAB = "scroll MMB/WHEEL           . wip   .. todo" #"*) parts under construction"
191 M_OBJ = 0
192
193 FILENAME_MAX = 180  #max length of path+file_name string  (FILE_MAXDIR + FILE_MAXFILE)
194 NAMELENGTH_MAX = 80   #max_obnamelength in DXF, (limited to 256? )
195 INIFILE_DEFAULT_NAME = 'exportDXF'
196 INIFILE_EXTENSION = '.ini'
197 INIFILE_HEADER = '#ExportDXF.py ver.1.0 config data'
198 INFFILE_HEADER = '#ExportDXF.py ver.1.0 analyze of DXF-data'
199
200 SCENE = None
201 WORLDX = Mathutils.Vector((1,0,0))
202 WORLDY = Mathutils.Vector((0,1,0))
203 WORLDZ = Mathutils.Vector((0,0,1))
204
205 AUTO = BezTriple.HandleTypes.AUTO
206 FREE = BezTriple.HandleTypes.FREE
207 VECT = BezTriple.HandleTypes.VECT
208 ALIGN = BezTriple.HandleTypes.ALIGN
209
210
211 #-------- DWG support ------------------------------------------
212 extCONV_OK = True
213 extCONV = 'DConvertCon.exe'
214 extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV)
215 if not os.path.isfile(extCONV_PATH):
216         extCONV_OK = False
217         extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\
218 Copy first %s into Blender script directory.|\
219 More details in online Help.' %extCONV
220 else:
221         if not os.sys.platform.startswith('win'):
222                 # check if Wine installed:   
223                 if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip():
224                         extCONV_PATH    = 'wine %s'%extCONV_PATH
225                 else: 
226                         extCONV_OK = False
227                         extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\
228 The external DWG-converter (%s) needs Wine installed on your system.|\
229 More details in online Help.' %extCONV
230 #print 'extCONV_PATH = ', extCONV_PATH
231
232
233 #----------------------------------------------
234 def updateMenuCAMERA():
235         global CAMERAS
236         global MenuCAMERA
237         global MenuLIGHT
238
239         scn = Scene.GetCurrent()
240         objs = scn.getChildren()
241         currcam = scn.getCurrentCamera()
242         if currcam: currcam = currcam.getName()
243         maincams = []
244         MenuCAMERA = "Select Camera%t"
245         for cam in objs:
246                 if cam.getType() == 'Camera':
247                         if cam.getName()[0:4] != "Temp":
248                                 maincams.append(cam.getName())
249         maincams.sort()
250         maincams.reverse() 
251         CAMERAS = maincams
252         for i, cam in enumerate(CAMERAS):
253                 if cam==currcam:
254                         MenuCAMERA += "|* " + cam
255                 else: MenuCAMERA += "| " + cam
256         MenuCAMERA += "|current 3d-View"                        
257         MenuLIGHT = "Select Sun%t| *todo"                       
258
259
260 #----------------------------------------------
261 def updateCAMERA():
262         global CAMERA, GUI_A
263         #CAMERA = 1
264         scn = Scene.GetCurrent()
265         currcam = scn.getCurrentCamera()
266         if currcam: currcam = currcam.getName()
267         if currcam in CAMERAS:
268                 CAMERA = CAMERAS.index(currcam)+1
269         GUI_A['camera_on'].val = CAMERA
270
271 #----------------------------------------------
272 def gotoCAMERA():
273         cam =   Object.Get(CAMERAS[CAMERA-1])
274         #print 'deb: CAMERA, cam',CAMERA, cam
275         if cam.getType() != 'Camera':
276                 sure = Draw.PupMenu("Info: %t| It is not a Camera Object.")
277         else:
278                 scn = Scene.getCurrent()   
279                 scn.setCurrentCamera(cam)
280                 Window.CameraView(0)
281                 Window.Redraw()
282                 updateMenuCAMERA()
283
284
285 #------- Duplicates support ----------------------------------------------
286 def dupTest(object):
287         """
288         Checks objects for duplicates enabled (any type)
289         object: Blender Object.
290         Returns: Boolean - True if object has any kind of duplicates enabled.
291         """
292         if (object.enableDupFrames or \
293                 object.enableDupGroup or \
294                 object.enableDupVerts):
295                 return True
296         else:
297                 return False
298
299 def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False):
300         """
301         Return a list of real objects and duplicates and optionally their matrices
302         oblist: List of Blender Objects
303         MATRICES: Boolean - Check to also get the objects matrices, default=False
304         HACK: Boolean - See note, default=False
305         Returns: List of objects or
306                          List of tuples of the form:(ob,matrix) if MATRICES is set to True
307         NOTE: There is an ugly hack here that excludes all objects whose name
308         starts with "dpl_" to exclude objects that are parented to a duplicating
309         object, User must name objects properly if hack is used.
310         """
311
312         result = []
313         for ob in oblist:
314                 if INCLUDE_DUPLIS and dupTest(ob):
315                         dup_obs=ob.DupObjects
316                         if len(dup_obs):
317                                 for dup_ob, dup_mx in dup_obs:
318                                         if MATRICES:
319                                                 result.append((dup_ob,dup_mx))
320                                         else:
321                                                 result.append(dup_ob)
322                 else:
323                         if HACK:
324                                 if ob.getName()[0:4] != "dpl_":
325                                         if MATRICES:
326                                                 mx = ob.mat
327                                                 result.append((ob,mx))
328                                         else:
329                                                 result.append(ob)
330                         else:
331                                 if MATRICES:
332                                         mx = ob.mat
333                                         result.append((ob,mx))
334                                 else:
335                                         result.append(ob)
336         return result
337
338 #-----------------------------------------------------
339 def hidden_status(faces, mx, mx_n):
340         # sort out back-faces = with normals pointed away from camera
341         #print 'HIDDEN_LINES: caution! not full implemented yet'
342         front_faces = []
343         front_edges = []
344         for f in faces:
345                 #print 'deb: face=', f #---------
346                 #print 'deb: dir(face)=', dir(f) #---------
347                 # get its normal-vector in localCS
348                 vec_normal = f.no.copy()
349                 #print 'deb: vec_normal=', vec_normal #------------------
350                 # must be transfered to camera/view-CS
351                 vec_normal *= mx_n
352                 #vec_normal *= mb.rotationPart()
353                 #print 'deb:2vec_normal=', vec_normal #------------------
354                 #vec_normal *= mw0.rotationPart()
355                 #print 'deb:3vec_normal=', vec_normal, '\n' #------------------
356
357                 
358                 frontFace = False
359                 if not PERSPECTIVE: #for ortho mode ----------
360                         # normal must point the Z direction-hemisphere
361                         if vec_normal[2] > 0.00001:
362                                 frontFace = True
363                 else:
364                         v = f.verts[0]
365                         vert = Mathutils.Vector(v.co) * mx
366                         if Mathutils.DotVecs(vert, vec_normal) < 0.00001:
367                                 frontFace = True
368
369                 if frontFace:
370                         front_faces.append(f.index)
371                         for key in f.edge_keys:
372                                 #this test can be done faster with set()
373                                 if key not in front_edges:
374                                          front_edges.append(key)
375
376         #print 'deb: amount of visible faces=', len(front_faces) #---------
377         #print 'deb: visible faces=', front_faces #---------
378         #print 'deb: amount of visible edges=', len(front_edges) #---------
379         #print 'deb: visible edges=', front_edges #---------
380         return front_faces, front_edges
381
382
383 #---- migration to 2.49-------------------------------------------------
384 if 'cross' in dir(Mathutils.Vector()):
385         #Draw.PupMenu('DXF exporter: Abort%t|This script version works for Blender up 2.49 only!')
386         def     M_CrossVecs(v1,v2):
387                 return v1.cross(v2) #for up2.49
388         def M_DotVecs(v1,v2):
389                 return v1.dot(v2) #for up2.49
390 else:
391         def     M_CrossVecs(v1,v2):
392                 return Mathutils.CrossVecs(v1,v2) #for pre2.49
393         def M_DotVecs(v1,v2):
394                 return Mathutils.DotVecs(v1,v2) #for pre2.49
395         
396
397 #-----------------------------------------------------
398 def     getExtrusion(matrix):
399         """calculates DXF-Extrusion = Arbitrary Xaxis and Zaxis vectors
400                 
401         """
402         AZaxis = matrix[2].copy().resize3D().normalize() # = ArbitraryZvector
403         Extrusion = [AZaxis[0],AZaxis[1],AZaxis[2]]
404         if AZaxis[2]==1.0:
405                 Extrusion = None
406                 AXaxis = matrix[0].copy().resize3D() # = ArbitraryXvector
407         else:
408                 threshold = 1.0 / 64.0
409                 if abs(AZaxis[0]) < threshold and abs(AZaxis[1]) < threshold:
410                         # AXaxis is the intersection WorldPlane and ExtrusionPlane
411                         AXaxis = M_CrossVecs(WORLDY,AZaxis)
412                 else:
413                         AXaxis = M_CrossVecs(WORLDZ,AZaxis)
414         #print 'deb:\n' #-------------
415         #print 'deb:getExtrusion()  Extrusion=', Extrusion #---------
416         return Extrusion, AXaxis.normalize()
417
418
419 #-----------------------------------------------------
420 def     getZRotation(AXaxis, rot_matrix_invert):
421         """calculates ZRotation = angle between ArbitraryXvector and obj.matrix.Xaxis
422                 
423         """
424         # this works: Xaxis is the obj.matrix-Xaxis vector
425         # but not correct for all orientations
426         #Xaxis = matrix[0].copy().resize3D() # = ArbitraryXvector
427         ##Xaxis.normalize() # = ArbitraryXvector
428         #ZRotation = - Mathutils.AngleBetweenVecs(Xaxis,AXaxis) #output in radians
429
430         # this works for all orientations, maybe a bit faster
431         # transform AXaxis into OCS:Object-Coord-System 
432         #rot_matrix = normalizeMat(matrix.rotationPart())
433         #rot_matrix_invert = rot_matrix.invert()
434         vec = AXaxis * rot_matrix_invert
435         ##vec = AXaxis * matrix.copy().invert()
436         ##vec.normalize() # not needed for atan2()
437         #print '\ndeb:getExtrusion()  vec=', vec #---------
438         ZRotation = - atan2(vec[1],vec[0]) #output in radians
439
440         #print 'deb:ZRotation()  ZRotation=', ZRotation*r2d #---------
441         return ZRotation
442
443
444 #------------------------------------------
445 def normalizeMat(matrix):
446         mat12 = matrix.copy()
447         mat12 = [Mathutils.Vector(v).normalize() for v in mat12]
448         if len(mat12)>3:
449                 matr12 = Mathutils.Matrix(mat12[0],mat12[1],mat12[2],mat12[3])
450         else:
451                 matr12 = Mathutils.Matrix(mat12[0],mat12[1],mat12[2])
452         return matr12
453
454
455 #-----------------------------------------------------
456 def projected_co(verts, matrix):
457         """ converts coordinates of points from OCS to WCS->ScreenCS
458         needs matrix: a projection matrix
459         needs verts: a list of vectors[x,y,z]
460         returns a list of [x,y,z]
461         """
462         #print 'deb:projected_co()  verts=', verts #---------
463         temp_verts = [Mathutils.Vector(v)*matrix for v in verts]
464         #print 'deb:projected_co()  temp_verts=', temp_verts #---------
465
466         if GUI_A['Z_force_on'].val: locZ = GUI_A['Z_elev'].val
467         else: locZ = 0.0
468
469         if PROJECTION:
470                 if PERSPECTIVE:
471                         clipStart = 10.0
472                         for v in temp_verts:
473                                 coef = - clipStart / v[2]
474                                 v[0] *= coef
475                                 v[1] *= coef
476                                 v[2] = locZ
477                 for v in temp_verts:
478                         v[2] = locZ
479         temp_verts = [v[:3] for v in temp_verts]
480         #print 'deb:projected_co()  out_verts=', temp_verts #---------
481         return temp_verts
482
483
484 #-----------------------------------------------------
485 def isLeftHand(matrix):
486         #Is the matrix a left-hand-system, or not?
487         ma = matrix.rotationPart()
488         crossXY = M_CrossVecs(ma[0], ma[1])
489         check = M_DotVecs(ma[2], crossXY)
490         if check < 0.00001: return 1
491         return 0
492
493
494 #-----------------------------------------------------
495 def     exportMesh(ob, mx, mx_n, me=None, **common):
496         """converts Mesh-Object to desired projection and representation(DXF-Entity type)
497         """
498         entities = []
499         #print 'deb:exportMesh() common=', common #---------
500         if me==None:
501                 me = ob.getData(mesh=1)
502         else:
503                 me.getFromObject(ob)
504         # me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state
505         # above is eventualy faster, but bad, cause
506         # invasive: directly transforms origin geometry and write back rounding errors
507         #we dont want to manipulate origin data
508         #temp_verts = me.verts[:] #doesn't work on ubuntu(Yorik), bug?
509         if me.verts:
510                 #print 'deb:exportMesh() started' #---------
511                 allpoints = [v.co for v in me.verts]
512                 allpoints = projected_co(allpoints, mx)
513                 if GUI_A['g_origin_on'].val:
514                         for p in allpoints:
515                                 p[0] += G_ORIGIN[0]
516                                 p[1] += G_ORIGIN[1]
517                                 p[2] += G_ORIGIN[2]
518                 faces=[]
519                 edges=[]
520                 if me.faces and PROJECTION and HIDDEN_LINES:
521                         if DEBUG: print 'deb:exportMesh HIDDEN_LINES mode' #---------
522                         faces, edges = hidden_status(me.faces, mx, mx_n)
523                         faces = [[v.index for v in me.faces[f_nr].verts] for f_nr in faces]
524                 else:
525                         if DEBUG: print 'deb:exportMesh STANDARD mode' #---------
526                         for e in me.edges: edges.append(e.key)
527                         #faces = [f.index for f in me.faces]
528                         faces = [[v.index for v in f.verts] for f in me.faces]
529                         #faces = [[allpoints[v.index] for v in f.verts] for f in me.faces]
530                 #print 'deb: allpoints=\n', allpoints #---------
531                 #print 'deb: edges=\n', edges #---------
532                 #print 'deb: faces=\n', faces #---------
533                 if isLeftHand(mx): # then change vertex-order in every face
534                         for f in faces:
535                                 f.reverse()
536                                 #f = [f[-1]] + f[:-1] #TODO: might be needed
537                 #print 'deb: faces=\n', faces #---------
538
539                 c = mesh_as_list[GUI_A['mesh_as'].val]
540                 if 'POINTs'==c: # export Mesh as multiple POINTs
541                         for p in allpoints:
542                                 dxfPOINT = DXF.Point(points=[p],**common)
543                                 entities.append(dxfPOINT)
544                 elif 'LINEs'==c or (not faces):
545                         if edges and allpoints:
546                                 if DEBUG: mesh_drawBlender(allpoints, edges, None) #deb: draw to blender scene
547                                 for e in edges:
548                                         points = [allpoints[e[0]], allpoints[e[1]]]
549                                         dxfLINE = DXF.Line(points, **common)
550                                         entities.append(dxfLINE)
551                 elif faces:
552                         if c in ('POLYFACE','POLYLINE'):
553                                 if allpoints:
554                                         #TODO: purge allpoints: left only vertices used by faces
555                                         if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene
556 #                                       faces = [[v+1 for v in f] for f in faces]
557
558                                         verts_state= [0]*len(allpoints)
559                                         for f in faces:
560                                                 for v in f:
561                                                         verts_state[v]=1
562                                         if 0: # in verts_state: # if dirty state
563                                                 i,new_position,newverts=0,[],[]
564                                                 for used_i,used in enumerate(verts_state):
565                                                         if used:
566                                                                 newverts.append(allpoints[used_i])      
567                                                                 new_position.append(i)
568                                                                 i+=1
569                                                 allpoints = newverts
570                                                 faces = [[new_position[v]+1 for v in f] for f in faces]
571                                         else:
572                                                 faces = [[v+1 for v in f] for f in faces]
573                                         dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag=64, **common)
574                                         #print '\n deb: dxfPOLYFACE=',dxfPOLYFACE #-------------
575                                         entities.append(dxfPOLYFACE)
576                         elif '3DFACEs'==c:
577                                 if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene
578                                 for f in faces:
579                                         #print 'deb: face=', f #---------
580                                         points = [allpoints[key] for key in f]
581                                         #points = [p.co[:3] for p in points]
582                                         #print 'deb: pointsXX=\n', points #---------
583                                         dxfFACE = DXF.Face(points, **common)
584                                         entities.append(dxfFACE)
585                                         
586         return entities
587
588 #-----------------------------------------------------
589 def mesh_drawBlender(vertList, edgeList, faceList, name="dxfMesh", flatten=False, AT_CUR=True, link=True):
590         #print 'deb:mesh_drawBlender started XXXXXXXXXXXXXXXXXX' #---------
591         ob = Object.New("Mesh",name)
592         me = Mesh.New(name)
593         #print 'deb: vertList=\n', vertList #---------
594         #print 'deb: edgeList=\n', edgeList #---------
595         #print 'deb: faceList=\n', faceList #---------
596         me.verts.extend(vertList)
597         if edgeList: me.edges.extend(edgeList)
598         if faceList: me.faces.extend(faceList)
599         if flatten:
600                 for v in me.verts: v.co.z = 0.0
601         ob.link(me)
602         if link:
603                 sce = Scene.getCurrent()
604                 sce.objects.link(ob)
605                 #me.triangleToQuad()
606                 if AT_CUR:
607                         cur_loc = Window.GetCursorPos()
608                         ob.setLocation(cur_loc)
609                 Blender.Redraw()
610         #return ob
611
612 #-----------------------------------------------------
613 def curve_drawBlender(vertList, org_point=[0.0,0.0,0.0], closed=0, name="dxfCurve", flatten=False, AT_CUR=True, link=True):
614         #print 'deb:curve_drawBlender started XXXXXXXXXXXXXXXXXX' #---------
615         ob = Object.New("Curve",name)
616         cu = Curve.New(name)
617         #print 'deb: vertList=\n', vertList #---------
618         curve = cu.appendNurb(BezTriple.New(vertList[0]))
619         for p in vertList[1:]:
620                 curve.append(BezTriple.New(p))
621         for point in curve:
622                 #point.handleTypes = [VECT, VECT]
623                 point.handleTypes = [FREE, FREE]
624                 point.radius = 1.0
625         curve.flagU = closed # 0 sets the curve not cyclic=open
626         cu.setResolu(6)
627         cu.update() #important for handles calculation
628         if flatten:
629                 for v in cu.verts: v.co.z = 0.0
630         ob.link(cu)
631         if link:
632                 sce = Scene.getCurrent()
633                 sce.objects.link(ob)
634                 #me.triangleToQuad()
635                 if AT_CUR:
636                         cur_loc = Window.GetCursorPos()
637                         ob.setLocation(cur_loc)
638                 elif org_point:
639                         cur_loc=org_point
640                         ob.setLocation(cur_loc)
641                 Blender.Redraw()
642         #return ob
643
644
645 #-----------------------------------------------------
646 def exportEmpty(ob, mx, mw, **common):
647         """converts Empty-Object to desired projection and representation(DXF-Entity type)
648         """
649         p =  Mathutils.Vector(ob.loc)
650         #print 'deb: is it a vector?:', p #---------------
651         [p] = projected_co([p], mx)
652         if GUI_A['g_origin_on'].val: #TODO: scale and object orientation
653                 p[0] += G_ORIGIN[0]
654                 p[1] += G_ORIGIN[1]
655                 p[2] += G_ORIGIN[2]
656
657         entities = []
658         c = empty_as_list[GUI_A['empty_as'].val]
659         if c=="POINT": # export Empty as POINT
660                 dxfPOINT = DXF.Point(points=[p],**common)
661                 entities.append(dxfPOINT)
662         return entities
663
664 #-----------------------------------------------------
665 def exportText(ob, mx, mw, **common):
666         """converts Text-Object to desired projection and representation(DXF-Entity type)
667         """
668         text3d = ob.getData()
669         textstr = text3d.getText()
670         WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
671         sizeX = ob.SizeX
672         sizeY = ob.SizeY
673         sizeZ = ob.SizeZ
674         rotX  = ob.RotX
675         rotY  = ob.RotY
676         rotZ  = ob.RotZ
677         #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
678
679         Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
680
681         AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
682         if not PROJECTION:
683                 #Extrusion, ZRotation, Elevation = getExtrusion(mx)
684                 Extrusion, AXaxis = getExtrusion(mx)
685
686                 # no thickness/width for TEXTs converted into ScreenCS
687                 if text3d.getExtrudeDepth():
688                         Thickness = text3d.getExtrudeDepth() * sizeZ
689
690         #Horizontal text justification type, code 72, (optional, default = 0)
691         # integer codes (not bit-coded)
692         #0=left, 1=center, 2=right
693         #3=aligned, 4=middle, 5=fit
694         Alignment = None
695         alignment = text3d.getAlignment().value
696         if alignment in (1,2): Alignment = alignment
697
698         textHeight = text3d.getSize() / 1.7
699         textFlag = 0
700         if sizeX < 0.0: textFlag |= 2 # set flag for horizontal mirrored
701         if sizeZ < 0.0: textFlag |= 4 # vertical mirrored
702
703         entities = []
704         c = text_as_list[GUI_A['text_as'].val]
705
706         if c=="TEXT": # export text as TEXT
707                 if not PROJECTION:
708                         ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
709                                 AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
710                         ZRotation *= r2d
711                         point = ECS_origin
712                 else:   #TODO: fails correct location
713                         point1 = Mathutils.Vector(ob.loc)
714                         [point] = projected_co([point1], mx)
715                         if PERSPECTIVE:
716                                 clipStart = 10.0
717                                 coef = -clipStart / (point1*mx)[2]
718                                 textHeight *= coef
719                                 #print 'deb: coef=', coef #--------------
720         
721                 #print 'deb: point=', point #--------------
722                 if GUI_A['g_origin_on'].val: #TODO: scale and object orientation
723                         point[0] += G_ORIGIN[0]
724                         point[1] += G_ORIGIN[1]
725                         point[2] += G_ORIGIN[2]
726                 point2 = point
727
728                 if 0: pass #DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene
729                 common['extrusion']= Extrusion
730                 #common['elevation']= Elevation
731                 common['thickness']= Thickness
732                 #print 'deb: common=', common #------------------
733                 if 0: #DEBUG
734                         #linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]]
735                         linepoints = [[0,0,0], point]
736                         dxfLINE = DXF.Line(linepoints,**common)
737                         entities.append(dxfLINE)
738
739                 dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\
740                         flag=textFlag,height=textHeight,justifyhor=Alignment,**common)
741                 entities.append(dxfTEXT)
742                 if Thickness:
743                         common['thickness']= -Thickness
744                         dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\
745                                 flag=textFlag,height=textHeight,justifyhor=Alignment,**common)
746                         entities.append(dxfTEXT)
747         return entities
748
749
750 #-------------------------------------------
751 def euler2matrix(rx, ry, rz):
752         """creates full 3D rotation matrix (optimized)
753         needs rx, ry, rz angles in radians
754         """
755         #print 'rx, ry, rz: ', rx, ry, rz
756         A, B = sin(rx), cos(rx)
757         C, D = sin(ry), cos(ry)
758         E, F = sin(rz), cos(rz)
759         AC, BC = A*C, B*C
760         return Mathutils.Matrix([D*F,  D*E, -C],
761                 [AC*F-B*E, AC*E+B*F, A*D],
762                 [BC*F+A*E, BC*E-A*F, B*D])
763                 
764         
765 #-----------------------------------------------------
766 def getTargetOrientation(mx,Extrusion,AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ):
767         """given 
768         """
769         if 1:
770                 rot_matrix = normalizeMat(mx.rotationPart())
771                 #TODO: workaround for blender negative-matrix.invert()
772                 # partially done: works only for rotX,rotY==0.0
773                 if sizeX<0.0: rot_matrix[0] *= -1
774                 if sizeY<0.0: rot_matrix[1] *= -1
775                 #if sizeZ<0.0: rot_matrix[2] *= -1
776                 rot_matrix_invert = rot_matrix.invert()
777         else: #TODO: to check, why below rot_matrix_invert is not equal above one
778                 rot_euler_matrix = euler2matrix(rotX,rotY,rotZ)
779                 rot_matrix_invert = euler2matrix(-rotX,-rotY,-rotZ)
780         
781         # OCS_origin is Global_Origin in ObjectCoordSystem
782         OCS_origin = Mathutils.Vector(WCS_loc) * rot_matrix_invert
783         #print 'deb: OCS_origin=', OCS_origin #---------
784
785         ZRotation = rotZ
786         if Extrusion!=None:
787                 ZRotation = getZRotation(AXaxis,rot_matrix_invert)
788         #Zrotmatrix = Mathutils.RotationMatrix(-ZRotation, 3, "Z")
789         rs, rc = sin(ZRotation), cos(ZRotation)
790         Zrotmatrix = Mathutils.Matrix([rc, rs,0.0],[-rs,rc,0.0],[0.0,0.0,1.0])
791         #print 'deb: Zrotmatrix=\n', Zrotmatrix #--------------
792
793         # ECS_origin is Global_Origin in EntityCoordSystem
794         ECS_origin = OCS_origin * Zrotmatrix
795         #print 'deb: ECS_origin=', ECS_origin #---------
796         #TODO: it doesnt work yet for negative scaled curve-objects!
797         return ZRotation,Zrotmatrix,OCS_origin,ECS_origin
798
799
800 #-----------------------------------------------------
801 def exportCurve(ob, mx, mw, **common):
802         """converts Curve-Object to desired projection and representation(DXF-Entity type)
803         """
804         entities = []
805         curve = ob.getData()
806         WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
807         #WCS_loc = [0.0,0.0,0.0]
808         #print 'deb: WCS_loc=', WCS_loc #---------
809         sizeX = ob.SizeX
810         sizeY = ob.SizeY
811         sizeZ = ob.SizeZ
812         rotX  = ob.RotX
813         rotY  = ob.RotY
814         rotZ  = ob.RotZ
815         #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
816
817         Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
818         AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
819         OCS_origin = [0,0,0]
820         if not PROJECTION:
821                 #Extrusion, ZRotation, Elevation = getExtrusion(mx)
822                 Extrusion, AXaxis = getExtrusion(mx)
823
824                 # no thickness/width for POLYLINEs converted into ScreenCS
825                 #print 'deb: curve.ext1=', curve.ext1 #---------
826                 if curve.ext1: Thickness = curve.ext1 * sizeZ
827                 if curve.ext2 and sizeX==sizeY:
828                         Width = curve.ext2 * sizeX
829                 if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE
830                         ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
831                                 AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
832         
833         for cur in curve:
834                 #print 'deb: START cur=', cur #--------------
835                 points = []
836                 if cur.isNurb():
837                         for point in cur:
838                                 #print 'deb:isNurb point=', point #---------
839                                 vec = point[0:3]
840                                 #print 'deb: vec=', vec #---------
841                                 pkt = Mathutils.Vector(vec)
842                                 #print 'deb: pkt=', pkt #---------
843                                 points.append(pkt)
844                 else:
845                         for point in cur:
846                                 #print 'deb:isBezier point=', point.getTriple() #---------
847                                 vec = point.getTriple()[1]
848                                 #print 'deb: vec=', vec #---------
849                                 pkt = Mathutils.Vector(vec)
850                                 #print 'deb: pkt=', pkt #---------
851                                 points.append(pkt)
852
853                 #print 'deb: points', points #--------------
854                 if len(points)>1:
855                         c = curve_as_list[GUI_A['curve_as'].val]
856
857                         if c=="POLYLINE": # export Curve as POLYLINE
858                                 if not PROJECTION:
859                                         # recalculate points(2d=X,Y) into Entity-Coords-System
860                                         for p in points: # list of vectors
861                                                 p[0] *= sizeX
862                                                 p[1] *= sizeY
863                                                 p2 = p * Zrotmatrix
864                                                 p2[0] += ECS_origin[0]
865                                                 p2[1] += ECS_origin[1]
866                                                 p[0],p[1] = p2[0],p2[1]
867                                 else:
868                                         points = projected_co(points, mx)
869                                 #print 'deb: points', points #--------------
870
871                                 if cur.isCyclic(): closed = 1
872                                 else: closed = 0
873                                 if GUI_A['g_origin_on'].val: #TODO: scale and object orientation
874                                         for p in points:
875                                                 p[0] += G_ORIGIN[0]
876                                                 p[1] += G_ORIGIN[1]
877                                                 p[2] += G_ORIGIN[2]
878                                 if DEBUG: curve_drawBlender(points,OCS_origin,closed) #deb: draw to scene
879                                 common['extrusion']= Extrusion
880                                 ##common['rotation']= ZRotation
881                                 ##common['elevation']= Elevation
882                                 common['thickness']= Thickness
883                                 #print 'deb: common=', common #------------------
884
885                                 if 0: #DEBUG
886                                         p=AXaxis[:3]
887                                         entities.append(DXF.Line([[0,0,0], p],**common))
888                                         p=ECS_origin[:3]
889                                         entities.append(DXF.Line([[0,0,0], p],**common))
890                                         common['color']= 5
891                                         p=OCS_origin[:3]
892                                         entities.append(DXF.Line([[0,0,0], p],**common))
893                                         #OCS_origin=[0,0,0] #only debug----------------
894                                         dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common)
895                                         entities.append(dxfPLINE)
896
897                                 dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common)
898                                 entities.append(dxfPLINE)
899                                 if Thickness:
900                                         common['thickness']= -Thickness
901                                         dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common)
902                                         entities.append(dxfPLINE)
903
904                         elif c=="LINEs": # export Curve as multiple LINEs
905                                 points = projected_co(points, mx)
906                                 if cur.isCyclic(): points.append(points[0])
907                                 #print 'deb: points', points #--------------
908                                 if GUI_A['g_origin_on'].val: #TODO: scale and object orientation
909                                         for p in points:
910                                                 p[0] += G_ORIGIN[0]
911                                                 p[1] += G_ORIGIN[1]
912                                                 p[2] += G_ORIGIN[2]
913                                 if DEBUG: curve_drawBlender(points,WCS_loc,closed) #deb: draw to scene
914                                 common['extrusion']= Extrusion
915                                 common['elevation']= Elevation
916                                 common['thickness']= Thickness
917                                 #print 'deb: common=', common #------------------
918                                 for i in range(len(points)-1):
919                                         linepoints = [points[i], points[i+1]]
920                                         dxfLINE = DXF.Line(linepoints,**common)
921                                         entities.append(dxfLINE)
922                                 if Thickness:
923                                         common['thickness']= -Thickness
924                                         for i in range(len(points)-1):
925                                                 linepoints = [points[i], points[i+1]]
926                                                 dxfLINE = DXF.Line(linepoints,**common)
927                                                 entities.append(dxfLINE)
928
929                         elif c=="POINTs": # export Curve as multiple POINTs
930                                 points = projected_co(points, mx)
931                                 for p in points:
932                                         dxfPOINT = DXF.Point(points=[p],**common)
933                                         entities.append(dxfPOINT)
934
935         return entities
936
937 #-----------------------------------------------------
938 def getClipBox(camera):
939         """calculates Field-of-View-Clipping-Box of given Camera
940         returns clip_box: a list of vertices
941         returns matr: translation matrix
942         """
943         sce = Scene.GetCurrent()
944         context = sce.getRenderingContext()
945         #print 'deb: context=\n', context #------------------
946         sizeX = context.sizeX
947         sizeY = context.sizeY
948         ratioXY = sizeX/float(sizeY)
949         #print 'deb: size X,Y, ratio=', sizeX, sizeY, ratioXY #------------------
950
951         clip1_Z = - camera.clipStart
952         clip2_Z = - camera.clipEnd
953         #print 'deb: clip Start=', camera.clipStart #------------------
954         #print 'deb: clip   End=', camera.clipEnd #------------------
955
956         if camera.type=='ortho':
957                 scale = camera.scale
958                 #print 'deb: camscale=', scale #------------------
959                 clip1shiftX = clip2shiftX = camera.shiftX * scale
960                 clip1shiftY = clip2shiftY = camera.shiftY * scale
961                 clip1_X = scale * 0.5
962                 clip1_Y = scale * 0.5
963                 if ratioXY > 1.0: clip1_Y /= ratioXY
964                 else: clip1_X *= ratioXY
965                 clip2_X = clip1_X
966                 clip2_Y = clip1_Y
967
968                 near = clip1_Z
969                 far = clip2_Z
970                 right, left = clip1_X, -clip1_X
971                 top, bottom = clip1_Y, -clip1_Y
972
973                 scaleX = 2.0/float(right - left)
974                 x3 = -float(right + left)/float(right - left)
975                 scaleY = 2.0/float(top - bottom)
976                 y3 = -float(top + bottom)/float(top - bottom)
977                 scaleZ = 1.0/float(far - near)
978                 z3 =  -float(near)/float(far - near)
979                 
980                 matr = Mathutils.Matrix(  [scaleX, 0.0, 0.0, x3],
981                                                 [0.0, scaleY, 0.0, y3],
982                                                 [0.0, 0.0, scaleZ, z3],
983                                                 [0.0, 0.0, 0.0, 1.0])
984
985         elif camera.type=='persp': 
986                 #viewpoint = [0.0, 0.0, 0.0] #camera's coordinate system, hehe
987                 #lens = camera.lens
988                 angle = camera.angle
989                 #print 'deb: cam angle=', angle #------------------
990                 shiftX = camera.shiftX
991                 shiftY = camera.shiftY
992                 fov_coef = atan(angle * d2r)
993                 fov_coef *= 1.3  #incl. passpartou
994                 clip1_k = clip1_Z * fov_coef
995                 clip2_k = clip2_Z * fov_coef
996                 clip1shiftX = - camera.shiftX * clip1_k
997                 clip2shiftX = - camera.shiftX * clip2_k
998                 clip1shiftY = - camera.shiftY * clip1_k
999                 clip2shiftY = - camera.shiftY * clip2_k
1000                 clip1_X = clip1_Y = clip1_k * 0.5
1001                 clip2_X = clip2_Y = clip2_k * 0.5
1002                 if ratioXY > 1.0:
1003                         clip1_Y /= ratioXY
1004                         clip2_Y /= ratioXY
1005                 else:
1006                         clip1_X *= ratioXY
1007                         clip2_X *= ratioXY
1008
1009                 near = clip1_Z
1010                 far = clip2_Z
1011                 right, left = clip1_X, -clip1_X
1012                 top, bottom = clip1_Y, -clip1_Y
1013                 #return Matrix(  [scaleX,   0.0,        x2,      0.0],
1014                                                 #[0.0,    scaleY, y2,    0.0],
1015                                                 #[0.0,    0.0,  scaleZ, wZ],
1016                                                 #[0.0,    0.0,  -1.0,   0.0])
1017                 matr = Mathutils.Matrix(  [(2.0 * near)/float(right - left), 0.0, float(right + left)/float(right - left), 0.0],
1018                                                 [0.0, (2.0 * near)/float(top - bottom), float(top + bottom)/float(top - bottom), 0.0],
1019                                                 [0.0, 0.0, -float(far + near)/float(far - near), -(2.0 * far * near)/float(far - near)],
1020                                                 [0.0, 0.0, -1.0, 0.0])
1021
1022
1023         clip_box = [
1024                 -clip1_X + clip1shiftX, clip1_X + clip1shiftX,
1025                 -clip1_Y + clip1shiftY, clip1_Y + clip1shiftY,
1026                 -clip2_X + clip2shiftX, clip2_X + clip2shiftX,
1027                 -clip2_Y + clip2shiftY, clip2_Y + clip2shiftY,
1028                 clip1_Z, clip2_Z]
1029         #print 'deb: clip_box=\n', clip_box #------------------
1030         #drawClipBox(clip_box)
1031         return clip_box, matr
1032
1033
1034 #-----------------------------------------------------
1035 def drawClipBox(clip_box):
1036         """debug tool: draws Clipping-Box of a Camera View
1037         """
1038         min_X1, max_X1, min_Y1, max_Y1,\
1039         min_X2, max_X2, min_Y2, max_Y2,\
1040                 min_Z, max_Z = clip_box
1041         verts = []
1042         verts.append([min_X1, min_Y1, min_Z])
1043         verts.append([max_X1, min_Y1, min_Z])
1044         verts.append([max_X1, max_Y1, min_Z])
1045         verts.append([min_X1, max_Y1, min_Z])
1046         verts.append([min_X2, min_Y2, max_Z])
1047         verts.append([max_X2, min_Y2, max_Z])
1048         verts.append([max_X2, max_Y2, max_Z])
1049         verts.append([min_X2, max_Y2, max_Z])
1050         faces = [[0,1,2,3],[4,5,6,7]]
1051         nme = Mesh.New()
1052         nme.verts.extend(verts)
1053         nme.faces.extend(faces)
1054         
1055         plan = Object.New('Mesh','clip_box')
1056         plan.link(nme)
1057         sce = Scene.GetCurrent()
1058         sce.objects.link(plan)
1059         plan.setMatrix(sce.objects.camera.matrix)
1060
1061
1062 #-------------------------------------------------
1063 def getCommons(ob):
1064         """set up common attributes for output style:
1065          color=None
1066          extrusion=None
1067          layer='0',
1068          lineType=None
1069          lineTypeScale=None
1070          lineWeight=None
1071          thickness=None
1072          parent=None
1073         """
1074
1075         layers = ob.layers #gives a list e.g.[1,5,19]
1076         if layers: ob_layer_nr = layers[0]
1077         #print 'ob_layer_nr=', ob_layer_nr #--------------
1078
1079         materials = ob.getMaterials()
1080         if materials:
1081                 ob_material = materials[0]
1082                 ob_mat_color = ob_material.rgbCol
1083         else: ob_mat_color, ob_material = None, None
1084         #print 'ob_mat_color, ob_material=', ob_mat_color, ob_material #--------------
1085
1086         data = ob.getData()
1087         data_materials = ob.getMaterials()
1088         if data_materials:
1089                 data_material = data_materials[0]
1090                 data_mat_color = data_material.rgbCol
1091         else: data_mat_color, data_material = None, None
1092         #print 'data_mat_color, data_material=', data_mat_color, data_material #--------------
1093         
1094         entitylayer = ENTITYLAYER_DEF
1095         c = entitylayer_from_list[GUI_A['entitylayer_from'].val]
1096         #["default_LAYER","obj.name","obj.layer","obj.material","obj.data.name","obj.data.material","..vertexgroup","..group","..map_table"]
1097         if c=="default_LAYER":
1098                 entitylayer = LAYERNAME_DEF
1099         elif c=="obj.layer" and ob_layer_nr:
1100                 entitylayer = 'LAYER'+ str(ob_layer_nr)
1101         elif c=="obj.material" and ob_material:
1102                 entitylayer = ob_material.name
1103         elif c=="obj.name":
1104                 entitylayer = ob.name
1105         elif c=="obj.data.material" and ob_material:
1106                 entitylayer = data_material.name
1107         elif c=="obj.data.name":
1108                 entitylayer = data.name
1109         entitylayer = validDXFr12name(PREFIX+entitylayer)
1110         if entitylayer=="": entitylayer = "BF_0"
1111
1112         entitycolor = ENTITYCOLOR_DEF
1113         c = entitycolor_from_list[GUI_A['entitycolor_from'].val]
1114         if c=="default_COLOR":
1115                 entitycolor = LAYERCOLOR_DEF
1116         elif c=="BYLAYER":
1117                 entitycolor = BYLAYER
1118         elif c=="BYBLOCK":
1119                 entitycolor = BYBLOCK
1120         elif c=="obj.layer" and ob_layer_nr:
1121                 entitycolor = ob_layer_nr
1122         elif c=="obj.color" and ob.color:
1123                 entitycolor = col2DXF(ob.color)
1124         elif c=="obj.material" and ob_mat_color:
1125                  entitycolor = col2DXF(ob_mat_color)
1126         elif c=="obj.data.material" and data_mat_color:
1127                  entitycolor = col2DXF(data_mat_color)
1128         #if entitycolor!=None:  layercolor = entitycolor
1129
1130         entityltype = ENTITYLTYPE_DEF
1131         c = entityltype_from_list[GUI_A['entityltype_from'].val]
1132         if c=="default_LTYPE":
1133                 entityltype = LAYERLTYPE_DEF
1134         elif c=="BYLAYER":
1135                 entityltype = BYLAYER
1136         elif c=="BYBLOCK":
1137                 entityltype = BYBLOCK
1138         elif c:
1139                 entityltype = c
1140
1141         return entitylayer,entitycolor,entityltype
1142
1143
1144 #-----------------------------------------------------
1145 def do_export(export_list, filepath):
1146         global PERSPECTIVE
1147         Window.WaitCursor(1)
1148         t = Blender.sys.time()
1149
1150         #init Drawing ---------------------
1151         d=DXF.Drawing()
1152         #add Tables -----------------
1153         #d.blocks.append(b)                              #table blocks
1154         #goes automatic: d.styles.append(DXF.Style())                   #table styles
1155         #d.views.append(DXF.View('Normal'))       #table view
1156         d.views.append(DXF.ViewByWindow('BF_TOPVIEW',leftBottom=(-10,-6),rightTop=(10,6)))  #idem
1157
1158         #add Entities --------------------
1159         something_ready = 0
1160         selected_len = len(export_list)
1161         sce = Scene.GetCurrent()
1162
1163         mw = Mathutils.Matrix(  [1.0, 0.0, 0.0, 0.0],
1164                                                 [0.0, 1.0, 0.0, 0.0],
1165                                                 [0.0, 0.0, 1.0, 0.0],
1166                                                 [0.0, 0.0, 0.0, 1.0])
1167         if PROJECTION:
1168                 if CAMERA<len(CAMERAS)+1: #the biggest number is the current view
1169                         act_camera =    Object.Get(CAMERAS[CAMERA-1])
1170                         context = sce.getRenderingContext()
1171                         #print 'deb: context=\n', context #------------------
1172                         #print 'deb: context=\n', dir(context) #------------------
1173                         #act_camera = sce.objects.camera
1174                         #print 'deb: act_camera=', act_camera #------------------
1175                         if act_camera:
1176                                 mc0 = act_camera.matrix.copy()
1177                                 #print 'deb: camera.Matrix=\n', mc0 #------------------
1178                                 camera = Camera.Get(act_camera.getData(name_only=True))
1179                                 #print 'deb: camera=', dir(camera) #------------------
1180                                 if camera.type=='persp': PERSPECTIVE = 1
1181                                 elif camera.type=='ortho': PERSPECTIVE = 0
1182                                 clip_box, mcp = getClipBox(camera)
1183         
1184                                 #mcp = getPerspMatrix(camera)
1185                                 mw = mc0.copy().invert()
1186         
1187                 else: # get 3D-View instead of camera           
1188                         #ViewVector = Mathutils.Vector(Window.GetViewVector())
1189                         #print 'deb: ViewVector=\n', ViewVector #------------------
1190                         #TODO: for what is Window.GetViewOffset() ??
1191                         #print 'deb: Window.GetViewOffset():', Window.GetViewOffset() #---------
1192                         #Window.SetViewOffset([0,0,0])
1193                         #print 'deb: Window.GetViewOffset():', Window.GetViewOffset() #---------
1194                         mw0 = Window.GetViewMatrix()
1195                         #print 'deb: mwOrtho    =\n', mw0        #---------
1196                         mwp = Window.GetPerspMatrix() #TODO: how get it working?
1197                         #print 'deb: mwPersp    =\n', mwp        #---------
1198                         #mw0 = mwp
1199                         #clip_box = getClipBox(camera, context)
1200                         mw = mw0.copy()
1201         
1202         #print 'deb: ViewMatrix=\n', mw #------------------
1203         
1204         if APPLY_MODIFIERS: tmp_me = Mesh.New('tmp')
1205         else: tmp_me = None
1206
1207         layernames = []
1208         for ob,mx in export_list:
1209                 entities = []
1210                 #mx = ob.matrix.copy()
1211                 #print 'deb: ob =', ob   #---------
1212                 #print 'deb: ob.type    =', ob.type      #---------
1213                 #print 'deb: mx =\n', mx         #---------
1214                 #print 'deb: mw0        =\n', mw0        #---------
1215                 #mx_n is trans-matrix for normal_vectors for front-side faces
1216                 mx_n = mx.rotationPart() * mw.rotationPart()
1217                 if G_SCALE!=1.0: mx *= G_SCALE
1218                 mx *= mw
1219                 
1220                 #mx_inv = mx.copy().invert()
1221                 #print 'deb: mx =\n', mx         #---------
1222                 #print 'deb: mx_inv=\n', mx_inv #---------
1223
1224                 if ob.type in ('Mesh', 'Curve', 'Empty', 'Text'):
1225                         if GUI_A['paper_space_on'].val==1: espace=1
1226                         else: espace=None
1227                         elayer,ecolor,eltype = getCommons(ob)
1228                         #print 'deb: elayer,ecolor,eltype =', elayer,ecolor,eltype #--------------
1229
1230                         if elayer!=None:
1231                                 if elayer not in layernames:
1232                                         layernames.append(elayer)
1233                                         if ecolor!=None: tempcolor = ecolor
1234                                         else: tempcolor = LAYERCOLOR_DEF
1235                                         d.layers.append(DXF.Layer(color=tempcolor, name=elayer))
1236
1237                         if (ob.type == 'Mesh') and GUI_B['bmesh'].val:
1238                                 entities = exportMesh(ob, mx, mx_n, tmp_me,\
1239                                                 paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
1240                         elif (ob.type == 'Curve') and GUI_B['bcurve'].val:
1241                                 entities = exportCurve(ob, mx, mw, \
1242                                                 paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
1243                         elif (ob.type == 'Empty') and GUI_B['empty'].val:
1244                                 entities = exportEmpty(ob, mx, mw, \
1245                                                 paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
1246                         elif (ob.type == 'Text') and GUI_B['text'].val:
1247                                 entities = exportText(ob, mx, mw, \
1248                                         paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
1249         
1250                         if entities:
1251                                 something_ready += 1
1252                                 for e in entities:
1253                                         d.append(e)
1254         
1255         if something_ready:
1256                 if not GUI_A['outputDWG_on'].val:
1257                         print 'exporting to %s' % filepath
1258                         try:
1259                                 d.saveas(filepath)
1260                                 Window.WaitCursor(0)
1261                                 #print '%s objects exported to %s' %(something_ready,filepath)
1262                                 print '%s/%s objects exported in %.2f seconds. -----DONE-----' %(something_ready,selected_len,(Blender.sys.time()-t))
1263                                 Draw.PupMenu('DXF Exporter: job finished!| %s/%s objects exported in %.2f sek.' %(something_ready,selected_len, (Blender.sys.time()-t)))
1264                         except IOError:
1265                                 Window.WaitCursor(0)
1266                                 Draw.PupMenu('DXF Exporter: Write Error:     Permission denied:| %s' %filepath)
1267                                 
1268                 else:
1269                         if not extCONV_OK:
1270                                 Draw.PupMenu(extCONV_TEXT)
1271                                 Window.WaitCursor(False)
1272                         else:
1273                                 print 'temp. exporting to %s' % filepath
1274                                 d.saveas(filepath)
1275                                 #Draw.PupMenu('DXF Exporter: job finished')
1276                                 #print 'exported to %s' % filepath
1277                                 #print 'finished in %.2f seconds' % (Blender.sys.time()-t)
1278                                 filedwg = filepath[:-3]+'dwg'
1279                                 print 'exporting to %s' % filedwg
1280                                 os.system('%s %s  -acad13 -dwg' %(extCONV_PATH,filepath))
1281                                 #os.chdir(cwd)
1282                                 os.remove(filepath)
1283                                 Window.WaitCursor(0)
1284                                 print '  finished in %.2f seconds. -----DONE-----' % (Blender.sys.time()-t)
1285                                 Draw.PupMenu('DWG Exporter: job finished!| %s/%s objects exported in %.2f sek.' %(something_ready,selected_len, (Blender.sys.time()-t)))
1286         else:
1287                 Window.WaitCursor(0)
1288                 print "Abort: selected objects dont match choosen export option, nothing exported!"
1289                 Draw.PupMenu('DXF Exporter:   nothing exported!|selected objects dont match choosen export option!')
1290
1291
1292 #------------------------------------------------------
1293 """
1294 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,\
1295 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,\
1296 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,\
1297 151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,\
1298 171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,\
1299 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,\
1300 211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,\
1301 231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254]
1302 invalid = ''.join([chr(i) for i in v])
1303 del v, i
1304 """
1305 #TODO: validDXFr14 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.'
1306 validDXFr12 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'
1307
1308 #------------------------------------------------------
1309 def cleanName(name,valid):
1310         validname = ''
1311         for ch in name:
1312                 if ch not in valid:     ch = '_'
1313                 validname += ch
1314         return validname
1315
1316 #------------------------------------------------------
1317 def validDXFr12name(str_name):
1318         dxfname = str(str_name)
1319         dxfname = dxfname[:NAMELENGTH_MAX].upper()
1320         dxfname = cleanName(dxfname,validDXFr12)
1321         return dxfname
1322
1323 #print cleanName('dumka',validDXFr12)
1324 #print validDXFr12name('dum 15%ka')
1325
1326 #------------------------------------------------------
1327 def col2RGB(color):
1328         return [int(floor(255*color[0])),
1329                         int(floor(255*color[1])),
1330                         int(floor(255*color[2]))]
1331
1332 global dxfColors
1333 dxfColors=None
1334
1335 #------------------------------------------------------
1336 def col2DXF(rgbcolor):
1337         global dxfColors
1338         if dxfColors is None:
1339                 from dxfColorMap import color_map
1340                 dxfColors = [(tuple(color),idx) for idx, color in color_map.iteritems()]
1341                 dxfColors.sort()
1342         entry = (tuple(rgbcolor), -1)
1343         dxfColors.append(entry)
1344         dxfColors.sort()
1345         i = dxfColors.index(entry)
1346         dxfColors.pop(i)
1347         return dxfColors[i-1][1]
1348
1349
1350
1351 # NEW UI -----#################################################-----------------
1352 # ------------#################################################-----------------
1353
1354 class Settings:  #-----------------------------------------------------------------
1355         """A container for all the export settings and objects.
1356
1357         This is like a collection of globally accessable persistant properties and functions.
1358         """
1359         # Optimization constants
1360         MIN = 0
1361         MID = 1
1362         PRO = 2
1363         MAX = 3
1364
1365         def __init__(self, keywords, drawTypes):
1366                 """initialize all the important settings used by the export functions.
1367                 """
1368                 self.obj_number = 1 #global object_number for progress_bar
1369
1370                 self.var = dict(keywords)        #a dictionary of (key_variable:Value) control parameter
1371                 self.drawTypes = dict(drawTypes) #a dictionary of (entity_type:True/False) = import on/off for this entity_type
1372
1373                 self.var['colorFilter_on'] = False   #deb:remi------------
1374                 self.acceptedColors = [0,2,3,4,5,6,7,8,9,
1375                                                            10 ]
1376
1377                 self.var['materialFilter_on'] = False   #deb:remi------------
1378                 self.acceptedLayers = ['3',
1379                                                    '0'
1380                                                   ]
1381
1382                 self.var['groupFilter_on'] = False   #deb:remi------------
1383                 self.acceptedLayers = ['3',
1384                                                    '0'
1385                                                   ]
1386
1387                 #self.var['objectFilter_on'] = 0   #deb:remi------------
1388                 self.acceptedBlocks = ['WALL_1871',
1389                                                    'BOX02'
1390                                                   ]
1391                 self.unwantedBlocks = ['BOX05',
1392                                                    'BOX04'
1393                                                   ]
1394
1395
1396         def update(self, keywords, drawTypes):
1397                 """update all the important settings used by the draw functions.
1398                 mostly used after loading parameters from INI-file
1399                 """
1400
1401                 for k, v in keywords.iteritems():
1402                         self.var[k] = v
1403                         #print 'deb:settings_update var %s= %s' %(k, self.var[k]) #--------------
1404                 for t, v in drawTypes.iteritems():
1405                         self.drawTypes[t] = v
1406                         #print 'deb:settings_update drawType %s= %s' %(t, self.drawTypes[t]) #--------------
1407
1408                 self.drawTypes['arc'] = self.drawTypes['surface']
1409                 self.drawTypes['circle'] = self.drawTypes['surface']
1410                 self.drawTypes['ellipse'] = self.drawTypes['surface']
1411                 self.drawTypes['trace'] = self.drawTypes['solid']
1412                 self.drawTypes['insert'] = self.drawTypes['group']
1413                 #self.drawTypes['vport'] = self.drawTypes['view']
1414
1415                 #print 'deb:self.drawTypes', self.drawTypes #---------------
1416
1417
1418         def validate(self, drawing):
1419                 """Given the drawing, build dictionaries of Layers, Colors and Blocks.
1420                 """
1421                 global oblist
1422                 #adjust the distance parameter to globalScale
1423                 if self.var['g_scale'] != 1.0:
1424                         self.var['dist_min']  = self.var['dist_min'] / self.var['g_scale']
1425                 self.g_origin = Mathutils.Vector(self.var['g_originX'], self.var['g_originY'], self.var['g_originZ'])
1426
1427
1428         def write(self, text, newline=True):
1429                 """Wraps the built-in print command in a optimization check.
1430                 """
1431                 if self.var['optimization'] <= self.MID:
1432                         if newline:
1433                                 print text
1434                         else:
1435                                 print text,
1436
1437
1438         def redraw(self):
1439                 """Update Blender if optimization level is low enough.
1440                 """
1441                 if self.var['optimization'] <= self.MIN:
1442                         Blender.Redraw()
1443
1444
1445         def progress(self, done, text):
1446                 """Wrapper for Blender.Window.DrawProgressBar.
1447                 """
1448                 if self.var['optimization'] <= self.PRO:
1449                         progressbar = done * self.obj_number
1450                         Window.DrawProgressBar(progressbar, text)
1451                         #print 'deb:drawer done, progressbar: ', done, progressbar  #-----------------------
1452
1453
1454
1455 # GUI STUFF -----#################################################-----------------
1456 from Blender.BGL import *
1457
1458 EVENT_NONE = 1
1459 EVENT_START = 2
1460 EVENT_REDRAW = 3
1461 EVENT_LOAD_INI = 4
1462 EVENT_SAVE_INI = 5
1463 EVENT_RESET = 6
1464 EVENT_CHOOSE_INI = 7
1465 EVENT_CHOOSE_DXF = 8
1466 EVENT_HELP = 9
1467 EVENT_CAMERA = 10
1468 EVENT_LIGHT =11
1469 EVENT_DXF_DIR = 12
1470 EVENT_setCAMERA = 13
1471 # = 14
1472 EVENT_ORIGIN = 15
1473 EVENT_SCALE = 16
1474 EVENT_PRESET2D = 20
1475 EVENT_PRESET3D = 21
1476 EVENT_PRESETPLINE = 22
1477 EVENT_PRESETS = 23
1478 EVENT_EXIT = 100
1479
1480 GUI_A = {}  # GUI-buttons dictionary for parameter
1481 GUI_B = {}  # GUI-buttons dictionary for drawingTypes
1482
1483 # settings default, initialize ------------------------
1484
1485 #-----------------------------------------------
1486 def prepareMenu(title,list):
1487         menu = title    
1488         for i, item in enumerate(list):
1489                 menu += '|'+ item + ' %x' + str(i)
1490         return menu
1491
1492 #-----------------------------------------------
1493 mesh_as_list  = ["3DFACEs","POLYFACE","POLYLINE","LINEs","POINTs"]
1494 mesh_as_menu = prepareMenu("export to: %t", mesh_as_list) 
1495
1496 curve_as_list  = ["LINEs","POLYLINE","..LWPOLYLINE r14","..SPLINE r14","POINTs"]
1497 curve_as_menu = prepareMenu("export to: %t", curve_as_list) 
1498
1499 surface_as_list   = ["..3DFACEs","..POLYFACE","..POINTs","..NURBS"]
1500 surface_as_menu = prepareMenu("export to: %t", surface_as_list) 
1501
1502 meta_as_list  = ["..3DFACEs","..POLYFACE","..3DSOLID"]
1503 meta_as_menu = prepareMenu("export to: %t", meta_as_list) 
1504
1505 text_as_list   = ["TEXT","..MTEXT","..ATTRIBUT"]
1506 text_as_menu = prepareMenu("export to: %t", text_as_list) 
1507
1508 empty_as_list  = ["POINT","..INSERT","..XREF"]
1509 empty_as_menu = prepareMenu("export to: %t|", empty_as_list) 
1510
1511 group_as_list  = ["..GROUP","..BLOCK","..ungroup"]
1512 group_as_menu = prepareMenu("export to: %t", group_as_list) 
1513
1514 parent_as_list = ["..BLOCK","..ungroup"]
1515 parent_as_menu = prepareMenu("export to: %t", parent_as_list) 
1516
1517 proxy_as_list = ["..BLOCK","..XREF","..ungroup","..POINT"]
1518 proxy_as_menu = prepareMenu("export to: %t", proxy_as_list) 
1519
1520 camera_as_list = ["..BLOCK","..A_CAMERA","..VPORT","..VIEW","..POINT"]
1521 camera_as_menu = prepareMenu("export to: %t", camera_as_list) 
1522         
1523 lamp_as_list  = ["..BLOCK","..A_LAMP","..POINT"]
1524 lamp_as_menu = prepareMenu("export to: %t", lamp_as_list) 
1525         
1526 material_to_list= ["COLOR","LAYER","..LINESTYLE","..BLOCK","..XDATA","..INI-File"]
1527 material_to_menu = prepareMenu("export to: %t", material_to_list) 
1528
1529 ltype_map_list= ["object_rgb","material_rgb","..map_table"]
1530 ltype_map_menu = prepareMenu("export to: %t", ltype_map_list) 
1531
1532
1533
1534 layername_from_list = [LAYERNAME_DEF,"drawing_name","scene_name"]
1535 layername_from_menu = prepareMenu("defaultLAYER: %t", layername_from_list)
1536
1537 layerltype_def_list = ["CONTINUOUS","..DOT","..DASHED","..DASHDOT","..BORDER","..HIDDEN"]
1538 layerltype_def_menu = prepareMenu("LINETYPE set to: %t",layerltype_def_list)
1539
1540 entitylayer_from_list = ["default_LAYER","obj.name","obj.layer","obj.material","obj.data.name","obj.data.material","..vertexgroup","..group","..map_table"]
1541 entitylayer_from_menu = prepareMenu("entityLAYER from: %t", entitylayer_from_list) 
1542 #print 'deb: entitylayer_from_menu=', entitylayer_from_menu #--------------
1543         
1544 entitycolor_from_list = ["default_COLOR","BYLAYER","BYBLOCK","obj.layer","obj.color","obj.material","obj.data.material","..map_table"]
1545 entitycolor_from_menu = prepareMenu("entityCOLOR set to: %t",entitycolor_from_list)
1546
1547 entityltype_from_list = ["default_LTYPE","BYLAYER","BYBLOCK","CONTINUOUS","..DOT","..DASHED","..DASHDOT","..BORDER","..HIDDEN"]
1548 entityltype_from_menu = prepareMenu("entityCOLOR set to: %t",entityltype_from_list)
1549
1550 #dxf-LINE,ARC,CIRCLE,ELLIPSE
1551
1552 g_scale_list    = ''.join((
1553         'scale factor: %t',
1554         '|user def. %x12',
1555         '|yard to m %x8',
1556         '|feet to m %x7',
1557         '|inch to m %x6',
1558         '|  x  100000 %x5',
1559         '|  x  10000 %x4',
1560         '|  x  1000 %x3',
1561         '|  x  100 %x2',
1562         '|  x  10 %x1',
1563         '|  x  1 %x0',
1564         '|  x  0.1 %x-1',
1565         '|  x  0.01 %x-2',
1566         '|  x  0.001 %x-3',
1567         '|  x  0.0001 %x-4',
1568         '|  x  0.00001 %x-5'))
1569
1570 #print 'deb:  g_scale_list', g_scale_list #-----------
1571
1572 dxfFileName = Draw.Create("")
1573 iniFileName = Draw.Create(INIFILE_DEFAULT_NAME + INIFILE_EXTENSION)
1574 user_preset = 0
1575 config_UI = Draw.Create(0)   #switch_on/off extended config_UI
1576 g_scale_as = Draw.Create(int(log10(G_SCALE)))
1577
1578
1579 keywords_org = {
1580         'optimization': 2,
1581         'dummy_on' : 0,
1582
1583         'xref_on' : 1,
1584         'block_nn': 0,
1585
1586         'paper_space_on': 0,
1587         'layFrozen_on': 0,
1588         'objectFilter_on': 0,
1589         'materialFilter_on': 0,
1590         'colorFilter_on': 0,
1591         'groupFilter_on': 0,
1592
1593         'only_selected_on': ONLYSELECTED,
1594         'projection_on' : PROJECTION,
1595         'hidden_lines_on': HIDDEN_LINES,
1596         'shadows_on'  : SHADOWS,
1597         'light_on'  : 1,
1598         'outputDWG_on' : OUTPUT_DWG,
1599         'to_polyline_on': POLYLINES,
1600         'to_polyface_on': POLYFACES,
1601         'apply_modifiers_on': APPLY_MODIFIERS,
1602         'include_duplis_on': INCLUDE_DUPLIS,
1603         'camera_on': CAMERA,
1604
1605         'g_originX'   : G_ORIGIN[0],
1606         'g_originY'   : G_ORIGIN[1],
1607         'g_originZ'   : G_ORIGIN[2],
1608         'g_origin_on': 0,
1609         'g_scale'   : float(G_SCALE),
1610 #   'g_scale_as': int(log10(G_SCALE)), #   0,
1611         'g_scale_on': 0,
1612         'Z_force_on': 0,
1613         'Z_elev': float(ELEVATION),
1614
1615
1616         'prefix_def' : PREFIX,
1617         'layername_def' : LAYERNAME_DEF,
1618         'layercolor_def': LAYERCOLOR_DEF,
1619         'layerltype_def': LAYERLTYPE_DEF,
1620         'entitylayer_from': 5,
1621         'entitycolor_from': 1,
1622         'entityltype_from' : 1,
1623
1624         'material_on': 1,
1625         'material_to': 2,
1626         'fill_on'   : 1,
1627
1628         'mesh_as'  : 1,
1629         'curve_as' : 1,
1630         'surface_as' : 1,
1631         'meta_as'  : 1,
1632         'text_as' : 0,
1633         'empty_as' : 0,
1634         'group_as' : 0,
1635         'parent_as' : 0,
1636         'proxy_as' : 0,
1637         'camera_as': 1,
1638         'lamp_as' : 1,
1639         }
1640
1641 drawTypes_org = {
1642         'bmesh' : 1,
1643         'bcurve': 1,
1644         'surface': 0,
1645         'bmeta' : 0,
1646         'text'  : 1,
1647         'empty' : 1,
1648         'group' : 1,
1649         'parent': 1,
1650         'proxy' : 0,
1651         'camera': 0,
1652         'lamp'  : 0,
1653
1654 #   'view' : 0,
1655         }
1656
1657 # creating of GUI-buttons
1658 # GUI_A - GUI-buttons dictionary for parameter
1659 # GUI_B - GUI-buttons dictionary for drawingTypes
1660 for k, v in keywords_org.iteritems():
1661         GUI_A[k] = Draw.Create(v)
1662 for k, v in drawTypes_org.iteritems():
1663         GUI_B[k] = Draw.Create(v)
1664 #print 'deb:init GUI_A: ', GUI_A #---------------
1665 #print 'deb:init GUI_B: ', GUI_B #---------------
1666
1667 model_space_on = Draw.Create(1)
1668
1669 # initialize settings-object controls how dxf entities are drawn
1670 settings = Settings(keywords_org, drawTypes_org)
1671
1672
1673 def update_RegistryKey(key, item): #
1674         """updates key in Blender.Registry
1675         """
1676         cache = True # data is also saved to a file
1677         rdict = Registry.GetKey('DXF_Exporter', cache)
1678         if not rdict: rdict = {}
1679         if item:
1680                 rdict[key] = item
1681                 Registry.SetKey('DXF_Exporter', rdict, cache)
1682                 #print  'deb:update_RegistryKey rdict', rdict #---------------
1683
1684
1685 def check_RegistryKey(key):
1686         """ check if the key is already there (saved on a previous execution of this script)
1687         """
1688         cache = True # data is also saved to a file
1689         rdict = Registry.GetKey('DXF_Exporter', cache)
1690         #print 'deb:check_RegistryKey  rdict:', rdict #----------------
1691         if rdict: # if found, get the values saved there
1692                 try:
1693                         item = rdict[key]
1694                         return item
1695                 except:
1696                         #update_RegistryKey() # if data isn't valid rewrite it
1697                         pass
1698
1699 def saveConfig():  #--todo-----------------------------------------------
1700         """Save settings/config/materials from GUI to INI-file.
1701
1702         Write all config data to INI-file.
1703         """
1704         global iniFileName
1705
1706         iniFile = iniFileName.val
1707         #print 'deb:saveConfig inifFile: ', inifFile #----------------------
1708         if iniFile.lower().endswith(INIFILE_EXTENSION):
1709
1710                 #--todo-- sort key.list for output
1711                 #key_list = GUI_A.keys().val
1712                 #key_list.sort()
1713                 #for key in key_list:
1714                 #   l_name, l_data = key, GUI_A[key].val
1715                 #   list_A
1716
1717                 output_str = '[%s,%s]' %(GUI_A, GUI_B)
1718                 if output_str =='None':
1719                         Draw.PupMenu('DXF-Exporter: INI-file:  Alert!%t|no config-data present to save!')
1720                 else:
1721                         if Blender.sys.exists(iniFile):
1722                                 f = file(iniFile, 'r')
1723                                 header_str = f.readline()
1724                                 f.close()
1725                                 if header_str.startswith(INIFILE_HEADER[0:13]):
1726                                         if Draw.PupMenu('  OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile) == 1:
1727                                                 save_ok = True
1728                                         else: save_ok = False
1729                                 elif Draw.PupMenu('  OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile +
1730                                          '|Alert: this file has no valid ImportDXF-header| ! it may belong to another aplication !') == 1:
1731                                         save_ok = True
1732                                 else: save_ok = False
1733                         else: save_ok = True
1734
1735                         if save_ok:
1736                                 # replace: ',' -> ',\n'
1737                                 # replace: '{' -> '\n{\n'
1738                                 # replace: '}' -> '\n}\n'
1739                                 output_str = ',\n'.join(output_str.split(','))
1740                                 output_str = '\n}'.join(output_str.split('}'))
1741                                 output_str = '{\n'.join(output_str.split('{'))
1742                                 try:
1743                                         f = file(iniFile, 'w')
1744                                         f.write(INIFILE_HEADER + '\n# this is a comment line\n')
1745                                         f.write(output_str)
1746                                         f.close()
1747                                         #Draw.PupMenu('DXF-Exporter: INI-file: Done!%t|config-data saved in ' + '\'%s\'' %iniFile)
1748                                 except:
1749                                         Draw.PupMenu('DXF-Exporter: INI-file: Error!%t|failure by writing to ' + '\'%s\'|no config-data saved!' %iniFile)
1750
1751         else:
1752                 Draw.PupMenu('DXF-Exporter: INI-file:  Alert!%t|no valid name/extension for INI-file selected!')
1753                 print "DXF-Exporter: Alert!: no valid INI-file selected."
1754                 if not iniFile:
1755                         if dxfFileName.val.lower().endswith('.dxf'):
1756                                 iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
1757
1758
1759 def loadConfig():  #remi--todo-----------------------------------------------
1760         """Load settings/config/materials from INI-file.
1761
1762         TODO: Read material-assignements from config-file.
1763         """
1764         #20070724 buggy Window.FileSelector(loadConfigFile, 'Load config data from INI-file', inifilename)
1765         global iniFileName, GUI_A, GUI_B
1766
1767         iniFile = iniFileName.val
1768         update_RegistryKey('iniFileName', iniFile)
1769         #print 'deb:loadConfig iniFile: ', iniFile #----------------------
1770         if iniFile.lower().endswith(INIFILE_EXTENSION) and Blender.sys.exists(iniFile):
1771                 f = file(iniFile, 'r')
1772                 header_str = f.readline()
1773                 if header_str.startswith(INIFILE_HEADER):
1774                         data_str = f.read()
1775                         f.close()
1776                         #print 'deb:loadConfig data_str from %s: \n' %iniFile , data_str #-----------------
1777                         data = eval(data_str)
1778                         for k, v in data[0].iteritems():
1779                                 try: GUI_A[k].val = v
1780                                 except: GUI_A[k] = Draw.Create(v)
1781                         for k, v in data[1].iteritems():
1782                                 try: GUI_B[k].val = v
1783                                 except: GUI_B[k] = Draw.Create(v)
1784                 else:
1785                         f.close()
1786                         Draw.PupMenu('DXF-Exporter: INI-file:  Alert!%t|no valid header in INI-file: ' + '\'%s\'' %iniFile)
1787         else:
1788                 Draw.PupMenu('DXF-Exporter: INI-file:  Alert!%t|no valid INI-file selected!')
1789                 print "DXF-Exporter: Alert!: no valid INI-file selected."
1790                 if not iniFileName:
1791                         if dxfFileName.val.lower().endswith('.dxf'):
1792                                 iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
1793
1794
1795
1796 def updateConfig(keywords, drawTypes):  #-----------------------------------------------
1797         """updates GUI_settings with given dictionaries
1798
1799         """
1800         global GUI_A, GUI_B
1801         #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
1802         for k, v in keywords.iteritems():
1803                 GUI_A[k].val = v
1804         for k, v in drawTypes.iteritems():
1805                 GUI_B[k].val = v
1806
1807 def resetDefaultConfig():  #-----------------------------------------------
1808         """Resets settings/config/materials to defaults.
1809
1810         """
1811         #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
1812         updateConfig(keywords_org, drawTypes_org)
1813
1814
1815 def presetConfig_polyline(activate):  #-----------------------------------------------
1816         """Sets settings/config for polygon representation: POLYLINE(FACE) or LINEs/3DFACEs.
1817
1818         """
1819         global GUI_A
1820         if activate:
1821                 GUI_A['to_polyline_on'].val = 1
1822                 GUI_A['mesh_as'].val = 1
1823                 GUI_A['curve_as'].val = 1
1824         else:
1825                 GUI_A['to_polyline_on'].val = 0
1826                 GUI_A['mesh_as'].val = 0
1827                 GUI_A['curve_as'].val = 0
1828         
1829 def resetDefaultConfig_2D():  #-----------------------------------------------
1830         """Sets settings/config/materials to defaults 2D.
1831
1832         """
1833         keywords2d = {
1834                 'projection_on' : 1,
1835                 'fill_on' : 1,
1836                 'text_as' : 0,
1837                 'group_as' : 0,
1838                 }
1839
1840         drawTypes2d = {
1841                 'bmesh' : 1,
1842                 'bcurve': 1,
1843                 'surface':0,
1844                 'bmeta' : 0,
1845                 'text'  : 1,
1846                 'empty' : 1,
1847                 'group' : 1,
1848                 'parent' : 1,
1849                 #'proxy' : 0,
1850                 #'camera': 0,
1851                 #'lamp'  : 0,
1852
1853                 }
1854         presetConfig_polyline(1)
1855         updateConfig(keywords2d, drawTypes2d)
1856
1857 def resetDefaultConfig_3D():  #-----------------------------------------------
1858         """Sets settings/config/materials to defaults 3D.
1859
1860         """
1861         keywords3d = {
1862                 'projection_on' : 0,
1863                 'fill_on' : 0,
1864                 'text_as' : 0,
1865                 'group_as' : 0,
1866                 }
1867
1868         drawTypes3d = {
1869                 'bmesh' : 1,
1870                 'bcurve': 1,
1871                 'surface':0,
1872                 'bmeta' : 0,
1873                 'text'  : 0,
1874                 'empty' : 1,
1875                 'group' : 1,
1876                 'parent' : 1,
1877                 #'proxy' : 0,
1878                 'camera': 1,
1879                 'lamp'  : 1,
1880                 }
1881         presetConfig_polyline(1)
1882         updateConfig(keywords3d, drawTypes3d)
1883
1884
1885 def inputGlobalScale():
1886         """Pop-up UI-Block for global scale factor
1887         """
1888         global GUI_A
1889         #print 'deb:inputGlobalScale ##########' #------------
1890         x_scale = Draw.Create(GUI_A['g_scale'].val)
1891         block = []
1892         #block.append("global translation vector:")
1893         block.append(("", x_scale, 0.0, 10000000.0))
1894
1895         retval = Draw.PupBlock("set global scale factor:", block)
1896
1897         GUI_A['g_scale'].val = float(x_scale.val)
1898
1899         
1900 def inputOriginVector():
1901         """Pop-up UI-Block for global translation vector
1902         """
1903         global GUI_A
1904         #print 'deb:inputOriginVector ##########' #------------
1905         x_origin = Draw.Create(GUI_A['g_originX'].val)
1906         y_origin = Draw.Create(GUI_A['g_originY'].val)
1907         z_origin = Draw.Create(GUI_A['g_originZ'].val)
1908         block = []
1909         #block.append("global translation vector:")
1910         block.append(("X: ", x_origin, -100000000.0, 100000000.0))
1911         block.append(("Y: ", y_origin, -100000000.0, 100000000.0))
1912         block.append(("Z: ", z_origin, -100000000.0, 100000000.0))
1913
1914         retval = Draw.PupBlock("set global translation vector:", block)
1915
1916         GUI_A['g_originX'].val = x_origin.val
1917         GUI_A['g_originY'].val = y_origin.val
1918         GUI_A['g_originZ'].val = z_origin.val
1919
1920
1921 def update_globals():  #-----------------------------------------------------------------
1922         """ update globals if GUI_A changed
1923         """
1924         global  ONLYSELECTED, DEBUG,\
1925         PROJECTION, HIDDEN_LINES,       CAMERA, \
1926         G_SCALE, G_ORIGIN,\
1927         PREFIX, LAYERNAME_DEF, LAYERCOLOR_DEF, LAYERLTYPE_DEF,\
1928         APPLY_MODIFIERS, INCLUDE_DUPLIS,\
1929         OUTPUT_DWG
1930         #global POLYLINES
1931         
1932         ONLYSELECTED = GUI_A['only_selected_on'].val
1933         """
1934         POLYLINES = GUI_A['to_polyline_on'].val
1935         if GUI_A['curve_as'].val==1: POLYLINES=1
1936         else: POLYLINES=0
1937         """
1938         
1939         if GUI_A['optimization'].val==0: DEBUG = 1
1940         else: DEBUG = 0
1941         PROJECTION = GUI_A['projection_on'].val
1942         HIDDEN_LINES = GUI_A['hidden_lines_on'].val
1943         CAMERA = GUI_A['camera_on'].val
1944         G_SCALE = GUI_A['g_scale'].val
1945         if GUI_A['g_origin_on'].val: #TODO: scale and object orientation
1946                 G_ORIGIN[0] = GUI_A['g_originX'].val
1947                 G_ORIGIN[1] = GUI_A['g_originY'].val
1948                 G_ORIGIN[2] = GUI_A['g_originZ'].val
1949         if GUI_A['g_scale_on'].val:
1950                 G_ORIGIN[0] *= G_SCALE
1951                 G_ORIGIN[1] *= G_SCALE
1952                 G_ORIGIN[2] *= G_SCALE
1953
1954         PREFIX = GUI_A['prefix_def'].val
1955         LAYERNAME_DEF  = GUI_A['layername_def'].val
1956         LAYERCOLOR_DEF = GUI_A['layercolor_def'].val
1957         LAYERLTYPE_DEF = layerltype_def_list[GUI_A['layerltype_def'].val]
1958
1959         APPLY_MODIFIERS = GUI_A['apply_modifiers_on'].val
1960         INCLUDE_DUPLIS = GUI_A['include_duplis_on'].val
1961         OUTPUT_DWG = GUI_A['outputDWG_on'].val
1962         #print 'deb: GUI HIDDEN_LINES=', HIDDEN_LINES #---------
1963         #print 'deb: GUI GUI_A: ', GUI_A['hidden_lines_on'].val #---------------
1964         #print 'deb: GUI GUI_B: ', GUI_B #---------------
1965
1966
1967 def draw_UI():  #-----------------------------------------------------------------
1968         """ Draw startUI and setup Settings.
1969         """
1970         global GUI_A, GUI_B #__version__
1971         global user_preset, iniFileName, dxfFileName, config_UI, g_scale_as
1972         global model_space_on
1973         global SCROLL
1974
1975         global mPAN_X, menu_orgX, mPAN_Xmax
1976         global mPAN_Y, menu_orgY, mPAN_Ymax
1977         global menu__Area, headerArea, screenArea, scrollArea
1978
1979         size=Buffer(GL_FLOAT, 4)
1980         glGetFloatv(GL_SCISSOR_BOX, size) #window X,Y,sizeX,sizeY
1981         size= size.list
1982         #print '-------------size:', size #--------------------------
1983         for s in [0,1,2,3]: size[s]=int(size[s])
1984         window_Area = [0,0,size[2],size[3]-2]
1985         scrollXArea = [0,0,window_Area[2],15]
1986         scrollYArea = [0,0,15,window_Area[3]]
1987
1988         menu_orgX = -mPAN_X
1989         #menu_orgX = 0 #scrollW
1990         #if menu_pan: menu_orgX -= mPAN_X
1991         if menu_orgX < -mPAN_Xmax: menu_orgX, mPAN_X = -mPAN_Xmax,mPAN_Xmax
1992         if menu_orgX > 0: menu_orgX, mPAN_X = 0,0
1993
1994         menu_orgY = -mPAN_Y
1995         #if menu_pan: menu_orgY -= mPAN_Y
1996         if menu_orgY < -mPAN_Ymax: menu_orgY, mPAN_Y = -mPAN_Ymax,mPAN_Ymax
1997         if menu_orgY > 0: menu_orgY, mPAN_Y = 0,0
1998
1999
2000         menu_margin = 10
2001         butt_margin = 10
2002         common_column = int((window_Area[2] - (3 * butt_margin) - (2 * menu_margin)-30) / 4.0)
2003         common_column = 70
2004         # This is for easy layout changes
2005         but_0c = common_column  #button 1.column width
2006         but_1c = common_column  #button 1.column width
2007         but_2c = common_column  #button 2.column
2008         but_3c = common_column  #button 3.column
2009         menu_w = (3 * butt_margin) + but_0c + but_1c + but_2c + but_3c  #menu width
2010
2011         simple_menu_h = 240
2012         extend_menu_h = 345
2013         menu_h = simple_menu_h          # y is menu upper.y
2014         if config_UI.val:
2015                 menu_h += extend_menu_h
2016
2017         mPAN_Xmax = menu_w-window_Area[2]+50
2018         mPAN_Ymax = menu_h-window_Area[3]+30
2019
2020         y = menu_h
2021         x = 0 #menu left.x
2022         x +=menu_orgX+20
2023         y +=menu_orgY+20
2024
2025
2026         but0c = x + menu_margin  #buttons 0.column position.x
2027         but1c = but0c + but_0c + butt_margin
2028         but2c = but1c + but_1c + butt_margin
2029         but3c = but2c + but_2c + butt_margin
2030         but4c = but3c + but_3c
2031
2032         # Here starts menu -----------------------------------------------------
2033         #glClear(GL_COLOR_BUFFER_BIT)
2034         #glRasterPos2d(8, 125)
2035
2036
2037         ui_box(x, y, x+menu_w+menu_margin*2, y-menu_h)
2038         y -= 20
2039         Draw.Label("DXF(r12)-Exporter  v" + __version__, but0c, y, menu_w, 20)
2040
2041         if config_UI.val:
2042                 b0, b0_ = but0c, but_0c-20 + butt_margin
2043                 b1, b1_ = but1c-20, but_1c+20
2044                 y_top = y
2045
2046                 y -= 10
2047                 y -= 20
2048                 Draw.BeginAlign()
2049                 GUI_B['bmesh'] = Draw.Toggle('Mesh', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['bmesh'].val, "Export Mesh-Objects   on/off")
2050                 if GUI_B['bmesh'].val:
2051                         GUI_A['mesh_as'] = Draw.Menu(mesh_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['mesh_as'].val, "Select target DXF-object")
2052                 Draw.EndAlign()
2053
2054                 y -= 20
2055                 Draw.BeginAlign()
2056                 GUI_B['bcurve'] = Draw.Toggle('Curve', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['bcurve'].val, "Export Curve-Objects   on/off")
2057                 if GUI_B['bcurve'].val:
2058                         GUI_A['curve_as'] = Draw.Menu(curve_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['curve_as'].val, "Select target DXF-object")
2059                 Draw.EndAlign()
2060
2061                 y -= 20
2062                 Draw.BeginAlign()
2063                 GUI_B['surface'] = Draw.Toggle('..Surface', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['surface'].val, "(*todo) Export Surface-Objects   on/off")
2064                 if GUI_B['surface'].val:
2065                         GUI_A['surface_as'] = Draw.Menu(surface_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['surface_as'].val, "Select target DXF-object")
2066                 Draw.EndAlign()
2067
2068                 y -= 20
2069                 Draw.BeginAlign()
2070                 GUI_B['bmeta'] = Draw.Toggle('..Meta', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['bmeta'].val, "(*todo) Export Meta-Objects   on/off")
2071                 if GUI_B['bmeta'].val:
2072                         GUI_A['meta_as'] = Draw.Menu(meta_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['meta_as'].val, "Select target DXF-object")
2073                 Draw.EndAlign()
2074
2075                 y -= 20
2076                 Draw.BeginAlign()
2077                 GUI_B['text'] = Draw.Toggle('Text', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['text'].val, "Export Text-Objects   on/off")
2078                 if GUI_B['text'].val:
2079                         GUI_A['text_as'] = Draw.Menu(text_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['text_as'].val, "Select target DXF-object")
2080                 Draw.EndAlign()
2081
2082                 y -= 20
2083                 Draw.BeginAlign()
2084                 GUI_B['empty'] = Draw.Toggle('Empty', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['empty'].val, "Export Empty-Objects   on/off")
2085                 if GUI_B['empty'].val:
2086                         GUI_A['empty_as'] = Draw.Menu(empty_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['empty_as'].val, "Select target DXF-object")
2087                 Draw.EndAlign()
2088
2089                 y_down = y
2090                 # -----------------------------------------------
2091
2092                 y = y_top
2093                 b0, b0_ = but2c, but_2c-20 + butt_margin
2094                 b1, b1_ = but3c-20, but_3c+20
2095
2096                 y -= 10
2097                 y -= 20
2098                 Draw.BeginAlign()
2099                 GUI_B['group'] = Draw.Toggle('..Group', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['group'].val, "(*todo) Export Group-Relationships   on/off")
2100                 if GUI_B['group'].val:
2101                         GUI_A['group_as'] = Draw.Menu(group_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['group_as'].val, "Select target DXF-object")
2102                 Draw.EndAlign()
2103
2104                 y -= 20
2105                 Draw.BeginAlign()
2106                 GUI_B['parent'] = Draw.Toggle('..Parent', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['parent'].val, "(*todo) Export Parent-Relationships   on/off")
2107                 if GUI_B['parent'].val:
2108                         GUI_A['parent_as'] = Draw.Menu(parent_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['parent_as'].val, "Select target DXF-object")
2109                 Draw.EndAlign()
2110
2111                 y -= 20
2112                 Draw.BeginAlign()
2113                 GUI_B['proxy'] = Draw.Toggle('..Proxy', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['proxy'].val, "(*todo) Export Proxy-Objects   on/off")
2114                 if GUI_B['proxy'].val:
2115                         GUI_A['proxy_as'] = Draw.Menu(proxy_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['proxy_as'].val, "Select target DXF-object")
2116                 Draw.EndAlign()
2117
2118                 y -= 20
2119                 Draw.BeginAlign()
2120                 GUI_B['camera'] = Draw.Toggle('..Camera', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['camera'].val, "(*todo) Export Camera-Objects   on/off")
2121                 if GUI_B['camera'].val:
2122                         GUI_A['camera_as'] = Draw.Menu(camera_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['camera_as'].val, "Select target DXF-object")
2123                 Draw.EndAlign()
2124
2125                 y -= 20
2126                 Draw.BeginAlign()
2127                 GUI_B['lamp'] = Draw.Toggle('..Lamp', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['lamp'].val, "(*todo) Export Lamp-Objects   on/off")
2128                 if GUI_B['lamp'].val:
2129                         GUI_A['lamp_as'] = Draw.Menu(lamp_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['lamp_as'].val, "Select target DXF-object")
2130                 Draw.EndAlign()
2131
2132
2133                 if y < y_down: y_down = y
2134                 # -----end supported objects--------------------------------------
2135
2136                 y_top = y_down
2137                 y = y_top
2138                 y -= 10
2139                 y -= 20
2140                 but_ = menu_w / 6
2141                 b0 = but0c + (menu_w - but_*6)/2
2142                 Draw.BeginAlign()
2143                 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")
2144                 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")
2145                 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")
2146                 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")
2147                 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")
2148                 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")
2149                 #GUI_A['dummy_on'] = Draw.Toggle('-', EVENT_NONE, but3c, y, but_3c, 20, GUI_A['dummy_on'].val, "dummy   on/off")
2150                 Draw.EndAlign()
2151
2152                 # -----end filters--------------------------------------
2153
2154                 b0, b0_ = but0c, but_0c + butt_margin
2155                 b1, b1_ = but1c, but_1c
2156
2157                 y -= 10
2158                 y -= 20
2159                 Draw.BeginAlign()
2160                 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")
2161                 if GUI_A['g_origin_on'].val:
2162                         tmp = Draw.PushButton('=', EVENT_ORIGIN, b1, y, 20, 20, "Edit relocation-vector (x,y,z in DXF units)")
2163                         origin_str = '(%.4f, %.4f, %.4f)'  % (
2164                                 GUI_A['g_originX'].val,
2165                                 GUI_A['g_originY'].val,
2166                                 GUI_A['g_originZ'].val
2167                                 )
2168                         tmp = Draw.Label(origin_str, b1+20, y, 300, 20)
2169                 Draw.EndAlign()
2170
2171                 y -= 20
2172                 Draw.BeginAlign()
2173                 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")
2174                 if GUI_A['g_scale_on'].val:
2175                         g_scale_as = Draw.Menu(g_scale_list, EVENT_SCALE, b1, y, 45, 20, g_scale_as.val, "Factor for scaling the DXFdata")
2176                         if g_scale_as.val == 12:
2177                                 pass
2178                         else:
2179                                 if g_scale_as.val == 6: #scale inches to meters
2180                                         GUI_A['g_scale'].val = 0.0254000
2181                                 elif g_scale_as.val == 7: #scale feets to meters
2182                                         GUI_A['g_scale'].val = 0.3048000
2183                                 elif g_scale_as.val == 8: #scale yards to meters
2184                                         GUI_A['g_scale'].val = 0.9144000
2185                                 else:
2186                                         GUI_A['g_scale'].val = 10.0 ** int(g_scale_as.val)
2187                         scale_float = GUI_A['g_scale'].val
2188                         if scale_float < 0.000001 or scale_float > 1000000:
2189                                 scale_str = ' = %s' % GUI_A['g_scale'].val
2190                         else:   
2191                                 scale_str = ' = %.6f' % GUI_A['g_scale'].val
2192                         Draw.Label(scale_str, b1+45, y, 200, 20)
2193                 Draw.EndAlign()
2194
2195                 y -= 20
2196                 Draw.BeginAlign()
2197                 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")
2198                 if GUI_A['Z_force_on'].val:
2199                         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)")
2200                 Draw.EndAlign()
2201
2202                 """
2203                 y -= 30
2204                 Draw.BeginAlign()
2205                 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")
2206                 if GUI_A['material_on'].val:
2207                         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?")
2208                 Draw.EndAlign()
2209                 """
2210
2211                 #b0, b0_ = but0c, but_0c + butt_margin
2212                 b0, b0_ = but0c, 50
2213                 b1, b1_ = b0+b0_, but_0c-b0_+ but_1c + butt_margin
2214                 b2, b2_ = but2c, but_2c
2215                 b3, b3_ = but3c, but_3c
2216
2217                 y -= 30
2218                 Draw.Label('Output:', b0, y, b0_, 20)
2219                 Draw.Label('LAYER:', b1, y, b1_, 20)
2220                 Draw.Label('COLOR:', b2, y, b2_, 20)
2221                 Draw.Label('LINETYPE:', b3, y, b3_, 20)
2222                 #Draw.Label('LINESIZE:', b4, y, b4_, 20)
2223
2224                 y -= 20
2225                 Draw.BeginAlign()
2226                 GUI_A['prefix_def'] = Draw.String('', EVENT_NONE, b0, y, b0_, 20, GUI_A['prefix_def'].val, 10, "Type Prefix for LAYERs")
2227                 GUI_A['layername_def'] = Draw.String('', EVENT_NONE, b1, y, b1_, 20, GUI_A['layername_def'].val, 10, "Type default LAYER name")
2228                 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)")
2229                 GUI_A['layerltype_def'] = Draw.Menu(layerltype_def_menu, EVENT_NONE, b3, y, b3_, 20, GUI_A['layerltype_def'].val, "Set default LINETYPE")
2230                 Draw.EndAlign()
2231
2232                 y -= 25
2233                 Draw.Label('Style:', b0, y, b0_, 20)
2234                 Draw.BeginAlign()
2235                 GUI_A['entitylayer_from'] = Draw.Menu(entitylayer_from_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['entitylayer_from'].val, "entity LAYER assigned to?")
2236                 GUI_A['entitycolor_from'] = Draw.Menu(entitycolor_from_menu, EVENT_NONE, b2, y, b2_, 20, GUI_A['entitycolor_from'].val, "entity COLOR assigned to?")
2237                 GUI_A['entityltype_from'] = Draw.Menu(entityltype_from_menu, EVENT_NONE, b3, y, b3_, 20, GUI_A['entityltype_from'].val, "Set entity LINETYPE")
2238                 Draw.EndAlign()
2239                 
2240                 y -= 10
2241
2242                 y_down = y
2243                 # -----end material,translate,scale------------------------------------------
2244
2245
2246                 #--------------------------------------
2247                 y_top = y_down
2248                 y = y_top
2249
2250                 y -= 30
2251                 Draw.BeginAlign()
2252                 Draw.PushButton('INI file >', EVENT_CHOOSE_INI, but0c, y, but_0c, 20, 'Select INI-file with file selector')
2253                 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")
2254                 but = but4c-60
2255                 Draw.PushButton('#', EVENT_PRESETS, but, y, 20, 20, "Toggle Preset-INI-files")
2256                 Draw.PushButton('L', EVENT_LOAD_INI, but+20, y, 20, 20, 'Loads configuration from selected ini-file: %s' % iniFileName.val)
2257                 Draw.PushButton('S', EVENT_SAVE_INI, but+40, y, 20, 20, 'Saves configuration to selected ini-file: %s' % iniFileName.val)
2258                 Draw.EndAlign()
2259
2260         bm = butt_margin/2
2261
2262         y -= 10
2263         y -= 20
2264         Draw.BeginAlign()
2265         Draw.PushButton('DXFfile >', EVENT_CHOOSE_DXF, but0c, y, but_0c, 20, 'Select DXF-file with file selector')
2266         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")
2267         Draw.EndAlign()
2268
2269         y -= 30
2270         config_UI = Draw.Toggle('CONFIG', EVENT_REDRAW, but0c, y, but_0c+bm, 20, config_UI.val, 'Advanced configuration   on/off' )
2271         Draw.BeginAlign()
2272         but, but_ = but1c, but_1c+bm
2273         but_ /= 3
2274         Draw.PushButton('X', EVENT_RESET, but, y, 15, 20, "Reset configuration to defaults")
2275         Draw.PushButton('2D', EVENT_PRESET2D, but+but_, y, but_, 20, 'Set to standard configuration for 2D export')
2276         Draw.PushButton('3D', EVENT_PRESET3D, but+(but_*2), y, but_, 20, 'Set to standard configuration for 3D import')
2277         Draw.EndAlign()
2278
2279
2280         y -= 30
2281         b0, b0_ = but0c, but_0c + butt_margin +but_1c
2282         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")
2283         b0, b0_ = but2c, but_2c + butt_margin + but_3c
2284
2285         y -= 20
2286         b0, b0_ = but0c, but_0c + butt_margin +but_1c
2287         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")
2288         b0, b0_ = but2c, but_2c + butt_margin + but_3c
2289
2290         Draw.BeginAlign()
2291         GUI_A['projection_on'] = Draw.Toggle('2d Projection', EVENT_REDRAW, b0, y+20, b0_, 20, GUI_A['projection_on'].val, "Export a 2d Projection according 3d-View or Camera-View   on/off")
2292         if GUI_A['projection_on'].val:
2293                 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')         
2294                 Draw.PushButton('>', EVENT_setCAMERA, b0+b0_-20, y, 20, 20, 'switch to selected Camera - make it active')
2295                 GUI_A['hidden_lines_on'] = Draw.Toggle('Hide back-Faces', EVENT_NONE, b0, y-20, b0_, 20, GUI_A['hidden_lines_on'].val, "Filter out back-Faces   on/off")
2296                 #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")
2297                 #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')           
2298         Draw.EndAlign()
2299
2300         y -= 20
2301         b0, b0_ = but0c, but_0c + butt_margin +but_1c
2302         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")
2303         b0, b0_ = but2c, but_2c + butt_margin + but_3c
2304
2305         y -= 20
2306         b0, b0_ = but0c, but_0c + butt_margin +but_1c
2307         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")
2308         b0, b0_ = but2c, but_2c + butt_margin + but_3c
2309         
2310         
2311         y -= 50
2312         Draw.PushButton('EXIT', EVENT_EXIT, but0c, y, but_0c+bm, 20, '' )
2313         Draw.PushButton('HELP', EVENT_HELP, but1c, y, but_1c+bm, 20, 'goes to online-Manual on wiki.blender.org')
2314         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")
2315         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")
2316
2317         Draw.BeginAlign()
2318         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')
2319         Draw.EndAlign()
2320
2321         y -= 20
2322         #Draw.BeginAlign()
2323         #Draw.Label(' ', but0c-menu_margin, y, menu_margin, 20)
2324         #Draw.Label(LAB, but0c, y, menu_w, 20)
2325         Draw.Label(LAB, 30, y, menu_w, 20)
2326         #Draw.Label(' ', but0c+menu_w, y, menu_margin, 20)
2327         #Draw.EndAlign()
2328
2329         ui_scrollbarX(menu_orgX, menu_w+50, scrollXArea, c_fg, c_bg)
2330         ui_scrollbarY(menu_orgY, menu_h+30, scrollYArea, c_fg, c_bg)
2331
2332
2333
2334
2335 #-- END GUI Stuf-----------------------------------------------------
2336
2337 c0=[0.2,0.2,0.2,0.0]
2338 c1=[0.7,0.7,0.9,0.0]
2339 c2=[0.71,0.71,0.71,0.0]
2340 c3=[0.4,0.4,0.4,0.0]
2341 c4=[0.95,0.95,0.9,0.0]
2342 c5=[0.64,0.64,0.64,0]
2343 c6=[0.75,0.75,0.75,0]
2344 c7=[0.6,0.6,0.6,0]
2345 c8=[1.0,0.0,0.0,0]
2346 c9=[0.7,0.0,0.0,0]
2347 c10=[0.64,0.81,0.81,0]
2348 c11=[0.57,0.71,0.71,0]
2349 c_nor= c5[:3]
2350 c_act= c10[:3]
2351 c_sel= c11[:3]
2352 c_tx = c0[:3]
2353 c_fg = c2[:3]
2354 c_bg = c5[:3]
2355
2356 def ui_rect(coords,color):
2357         [X1,Y1,X2,Y2],[r,g,b] = coords,color
2358         glColor3f(r,g,b)
2359         glRecti(X1,Y1,X2,Y2)
2360 def ui_rectA(coords,color):
2361         [X1,Y1,X2,Y2],[r,g,b,a] = coords,color
2362         glColor4f(r,g,b,a)
2363         glRecti(X1,Y1,X2,Y2)  #integer coords
2364         #glRectf(X1,Y1,X2,Y2) #floating coords
2365 def ui_line(coords,color):
2366         [X1,Y1,X2,Y2],[r,g,b] = coords,color
2367         glColor3f(r,g,b)
2368         glBegin(GL_LINES)
2369         glVertex2i(X1,Y1)
2370         glVertex2i(X2,Y2)
2371         glEnd()
2372 def ui_panel(posX,posY,L,H,color):
2373         [r,g,b] = color
2374         ui_rect([posX+4,posY-4,posX+L+4,posY-H-4],[.55,.55,.55])                #1st shadow
2375         ui_rect([posX+3,posY-3,posX+L+3,posY-H-3],[.45,.45,.45])
2376         ui_rect([posX+3,posY-3,posX+L+2,posY-H-2],[.30,.30,.30])                #2nd shadow
2377         ui_rect([posX,posY-H,posX+L,posY],[r,g,b])                                              #Main
2378         ui_rect([posX+3,posY-19,posX+L-3,posY-2],[.75*r,.75*g,.75*b])   #Titlebar
2379         ui_line([posX+3,posY-19,posX+3,posY-2],[.25,.25,.25])
2380         ui_line([posX+4,posY-19,posX+4,posY-2],[(r+.75)/4,(g+.75)/4,(b+.75)/4])
2381         ui_line([posX+4,posY-2,posX+L-3,posY-2],[(r+.75)/4,(g+.75)/4,(b+.75)/4])
2382 def ui_box(x,y,xright,bottom):
2383         color = [0.75, 0.75, 0.75]
2384         coords = x+1,y+1,xright-1,bottom-1
2385         ui_rect(coords,color)
2386
2387 def ui_scrollbarX(Focus,PanelH,Area, color_fg, color_bg):
2388         # Area = ScrollBarArea
2389         # point1=down/left, point2=top/right
2390         P1X,P1Y,P2X,P2Y = Area
2391         AreaH = P2X-P1X
2392         if PanelH > AreaH:
2393                 Slider = int(AreaH * (AreaH / float(PanelH)))
2394                 if Slider<3: Slider = 3 #minimal slider heigh
2395                 posX = -int(AreaH * (Focus / float(PanelH)))
2396                 ui_rect([P1X,P1Y,P2X,P2Y], color_bg)
2397                 ui_rect([P1X+posX,P1Y+3,P1X+posX+Slider,P2Y-3], color_fg)
2398
2399 def ui_scrollbarY(Focus,PanelH,Area, color_fg, color_bg):
2400         # Area = ScrollBarArea
2401         # point1=down/left, point2=top/right
2402         P1X,P1Y,P2X,P2Y = Area
2403         AreaH = P2Y-P1Y
2404         if PanelH > AreaH:
2405                 Slider = int(AreaH * (AreaH / float(PanelH)))
2406                 if Slider<3: Slider = 3 #minimal slider heigh
2407                 posY = -int(AreaH * (Focus / float(PanelH)))
2408                 ui_rect([P1X,P1Y,P2X-1,P2Y], color_bg)
2409                 #ui_rect([P1X+3,P2Y-posY,P2X-4,P2Y-posY-Slider], color_fg)
2410                 ui_rect([P1X+3,P1Y+posY,P2X-4,P1Y+posY+Slider], color_fg)
2411
2412
2413 #------------------------------------------------------------
2414 def dxf_callback(input_filename):
2415         global dxfFileName
2416         dxfFileName.val=input_filename
2417 #   dirname == Blender.sys.dirname(Blender.Get('filename'))
2418 #   update_RegistryKey('DirName', dirname)
2419 #   update_RegistryKey('dxfFileName', input_filename)
2420         
2421 def ini_callback(input_filename):
2422         global iniFileName
2423         iniFileName.val=input_filename
2424
2425 #------------------------------------------------------------
2426 def getSpaceRect():
2427         __UI_RECT__ = Buffer(GL_FLOAT, 4)
2428         glGetFloatv(GL_SCISSOR_BOX, __UI_RECT__)
2429         __UI_RECT__ = __UI_RECT__.list
2430         return (int(__UI_RECT__[0]), int(__UI_RECT__[1]), int(__UI_RECT__[2]), int(__UI_RECT__[3]))
2431
2432 def getRelMousePos(mco, winRect):
2433         # mco = Blender.Window.GetMouseCoords()
2434         if pointInRect(mco, winRect):
2435                 return (mco[0] - winRect[0], mco[1] - winRect[1])
2436         return None
2437
2438
2439 def pointInRect(pt, rect):
2440         if  rect[0] < pt[0] < rect[0]+rect[2] and\
2441                 rect[1] < pt[1] < rect[1]+rect[3]:
2442                 return True
2443         else:
2444                 return False
2445
2446
2447
2448 #--- variables UI menu ---------------------------
2449 mco = [0,0]  # mouse coordinaten
2450 mbX, mbY = 0,0  # mouse buffer coordinaten
2451 scrollW = 20 # width of scrollbar
2452 rowH = 20 # height of menu raw
2453 menu__H = 2 * rowH +5 # height of menu bar
2454 headerH = 1 * rowH # height of column header bar
2455 scroll_left = True # position of scrollbar
2456 menu_bottom = False # position of menu
2457 edit_mode = False # indicator/activator
2458 iconlib_mode = False # indicator/activator
2459 icon_maps = [] #[['blenderbuttons.png',12,25,20,21],
2460 #['referenceicons.png',12,25,20,21]]
2461 help_text = False # indicator/activator
2462 menu_pan = False # indicator/activator
2463 compact_DESIGN = True # toggle UI
2464 showLINK = True # toggle Links
2465 filterList=[-1,-1,-1,-1,-1]
2466 dubbleclik_delay = 0.25
2467
2468 PAN_X,PAN_Y = 0,0 # pan coordinates in characters
2469 mPAN_X,mPAN_Y = 0,0 # manu pan coordinates in characters
2470 menu_orgX = 0
2471 menu_orgY = 0
2472 mPAN_Xmax = 800
2473 mPAN_Ymax = 800
2474
2475
2476 #------------------------------------------------------------
2477 def event(evt, val):
2478         global mbX, mbY, UP, UP0, scroll_pan, FOCUS_fix
2479         global menu_bottom, scroll_left, mco
2480         global PAN_X, PAN_Y, PAN_X0, PAN_Y0
2481         global mPAN_X, mPAN_Y, mPAN_X0, mPAN_Y0, menu_pan
2482
2483         #if Blender.event:
2484         #       print 'Blender.event:%s, evt:%s' %(Blender.event, evt) #------------
2485
2486         if evt in (Draw.QKEY, Draw.ESCKEY) and not val:
2487                 print 'DXF-Exporter  *** end ***'   #---------------------
2488                 Draw.Exit()
2489
2490         elif val:
2491                 if evt==Draw.MIDDLEMOUSE:
2492                         mco2 = Window.GetMouseCoords()
2493                         relativeMouseCo = getRelMousePos(mco2, getSpaceRect())
2494                         if relativeMouseCo != None:
2495                                 #rect = [menu__X1,menu__Y1,menu__X2,menu__Y2]
2496                                 if 1: #pointInRect(relativeMouseCo, menu__Area):
2497                                         menu_pan = True
2498                                         mPAN_X0 = mPAN_X
2499                                         mPAN_Y0 = mPAN_Y
2500                                         mco = mco2
2501                 elif evt == Draw.MOUSEY or evt == Draw.MOUSEX:
2502                         if menu_pan:
2503                                 mco2 = Window.GetMouseCoords()
2504                                 mbX = mco2[0]-mco[0]
2505                                 mbY = mco2[1]-mco[1]
2506                                 mPAN_X = mPAN_X0 - mbX
2507                                 mPAN_Y = mPAN_Y0 - mbY
2508                                 #print mbX, mbY #--------------------
2509                                 Draw.Redraw()
2510                 elif evt == Draw.WHEELDOWNMOUSE:
2511                         mPAN_Y -= 80
2512                         Draw.Redraw()
2513                 elif evt == Draw.WHEELUPMOUSE:
2514                         mPAN_Y += 80
2515                         Draw.Redraw()
2516         else: # = if val==False:
2517                 if evt==Draw.LEFTMOUSE:
2518                         scroll_pan = False
2519                 elif evt==Draw.MIDDLEMOUSE:
2520                         menu_pan = False
2521
2522 def bevent(evt):
2523         global config_UI, user_preset
2524         global CAMERA, GUI_A
2525
2526         ######### Manages GUI events
2527         if (evt==EVENT_EXIT):
2528                 Draw.Exit()
2529                 print 'DXF-Exporter  *** end ***'   #---------------------
2530         elif (evt==EVENT_CHOOSE_INI):
2531                 Window.FileSelector(ini_callback, "INI-file Selection", '*.ini')
2532         elif (evt==EVENT_REDRAW):
2533                 Draw.Redraw()
2534         elif (evt==EVENT_RESET):
2535                 resetDefaultConfig()
2536                 Draw.Redraw()
2537         elif (evt==EVENT_PRESET2D):
2538                 resetDefaultConfig_2D()
2539                 Draw.Redraw()
2540         elif (evt==EVENT_PRESET3D):
2541                 resetDefaultConfig_3D()
2542                 Draw.Redraw()
2543         elif evt in (EVENT_CAMERA,EVENT_LIGHT):
2544                 CAMERA = GUI_A['camera_on'].val
2545                 if CAMERA==len(CAMERAS)+1:
2546                         doAllCameras = True
2547                 else:
2548                         print 'deb: CAMERAS=',CAMERAS #----------------
2549                 Draw.Redraw()
2550         elif (evt==EVENT_setCAMERA):
2551                 if CAMERA<len(CAMERAS)+1:
2552                         gotoCAMERA()
2553
2554         elif (evt==EVENT_SCALE):
2555                 if g_scale_as.val == 12:
2556                         inputGlobalScale()
2557                 if GUI_A['g_scale'].val < 0.00000001:
2558                         GUI_A['g_scale'].val = 0.00000001
2559                 Draw.Redraw()
2560         elif (evt==EVENT_ORIGIN):
2561                 inputOriginVector()
2562                 Draw.Redraw()
2563         elif (evt==EVENT_PRESETPLINE):
2564                 presetConfig_polyline(GUI_A['to_polyline_on'].val)
2565                 Draw.Redraw()
2566         elif (evt==EVENT_PRESETS):
2567                 user_preset += 1
2568                 index = str(user_preset)
2569                 if user_preset > 5: user_preset = 0; index = ''
2570                 iniFileName.val = INIFILE_DEFAULT_NAME + index + INIFILE_EXTENSION
2571                 Draw.Redraw()
2572         elif (evt==EVENT_HELP):
2573                 try:
2574                         import webbrowser
2575                         webbrowser.open('http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf')
2576                 except:
2577                         Draw.PupMenu('DXF-Exporter: HELP Alert!%t|no connection to manual-page on Blender-Wiki! try:|\
2578 http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf')
2579                 Draw.Redraw()
2580         elif (evt==EVENT_LOAD_INI):
2581                 loadConfig()
2582                 Draw.Redraw()
2583         elif (evt==EVENT_SAVE_INI):
2584                 saveConfig()
2585                 Draw.Redraw()
2586         elif (evt==EVENT_DXF_DIR):
2587                 dxfFile = dxfFileName.val
2588                 dxfPathName = ''
2589                 if '/' in dxfFile:
2590                         dxfPathName = '/'.join(dxfFile.split('/')[:-1]) + '/'
2591                 elif '\\' in dxfFile:
2592                         dxfPathName = '\\'.join(dxfFile.split('\\')[:-1]) + '\\'
2593                 dxfFileName.val = dxfPathName + '*.dxf'
2594 #          dirname == Blender.sys.dirname(Blender.Get('filename'))
2595 #          update_RegistryKey('DirName', dirname)
2596 #          update_RegistryKey('dxfFileName', dxfFileName.val)
2597                 GUI_A['only_selected_on'].val = 1
2598                 Draw.Redraw()
2599         elif (evt==EVENT_CHOOSE_DXF):
2600                 filename = '' # '*.dxf'
2601                 if dxfFileName.val: filename = dxfFileName.val
2602                 Window.FileSelector(dxf_callback, "DXF-file Selection", filename)
2603         elif (evt==EVENT_START):
2604                 dxfFile = dxfFileName.val
2605                 #print 'deb: dxfFile file: ', dxfFile #----------------------
2606                 if E_M: dxfFileName.val, dxfFile = e_mode(dxfFile) #evaluation mode
2607                 update_RegistryKey('dxfFileName', dxfFileName.val)
2608                 update_globals()
2609                 if dxfFile.lower().endswith('*.dxf'):
2610                         if Draw.PupMenu('DXF-Exporter:  OK?|will write multiple DXF-files, one for each Scene, in:|%s' % dxfFile) == 1:
2611                                 global UI_MODE
2612                                 UI_MODE = False
2613                                 #TODO: multi_export(dxfFile[:-5])  # cut last 5 characters '*.dxf'
2614                                 Draw.Redraw()
2615                                 UI_MODE = True
2616                         else:
2617                                 Draw.Redraw()
2618                 elif dxfFile.lower()[-4:] in ('.dxf','.dwg'): # and Blender.sys.exists(dxfFile):
2619                         print '\nStandard Mode: active'
2620                         filepath = dxfFile
2621                         sce = Scene.GetCurrent()
2622                         if ONLYSELECTED: sel_group = sce.objects.selected
2623                         else: sel_group = sce.objects
2624                         
2625                         export_list = getObjectsAndDuplis(sel_group,MATRICES=True)
2626                 
2627                         if export_list: do_export(export_list, filepath)
2628                         else:
2629                                 print "Abort: selection was empty, no object to export!"
2630                                 Draw.PupMenu('DXF Exporter:   nothing exported!|empty selection!')
2631                 else:
2632                         Draw.PupMenu('DXF-Exporter:  Alert!%t|no valid DXF-file selected!')
2633                         print "DXF-Exporter: error, no valid DXF-file selected! try again"
2634                         Draw.Redraw()
2635
2636
2637
2638
2639 def multi_export(DIR): #TODO:
2640         """Imports all DXF-files from directory DIR.
2641         
2642         """
2643         global SCENE
2644         batchTIME = Blender.sys.time()
2645         #if #DIR == "": DIR = os.path.curdir
2646         if DIR == "": DIR = Blender.sys.dirname(Blender.Get('filename'))
2647         print 'Multifiles Import from %s' %DIR
2648         files = \
2649                 [Blender.sys.join(DIR, f) for f in os.listdir(DIR) if f.lower().endswith('.dxf')] 
2650         if not files:
2651                 print '...None DXF-files found. Abort!'
2652                 return
2653         
2654         i = 0
2655         for dxfFile in files:
2656                 i += 1
2657                 print '\nDXF-file', i, 'of', len(files) #,'\nImporting', dxfFile
2658                 if ONLYSELECTED:
2659                         _dxf_file = dxfFile.split('/')[-1].split('\\')[-1]
2660                         _dxf_file = _dxf_file[:-4]  # cut last char:'.dxf'
2661                         _dxf_file = _dxf_file[:NAMELENGTH_MAX]  #? [-NAMELENGTH_MAX:])
2662                         SCENE = Blender.Scene.New(_dxf_file)
2663                         SCENE.makeCurrent()
2664                         #or so? Blender.Scene.makeCurrent(_dxf_file)
2665                         #sce = bpy.data.scenes.new(_dxf_file)
2666                         #bpy.data.scenes.active = sce
2667                 else:
2668                         SCENE = Blender.Scene.GetCurrent()
2669                         SCENE.objects.selected = [] # deselect all
2670                 main(dxfFile)
2671                 #Blender.Redraw()
2672
2673         print 'TOTAL TIME: %.6f' % (Blender.sys.time() - batchTIME)
2674         print '\a\r', # beep when done
2675
2676
2677 #-----------------------------------------------------
2678 if __name__=='__main__':
2679
2680         if not DXF.copy:
2681                 Draw.PupMenu('Error%t|The dxfLibrary.py script requires a full python install')
2682         #Window.FileSelector(dxf_export_ui, 'EXPORT DXF', Blender.sys.makename(ext='.dxf'))
2683         # recall last used DXF-file and INI-file names
2684         dxffilename = check_RegistryKey('dxfFileName')
2685         #print 'deb:start dxffilename:', dxffilename #----------------
2686         if dxffilename: dxfFileName.val = dxffilename
2687         else:
2688                 dirname = Blender.sys.dirname(Blender.Get('filename'))
2689                 #print 'deb:start dirname:', dirname #----------------
2690                 dxfFileName.val = Blender.sys.join(dirname, '')
2691         inifilename = check_RegistryKey('iniFileName')
2692         if inifilename: iniFileName.val = inifilename
2693
2694         updateMenuCAMERA()
2695         updateCAMERA()
2696
2697         Draw.Register(draw_UI, event, bevent)
2698         
2699