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