~diresu/blender/blender-command-port

« back to all changes in this revision

Viewing changes to release/scripts/import_dxf.py

  • Committer: theeth
  • Date: 2008-10-14 16:52:04 UTC
  • Revision ID: vcs-imports@canonical.com-20081014165204-r32w2gm6s0osvdhn
copy back trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!BPY
 
2
 
 
3
"""
 
4
Name: 'Autodesk DXF (.dxf)'
 
5
Blender: 246
 
6
Group: 'Import'
 
7
Tooltip: 'Import for DXF geometry data (Drawing eXchange Format).'
 
8
"""
 
9
__author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)'
 
10
__version__ = '1.12 - 2008.08.03 by migius'
 
11
__url__ = ["http://blenderartists.org/forum/showthread.php?t=84319",
 
12
         "http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"]
 
13
__email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"]
 
14
__bpydoc__ = """\
 
15
This script imports objects from DXF (2d/3d) into Blender.
 
16
 
 
17
This script imports 2d and 3d geometery from DXF files.
 
18
Supported DXF format versions: from (r2.5) r12 up to 2008.
 
19
Enhanced features are:
 
20
- configurable object filtering and geometry manipulation,
 
21
- configurable material pre-processing,
 
22
- DXF-code analyze and reporting.
 
23
 
 
24
Supported DXF r12 objects:
 
25
LINE,
 
26
POINT,
 
27
SOLID,
 
28
TRACE,
 
29
TEXT,
 
30
INSERT (=block),
 
31
MINSERT (=array of blocks),
 
32
CIRCLE,
 
33
ARC,
 
34
3DFACE,
 
35
2d-POLYLINE (=plane, incl. arc, variable-width, curve, spline),
 
36
3d-POLYLINE (=non-plane),
 
37
3d-POLYMESH,
 
38
3d-POLYFACE,
 
39
VIEW, VPORT
 
40
XREF (External Reference).
 
41
 
 
42
Supported DXF>r12 objects:
 
43
ELLIPSE,
 
44
LWPOLYLINE (LightWeight Polyline),
 
45
SPLINE,
 
46
(wip v1.13) MLINE,
 
47
(wip v1.13) MTEXT
 
48
 
 
49
Unsupported objects:
 
50
DXF r12: DIMENSION.
 
51
DXF>r12: GROUP, RAY/XLINE, LEADER, 3DSOLID, BODY, REGION, dynamic BLOCK
 
52
 
 
53
Supported geometry: 2d and 3d DXF-objects.
 
54
Curves imported as Blender curves or meshes optionally.
 
55
 
 
56
Supported layout modes:
 
57
"model space" is default,
 
58
"paper space" as option (= "layout views")
 
59
 
 
60
Supported scene definition objescts produced with AVE_RENDER:
 
61
scene: selection of lights assigned to the camera,
 
62
lights: DIRECT, OVERHEAD, SH_SPOT,
 
63
(wip v1.13 import of AVE_RENDER material definitions)
 
64
 
 
65
Hierarchy:
 
66
Entire DXF BLOCK hierarchy is preserved after import into Blender
 
67
(BLOCKs as groups on layer19, INSERTs as dupliGroups on target layer).
 
68
 
 
69
Supported properties:
 
70
visibility status,
 
71
frozen status,
 
72
thickness,
 
73
width,
 
74
color,
 
75
layer,
 
76
(wip v1.13: XDATA, grouped status)
 
77
It is recommended to use DXF-object properties for assign Blender materials.
 
78
 
 
79
Notes:
 
80
- Recommend that you run 'RemoveDoubles' on each imported mesh after using this script
 
81
- Blocks are created on layer 19 then referenced at each insert point.
 
82
- support for DXF-files up to 160MB on systems with 1GB RAM
 
83
- DXF-files with over 1500 objects decrease import performance.
 
84
The problem is not the inefficiency of python-scripting but Blenders performance
 
85
in creating new objects in scene database - probably a database management problem.
 
86
 
 
87
"""
 
88
 
 
89
"""
 
90
History:
 
91
 v1.0 - 2007/2008 by migius
 
92
 planned tasks:
 
93
 -- (to see more, search for "--todo--" in script code)
 
94
 -- command-line-mode/batch-mode
 
95
 -- in-place-editing for dupliGroups
 
96
 -- support for MLINE (is exported to r12 as BLOCK*Unnamed with LINEs)
 
97
 -- support for MTEXT (is exported to r12 as TEXT???)
 
98
 -- blender_object.properties['dxf_layer_name']
 
99
 -- better support for long dxf-layer-names 
 
100
 -- add configuration file.ini handles multiple material setups
 
101
 -- added f_layerFilter
 
102
 -- to-check: obj/mat/group/_mapping-idea from ideasman42:
 
103
 -- curves: added "fill/non-fill" option for closed curves: CIRCLEs,ELLIPSEs,POLYLINEs
 
104
 -- "normalize Z" option to correct non-planar figures
 
105
 -- LINEs need "width" in 3d-space incl vGroups
 
106
 -- support width_force for LINEs/ELLIPSEs = "solidify"
 
107
 -- add better support for color_index BYLAYER=256, BYBLOCK=0 
 
108
 -- bug: "oneMesh" produces irregularly errors
 
109
 -- bug: Registry recall from hd_cache ?? only win32 bug??
 
110
 -- support DXF-definitions of scene, lights and cameras
 
111
 -- support ortho mode for VIEWs and VPORTs as cameras 
 
112
 
 
113
 
 
114
 v1.12 - 2008.08.03 by migius
 
115
 c2 warningfix: relocating of globals: layersmap, oblist 
 
116
 c2 modif UI: buttons newScene+targetLayer moved to start panel
 
117
 v1.12 - 2008.07.04 by migius
 
118
 c1 added control Curve's OrderU parameter
 
119
 c1 modif UI: preset buttons X-2D-3D moved to start panel
 
120
 b6 added handling exception of not registered LAYERs (Hammer-HL-editor DXF output)
 
121
 b5 rebuild UI: global preset 2D for Curve-Import
 
122
 b5 added UI-options: PL-MESH N+N plmesh_flip and normals_out 
 
123
 b5 added support for SPLINEs, added control OrderU parameter
 
124
 b5 rewrote draw module for NURBS_curve and Bezier_curve
 
125
 v1.12 - 2008.06.22 by migius
 
126
 b4 change versioning system 1.0.12 -> 1.12
 
127
 b4 print at start version-info to console
 
128
 b3 bugfix: ob.name conflict with existing meshes (different ob.name/mesh.name)
 
129
 v1.0.12: 2008.05.24 by migius
 
130
 b2 added support for LWPOLYLINEs
 
131
 b2 added support for ProE in readerDXF.py
 
132
 v1.0.12: 2008.02.08 by migius
 
133
 b1 update: object = Object.Get(obname) -> f_getSceChild().getChildren()
 
134
 a9 bugfix by non-existing tables views, vports, layers (Kai reported)
 
135
 v1.0.12: 2008.01.17 by migius
 
136
 a8 lately used INI-dir/filename persistently stored in Registry
 
137
 a8 lately used DXF-dir/filename persistently stored in Registry
 
138
 a7 fix missing layersmap{} for dxf-files without "section:layer"
 
139
 a6 added support for XREF external referenced BLOCKs
 
140
 a6 check for bug in AutoCAD2002:DXFr12export: ELLIPSE->POLYLINE_ARC fault angles
 
141
 a6 support VIEWs and VPORTs as cameras: ortho and perspective mode
 
142
 a6 save resources through ignoring unused BLOCKs (not-inserted or on frozen/blocked layers)
 
143
 a6 added try_finally: f.close() for all IO-files
 
144
 a6 added handling for TypeError raise
 
145
 a5 bugfix f_getOCS for (0,0,z!=1.0) (ellipse in Kai's dxf)
 
146
 a4 added to analyzeTool: report about VIEWs, VPORTs, unused/xref BLOCKs
 
147
 a4 bugfix: individual support for 2D/3DPOLYLINE/POLYMESH
 
148
 a4 added to UI: (*wip)BLOCK-(F): name filtering for BLOCKs
 
149
 a4 added to UI: BLOCK-(n): filter anoname/hatch BLOCKs *X...
 
150
 a2 g_scale_as is no more GUI_A-variable
 
151
 a2 bugfix "material": negative sign color_index
 
152
 a2 added support for BLOCKs defined with origin !=(0,0,0)
 
153
 a1 added 'global.reLocation-vector' option
 
154
 
 
155
 v1.0.11: 2007.11.24 by migius
 
156
 c8 added 'curve_resolution_U' option 
 
157
 c8 added context_sensitivity for some UI-buttons
 
158
 c8 bugfix ELLIPSE rotation, added closed_variant and caps
 
159
 c7 rebuild UI: new layout, grouping and meta-buttons
 
160
 c6 rewritten support for ELLIPSE mesh & curve representation
 
161
 c6 restore selector-buttons for DXF-drawTypes: LINE & Co
 
162
 c6 change header of INI/INF-files: # at begin
 
163
 c6 apply scale(1,1,1) after glob.Scale for all mesh objects, not for curve objects.
 
164
 c5 fixing 'material_on' option
 
165
 c4 added "analyze DXF-file" UI-option: print LAYER/BLOCK-dependences into a textfile
 
166
 c3 human-formating of data in INI-Files
 
167
 c2 added "caps" for closed Bezier-curves
 
168
 c2 added "set elevation" UI-option
 
169
 c1 rewrite POLYLINE2d-arc-segments Bezier-interpreter
 
170
 b9 many bugs fixed
 
171
 b9 rewrite POLYLINE2d-arc-segments trimming (clean-trim)
 
172
 b8 added "import from frozen layers" UI-option
 
173
 b8 added "import from paper space" UI-option
 
174
 b8 support Bezier curves for LINEs incl.thickness(0.0-10.0)
 
175
 b8 added meshSmooth_on for circle/arc/polyline 
 
176
 b8 added vertexGroups for circle/arc 
 
177
 b7 added width_force for ARCs/CIRCLEs = "thin_box" option
 
178
 b3 cleanup code, rename f_drawArc/Bulg->f_calcArc/Bulg
 
179
 b2 fixing material assignment by LAYER+COLOR
 
180
 b1 fixing Bezier curves representation of POLYLINEs-arc-segments
 
181
 b0 added global_scale_presets: "yard/feet/inch to meter"
 
182
 
 
183
 v1.0.10: 2007.10.18 by migius
 
184
 a6 bugfix CircleDrawCaps for OSX 
 
185
 a5 added two "curve_res" UI-buttons for Bezier curves representation
 
186
 a5 improved Bezier curves representation of circles/arcs: correct handlers
 
187
 a4 try to fix malformed endpoints of Blender curves of ARC/POLYLINE-arc segments. 
 
188
 a3 bugfix: open-POLYLINEs with end_point.loc==start_point.loc
 
189
 a2 bugfix: f_transform for OCS=(0,0,-1) oriented objects
 
190
 a1 added "fill_on=caps" option to draw top and bottom sides of CIRCLEs and ELLIPSEs
 
191
 a1 rewrite f_CIRCLE.Draw: from Mesh.Primitive to Mesh
 
192
 a1 bugfix "newScene"-mode: all Cylinders/Arcs were drawn at <0,0,0>location
 
193
 
 
194
 v1.0.beta09: 2007.09.02 by migius
 
195
 g5 redesign UI: grouping of buttons
 
196
 g3 update multi-import-mode: <*.*> button
 
197
 g- added multi-import-mode: (path/*) for importing many dxf-files at once
 
198
 g- added import into newScene
 
199
 g- redesign UI: user presets, into newScene-import  
 
200
 f- cleanup code
 
201
 f- bugfix: thickness for Bezier/Bsplines into Blender-curves
 
202
 f- BlenderWiki documentation, on-line Manual
 
203
 f- added import POLYLINE-Bsplines into Blender-NURBSCurves
 
204
 f- added import POLYLINE-arc-segments into Blender-BezierCurves
 
205
 f- added import POLYLINE-Bezier-curves into Blender-Curves
 
206
 d5 rewrite: Optimization Levels, added 'directDrawing'
 
207
 d4 added: f_set_thick(controlled by ini-parameters)
 
208
 d4 bugfix: face-normals in objects with minus thickness
 
209
 d4 added: placeholder'Empty'-size in f_Insert.draw
 
210
 d3 rewrite f_Text.Draw: added support for all Text's parameters
 
211
 d2 redesign: progressbar 
 
212
 e- tuning by ideasman42: better use of the Py API.
 
213
 c- tuning by ideasman42
 
214
 b- rewrite f_Text.Draw rotation/transform
 
215
 b- bugfix: POLYLINE-segment-intersection more reliable now
 
216
 b- bugfix: circle:_thic, 'Empties':no material_assignment
 
217
 b- added material assignment (from layer and/or color)
 
218
 a- added empty, cylinder and UVsphere for POINTs
 
219
 a- added support for 2d-POLYLINE: splines, fitted curves, fitted surfaces
 
220
 a- redesign f_Drawer for block_definitions
 
221
 a- rewrite import into Blender-Curve-Object
 
222
 
 
223
 v1.0.beta08 - 2007.07.27 by migius: "full 3d"-release
 
224
 l- bugfix: solid_vgroups, clean:scene.objects.new()
 
225
 l- redesign UI to standard Draw.Register+FileSelector, advanced_config_option
 
226
 k- bugfix UI:fileSelect() for MacOSX os.listdir()
 
227
 k- added reset/save/load for config-data
 
228
 k- redesign keywords/drawTypes/Draw.Create_Buttons
 
229
 j- new UI using UIBlock() with own FileSelector, cause problem Window.FileSelector()
 
230
 i- rewritten Class:Settings for better config-parameter management
 
231
 h- bugfix: face-normals in objects with minus thickness
 
232
 h- added Vertex-Groups in POLYLINE and SOLID meshes, for easy material assignment
 
233
 h- beautify code, whitespace->tabs
 
234
 h- added settings.thic_force switch for forcing thickness
 
235
 h- added "one Mesh" option for all entities from the same Layer, sorted in<br>
 
236
 Vertex-Groups(color_name)  (fewer objects = better import performance)
 
237
 g- rewrote: insert-point-handle-object is a small tetrahedron
 
238
 e- bugfix: closed-polymesh3d
 
239
 - rewrote: UI, type_map.keys, f_drawer, all class_f_draw(added "settings" as attribut)
 
240
 - added 2d/3d-support for Polyline_Width incl. angle intersection
 
241
 beta07: 2007.06.19 by migius
 
242
 - added 3d-support for LWPolylines
 
243
 - added 2d/3d-support for Points
 
244
 beta06: 2007.06.15 by migius
 
245
 - cleanup code
 
246
 - added 2d/3d-support for MINSERT=BlockArray in f_drawer, added f_rotXY_Vec
 
247
 beta05: 2007.06.14 by migius
 
248
 - added 2d/3d-support for 3d-PolyLine, PolyMesh and PolyFace
 
249
 - added Global-Scale for size control of imported scenes
 
250
 beta04: 2007.06.12 by migius
 
251
 - rewrote the f_drawBulge for correct import the arc-segments of Polylines
 
252
 beta03: 2007.06.10 by migius
 
253
 - rewrote interface
 
254
 beta02: 2007.06.09 by migius
 
255
 - added 3d-support for Arcs and Circles
 
256
 - added support for Object_Thickness(=height)
 
257
 beta01: 2007.06.08 by migius
 
258
 - added 3d-support for Blocks/Inserts within nested-structures
 
259
 - rewrote f_transform for correct 3d-location/3d-rotation
 
260
 - added 3d-support Lines, 3dFaces
 
261
 - added 2d+3d-support for Solids and Traces
 
262
 
 
263
 v0.9 - 2007.01 by kitsu: (for 2.43)
 
264
 - first draft of true POLYLINE import
 
265
 -
 
266
 
 
267
 v0.8 - 2006.12 by kitsu:
 
268
 - first draft of object space coordinates OCS import
 
269
 -
 
270
 
 
271
 v0.5b - 2006.10 by kitsu: (for 2.42a)
 
272
 - dxfReader.py
 
273
 - color_map.py
 
274
 
 
275
"""
 
276
 
 
277
# --------------------------------------------------------------------------
 
278
# DXF Import v1.0 by Ed Blake (AKA kitsu) and Remigiusz Fiedler (AKA migius)
 
279
# --------------------------------------------------------------------------
 
280
# ***** BEGIN GPL LICENSE BLOCK *****
 
281
#
 
282
# This program is free software; you can redistribute it and/or
 
283
# modify it under the terms of the GNU General Public License
 
284
# as published by the Free Software Foundation; either version 2
 
285
# of the License, or (at your option) any later version.
 
286
#
 
287
# This program is distributed in the hope that it will be useful,
 
288
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
289
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
290
# GNU General Public License for more details.
 
291
#
 
292
# You should have received a copy of the GNU General Public License
 
293
# along with this program; if not, write to the Free Software Foundation,
 
294
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
295
#
 
296
# ***** END GPL LICENCE BLOCK *****
 
297
# --------------------------------------------------------------------------
 
298
 
 
299
import Blender
 
300
from Blender import *
 
301
#from Blender.Mathutils import Vector, Matrix
 
302
import bpy
 
303
#import BPyMessages
 
304
 
 
305
from dxfReader import readDXF
 
306
#from dxfReader import get_name, get_layer
 
307
from dxfReader import Object as dxfObject
 
308
from dxfColorMap import color_map
 
309
 
 
310
from math import *
 
311
 
 
312
try:
 
313
        import os
 
314
        if os.name:# != 'mac':
 
315
                import psyco
 
316
                psyco.log(Blender.Get('tempdir')+"/blender.log-psyco")
 
317
                #psyco.log()
 
318
                psyco.full(memory=100)
 
319
                psyco.profile(0.05, memory=100)
 
320
                psyco.profile(0.2)
 
321
                #print 'psyco imported'
 
322
except ImportError:
 
323
        #print 'psyco not imported'
 
324
        pass
 
325
 
 
326
#try: Curve.orderU
 
327
 
 
328
print '\n\n\n'
 
329
print 'DXF-Importer v%s *** start ***' %(__version__)   #---------------------
 
330
 
 
331
SCENE = None
 
332
WORLDX = Mathutils.Vector((1,0,0))
 
333
WORLDY = Mathutils.Vector((1,1,0))
 
334
WORLDZ = Mathutils.Vector((0,0,1))
 
335
 
 
336
G_SCALE = 1.0      #(0.0001-1000) global scaling factor for all dxf data
 
337
G_ORIGIN_X = 0.0   #global translation-vector (x,y,z) in DXF units
 
338
G_ORIGIN_Y = 0.0
 
339
G_ORIGIN_Z = 0.0
 
340
MIN_DIST = 0.001        #cut-off value for sort out short-distance polyline-"duoble_vertex"
 
341
ARC_RESOLUTION = 64   #(4-500) arc/circle resolution - number of segments
 
342
ARC_RADIUS = 1.0   #(0.01-100) arc/circle radius for number of segments algorithm
 
343
CURV_RESOLUTION = 12 #(1-128) Bezier curves U-resolution
 
344
CURVARC_RESOLUTION = 4 #(3-32) resolution of circle represented as Bezier curve 
 
345
THIN_RESOLUTION = 8   #(4-64) thin_cylinder arc_resolution - number of segments
 
346
MIN_THICK = MIN_DIST * 10.0  #minimal thickness by forced thickness
 
347
MIN_WIDTH = MIN_DIST * 10.0  #minimal width by forced width
 
348
TRIM_LIMIT = 3.0         #limit for triming of polylines-wide-segments (values:0.0 - 5.0)
 
349
ELEVATION = 0.0 #standard elevation = coordinate Z
 
350
 
 
351
BYBLOCK = 0
 
352
BYLAYER = 256
 
353
TARGET_LAYER = 3        #target blender_layer
 
354
GROUP_BYLAYER = 0   #(0/1) all entities from same layer import into one blender-group
 
355
LAYER_DEF_NAME = 'AAAA' #default layer name
 
356
LAYER_DEF_COLOR = 4 #default layer color
 
357
E_M = 0
 
358
LAB = "*) parts under construction"
 
359
M_OBJ = 0
 
360
 
 
361
FILENAME_MAX = 180      #max length of path+file_name string  (FILE_MAXDIR + FILE_MAXFILE)
 
362
MAX_NAMELENGTH = 17   #max_effective_obnamelength in blender =21=17+(.001)
 
363
INIFILE_DEFAULT_NAME = 'importDXF'
 
364
INIFILE_EXTENSION = '.ini'
 
365
INIFILE_HEADER = '#ImportDXF.py ver.1.0 config data'
 
366
INFFILE_HEADER = '#ImportDXF.py ver.1.0 analyze of DXF-data'
 
367
 
 
368
AUTO = BezTriple.HandleTypes.AUTO
 
369
FREE = BezTriple.HandleTypes.FREE
 
370
VECT = BezTriple.HandleTypes.VECT
 
371
ALIGN = BezTriple.HandleTypes.ALIGN
 
372
 
 
373
 
 
374
class View:  #-----------------------------------------------------------------
 
375
        """Class for objects representing dxf VIEWs.
 
376
        """
 
377
        def __init__(self, obj, active=None):
 
378
                """Expects an object of type VIEW as input.
 
379
                """
 
380
                if not obj.type == 'view':
 
381
                        raise TypeError, "Wrong type %s for VIEW object!" %obj.type
 
382
 
 
383
                self.type = obj.type
 
384
                self.name = obj.get_type(2)[0]
 
385
#               self.data = obj.data[:]
 
386
 
 
387
 
 
388
                self.centerX = getit(obj, 10, 0.0) #view center pointX (in DCS)
 
389
                self.centerY = getit(obj, 20, 0.0) #view center pointY (in DCS)
 
390
                self.height = obj.get_type(40)[0] #view height (in DCS)
 
391
                self.width = obj.get_type(41)[0] #view width (in DCS)
 
392
 
 
393
                self.dir = [0,0,0]
 
394
                self.dir[0] = getit(obj, 11, 0.0) #view directionX from target (in WCS)
 
395
                self.dir[1] = getit(obj, 21, 0.0) #
 
396
                self.dir[2] = getit(obj, 31, 0.0) #
 
397
 
 
398
                self.target = [0,0,0]
 
399
                self.target[0] = getit(obj, 12, 0.0) #target pointX(in WCS)
 
400
                self.target[1] = getit(obj, 22, 0.0) #
 
401
                self.target[2] = getit(obj, 32, 0.0) #
 
402
 
 
403
                self.length = obj.get_type(42)[0] #Lens length
 
404
                self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
 
405
                self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
 
406
                self.twist  = obj.get_type(50)[0] #view twist angle in degrees
 
407
 
 
408
                self.flags = getit(obj, 70, 0)
 
409
                self.paperspace = self.flags & 1 #
 
410
 
 
411
                self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
 
412
 
 
413
        def __repr__(self):
 
414
                return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
 
415
 
 
416
 
 
417
        def draw(self, settings):
 
418
                """for VIEW: generate Blender_camera.
 
419
                """
 
420
                obname = 'vw_%s' %self.name  # create camera object name
 
421
                #obname = 'ca_%s' %self.name  # create camera object name
 
422
                obname = obname[:MAX_NAMELENGTH]
 
423
 
 
424
                if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
 
425
                        cam= Camera.New('ortho', obname)
 
426
                        ob= SCENE.objects.new(cam)
 
427
                        cam.type = 'ortho'
 
428
                        cam.scale = 1.0  # for ortho cameras
 
429
                else:
 
430
                        cam= Camera.New('persp', obname)
 
431
                        ob= SCENE.objects.new(cam)
 
432
                        cam.type = 'persp'
 
433
                        cam.angle = 60.0  # for persp cameras
 
434
                        if self.length:
 
435
                                #cam.angle = 2 * atan(17.5/self.length) * 180/pi
 
436
                                cam.lens = self.length #for persp cameras
 
437
                        # hack to update Camera>Lens setting (inaccurate as a focal length) 
 
438
                        #curLens = cam.lens; cam.lens = curLens
 
439
                        # AutoCAD gets clip distance from target:
 
440
                        dist = Mathutils.Vector(self.dir).length
 
441
                        cam.clipEnd = dist - self.clip_back
 
442
                        cam.clipStart = dist - self.clip_front
 
443
        
 
444
                cam.drawLimits = 1 
 
445
                cam.drawSize = 10
 
446
                
 
447
                v = Mathutils.Vector(self.dir)
 
448
#               print 'deb:view cam:', cam #------------
 
449
#               print 'deb:view self.target:', self.target #------------
 
450
#               print 'deb:view self.dir:', self.dir #------------
 
451
#               print 'deb:view self.twist:', self.twist #------------
 
452
#               print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
 
453
                transform(v.normalize(), -self.twist, ob)
 
454
                ob.loc =  Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
 
455
                return ob
 
456
 
 
457
 
 
458
class Vport:  #-----------------------------------------------------------------
 
459
        """Class for objects representing dxf VPORTs.
 
460
        """
 
461
        def __init__(self, obj, active=None):
 
462
                """Expects an object of type VPORT as input.
 
463
                """
 
464
                if not obj.type == 'vport':
 
465
                        raise TypeError, "Wrong type %s for VPORT object!" %obj.type
 
466
 
 
467
                self.type = obj.type
 
468
                self.name = obj.get_type(2)[0]
 
469
#               self.data = obj.data[:]
 
470
                #print 'deb:vport name, data:', self.name #-------
 
471
                #print 'deb:vport data:', self.data #-------
 
472
 
 
473
                self.height = obj.get_type(40)[0] #vport height (in DCS)
 
474
                self.centerX = getit(obj, 12, 0.0) #vport center pointX (in DCS)
 
475
                self.centerY = getit(obj, 22, 0.0) #vport center pointY (in DCS)
 
476
                self.width = self.height * obj.get_type(41)[0] #vport aspect ratio - width (in DCS)
 
477
 
 
478
                self.dir = [0,0,0]
 
479
                self.dir[0] = getit(obj, 16, 0.0) #vport directionX from target (in WCS)
 
480
                self.dir[1] = getit(obj, 26, 0.0) #
 
481
                self.dir[2] = getit(obj, 36, 0.0) #
 
482
 
 
483
                self.target = [0,0,0]
 
484
                self.target[0] = getit(obj, 17, 0.0) #target pointX(in WCS)
 
485
                self.target[1] = getit(obj, 27, 0.0) #
 
486
                self.target[2] = getit(obj, 37, 0.0) #
 
487
 
 
488
                self.length = obj.get_type(42)[0] #Lens length
 
489
                self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
 
490
                self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
 
491
                self.twist  = obj.get_type(51)[0] #view twist angle
 
492
 
 
493
                self.flags = getit(obj, 70, 0)
 
494
                self.paperspace = self.flags & 1 #
 
495
 
 
496
                self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
 
497
 
 
498
        def __repr__(self):
 
499
                return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
 
500
 
 
501
        def draw(self, settings):
 
502
                """for VPORT: generate Blender_camera.
 
503
                """
 
504
                obname = 'vp_%s' %self.name  # create camera object name
 
505
                #obname = 'ca_%s' %self.name  # create camera object name
 
506
                obname = obname[:MAX_NAMELENGTH]
 
507
 
 
508
                if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
 
509
                        cam= Camera.New('ortho', obname)
 
510
                        ob= SCENE.objects.new(cam)
 
511
                        cam.type = 'ortho'
 
512
                        cam.scale = 1.0  # for ortho cameras
 
513
                else:
 
514
                        cam= Camera.New('persp', obname)
 
515
                        ob= SCENE.objects.new(cam)
 
516
                        cam.type = 'persp'
 
517
                        cam.angle = 60.0  # for persp cameras
 
518
                        if self.length:
 
519
                                #cam.angle = 2 * atan(17.5/self.length) * 180/pi
 
520
                                cam.lens = self.length #for persp cameras
 
521
                        # hack to update Camera>Lens setting (inaccurate as a focal length) 
 
522
                        #curLens = cam.lens; cam.lens = curLens
 
523
                        # AutoCAD gets clip distance from target:
 
524
                        dist = Mathutils.Vector(self.dir).length
 
525
                        cam.clipEnd = dist - self.clip_back
 
526
                        cam.clipStart = dist - self.clip_front
 
527
        
 
528
                cam.drawLimits = 1 
 
529
                cam.drawSize = 10
 
530
                
 
531
                v = Mathutils.Vector(self.dir)
 
532
#               print 'deb:view cam:', cam #------------
 
533
#               print 'deb:view self.target:', self.target #------------
 
534
#               print 'deb:view self.dir:', self.dir #------------
 
535
#               print 'deb:view self.twist:', self.twist #------------
 
536
#               print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
 
537
                transform(v.normalize(), -self.twist, ob)
 
538
                ob.loc =  Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
 
539
                return ob
 
540
 
 
541
 
 
542
 
 
543
class Layer:  #-----------------------------------------------------------------
 
544
        """Class for objects representing dxf LAYERs.
 
545
        """
 
546
        def __init__(self, obj, name=None, color=None, frozen=None):
 
547
                """Expects an dxfobject of type layer as input.
 
548
                        if no dxfobject - creates surogate layer with default parameters
 
549
                """
 
550
 
 
551
                if obj==None:
 
552
                        self.type = 'layer'
 
553
                        if name: self.name = name
 
554
                        else: self.name = LAYER_DEF_NAME
 
555
 
 
556
                        if color: self.color = color
 
557
                        else: self.color = LAYER_DEF_COLOR
 
558
 
 
559
                        if frozen!=None: self.frozen = frozen
 
560
                        else: self.frozen = 0
 
561
                else:   
 
562
                        if obj.type=='layer':
 
563
                                self.type = obj.type
 
564
                                #self.data = obj.data[:]
 
565
                                if name: self.name = name
 
566
                                        #self.bfname = name  #--todo---see layernamesmap in f_getLayersmap ---
 
567
                                else: self.name = obj.get_type(2)[0] #layer name of object
 
568
                
 
569
                                if color: self.color = color
 
570
                                else: self.color = obj.get_type(62)[0]  #color of object
 
571
                
 
572
                                if frozen!=None: self.frozen = frozen
 
573
                                else:
 
574
                                        self.flags = obj.get_type(70)[0]
 
575
                                        self.frozen = self.flags & 1
 
576
        
 
577
        def __repr__(self):
 
578
                return "%s: name - %s, color - %s" %(self.__class__.__name__, self.name, self.color)
 
579
 
 
580
 
 
581
 
 
582
def getit(obj, typ, default=None):  #------------------------------------------
 
583
        """Universal procedure for geting data from list/objects.
 
584
        """
 
585
        it = default
 
586
        if type(obj) == list:  #if obj is a list, then searching in a list
 
587
                for item in obj:
 
588
                        #print 'deb:getit item, type(item)', item, type(item)
 
589
                        try:
 
590
                                if item[0] == typ:
 
591
                                        it = item[1]
 
592
                                        break  #as soon as the first found
 
593
                        except:
 
594
                                # --todo-- I found one case where item was a text instance
 
595
                                # that failed with no __getitem__
 
596
                                pass
 
597
        else:   #else searching in Object with get_type-Methode
 
598
                item = obj.get_type(typ)
 
599
                if item:
 
600
                        it = item[0]
 
601
        #print 'deb:getit:typ, it', typ, it #----------
 
602
        return it
 
603
 
 
604
 
 
605
 
 
606
def get_extrusion(data):         #-------------------------------------------------
 
607
        """Find the axis of extrusion.
 
608
 
 
609
        Used to get from object_data the objects Object_Coordinate_System (ocs).
 
610
        """
 
611
        #print 'deb:get_extrusion: data: \n', data  #---------------
 
612
        vec = [0,0,1]
 
613
        vec[0] = getit(data, 210, 0) # 210 = x
 
614
        vec[1] = getit(data, 220, 0) # 220 = y
 
615
        vec[2] = getit(data, 230, 1) # 230 = z
 
616
        #print 'deb:get_extrusion: vec: ', vec  #---------------
 
617
        return vec
 
618
 
 
619
 
 
620
#------------------------------------------
 
621
def getSceneChild(name):
 
622
        dudu = [i for i in SCENE.objects if i.name==name]
 
623
#       dudu = [i for i in SCENE.getChildren() if i.name==name]
 
624
        #print 'deb:getSceneChild %s -result: %s:' %(name,dudu) #-----------------
 
625
        if dudu!=[]: return dudu[0]
 
626
        return None
 
627
 
 
628
 
 
629
class Solid:  #-----------------------------------------------------------------
 
630
        """Class for objects representing dxf SOLID or TRACE.
 
631
        """
 
632
        def __init__(self, obj):
 
633
                """Expects an entity object of type solid or trace as input.
 
634
                """
 
635
                if obj.type == 'trace':
 
636
                        obj.type = 'solid'
 
637
                if not obj.type == 'solid':
 
638
                        raise TypeError, "Wrong type \'%s\' for solid/trace object!" %obj.type
 
639
 
 
640
                self.type = obj.type
 
641
#               self.data = obj.data[:]
 
642
 
 
643
                self.space = getit(obj, 67, 0)
 
644
                self.thic =  getit(obj, 39, 0)
 
645
                self.color_index = getit(obj, 62, BYLAYER)
 
646
 
 
647
                self.layer = getit(obj, 8, None)
 
648
                self.extrusion = get_extrusion(obj)
 
649
                self.points = self.get_points(obj)
 
650
 
 
651
 
 
652
 
 
653
        def get_points(self, data):
 
654
                """Gets start and end points for a solid type object.
 
655
 
 
656
                Solids have 3 or 4 points and fixed codes for each value.
 
657
                """
 
658
 
 
659
                # start x, y, z and end x, y, z = 0
 
660
                a = [0, 0, 0]
 
661
                b = [0, 0, 0]
 
662
                c = [0, 0, 0]
 
663
                d = [0, 0, 0]
 
664
                a[0] = getit(data, 10, None) # 10 = x
 
665
                a[1] = getit(data, 20, None) # 20 = y
 
666
                a[2] = getit(data, 30,  0)   # 30 = z
 
667
                b[0] = getit(data, 11, None)
 
668
                b[1] = getit(data, 21, None)
 
669
                b[2] = getit(data, 31,  0)
 
670
                c[0] = getit(data, 12, None)
 
671
                c[1] = getit(data, 22, None)
 
672
                c[2] = getit(data, 32,  0)
 
673
                out = [a,b,c]
 
674
 
 
675
                d[0] =  getit(data, 13, None)
 
676
                if d[0] != None:
 
677
                        d[1] = getit(data, 23, None)
 
678
                        d[2] = getit(data, 33,  0)
 
679
                        out.append(d)
 
680
                #print 'deb:solid.vertices:---------\n', out  #-----------------------
 
681
                return out
 
682
 
 
683
 
 
684
        def __repr__(self):
 
685
                return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
 
686
 
 
687
 
 
688
        def draw(self, settings):
 
689
                """for SOLID: generate Blender_geometry.
 
690
                """
 
691
                points = self.points
 
692
                if not points: return
 
693
                edges, faces = [], []
 
694
                l = len(self.points)
 
695
 
 
696
                obname = 'so_%s' %self.layer  # create object name from layer name
 
697
                obname = obname[:MAX_NAMELENGTH]
 
698
 
 
699
                vg_left, vg_right, vg_top, vg_bottom, vg_start, vg_end = [], [], [], [], [], []
 
700
                thic = set_thick(self.thic, settings)
 
701
                if thic != 0:
 
702
                        thic_points = [[v[0], v[1], v[2] + thic] for v in points[:]]
 
703
                        if thic < 0.0:
 
704
                                thic_points.extend(points)
 
705
                                points = thic_points
 
706
                        else:
 
707
                                points.extend(thic_points)
 
708
 
 
709
                        if   l == 4:
 
710
                                faces = [[0,1,3,2], [4,6,7,5], [0,4,5,1],
 
711
                                                 [1,5,7,3], [3,7,6,2], [2,6,4,0]]
 
712
                                vg_left = [2,6,4,0]
 
713
                                vg_right = [1,5,7,3]
 
714
                                vg_top = [4,6,7,5]
 
715
                                vg_bottom = [0,1,3,2]
 
716
                                vg_start = [0,4,5,1]
 
717
                                vg_end = [3,7,6,2]
 
718
                        elif l == 3:
 
719
                                faces = [[0,1,2], [3,5,4], [0,3,4,1], [1,4,5,2], [2,5,3,0]]
 
720
                                vg_top = [3,4,5]
 
721
                                vg_bottom = [0,1,2]
 
722
                                vg_left = [2,5,3,0]
 
723
                                vg_right = [1,4,5,2]
 
724
                                vg_start = [0,3,4,1]
 
725
                        elif l == 2: faces = [[0,1,3,2]]
 
726
                else:
 
727
                        if   l == 4: faces = [[0,1,3,2]]
 
728
                        elif l == 3: faces = [[0,1,2]]
 
729
                        elif l == 2: edges = [[0,1]]
 
730
                
 
731
                if M_OBJ: obname, me, ob = makeNewObject()
 
732
                else: 
 
733
                        me = Mesh.New(obname)           # create a new mesh
 
734
                        ob = SCENE.objects.new(me) # create a new mesh_object
 
735
                me.verts.extend(points)         # add vertices to mesh
 
736
                if faces: me.faces.extend(faces)                   # add faces to the mesh
 
737
                if edges: me.edges.extend(edges)                   # add faces to the mesh
 
738
 
 
739
                if settings.var['vGroup_on'] and not M_OBJ:
 
740
                        # each MeshSide becomes vertexGroup for easier material assignment ---------------------
 
741
                        replace = Blender.Mesh.AssignModes.ADD  #or .AssignModes.ADD/REPLACE
 
742
                        if vg_left: me.addVertGroup('side.left')  ; me.assignVertsToGroup('side.left',  vg_left, 1.0, replace)
 
743
                        if vg_right:me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
 
744
                        if vg_top:  me.addVertGroup('side.top')   ; me.assignVertsToGroup('side.top',   vg_top, 1.0, replace)
 
745
                        if vg_bottom:me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
 
746
                        if vg_start:me.addVertGroup('side.start') ; me.assignVertsToGroup('side.start', vg_start, 1.0, replace)
 
747
                        if vg_end:  me.addVertGroup('side.end')   ; me.assignVertsToGroup('side.end',   vg_end,   1.0, replace)
 
748
 
 
749
                transform(self.extrusion, 0, ob)
 
750
 
 
751
                return ob
 
752
 
 
753
class Line:  #-----------------------------------------------------------------
 
754
        """Class for objects representing dxf LINEs.
 
755
        """
 
756
        def __init__(self, obj):
 
757
                """Expects an entity object of type line as input.
 
758
                """
 
759
                if not obj.type == 'line':
 
760
                        raise TypeError, "Wrong type \'%s\' for line object!" %obj.type
 
761
                self.type = obj.type
 
762
#               self.data = obj.data[:]
 
763
 
 
764
                self.space = getit(obj, 67, 0)
 
765
                self.thic =  getit(obj, 39, 0)
 
766
                #print 'deb:self.thic: ', self.thic #---------------------
 
767
                self.color_index = getit(obj, 62, BYLAYER)
 
768
 
 
769
                self.layer = getit(obj, 8, None)
 
770
                self.extrusion = get_extrusion(obj)
 
771
                self.points = self.get_points(obj)
 
772
 
 
773
 
 
774
        def get_points(self, data):
 
775
                """Gets start and end points for a line type object.
 
776
 
 
777
                Lines have a fixed number of points (two) and fixed codes for each value.
 
778
                """
 
779
                # start x,y,z and end x,y,z = 0
 
780
                a = [0, 0, 0]
 
781
                b = [0, 0, 0]
 
782
                a[0] = getit(data, 10, None) # 10 = x
 
783
                a[1] = getit(data, 20, None) # 20 = y
 
784
                a[2] = getit(data, 30,  0) # 30 = z
 
785
                b[0] = getit(data, 11, None)
 
786
                b[1] = getit(data, 21, None)
 
787
                b[2] = getit(data, 31,  0)
 
788
                out = [a,b]
 
789
                return out
 
790
 
 
791
 
 
792
        def __repr__(self):
 
793
                return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
 
794
 
 
795
 
 
796
        def draw(self, settings):
 
797
                """for LINE: generate Blender_geometry.
 
798
                """
 
799
                # Generate the geometery
 
800
                #settings.var['curves_on']=False
 
801
 
 
802
                points = self.points
 
803
                thic = set_thick(self.thic, settings)
 
804
                width = 0.0
 
805
                if settings.var['lines_as'] == 4: # as thin_box
 
806
                        thic = settings.var['thick_min']
 
807
                        width = settings.var['width_min']
 
808
                elif settings.var['lines_as'] == 3: # as thin cylinder
 
809
                        cyl_rad = 0.5 * settings.var['width_min']
 
810
 
 
811
                elif settings.var['lines_as'] == 5: # LINE curve representation-------------------------
 
812
                        obname = 'li_%s' %self.layer  # create object name from layer name
 
813
                        obname = obname[:MAX_NAMELENGTH]
 
814
 
 
815
                        c = Curve.New(obname) # create new curve data
 
816
                        curve = c.appendNurb(BezTriple.New(points[0]))
 
817
                        curve.append(BezTriple.New(points[1]))
 
818
                        for point in curve:
 
819
                                point.handleTypes = [VECT, VECT]
 
820
                        curve.flagU = 0 # 0 sets the curve not cyclic=open
 
821
                        c.setResolu(settings.var['curve_res'])
 
822
                        c.update() #important for handles calculation
 
823
 
 
824
                        ob = SCENE.objects.new(c) # create a new curve_object
 
825
 
 
826
                        #if False:  # --todo-- better support for 210-group
 
827
                        if thic != 0.0: #hack: Blender2.45 curve-extrusion
 
828
                                t = thic * 0.5
 
829
                                if abs(t) > 5.0: t = 5.0 * cmp(t,0) # Blender2.45 accepts only (0.0 - 5.0)
 
830
                                e = self.extrusion
 
831
                                c.setExt1(abs(t))  # curve-extrusion
 
832
                                ob.LocX += t * e[0]
 
833
                                ob.LocY += t * e[1]
 
834
                                ob.LocZ += t * e[2]
 
835
                                #c.setExt1(1.0)  # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
 
836
                                #ob.LocZ = t + self.loc[2]
 
837
                                #ob.SizeZ *= abs(t)
 
838
                        return ob
 
839
 
 
840
                else:  # LINE mesh representation ------------------------------
 
841
                        global activObjectLayer
 
842
                        global activObjectName
 
843
                        #print 'deb:draw:line.ob IN activObjectName: ', activObjectName #---------------------
 
844
        
 
845
                        if M_OBJ: obname, me, ob = makeNewObject()
 
846
                        else: 
 
847
                                if activObjectLayer == self.layer and settings.var['one_mesh_on']:
 
848
                                        obname = activObjectName
 
849
                                        #print 'deb:line.draw obname from activObjectName: ', obname #---------------------
 
850
                                        ob = getSceneChild(obname)  # open an existing mesh_object
 
851
                                        #ob = SCENE.getChildren(obname)  # open an existing mesh_object
 
852
                                        #me = Mesh.Get(ob.name)   # open objects mesh data
 
853
                                        me = ob.getData(name_only=False, mesh=True)
 
854
                                else:
 
855
                                        obname = 'li_%s' %self.layer  # create object name from layer name
 
856
                                        obname = obname[:MAX_NAMELENGTH]
 
857
                                        me = Mesh.New(obname)             # create a new mesh
 
858
                                        ob = SCENE.objects.new(me) # create a new mesh_object
 
859
                                        activObjectName = ob.name
 
860
                                        activObjectLayer = self.layer
 
861
                                        #print ('deb:line.draw new line.ob+mesh:"%s" created!' %ob.name) #---------------------
 
862
        
 
863
                        faces, edges = [], []
 
864
                        n = len(me.verts)
 
865
 
 
866
                        #if settings.var['width_force']: #--todo-----------
 
867
 
 
868
                        if thic != 0:
 
869
                                t, e = thic, self.extrusion
 
870
                                #print 'deb:thic, extr: ', t, e #---------------------
 
871
                                points.extend([[v[0]+t*e[0], v[1]+t*e[1], v[2]+t*e[2]] for v in points[:]])
 
872
                                faces = [[0+n, 1+n, 3+n, 2+n]]
 
873
                        else:
 
874
                                edges = [[0+n, 1+n]]
 
875
        
 
876
                        me.verts.extend(points) # adds vertices to global mesh
 
877
                        if faces: me.faces.extend(faces)           # add faces to the mesh
 
878
                        if edges: me.edges.extend(edges)           # add faces to the mesh
 
879
        
 
880
                        if settings.var['vGroup_on'] and not M_OBJ:
 
881
                                # entities with the same color build one vertexGroup for easier material assignment ----
 
882
                                ob.link(me) # link mesh to that object
 
883
                                vG_name = 'color_%s' %self.color_index
 
884
                                if edges: faces = edges
 
885
                                replace = Blender.Mesh.AssignModes.ADD  #or .AssignModes.REPLACE or ADD
 
886
                                try:
 
887
                                        me.assignVertsToGroup(vG_name,  faces[0], 1.0, replace)
 
888
                                        #print 'deb: existed vGroup:', vG_name #---------------------
 
889
                                except:
 
890
                                        me.addVertGroup(vG_name)
 
891
                                        me.assignVertsToGroup(vG_name,  faces[0], 1.0, replace)
 
892
                                        #print 'deb: create new vGroup:', vG_name #---------------------
 
893
        
 
894
        
 
895
                        #print 'deb:draw:line.ob OUT activObjectName: ', activObjectName #---------------------
 
896
                        return ob
 
897
        
 
898
 
 
899
 
 
900
class Point:  #-----------------------------------------------------------------
 
901
        """Class for objects representing dxf POINTs.
 
902
        """
 
903
        def __init__(self, obj):
 
904
                """Expects an entity object of type point as input.
 
905
                """
 
906
                if not obj.type == 'point':
 
907
                        raise TypeError, "Wrong type %s for point object!" %obj.type
 
908
                self.type = obj.type
 
909
#               self.data = obj.data[:]
 
910
 
 
911
                self.space = getit(obj, 67, 0)
 
912
                self.thic =  getit(obj, 39, 0)
 
913
                #print 'deb:self.thic: ', self.thic #---------------------
 
914
                self.color_index = getit(obj, 62, BYLAYER)
 
915
 
 
916
                self.layer = getit(obj, 8, None)
 
917
                self.extrusion = get_extrusion(obj)
 
918
                self.points = self.get_points(obj)
 
919
 
 
920
 
 
921
        def get_points(self, data):
 
922
                """Gets coordinates for a point type object.
 
923
 
 
924
                Points have fixed codes for each value.
 
925
                """
 
926
                a = [0, 0, 0]
 
927
                a[0] = getit(data, 10, None) # 10 = x
 
928
                a[1] = getit(data, 20, None) # 20 = y
 
929
                a[2] = getit(data, 30,  0) # 30 = z
 
930
                out = [a]
 
931
                return out
 
932
 
 
933
 
 
934
        def __repr__(self):
 
935
                return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
 
936
 
 
937
 
 
938
        def draw(self, settings):
 
939
                """for POINT: generate Blender_geometry.
 
940
                """
 
941
                points = self.points
 
942
                obname = 'po_%s' %self.layer  # create object name from layer name
 
943
                obname = obname[:MAX_NAMELENGTH]
 
944
                points_as = settings.var['points_as']
 
945
                thic = settings.var['thick_min']
 
946
                if thic < settings.var['dist_min']: thic = settings.var['dist_min']
 
947
 
 
948
                if points_as in [1,3,4,5]:
 
949
                        if True: # points_as in [1,5]: # as 'empty'
 
950
                                c = 'Empty'
 
951
                        elif points_as == 3: # as 'thin sphere'
 
952
                                res = settings.var['thin_res']
 
953
                                c = Mesh.Primitives.UVsphere(res,res,thic)
 
954
                        elif points_as == 4: # as 'thin box'
 
955
                                c = Mesh.Primitives.Cube(thic)
 
956
                        ob = SCENE.objects.new(c, obname) # create a new object
 
957
                        transform(self.extrusion, 0, ob)
 
958
                        ob.loc = tuple(points[0])
 
959
 
 
960
                elif points_as == 2: # as 'vertex'
 
961
                        global activObjectLayer
 
962
                        global activObjectName
 
963
                        #print 'deb:draw:point.ob IN activObjectName: ', activObjectName #---------------------
 
964
                        if M_OBJ: obname, me, ob = makeNewObject()
 
965
                        else: 
 
966
                                if activObjectLayer == self.layer and settings.var['one_mesh_on']:
 
967
                                        obname = activObjectName
 
968
                                        #print 'deb:draw:point.ob obname from activObjectName: ', obname #---------------------
 
969
                                        ob = getSceneChild(obname)  # open an existing mesh_object
 
970
                                        #ob = SCENE.getChildren(obname)  # open an existing mesh_object
 
971
                                        me = ob.getData(name_only=False, mesh=True)
 
972
                                        #me = Mesh.Get(ob.name)   # open objects mesh data
 
973
                                else:
 
974
                                        me = Mesh.New(obname)             # create a new mesh
 
975
                                        ob = SCENE.objects.new(me) # create a new mesh_object
 
976
                                        activObjectName = ob.name
 
977
                                        activObjectLayer = self.layer
 
978
                                        #print ('deb:draw:point new point.ob+mesh:"%s" created!' %ob.name) #---------------------
 
979
                        me.verts.extend(points) # add vertices to mesh
 
980
 
 
981
                return ob
 
982
 
 
983
 
 
984
 
 
985
class Polyline:  #-----------------------------------------------------------------
 
986
        """Class for objects representing dxf POLYLINEs.
 
987
        """
 
988
        def __init__(self, obj):
 
989
                """Expects an entity object of type polyline as input.
 
990
                """
 
991
                #print 'deb:polyline.init.START:----------------' #------------------------
 
992
                if not obj.type == 'polyline':
 
993
                        raise TypeError, "Wrong type %s for polyline object!" %obj.type
 
994
                self.type = obj.type
 
995
#               self.data = obj.data[:]
 
996
 
 
997
                self.space = getit(obj, 67, 0)
 
998
                self.elevation =  getit(obj, 30, 0)
 
999
                #print 'deb:elevation: ', self.elevation #---------------
 
1000
                self.thic =  getit(obj, 39, 0)
 
1001
                self.color_index = getit(obj, 62, BYLAYER)
 
1002
 
 
1003
                self.flags = getit(obj, 70, 0)
 
1004
                self.closed = self.flags & 1   # closed in the M direction
 
1005
                self.curved = self.flags & 2   # Bezier-curve-fit vertices have been added
 
1006
                self.spline = self.flags & 4   # NURBS-curve-fit vertices have been added
 
1007
                self.poly3d = self.flags & 8   # 3D-polyline
 
1008
                self.plmesh = self.flags & 16  # 3D-polygon mesh
 
1009
                self.closeN = self.flags & 32  # closed in the N direction
 
1010
                self.plface = self.flags & 64  # 3D-polyface mesh
 
1011
                self.contin = self.flags & 128 # the linetype pattern is generated continuously
 
1012
 
 
1013
                self.pltype='poly2d'   # default is a 2D-polyline
 
1014
                if self.poly3d: self.pltype='poly3d'
 
1015
                elif self.plface: self.pltype='plface'
 
1016
                elif self.plmesh: self.pltype='plmesh'
 
1017
 
 
1018
                self.swidth =  getit(obj, 40, 0) # default start width
 
1019
                self.ewidth =  getit(obj, 41, 0) # default end width
 
1020
                #self.bulge  =  getit(obj, 42, None) # bulge of the segment
 
1021
                self.vectorsM =  getit(obj, 71, None) # PolyMesh: expansion in M-direction / PolyFace: number of the vertices
 
1022
                self.vectorsN =  getit(obj, 72, None) # PolyMesh: expansion in M-direction / PolyFace: number of faces
 
1023
                #self.resolM =  getit(obj, 73, None) # resolution of surface in M direction
 
1024
                #self.resolN =  getit(obj, 74, None) # resolution of surface in N direction
 
1025
                self.curvNoFitted = False
 
1026
                self.curvQuadrati = False
 
1027
                self.curvCubicBsp = False
 
1028
                self.curvBezier = False
 
1029
                curvetype =  getit(obj, 75, 0) # type of curve/surface: 0=None/5=Quadric/6=Cubic/8=Bezier
 
1030
                if   curvetype == 0: self.curvNoFitted = True
 
1031
                elif curvetype == 5: self.curvQuadrati = True
 
1032
                elif curvetype == 6: self.curvCubicBsp = True
 
1033
                elif curvetype == 8: self.curvBezier = True
 
1034
 
 
1035
                self.layer = getit(obj, 8, None)
 
1036
                self.extrusion = get_extrusion(obj)
 
1037
 
 
1038
                self.points = []  #list with vertices coordinats
 
1039
                self.faces  = []  #list with vertices assigment to faces
 
1040
                #print 'deb:polyline.init.ENDinit:----------------' #------------
 
1041
 
 
1042
 
 
1043
 
 
1044
        def __repr__(self):
 
1045
                return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
 
1046
 
 
1047
 
 
1048
 
 
1049
        def doubles_out(self, settings, d_points):
 
1050
                """routine to sort out of double.vertices-----------------------------
 
1051
                """
 
1052
                minimal_dist =  settings.var['dist_min'] * 0.1
 
1053
                dv_count = 0
 
1054
                temp_points = []
 
1055
                for i in xrange(len(d_points)-1):
 
1056
                        point = d_points[i]
 
1057
                        point2 = d_points[i+1]
 
1058
                        #print 'deb:double.vertex p1,p2', point, point2 #------------------------
 
1059
                        delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
 
1060
                        if delta.length > minimal_dist:
 
1061
                                 temp_points.append(point)
 
1062
                        else:
 
1063
                                dv_count+=1
 
1064
                #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
 
1065
                temp_points.append(d_points[-1])  #------ incl. last vertex -------------
 
1066
                #if self.closed: temp_points.append(d_points[1])  #------ loop start vertex -------------
 
1067
                d_points = temp_points   #-----vertex.list without "double.vertices"
 
1068
                #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
 
1069
                return d_points
 
1070
 
 
1071
 
 
1072
        def tribles_out(self, settings, d_points):
 
1073
                """routine to sort out of three_in_place.vertices-----------------------------
 
1074
                """
 
1075
                minimal_dist = settings.var['dist_min'] * 0.1
 
1076
                dv_count = 0
 
1077
                temp_points = []
 
1078
                for i in xrange(len(d_points)-2):
 
1079
                        point1 = d_points[i]
 
1080
                        point2 = d_points[i+1]
 
1081
                        point3 = d_points[i+2]
 
1082
                        #print 'deb:double.vertex p1,p2', point, point2 #------------------------
 
1083
                        delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
 
1084
                        delta23 = Mathutils.Vector(point3.loc) - Mathutils.Vector(point2.loc)
 
1085
                        if delta12.length < minimal_dist and delta23.length < minimal_dist:
 
1086
                                dv_count+=1
 
1087
                        else:
 
1088
                                temp_points.append(point1)
 
1089
                #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
 
1090
                point1 = d_points[-2]
 
1091
                point2 = d_points[-1]
 
1092
                delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
 
1093
                if delta12.length > minimal_dist:
 
1094
                        temp_points.append(d_points[-2])  #------ incl. 2last vertex -------------
 
1095
                temp_points.append(d_points[-1])  #------ incl. 1last vertex -------------
 
1096
                #if self.closed: temp_points.append(d_points[1])  #------ loop start vertex -------------
 
1097
                d_points = temp_points   #-----vertex.list without "double.vertices"
 
1098
                #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
 
1099
                return d_points
 
1100
 
 
1101
 
 
1102
        def draw(self, settings):   #-------------%%%% DRAW POLYLINE %%%---------------
 
1103
                """for POLYLINE: generate Blender_geometry.
 
1104
                """
 
1105
                #print 'deb:drawPOLYLINE.START:----------------' #------------------------
 
1106
                #print 'deb:POLYLINEdraw self.pltype:', self.pltype #------------------------
 
1107
                #print 'deb:POLYLINEdraw self.points:\n', self.points #------------------------
 
1108
                ob = []
 
1109
                #---- 3dPolyFace - mesh with free topology
 
1110
                if self.pltype=='plface' and settings.drawTypes['plmesh']:
 
1111
                        ob = self.drawPlFace(settings)
 
1112
                #---- 3dPolyMesh - mesh with ortogonal topology
 
1113
                elif self.pltype=='plmesh' and settings.drawTypes['plmesh']:
 
1114
                        ob = self.drawPlMesh(settings)
 
1115
 
 
1116
                #---- 2dPolyline - plane polyline with arc/wide/thic segments
 
1117
                elif self.pltype=='poly2d' and settings.drawTypes['polyline']:
 
1118
                        if settings.var['plines_as'] in [5,6]: # and self.spline:
 
1119
                                ob = self.drawPolyCurve(settings)
 
1120
                        else:
 
1121
                                ob = self.drawPoly2d(settings)
 
1122
 
 
1123
                #---- 3dPolyline - non-plane polyline (thin segments = without arc/wide/thic)
 
1124
                elif self.pltype=='poly3d' and settings.drawTypes['pline3']:
 
1125
                        if settings.var['plines3_as'] in [5,6]: # and self.spline:
 
1126
                                ob = self.drawPolyCurve(settings)
 
1127
                        else:
 
1128
                                ob = self.drawPoly2d(settings)
 
1129
 
 
1130
                #---- Spline - curved polyline (thin segments = without arc/wide/thic)
 
1131
                elif self.pltype=='spline' and settings.drawTypes['spline']:
 
1132
                        if settings.var['splines_as'] in [5,6]:
 
1133
                                ob = self.drawPolyCurve(settings)
 
1134
                        else:
 
1135
                                ob = self.drawPoly2d(settings)
 
1136
                return ob
 
1137
 
 
1138
 
 
1139
        def drawPlFace(self, settings):  #---- 3dPolyFace - mesh with free topology
 
1140
                """Generate the geometery of polyface.
 
1141
                """
 
1142
                #print 'deb:drawPlFace.START:----------------' #------------------------
 
1143
                points = []
 
1144
                faces = []
 
1145
                #print 'deb:len of pointsList ====== ', len(self.points) #------------------------
 
1146
                for point in self.points:
 
1147
                        if point.face:
 
1148
                                faces.append(point.face)
 
1149
                        else:
 
1150
                                points.append(point.loc)
 
1151
 
 
1152
                if settings.var['plmesh_flip']:  # ----------------------
 
1153
                        for face in faces:
 
1154
                                face.reverse()
 
1155
                                face = [face[-1]] + face[:-1]
 
1156
 
 
1157
                #print 'deb:drawPlFace: len of points_list:\n', len(points)  #-----------------------
 
1158
                #print 'deb:drawPlFace: len of faces_list:\n', len(faces)  #-----------------------
 
1159
                #print 'deb:drawPlFace: points_list:\n', points  #-----------------------
 
1160
                #print 'deb:drawPlFace: faces_list:\n', faces  #-----------------------
 
1161
                obname = 'pf_%s' %self.layer  # create object name from layer name
 
1162
                obname = obname[:MAX_NAMELENGTH]
 
1163
                me = Mesh.New(obname)             # create a new mesh
 
1164
                ob = SCENE.objects.new(me) # create a new mesh_object
 
1165
                me.verts.extend(points) # add vertices to mesh
 
1166
                me.faces.extend(faces)   # add faces to the mesh
 
1167
                if settings.var['normals_out']:  # ----------------------
 
1168
                        #me.flipNormals()
 
1169
                        me.recalcNormals(0)
 
1170
                        #me.update()
 
1171
                #print 'deb:drawPlFace: len of me.faces:\n', len(me.faces)  #-----------------------
 
1172
 
 
1173
                if settings.var['meshSmooth_on']:  # ----------------------
 
1174
                        for i in xrange(len(me.faces)):
 
1175
                                me.faces[i].smooth = True
 
1176
                        #me.Mode(AUTOSMOOTH)
 
1177
                transform(self.extrusion, 0, ob)
 
1178
                #print 'deb:drawPlFace.END:----------------' #------------------------
 
1179
                return ob
 
1180
 
 
1181
 
 
1182
 
 
1183
        def drawPlMesh(self, settings):  #---- 3dPolyMesh - mesh with orthogonal topology
 
1184
                """Generate the geometery of polymesh.
 
1185
                """
 
1186
                #print 'deb:polymesh.draw.START:----------------' #------------------------
 
1187
                #points = []
 
1188
                #print 'deb:len of pointsList ====== ', len(self.points) #------------------------
 
1189
                faces = []
 
1190
                m = self.vectorsM
 
1191
                n = self.vectorsN
 
1192
                for j in xrange(m - 1):
 
1193
                        for i in xrange(n - 1):
 
1194
                                nn = j * n
 
1195
                                faces.append([nn+i, nn+i+1, nn+n+i+1, nn+n+i])
 
1196
 
 
1197
                if self.closed:   #mesh closed in N-direction
 
1198
                        nn = (m-1)*n
 
1199
                        for i in xrange(n - 1):
 
1200
                                faces.append([nn+i, nn+i+1, i+1, i])
 
1201
 
 
1202
                if self.closeN:   #mesh closed in M-direction
 
1203
                        for j in xrange(m-1):
 
1204
                                nn = j * n
 
1205
                                faces.append([nn+n-1, nn, nn+n, nn+n-1+n])
 
1206
 
 
1207
                if self.closed and self.closeN:   #mesh closed in M/N-direction
 
1208
                                faces.append([ (n*m)-1, (m-1)*n, 0, n-1])
 
1209
 
 
1210
                #print 'deb:len of points_list:\n', len(points)  #-----------------------
 
1211
                #print 'deb:faces_list:\n', faces  #-----------------------
 
1212
                obname = 'pm_%s' %self.layer  # create object name from layer name
 
1213
                obname = obname[:MAX_NAMELENGTH]
 
1214
                me = Mesh.New(obname)             # create a new mesh
 
1215
                ob = SCENE.objects.new(me) # create a new mesh_object
 
1216
                me.verts.extend([point.loc for point in self.points]) # add vertices to mesh
 
1217
                me.faces.extend(faces)   # add faces to the mesh
 
1218
                if settings.var['normals_out']:  # ----------------------
 
1219
                        #me.flipNormals()
 
1220
                        me.recalcNormals(0)
 
1221
                        #me.update()
 
1222
                if settings.var['meshSmooth_on']:  # ----------------------
 
1223
                        for i in xrange(len(faces)):
 
1224
                                me.faces[i].smooth = True
 
1225
                        #me.Mode(AUTOSMOOTH)
 
1226
 
 
1227
                transform(self.extrusion, 0, ob)
 
1228
                #print 'deb:polymesh.draw.END:----------------' #------------------------
 
1229
                return ob
 
1230
 
 
1231
 
 
1232
        def drawPolyCurve(self, settings):  #---- Polyline - draw as Blender-curve
 
1233
                """Generate the geometery of polyline as Blender-curve.
 
1234
                """
 
1235
                #print 'deb:polyline2dCurve.draw.START:----------------' #---
 
1236
                if len(self.points) < 2:
 
1237
                        #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
 
1238
                        return
 
1239
 
 
1240
                if self.spline: pline_typ = 'ps'        # Polyline-NURBSpline
 
1241
                elif self.curved: pline_typ = 'pc'      # Polyline-BezierCurve
 
1242
                else: pline_typ = 'pl'                          # Polyline classic
 
1243
                obname = '%s_%s' %(pline_typ, self.layer)  # create object_name from layer name
 
1244
                obname = obname[:MAX_NAMELENGTH]
 
1245
                d_points = []
 
1246
 
 
1247
                if settings.var['Z_force_on']:
 
1248
                        self.elevation = settings.var['Z_elev']
 
1249
                        for point in self.points:
 
1250
                                point.loc[2] = self.elevation
 
1251
                                d_points.append(point)
 
1252
                else: #for DXFr10-format: update all points[].loc[2] == None -> 0.0 
 
1253
                        for point in self.points:
 
1254
                                if point.loc[2] == None:
 
1255
                                        point.loc[2] = self.elevation
 
1256
                                d_points.append(point)
 
1257
 
 
1258
                #d_points = self.tribles_out(settings, d_points)
 
1259
                #d_points = self.doubles_out(settings, d_points)
 
1260
                #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
 
1261
 
 
1262
                thic = set_thick(self.thic, settings)
 
1263
                if thic != 0.0:   #hack: Blender<2.45 curve-extrusion
 
1264
                        LocZ = d_points[0].loc[2]
 
1265
                        temp_points = []
 
1266
                        for point in d_points:
 
1267
                                point.loc[2] = 0.0
 
1268
                                temp_points.append(point)
 
1269
                        d_points = temp_points
 
1270
                
 
1271
                #print 'deb:polyline2dCurve.draw d_points=', d_points  #---------------
 
1272
                pline = Curve.New(obname)   # create new curve data
 
1273
                #pline.setResolu(24) #--todo-----                                               
 
1274
 
 
1275
                if False: #old self.spline:  # NURBSplines-----OK-----
 
1276
                        #print 'deb:polyline2dCurve.draw self.spline!' #---------------
 
1277
                        weight1 = 0.5
 
1278
                        weight2 = 1.0
 
1279
                        if self.curvQuadrati:
 
1280
                                # Bezier-curve form simulated in NURBS-curve
 
1281
                                # generate middlepoints except start/end-segments ---
 
1282
                                #print 'deb:polyline2dCurve.draw extraQBspline!' #---------------
 
1283
                                temp_points = []
 
1284
                                point = d_points[0].loc
 
1285
                                point.append(weight1)
 
1286
                                temp_points.append(point)
 
1287
                                for i in xrange(1,len(d_points)-2):
 
1288
                                        point1 = d_points[i].loc
 
1289
                                        point2 = d_points[i+1].loc
 
1290
                                        mpoint = list((Mathutils.Vector(point1) + Mathutils.Vector(point2)) * 0.5)
 
1291
                                        mpoint.append(weight2)
 
1292
                                        point1.append(weight1)
 
1293
                                        temp_points.append(point1)
 
1294
                                        temp_points.append(mpoint)
 
1295
                                point2.append(weight1)
 
1296
                                temp_points.append(point2)
 
1297
                                point = d_points[-1].loc
 
1298
                                point.append(weight1)
 
1299
                                temp_points.append(point)
 
1300
                                d_points = temp_points
 
1301
                        else:
 
1302
                                temp_points = []
 
1303
                                for d in d_points:
 
1304
                                        d = d.loc
 
1305
                                        d.append(weight1)
 
1306
                                        temp_points.append(d)
 
1307
                                d_points = temp_points
 
1308
 
 
1309
                        if not self.closed:
 
1310
                                # generate extended startpoint and endpoint------
 
1311
                                point1 = Mathutils.Vector(d_points[0][:3])
 
1312
                                point2 = Mathutils.Vector(d_points[1][:3])
 
1313
                                startpoint = list(point1 - point2 + point1)
 
1314
                                startpoint.append(weight1)
 
1315
                                point1 = Mathutils.Vector(d_points[-1][:3])
 
1316
                                point2 = Mathutils.Vector(d_points[-2][:3])
 
1317
                                endpoint = list(point1 - point2 + point1)
 
1318
                                endpoint.append(weight1)
 
1319
                                temp_points = []
 
1320
                                temp_points.append(startpoint)
 
1321
                                temp_points.extend(d_points)
 
1322
                                d_points = temp_points
 
1323
                                d_points.append(endpoint)
 
1324
 
 
1325
                        point = d_points[0]
 
1326
                        curve = pline.appendNurb(point)
 
1327
                        curve.setType(4) #NURBS curve
 
1328
                        for point in d_points[1:]:
 
1329
                                curve.append(point)
 
1330
                        if self.closed:
 
1331
                                curve.flagU = 1 # Set curve cyclic=close
 
1332
                        else:
 
1333
                                curve.flagU = 0 # Set curve not cyclic=open
 
1334
 
 
1335
                if self.spline:  # NURBSplines-----OK-----
 
1336
                        #print 'deb:polyline2dCurve.draw self.spline!' #---------------
 
1337
                        nurbs_points = []
 
1338
                        for d in d_points:
 
1339
                                pkt = d.loc
 
1340
                                pkt.append(d.weight)
 
1341
                                nurbs_points.append(pkt)
 
1342
                        firstpoint = nurbs_points[0]
 
1343
                        curve = pline.appendNurb(firstpoint)
 
1344
                        curve.setType(4) # set curvetype NURBS
 
1345
                        for point in nurbs_points[1:]:
 
1346
                                curve.append(point)
 
1347
                        if self.closed:
 
1348
                                curve.flagU = 1+0 # Set curve cyclic=close and uni
 
1349
                        else:
 
1350
                                curve.flagU = 0+2 # Set curve not cyclic=open
 
1351
                        try: curve.orderU = 5 # works only with >2.46svn080625
 
1352
                        except AttributeError: pass
 
1353
                        #print 'deb: dir(curve):', dir(curve) #----------------
 
1354
 
 
1355
                elif  False: #orig self.curved:  #--Bezier-curves---OK-------
 
1356
                        #print 'deb:polyline2dCurve.draw self.curved!' #---------------
 
1357
                        curve = pline.appendNurb(BezTriple.New(d_points[0]))
 
1358
                        for p in d_points[1:]:
 
1359
                                curve.append(BezTriple.New(p))
 
1360
                        for point in curve:
 
1361
                                point.handleTypes = [AUTO, AUTO]
 
1362
                        if self.closed:
 
1363
                                curve.flagU = 1 # Set curve cyclic=close
 
1364
                        else:
 
1365
                                curve.flagU = 0 # Set curve not cyclic=open
 
1366
                                curve[0].handleTypes = [FREE, ALIGN]   #remi--todo-----
 
1367
                                curve[-1].handleTypes = [ALIGN, FREE]   #remi--todo-----
 
1368
 
 
1369
                elif  self.curved:  #--SPLINE as Bezier-curves---wip------
 
1370
                        #print 'deb:polyline2dCurve.draw self.curved!' #---------------
 
1371
                        begtangent, endtangent = None, None
 
1372
                        if d_points[0].tangent:
 
1373
                                begtangent = d_points[0]
 
1374
                                d_points = d_points[1:]
 
1375
                        if d_points[-1].tangent:
 
1376
                                endtangent = d_points[-1]
 
1377
                                d_points = d_points[:-1]
 
1378
                        curve = pline.appendNurb(BezTriple.New(d_points[0]))
 
1379
                        for p in d_points[1:]:
 
1380
                                curve.append(BezTriple.New(p))
 
1381
                        for point in curve:
 
1382
                                point.handleTypes = [AUTO, AUTO]
 
1383
                        #curve.setType(1) #Bezier curve
 
1384
                        if self.closed:
 
1385
                                curve.flagU = 5 #1 # Set curve cyclic=close
 
1386
                        else:
 
1387
                                curve.flagU = 4 #0 # Set curve not cyclic=open
 
1388
                                if begtangent:
 
1389
                                        #print 'deb:polyline2dCurve.draw curve[0].vec:', curve[0].vec #-----
 
1390
                                        #print 'deb:polyline2dCurve.draw begtangent:', begtangent #-----
 
1391
                                        p0h1,p0,p0h2 = curve[0].vec 
 
1392
                                        p0h1 = [p0h1[i]+begtangent[i] for i in range(3)]
 
1393
                                        curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
 
1394
                                curve[0].handleTypes = [FREE, ALIGN]   #remi--todo-----
 
1395
                                if endtangent:
 
1396
                                        #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
 
1397
                                        #print 'deb:polyline2dCurve.draw endtangent:', endtangent #-----
 
1398
                                        p0h1,p0,p0h2 = curve[-1].vec 
 
1399
                                        p0h2 = [p0h2[i]+endtangent[i] for i in range(3)]
 
1400
                                        #print 'deb:drawPlineCurve: p0h2:', p0h2 #----------
 
1401
                                        curve.__setitem__(-1,BezTriple.New(p0h1+p0+p0h2))
 
1402
                                        #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
 
1403
                                curve[-1].handleTypes = [ALIGN, FREE]   #remi--todo-----
 
1404
 
 
1405
 
 
1406
 
 
1407
                else:   #-- only straight line- and arc-segments----OK------
 
1408
                        #print 'deb:polyline2dCurve.draw curve:', curve #-----
 
1409
                        points = []
 
1410
                        arc_res = settings.var['curve_arc']
 
1411
                        prevHandleType = VECT
 
1412
                        #d_points.append(d_points[0])  #------ first vertex added at the end of list --------
 
1413
                        #curve.setType(0) #polygon_type of Blender_curve
 
1414
                        for i in xrange(len(d_points)):
 
1415
                                point1 = d_points[i]
 
1416
                                #point2 = d_points[i+1]
 
1417
                                if False: #-----outdated!- standard calculation ----------------------------------
 
1418
                                        if point1.bulge and (i < len(d_points)-2 or self.closed):
 
1419
                                                verts, center = calcBulge(point1, point2, arc_res, triples=False)
 
1420
                                                if i == 0: curve = pline.appendNurb(BezTriple.New(verts[0]))
 
1421
                                                else: curve.append(BezTriple.New(verts[0]))
 
1422
                                                curve[-1].handleTypes = [VECT, VECT]  #--todo--calculation of bezier-tangents
 
1423
                                                for p in verts[1:]:
 
1424
                                                        curve.append(BezTriple.New(p))
 
1425
                                                        curve[-1].handleTypes = [AUTO, AUTO]
 
1426
                                        else:
 
1427
                                                if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
 
1428
                                                else: curve.append(BezTriple.New(point1.loc))
 
1429
                                                curve[-1].handleTypes = [VECT, VECT]   #--todo--calculation of bezier-tangents
 
1430
 
 
1431
                                elif True:   #----- optimised Bezier-Handles calculation --------------------------------
 
1432
                                        #print 'deb:drawPlineCurve: i:', i #---------
 
1433
                                        if point1.bulge and not (i == len(d_points)-1 and point1.bulge and not self.closed):
 
1434
                                                if i == len(d_points)-1: point2 = d_points[0]
 
1435
                                                else: point2 = d_points[i+1]
 
1436
 
 
1437
 
 
1438
                                                # calculate additional points for bulge
 
1439
                                                VectorTriples = calcBulge(point1, point2, arc_res, triples=True)
 
1440
 
 
1441
                                                if prevHandleType == FREE:
 
1442
                                                        #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
 
1443
                                                        VectorTriples[0][:3] = prevHandleVect
 
1444
                                                        #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
 
1445
 
 
1446
                                                if i == 0: curve = pline.appendNurb(BezTriple.New(VectorTriples[0]))
 
1447
                                                else: curve.append(BezTriple.New(VectorTriples[0]))
 
1448
                                                curve[-1].handleTypes = [prevHandleType, FREE]
 
1449
 
 
1450
                                                for p in VectorTriples[1:-1]:
 
1451
                                                        curve.append(BezTriple.New(p))
 
1452
                                                        curve[-1].handleTypes = [FREE, FREE]
 
1453
 
 
1454
                                                prevHandleVect = VectorTriples[-1][:3]
 
1455
                                                prevHandleType = FREE
 
1456
                                                #print 'deb:drawPlineCurve: prevHandleVect:', prevHandleVect #---------
 
1457
                                        else:
 
1458
                                                #print 'deb:drawPlineCurve: else' #----------
 
1459
                                                if prevHandleType == FREE:
 
1460
                                                        VectorTriples = prevHandleVect + list(point1) + list(point1)
 
1461
                                                        #print 'deb:drawPlineCurve: VectorTriples:', VectorTriples #---------
 
1462
                                                        curve.append(BezTriple.New(VectorTriples))
 
1463
                                                        curve[-1].handleTypes = [FREE, VECT]
 
1464
                                                        prevHandleType = VECT
 
1465
                                                else:
 
1466
                                                        if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
 
1467
                                                        else: curve.append(BezTriple.New(point1.loc))
 
1468
                                                        curve[-1].handleTypes = [VECT, VECT]
 
1469
                                                        
 
1470
 
 
1471
 
 
1472
                                        #print 'deb:drawPlineCurve: curve[-1].vec[0]', curve[-1].vec[0] #----------
 
1473
 
 
1474
                        if self.closed:
 
1475
                                curve.flagU = 1 # Set curve cyclic=close
 
1476
                                if prevHandleType == FREE:
 
1477
                                        #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
 
1478
                                        #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
 
1479
                                        prevHandleType2 = curve[0].handleTypes[1]
 
1480
                                        p0h1,p0,p0h2 = curve[0].vec 
 
1481
                                        #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
 
1482
                                        p0h1 = prevHandleVect
 
1483
                                        #p0h1 = [0,0,0]
 
1484
                                        #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
 
1485
                                        #curve[0].vec = [p0h1,p0,p0h2]
 
1486
                                        curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
 
1487
 
 
1488
                                        curve[0].handleTypes = [FREE,prevHandleType2]
 
1489
                                        #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
 
1490
                                        #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
 
1491
                                else: 
 
1492
                                        curve[0].handleTypes[0] = VECT
 
1493
                        else: 
 
1494
                                curve.flagU = 0 # Set curve not cyclic=open
 
1495
 
 
1496
                if settings.var['fill_on']:
 
1497
                        pline.setFlag(6) # 2+4 set top and button caps
 
1498
                else:
 
1499
                        pline.setFlag(pline.getFlag() & ~6) # dont set top and button caps
 
1500
 
 
1501
                pline.setResolu(settings.var['curve_res'])
 
1502
                pline.update()
 
1503
                ob = SCENE.objects.new(pline) # create a new curve_object
 
1504
 
 
1505
                if thic != 0.0: #hack: Blender<2.45 curve-extrusion
 
1506
                        thic = thic * 0.5
 
1507
                        pline.setExt1(1.0)  # curve-extrusion accepts only (0.0 - 2.0)
 
1508
                        ob.LocZ = thic + LocZ
 
1509
 
 
1510
                transform(self.extrusion, 0, ob)
 
1511
                if thic != 0.0:
 
1512
                        ob.SizeZ *= abs(thic)
 
1513
 
 
1514
                #print 'deb:polyline2dCurve.draw.END:----------------' #-----
 
1515
                return ob
 
1516
 
 
1517
 
 
1518
        def drawPoly2d(self, settings):  #---- 2dPolyline - plane lines/arcs with wide/thic
 
1519
                """Generate the geometery of regular polyline.
 
1520
                """
 
1521
                #print 'deb:polyline2d.draw.START:----------------' #------------------------
 
1522
                points = []
 
1523
                d_points = []
 
1524
                swidths = []
 
1525
                ewidths = []
 
1526
                swidth_default = self.swidth #default start width of POLYLINEs segments
 
1527
                ewidth_default = self.ewidth #default end width of POLYLINEs segments
 
1528
                #print 'deb:drawPoly2d self.swidth=', self.swidth #------------------------
 
1529
                thic = set_thick(self.thic, settings)
 
1530
                if self.spline: pline_typ = 'ps'
 
1531
                elif self.curved: pline_typ = 'pc'
 
1532
                else: pline_typ = 'pl'
 
1533
                obname = '%s_%s' %(pline_typ, self.layer)  # create object_name from layer name
 
1534
                obname = obname[:MAX_NAMELENGTH]
 
1535
 
 
1536
                if len(self.points) < 2:
 
1537
                        #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
 
1538
                        return
 
1539
                
 
1540
                if settings.var['Z_force_on']:
 
1541
                        self.elevation = settings.var['Z_elev']
 
1542
                        for point in self.points:
 
1543
                                point.loc[2] = self.elevation
 
1544
                                d_points.append(point)
 
1545
                else: #for DXFr10-format: update all non-existing LocZ points[].loc[2] == None -> 0.0 elevation
 
1546
                        for point in self.points:
 
1547
                                if point.loc[2] == None:
 
1548
                                        point.loc[2] = self.elevation
 
1549
                                d_points.append(point)
 
1550
                #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
 
1551
                #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
 
1552
 
 
1553
 
 
1554
                #if closed polyline, add duplic of the first vertex at the end of pointslist
 
1555
                if self.closed:  #new_b8
 
1556
                        if d_points[-1].loc != d_points[0].loc: # if not equal, then set the first at the end of pointslist
 
1557
                                d_points.append(d_points[0])
 
1558
                else:
 
1559
                        if d_points[-1].loc == d_points[0].loc: # if equal, then set to closed, and modify the last point
 
1560
                                d_points[-1] = d_points[0]
 
1561
                                self.closed = True
 
1562
                #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
 
1563
                #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
 
1564
 
 
1565
                d_points = self.doubles_out(settings, d_points)
 
1566
                #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
 
1567
 
 
1568
                """# routine to sort out of "double.vertices" ------------------------------------
 
1569
                minimal_dist =  settings.var['dist_min'] * 0.1
 
1570
                temp_points = []
 
1571
                for i in xrange(len(d_points)-1):
 
1572
                        point = d_points[i]
 
1573
                        point2 = d_points[i+1]
 
1574
                        #print 'deb:double.vertex p1,p2', point, point2 #------------------------
 
1575
                        delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
 
1576
                        if delta.length > minimal_dist:
 
1577
                                 temp_points.append(point)
 
1578
                        #else: print 'deb:drawPoly2d double.vertex sort out!' #------------------------
 
1579
                temp_points.append(d_points[-1])  #------ incl. last vertex -------------
 
1580
                #if self.closed: temp_points.append(d_points[1])  #------ loop start vertex -------------
 
1581
                d_points = temp_points   #-----vertex.list without "double.vertices"
 
1582
                #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
 
1583
                """
 
1584
 
 
1585
                #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
 
1586
                if len(d_points) < 2:  #if too few vertex, then return
 
1587
                        #print 'deb:drawPoly2d corrupted Vertices' #---------
 
1588
                        return
 
1589
 
 
1590
                # analyze of straight- and bulge-segments
 
1591
                # generation of additional points for bulge segments
 
1592
                arc_res = settings.var['arc_res']/sqrt(settings.var['arc_rad'])
 
1593
                wide_segment_exist = False
 
1594
                bulg_points = []  # for each point set None (or center for arc-subPoints)
 
1595
                for i in xrange(len(d_points)-1):
 
1596
                        point1 = d_points[i]
 
1597
                        point2 = d_points[i+1]
 
1598
                        #print 'deb:drawPoly2d_bulg tocalc.point1:', point1 #------------------------
 
1599
                        #print 'deb:drawPoly2d_bulg tocalc.point2:', point2 #------------------------
 
1600
 
 
1601
                        swidth = point1.swidth
 
1602
                        ewidth = point1.ewidth
 
1603
                        #print 'deb:drawPoly2d point1.swidth=', swidth #------------------------
 
1604
                        if swidth == None: swidth = swidth_default
 
1605
                        if ewidth == None: ewidth = ewidth_default
 
1606
                        if swidth != 0.0 or ewidth != 0.0: wide_segment_exist = True
 
1607
                        #print 'deb:drawPoly2d vertex_swidth=', swidth #------------------------
 
1608
 
 
1609
                        if settings.var['width_force']:  # force minimal width for thin segments
 
1610
                                width_min = settings.var['width_min']
 
1611
                                if swidth < width_min: swidth = width_min
 
1612
                                if ewidth < width_min: ewidth = width_min
 
1613
                                if not settings.var['width_on']:  # then force minimal width for all segments
 
1614
                                        swidth = width_min
 
1615
                                        ewidth = width_min
 
1616
 
 
1617
                        #if point1.bulge and (i < (len(d_points)-1) or self.closed):
 
1618
                        if point1.bulge and i < (len(d_points)-1): #10_b8
 
1619
                                verts, center = calcBulge(point1, point2, arc_res) #calculate additional points for bulge
 
1620
                                points.extend(verts)
 
1621
                                delta_width = (ewidth - swidth) / len(verts)
 
1622
                                width_list = [swidth + (delta_width * ii) for ii in xrange(len(verts)+1)]
 
1623
                                swidths.extend(width_list[:-1])
 
1624
                                ewidths.extend(width_list[1:])
 
1625
                                bulg_list = [center for ii in xrange(len(verts))]
 
1626
                                #the last point in bulge has index False for better indexing of bulg_end!
 
1627
                                bulg_list[-1] = None
 
1628
                                bulg_points.extend(bulg_list)
 
1629
 
 
1630
                        else:
 
1631
                                points.append(point1.loc)
 
1632
                                swidths.append(swidth)
 
1633
                                ewidths.append(ewidth)
 
1634
                                bulg_points.append(None)
 
1635
                points.append(d_points[-1].loc)
 
1636
 
 
1637
 
 
1638
                #--calculate width_vectors: left-side- and right-side-points ----------------
 
1639
                # 1.level:IF width  ---------------------------------------
 
1640
                if (settings.var['width_on'] and wide_segment_exist) or settings.var['width_force']:
 
1641
                        #new_b8 points.append(d_points[0].loc)  #temporarly add first vertex at the end (for better loop)
 
1642
                        dist_min05 = 0.5 * settings.var['dist_min'] #minimal width for zero_witdh
 
1643
                        
 
1644
                        pointsLs = []   # list of left-start-points
 
1645
                        pointsLe = []   # list of left-end-points
 
1646
                        pointsRs = []   # list of right-start-points
 
1647
                        pointsRe = []   # list of right-end-points
 
1648
                        pointsW  = []   # list of all border-points
 
1649
                        #rotMatr90 = Mathutils.Matrix(rotate 90 degree around Z-axis) = normalvectorXY
 
1650
                        rotMatr90 = Mathutils.Matrix([0, -1, 0], [1, 0, 0], [0, 0, 1])
 
1651
                        bulg_in = False
 
1652
                        last_bulg_point = False
 
1653
                        for i in xrange(len(points)-1):
 
1654
                                point1 = points[i]
 
1655
                                point2 = points[i+1]
 
1656
                                point1vec = Mathutils.Vector(point1)
 
1657
                                point2vec = Mathutils.Vector(point2)
 
1658
                                swidth05 = swidths[i] * 0.5
 
1659
                                ewidth05 = ewidths[i] * 0.5
 
1660
                                if swidth05 == 0: swidth05 = dist_min05
 
1661
                                if ewidth05 == 0: ewidth05 = dist_min05
 
1662
                                normal_vector = rotMatr90 * (point2vec-point1vec).normalize()
 
1663
                                if last_bulg_point:
 
1664
                                        last_bulg_point = False
 
1665
                                        bulg_in = True
 
1666
                                elif bulg_points[i] != None:
 
1667
                                        centerVec = Mathutils.Vector(bulg_points[i])
 
1668
                                        if bulg_points[i+1] == None: last_bulg_point = True
 
1669
                                        bulg_in = True
 
1670
                                else: bulg_in = False
 
1671
 
 
1672
                                if bulg_in:
 
1673
                                        #makes clean intersections for arc-segments
 
1674
                                        radius1vec = point1vec - centerVec
 
1675
                                        radius2vec = point2vec - centerVec
 
1676
                                        angle = Mathutils.AngleBetweenVecs(normal_vector, radius1vec)
 
1677
                                        if angle < 90.0:
 
1678
                                                normal_vector1 = radius1vec.normalize()
 
1679
                                                normal_vector2 = radius2vec.normalize()
 
1680
                                        else:   
 
1681
                                                normal_vector1 = - radius1vec.normalize()
 
1682
                                                normal_vector2 = - radius2vec.normalize()
 
1683
 
 
1684
                                        swidth05vec = swidth05 * normal_vector1
 
1685
                                        ewidth05vec = ewidth05 * normal_vector2
 
1686
                                        pointsLs.append(point1vec + swidth05vec) #vertex left start
 
1687
                                        pointsRs.append(point1vec - swidth05vec) #vertex right start
 
1688
                                        pointsLe.append(point2vec + ewidth05vec) #vertex left end
 
1689
                                        pointsRe.append(point2vec - ewidth05vec) #vertex right end
 
1690
 
 
1691
                                else:
 
1692
                                        swidth05vec = swidth05 * normal_vector
 
1693
                                        ewidth05vec = ewidth05 * normal_vector
 
1694
                                        pointsLs.append(point1vec + swidth05vec) #vertex left start
 
1695
                                        pointsRs.append(point1vec - swidth05vec) #vertex right start
 
1696
                                        pointsLe.append(point2vec + ewidth05vec) #vertex left end
 
1697
                                        pointsRe.append(point2vec - ewidth05vec) #vertex right end
 
1698
        
 
1699
                        # additional last point is also calculated
 
1700
                        #pointsLs.append(pointsLs[0])
 
1701
                        #pointsRs.append(pointsRs[0])
 
1702
                        #pointsLe.append(pointsLe[0])
 
1703
                        #pointsRe.append(pointsRe[0])
 
1704
 
 
1705
                        pointsLc, pointsRc = [], [] # lists Left/Right corners = intersection points
 
1706
 
 
1707
                        # 2.level:IF width and corner-trim
 
1708
                        if settings.var['pl_trim_on']:  #optional clean corner-intersections
 
1709
                                # loop preset
 
1710
                                # set STARTpoints of the first point points[0]
 
1711
                                if not self.closed:
 
1712
                                        pointsLc.append(pointsLs[0])
 
1713
                                        pointsRc.append(pointsRs[0])
 
1714
                                else:
 
1715
                                        pointsLs.append(pointsLs[0])
 
1716
                                        pointsRs.append(pointsRs[0])
 
1717
                                        pointsLe.append(pointsLe[0])
 
1718
                                        pointsRe.append(pointsRe[0])
 
1719
                                        points.append(points[0])
 
1720
                                vecL3, vecL4 = pointsLs[0], pointsLe[0]
 
1721
                                vecR3, vecR4 = pointsRs[0], pointsRe[0]
 
1722
                                lenL = len(pointsLs)-1
 
1723
                                #print 'deb:drawPoly2d pointsLs():\n',  pointsLs  #----------------
 
1724
                                #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs)  #----------------
 
1725
                                bulg_in = False
 
1726
                                last_bulg_point = False
 
1727
 
 
1728
                                # LOOP: makes (ENDpoints[i],STARTpoints[i+1])
 
1729
                                for i in xrange(lenL):
 
1730
                                        if bulg_points[i] != None:
 
1731
                                                if bulg_points[i+1] == None: #makes clean intersections for arc-segments
 
1732
                                                        last_bulg_point = True
 
1733
                                                if not bulg_in:
 
1734
                                                        bulg_in = True
 
1735
                                                        #pointsLc.extend((points[i], pointsLs[i]))
 
1736
                                                        #pointsRc.extend((points[i], pointsRs[i]))
 
1737
                                        vecL1, vecL2 = vecL3, vecL4
 
1738
                                        vecR1, vecR2 = vecR3, vecR4
 
1739
                                        vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
 
1740
                                        vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
 
1741
                                        #compute left- and right-cornerpoints
 
1742
                                        #cornerpointL = Geometry.LineIntersect2D(vec1, vec2, vec3, vec4)
 
1743
                                        cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
 
1744
                                        cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
 
1745
                                        #print 'deb:drawPoly2d cornerpointL: ', cornerpointL  #-------------
 
1746
                                        #print 'deb:drawPoly2d cornerpointR: ', cornerpointR  #-------------
 
1747
 
 
1748
                                        # IF not cornerpoint THEN check if identic start-endpoints (=collinear segments)
 
1749
                                        if cornerpointL == None or cornerpointR == None:
 
1750
                                                if vecL2 == vecL3 and vecR2 == vecR3:
 
1751
                                                        #print 'deb:drawPoly2d pointVec: ####### identic ##########' #----------------
 
1752
                                                        pointsLc.append(pointsLe[i])
 
1753
                                                        pointsRc.append(pointsRe[i])
 
1754
                                                else:
 
1755
                                                        pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
 
1756
                                                        pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
 
1757
                                        else:
 
1758
                                                cornerpointL = cornerpointL[0] # because Mathutils.LineIntersect() -> (pkt1,pkt2)
 
1759
                                                cornerpointR = cornerpointR[0]
 
1760
                                                #print 'deb:drawPoly2d cornerpointL: ', cornerpointL  #-------------
 
1761
                                                #print 'deb:drawPoly2d cornerpointR: ', cornerpointR  #-------------
 
1762
                                                pointVec0 = Mathutils.Vector(points[i])
 
1763
                                                pointVec = Mathutils.Vector(points[i+1])
 
1764
                                                pointVec2 = Mathutils.Vector(points[i+2])
 
1765
                                                #print 'deb:drawPoly2d pointVec0: ', pointVec0  #-------------
 
1766
                                                #print 'deb:drawPoly2d pointVec: ', pointVec  #-------------
 
1767
                                                #print 'deb:drawPoly2d pointVec2: ', pointVec2  #-------------
 
1768
                                                # if diststance(cornerL-center-cornerR) < limiter * (seg1_endWidth + seg2_startWidth)
 
1769
                                                max_cornerDist = (vecL2 - vecR2).length + (vecL3 - vecR3).length
 
1770
                                                is_cornerDist = (cornerpointL - pointVec).length + (cornerpointR - pointVec).length
 
1771
                                                #corner_angle = Mathutils.AngleBetweenVecs((pointVec0 - pointVec),(pointVec - pointVec2))
 
1772
                                                #print 'deb:drawPoly2d corner_angle: ', corner_angle  #-------------
 
1773
                                                #print 'deb:drawPoly2d max_cornerDist, is_cornerDist: ', max_cornerDist, is_cornerDist  #-------------
 
1774
                                                #if abs(corner_angle) < 90.0:
 
1775
                                                # intersection --------- limited by TRIM_LIMIT (1.0 - 5.0)
 
1776
                                                if is_cornerDist < max_cornerDist * settings.var['pl_trim_max']:
 
1777
                                                        # clean corner intersection
 
1778
                                                        pointsLc.append(cornerpointL)
 
1779
                                                        pointsRc.append(cornerpointR)
 
1780
                                                elif False: # the standard no-intersection
 
1781
                                                        # --todo-- not optimal, because produces X-face
 
1782
                                                        pointsLc.extend((pointsLe[i],pointsLs[i+1]))
 
1783
                                                        pointsRc.extend((pointsRe[i],pointsRs[i+1]))
 
1784
                                                elif False: # --todo-- the optimised non-intersection
 
1785
                                                        if (cornerpointL - vecL1).length < (cornerpointR - vecR1).length:
 
1786
                                                                left_angle = True
 
1787
                                                        else:
 
1788
                                                                left_angle = False
 
1789
                                                        limit_dist = settings.var['dist_min']
 
1790
                                                        if left_angle:  # if left turning angle
 
1791
                                                                #print 'deb:drawPoly2d it is left turning angle' #-------------
 
1792
                                                                # to avoid triangelface/doubleVertex
 
1793
                                                                delta1 = (cornerpointL - vecL1).normalize() * limit_dist
 
1794
                                                                delta4 = (cornerpointL - vecL4).normalize() * limit_dist
 
1795
                                                                pointsLc.extend((cornerpointL - delta1, cornerpointL - delta4))
 
1796
                                                                pointsRc.extend((pointsRe[i],pointsRs[i+1]))
 
1797
                                                        else:  # if right turning angle
 
1798
                                                                #print 'deb:drawPoly2d right turning angle' #-------------
 
1799
                                                                delta1 = (cornerpointR - vecR1).normalize() * limit_dist
 
1800
                                                                delta4 = (cornerpointR - vecR4).normalize() * limit_dist
 
1801
                                                                pointsRc.extend((cornerpointR - delta1, cornerpointR - delta4))
 
1802
                                                                pointsLc.extend((pointsLe[i],pointsLs[i+1]))
 
1803
                                                else:
 
1804
                                                        pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
 
1805
                                                        pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
 
1806
                                if not self.closed:
 
1807
                                        pointsLc.append(pointsLe[-1])
 
1808
                                        pointsRc.append(pointsRe[-1])
 
1809
 
 
1810
                        # 2.level:IF width but no-trim
 
1811
                        else:
 
1812
                                # loop preset
 
1813
                                # set STARTpoints of the first point points[0]
 
1814
                                if not self.closed:
 
1815
                                        pointsLc.append(pointsLs[0])
 
1816
                                        pointsRc.append(pointsRs[0])
 
1817
                                else:
 
1818
                                        pointsLs.append(pointsLs[0])
 
1819
                                        pointsRs.append(pointsRs[0])
 
1820
                                        pointsLe.append(pointsLe[0])
 
1821
                                        pointsRe.append(pointsRe[0])
 
1822
                                        points.append(points[0])
 
1823
                                vecL3, vecL4 = pointsLs[0], pointsLe[0]
 
1824
                                vecR3, vecR4 = pointsRs[0], pointsRe[0]
 
1825
                                lenL = len(pointsLs)-1
 
1826
                                #print 'deb:drawPoly2d pointsLs():\n',  pointsLs  #----------------
 
1827
                                #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs)  #----------------
 
1828
                                bulg_in = False
 
1829
                                last_bulg_point = False
 
1830
 
 
1831
                                # LOOP: makes (ENDpoints[i],STARTpoints[i+1])
 
1832
                                for i in xrange(lenL):
 
1833
                                        vecL1, vecL2 = vecL3, vecL4
 
1834
                                        vecR1, vecR2 = vecR3, vecR4
 
1835
                                        vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
 
1836
                                        vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
 
1837
                                        if bulg_points[i] != None:
 
1838
                                                #compute left- and right-cornerpoints
 
1839
                                                if True:
 
1840
                                                        cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
 
1841
                                                        cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
 
1842
                                                        pointsLc.append(cornerpointL[0])
 
1843
                                                        pointsRc.append(cornerpointR[0])
 
1844
                                                else:
 
1845
                                                        pointVec = Mathutils.Vector(point[i])
 
1846
 
 
1847
                                        else: # IF non-bulg
 
1848
                                                pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
 
1849
                                                pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
 
1850
                                if not self.closed:
 
1851
                                        pointsLc.append(pointsLe[-1])
 
1852
                                        pointsRc.append(pointsRe[-1])
 
1853
 
 
1854
                        len1 = len(pointsLc)
 
1855
                        #print 'deb:drawPoly2d len1:', len1  #-----------------------
 
1856
                        #print 'deb:drawPoly2d len1 len(pointsLc),len(pointsRc):', len(pointsLc),len(pointsRc)  #-----------------------
 
1857
                        pointsW = pointsLc + pointsRc  # all_points_List = left_side + right_side
 
1858
                        #print 'deb:drawPoly2d pointsW():\n',  pointsW  #----------------
 
1859
 
 
1860
                        # 2.level:IF width and thickness  ---------------------
 
1861
                        if thic != 0:
 
1862
                                thic_pointsW = []
 
1863
                                thic_pointsW.extend([[point[0], point[1], point[2]+thic] for point in pointsW])
 
1864
                                if thic < 0.0:
 
1865
                                        thic_pointsW.extend(pointsW)
 
1866
                                        pointsW = thic_pointsW
 
1867
                                else:
 
1868
                                        pointsW.extend(thic_pointsW)
 
1869
                                faces = []
 
1870
                                f_start, f_end = [], []
 
1871
                                f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
 
1872
                                f_top   = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
 
1873
                                f_left   = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
 
1874
                                f_right  = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
 
1875
 
 
1876
                                if self.closed:
 
1877
                                        f_bottom.append([len1-1, 0, len1, len1+len1-1])  #bottom face
 
1878
                                        f_top.append(   [len1+len1+len1-1, len1+len1+len1+len1-1, len1+len1+len1, len1+len1+0])  #top face
 
1879
                                        f_left.append(  [0, len1-1, len1+len1+len1-1, len1+len1])  #left face
 
1880
                                        f_right.append( [len1, len1+len1+len1, len1+len1+len1+len1-1, len1+len1-1])  #right face
 
1881
                                else:
 
1882
                                        f_start = [[0, len1, len1+len1+len1, len1+len1]]
 
1883
                                        f_end   = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
 
1884
 
 
1885
                                faces = f_left + f_right + f_bottom + f_top + f_start + f_end
 
1886
                                #faces = f_bottom + f_top
 
1887
                                #faces = f_left + f_right + f_start + f_end
 
1888
                                #print 'deb:faces_list:\n', faces  #-----------------------
 
1889
                                if M_OBJ: obname, me, ob = makeNewObject()
 
1890
                                else: 
 
1891
                                        me = Mesh.New(obname)           # create a new mesh
 
1892
                                        ob = SCENE.objects.new(me) # create a new mesh_object
 
1893
                                me.verts.extend(pointsW)                # add vertices to mesh
 
1894
                                me.faces.extend(faces)  # add faces to the mesh
 
1895
 
 
1896
                                # each MeshSide becomes vertexGroup for easier material assignment ---------------------
 
1897
                                # The mesh must first be linked to an object so the method knows which object to update.
 
1898
                                # This is because vertex groups in Blender are stored in the object -- not in the mesh,
 
1899
                                # which may be linked to more than one object.
 
1900
                                if settings.var['vGroup_on'] and not M_OBJ:
 
1901
                                        # each MeshSide becomes vertexGroup for easier material assignment ---------------------
 
1902
                                        replace = Blender.Mesh.AssignModes.REPLACE  #or .AssignModes.ADD
 
1903
                                        vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
 
1904
                                        for v in f_left: vg_left.extend(v)
 
1905
                                        for v in f_right: vg_right.extend(v)
 
1906
                                        for v in f_top: vg_top.extend(v)
 
1907
                                        for v in f_bottom: vg_bottom.extend(v)
 
1908
                                        me.addVertGroup('side.left')  ; me.assignVertsToGroup('side.left',  list(set(vg_left)), 1.0, replace)
 
1909
                                        me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
 
1910
                                        me.addVertGroup('side.top')   ; me.assignVertsToGroup('side.top',   list(set(vg_top)), 1.0, replace)
 
1911
                                        me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
 
1912
                                        if not self.closed:
 
1913
                                                me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
 
1914
                                                me.addVertGroup('side.end')  ; me.assignVertsToGroup('side.end',   f_end[0],   1.0, replace)
 
1915
 
 
1916
                                if settings.var['meshSmooth_on']:  # left and right side become smooth ----------------------
 
1917
                                        #if self.spline or self.curved:
 
1918
                                        if True:
 
1919
                                                smooth_len = len(f_left) + len(f_right)
 
1920
                                                for i in xrange(smooth_len):
 
1921
                                                        me.faces[i].smooth = True
 
1922
                                                #me.Modes(AUTOSMOOTH)
 
1923
 
 
1924
                        # 2.level:IF width, but no-thickness  ---------------------
 
1925
                        else:
 
1926
                                faces = []
 
1927
                                faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
 
1928
                                if self.closed:
 
1929
                                        faces.append([len1, 0, len1-1, len1+len1-1])
 
1930
                                if M_OBJ: obname, me, ob = makeNewObject()
 
1931
                                else: 
 
1932
                                        me = Mesh.New(obname)           # create a new mesh
 
1933
                                        ob = SCENE.objects.new(me) # create a new mesh_object
 
1934
                                me.verts.extend(pointsW)                # add vertices to mesh
 
1935
                                me.faces.extend(faces)  # add faces to the mesh
 
1936
 
 
1937
 
 
1938
                # 1.level:IF no-width, but thickness ---------------------
 
1939
                elif thic != 0:
 
1940
                        len1 = len(points)
 
1941
                        thic_points = []
 
1942
                        thic_points.extend([[point[0], point[1], point[2]+thic] for point in points])
 
1943
                        if thic < 0.0:
 
1944
                                thic_points.extend(points)
 
1945
                                points = thic_points
 
1946
                        else:
 
1947
                                points.extend(thic_points)
 
1948
                        faces = []
 
1949
                        faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
 
1950
                        if self.closed:
 
1951
                                faces.append([len1-1, 0, len1, 2*len1-1])
 
1952
                        if M_OBJ: obname, me, ob = makeNewObject()
 
1953
                        else: 
 
1954
                                me = Mesh.New(obname)           # create a new mesh
 
1955
                                ob = SCENE.objects.new(me) # create a new mesh_object
 
1956
                        me.verts.extend(points)   # add vertices to mesh
 
1957
                        me.faces.extend(faces)  # add faces to the mesh
 
1958
 
 
1959
                        if settings.var['meshSmooth_on']:  # left and right side become smooth ----------------------
 
1960
                                #if self.spline or self.curved:
 
1961
                                if True:
 
1962
                                        for i in xrange(len(faces)):
 
1963
                                                me.faces[i].smooth = True
 
1964
                                        #me.Modes(AUTOSMOOTH)
 
1965
 
 
1966
                # 1.level:IF no-width and no-thickness  ---------------------
 
1967
                else:
 
1968
                        edges = [[num, num+1] for num in xrange(len(points)-1)]
 
1969
                        if self.closed:
 
1970
                                edges.append([len(points)-1, 0])
 
1971
                        if M_OBJ: obname, me, ob = makeNewObject()
 
1972
                        else: 
 
1973
                                me = Mesh.New(obname)           # create a new mesh
 
1974
                                ob = SCENE.objects.new(me) # create a new mesh_object
 
1975
                        me.verts.extend(points)   # add vertices to mesh
 
1976
                        me.edges.extend(edges)  # add edges to the mesh
 
1977
 
 
1978
                transform(self.extrusion, 0, ob)
 
1979
                #print 'deb:polyline.draw.END:----------------' #-----------------------
 
1980
                return ob
 
1981
 
 
1982
 
 
1983
 
 
1984
 
 
1985
class Vertex(object):  #-----------------------------------------------------------------
 
1986
        """Generic vertex object used by POLYLINEs, (and maybe others).
 
1987
        also used by class_LWPOLYLINEs but without obj-parameter
 
1988
        """
 
1989
 
 
1990
        def __init__(self, obj=None):
 
1991
                """Initializes vertex data.
 
1992
 
 
1993
                The optional obj arg is an entity object of type vertex.
 
1994
                """
 
1995
                #print 'deb:Vertex.init.START:----------------' #-----------------------
 
1996
                self.loc = [0,0,0]
 
1997
                self.face = []
 
1998
                self.swidth = None #0
 
1999
                self.ewidth = None #0
 
2000
                self.bulge = 0
 
2001
                self.tangent = False
 
2002
                self.weight =  1.0
 
2003
                if obj is not None:
 
2004
                        if not obj.type == 'vertex':
 
2005
                                raise TypeError, "Wrong type %s for vertex object!" %obj.type
 
2006
                        self.type = obj.type
 
2007
#                       self.data = obj.data[:]
 
2008
                        self.get_props(obj)
 
2009
                else:
 
2010
                        pass
 
2011
                #print 'deb:Vertex.init.END:----------------' #------------------------
 
2012
 
 
2013
 
 
2014
        def get_props(self, data):
 
2015
                """Gets coords for a VERTEX type object.
 
2016
 
 
2017
                Each vert can have a number of properties.
 
2018
                Verts should be coded as
 
2019
                10:xvalue
 
2020
                20:yvalue
 
2021
                40:startwidth or 0
 
2022
                41:endwidth or 0
 
2023
                42:bulge or 0
 
2024
                """
 
2025
                self.x = getit(data, 10, None)
 
2026
                self.y = getit(data, 20, None)
 
2027
                self.z = getit(data, 30, None)
 
2028
 
 
2029
                self.flags  = getit(data, 70, 0) # flags
 
2030
                self.curved = self.flags&1   # Bezier-curve-fit:additional-vertex
 
2031
                self.curved_t = self.flags&2   # Bezier-curve-fit:tangent exists
 
2032
                self.spline = self.flags&8   # NURBSpline-fit:additional-vertex
 
2033
                self.spline_c = self.flags&16  # NURBSpline-fit:control-vertex
 
2034
                self.poly3d = self.flags&32  # polyline3d:control-vertex
 
2035
                self.plmesh = self.flags&64  # polymesh3d:control-vertex
 
2036
                self.plface = self.flags&128 # polyface
 
2037
 
 
2038
                # if PolyFace.Vertex with Face_definition
 
2039
                if self.curved_t:
 
2040
                        self.curve_tangent =  getit(data, 50, None) # curve_tangent
 
2041
                        if not self.curve_tangent==None:
 
2042
                                self.tangent = True
 
2043
                #elif self.spline_c: # NURBSpline:control-vertex
 
2044
                #       self.weight =  getit(data, 41, 1.0) # weight od control point
 
2045
 
 
2046
                elif self.plface and not self.plmesh:
 
2047
                        v1 = getit(data, 71, 0) # polyface:Face.vertex 1.
 
2048
                        v2 = getit(data, 72, 0) # polyface:Face.vertex 2.
 
2049
                        v3 = getit(data, 73, 0) # polyface:Face.vertex 3.
 
2050
                        v4 = getit(data, 74, None) # polyface:Face.vertex 4.
 
2051
                        self.face = [abs(v1)-1,abs(v2)-1,abs(v3)-1]
 
2052
                        if v4 != None:
 
2053
                                if abs(v4) != abs(v1):
 
2054
                                        self.face.append(abs(v4)-1)
 
2055
                else:   #--parameter for polyline2d
 
2056
                        self.swidth = getit(data, 40, None) # start width
 
2057
                        self.ewidth = getit(data, 41, None) # end width
 
2058
                        self.bulge  = getit(data, 42, 0) # bulge of segment
 
2059
 
 
2060
 
 
2061
        def __len__(self):
 
2062
                return 3
 
2063
 
 
2064
 
 
2065
        def __getitem__(self, key):
 
2066
                return self.loc[key]
 
2067
 
 
2068
 
 
2069
        def __setitem__(self, key, value):
 
2070
                if key in [0,1,2]:
 
2071
                        self.loc[key]
 
2072
 
 
2073
 
 
2074
        def __iter__(self):
 
2075
                return self.loc.__iter__()
 
2076
 
 
2077
 
 
2078
        def __str__(self):
 
2079
                return str(self.loc)
 
2080
 
 
2081
 
 
2082
        def __repr__(self):
 
2083
                return "Vertex %s, swidth=%s, ewidth=%s, bulge=%s, face=%s" %(self.loc, self.swidth, self.ewidth, self.bulge, self.face)
 
2084
 
 
2085
 
 
2086
        def getx(self):
 
2087
                return self.loc[0]
 
2088
        def setx(self, value):
 
2089
                self.loc[0] = value
 
2090
        x = property(getx, setx)
 
2091
 
 
2092
 
 
2093
        def gety(self):
 
2094
                return self.loc[1]
 
2095
        def sety(self, value):
 
2096
                self.loc[1] = value
 
2097
        y = property(gety, sety)
 
2098
 
 
2099
 
 
2100
        def getz(self):
 
2101
                return self.loc[2]
 
2102
        def setz(self, value):
 
2103
                self.loc[2] = value
 
2104
        z = property(getz, setz)
 
2105
 
 
2106
 
 
2107
 
 
2108
class Spline(Polyline):  #-----------------------------------------------------------------
 
2109
        """Class for objects representing dxf SPLINEs.
 
2110
        """
 
2111
        """Expects an entity object of type spline as input.
 
2112
100 - Subclass marker (AcDbSpline)
 
2113
210,220, 230  - Normal vector (omitted if the spline is nonplanar) X,Y,Z values of normal vector
 
2114
70 - Spline flag (bit coded):
 
2115
  1 = Closed spline
 
2116
  2 = Periodic spline
 
2117
  4 = Rational spline
 
2118
  8 = Planar
 
2119
 16 = Linear (planar bit is also set)
 
2120
71 - Degree of the spline curve
 
2121
72 - Number of knots
 
2122
73 - Number of control points
 
2123
74 - Number of fit points (if any)
 
2124
42 - Knot tolerance (default = 0.0000001)
 
2125
43 - Control-point tolerance (default = 0.0000001)
 
2126
44 - Fit tolerance (default = 0.0000000001)
 
2127
12,22,32 - Start tangent--may be omitted (in WCS). X,Y,Z values of start tangent--may be omitted (in WCS).
 
2128
13,23, 33 - End tangent--may be omitted (in WCS). X,Y,Z values of end tangent--may be omitted (in WCS)
 
2129
40 - Knot value (one entry per knot)
 
2130
41 - Weight (if not 1); with multiple group pairs, are present if all are not 1
 
2131
10,20, 30  - Control points (in WCS) one entry per control point.
 
2132
DXF: X value; APP: 3D point, Y and Z values of control points (in WCS) (one entry per control point)
 
2133
11,21, 31 - Fit points (in WCS) one entry per fit point.
 
2134
 X,Y,Z values of fit points (in WCS) (one entry per fit point)
 
2135
        """
 
2136
        def __init__(self, obj):
 
2137
                #print 'deb:Spline.START:----------------' #------------------------
 
2138
                if not obj.type == 'spline':
 
2139
                        raise TypeError, "Wrong type %s for spline object!" %obj.type
 
2140
                self.type = obj.type
 
2141
#               self.data = obj.data[:]
 
2142
 
 
2143
                # required data
 
2144
                self.num_points = obj.get_type(73)[0]
 
2145
 
 
2146
                # optional data (with defaults)
 
2147
                self.space = getit(obj, 67, 0)
 
2148
 
 
2149
                self.color_index = getit(obj, 62, BYLAYER)
 
2150
 
 
2151
                #self.elevation =  getit(obj, 30, 0)
 
2152
                self.thic = 0 # getit(obj, 39, 0)
 
2153
 
 
2154
                width = 0
 
2155
                self.swidth =  width # default start width
 
2156
                self.ewidth =  width # default end width
 
2157
 
 
2158
                self.flags = getit(obj, 70, 0)
 
2159
                self.closed = self.flags & 1   # closed spline
 
2160
                self.period = self.flags & 2   # Periodic spline
 
2161
                self.ration = self.flags & 4   # Rational spline
 
2162
                self.planar = self.flags & 8   # Planar
 
2163
                self.linear = self.flags & 16  # Linear (and Planar)
 
2164
 
 
2165
                self.curvNoFitted = False
 
2166
                self.curvQuadrati = False
 
2167
                self.curvCubicBsp = False
 
2168
                self.curvBezier = False
 
2169
                self.degree = getit(obj, 71, 0) # Degree of the spline curve
 
2170
                if   self.degree == 0: self.curvNoFitted = True
 
2171
                elif self.degree == 1: self.curvQuadrati = True
 
2172
                elif self.degree == 2: self.curvCubicBsp = True
 
2173
                #elif self.degree == 3: self.curvBezier = True
 
2174
                #elif self.degree == 3: self.spline = True
 
2175
        
 
2176
                self.knotpk_len = getit(obj, 72, 0) # Number of knots
 
2177
                self.ctrlpk_len = getit(obj, 73, 0) # Number of control points
 
2178
                self.fit_pk_len = getit(obj, 74, 0) # Number of fit points (if any)
 
2179
 
 
2180
                #print 'deb:Spline self.fit_pk_len=', self.fit_pk_len #------------------------
 
2181
                #self.fit_pk_len = 0 # temp for debug
 
2182
                if self.fit_pk_len and 'spline_as'==5:
 
2183
                        self.spline = False
 
2184
                        self.curved = True
 
2185
                else:
 
2186
                        self.spline = True
 
2187
                        self.curved = False
 
2188
 
 
2189
                self.knotpk_tol = getit(obj, 42, 0.0000001) # Knot tolerance (default = 0.0000001)
 
2190
                self.ctrlpk_tol = getit(obj, 43, 0.0000001) # Control-point tolerance (default = 0.0000001)
 
2191
                self.fit_pk_tol = getit(obj, 44, 0.0000000001) # Fit tolerance (default = 0.0000000001)
 
2192
 
 
2193
                self.layer = getit(obj, 8, None)
 
2194
                self.extrusion = get_extrusion(obj)
 
2195
 
 
2196
                self.pltype = 'spline'   # spline is a 2D- or 3D-polyline
 
2197
 
 
2198
                self.points = self.get_points(obj.data)
 
2199
                #self.knots_val = self.get_knots_val(obj.data) # 40 - Knot value (one entry per knot)
 
2200
                #self.knots_wgh = self.get_knots_wgh(obj.data) # 41 - Weight (default 1)
 
2201
 
 
2202
                #print 'deb:Spline obj.data:\n', obj.data #------------------------
 
2203
                #print 'deb:Spline self.points:\n', self.points #------------------------
 
2204
                #print 'deb:Spline.ENDinit:----------------' #------------------------
 
2205
 
 
2206
 
 
2207
        def get_points(self, data):
 
2208
                """Gets points for a spline type object.
 
2209
 
 
2210
                Splines have fixed number of verts, and
 
2211
                each vert can have a number of properties.
 
2212
                Verts should be coded as
 
2213
                10:xvalue
 
2214
                20:yvalue
 
2215
                for each vert
 
2216
                """
 
2217
                point = None
 
2218
                points = []
 
2219
                pointend = None
 
2220
                #point = Vertex()
 
2221
                if self.spline: # NURBSpline definition
 
2222
                        for item in data:
 
2223
                                #print 'deb:Spline.get_points spilne_item:', item #------------------------
 
2224
                                if item[0] == 10:   # control point
 
2225
                                        if point: points.append(point)
 
2226
                                        point = Vertex()
 
2227
                                        point.curved = True
 
2228
                                        point.x = item[1]
 
2229
                                elif item[0] == 20: # 20 = y
 
2230
                                        point.y = item[1]
 
2231
                                elif item[0] == 30: # 30 = z
 
2232
                                        point.z = item[1]
 
2233
                                elif item[0] == 41: # 41 = weight
 
2234
                                        point.weight = item[1]
 
2235
                                        #print 'deb:Spline.get_points control point:', point #------------------------
 
2236
 
 
2237
                elif self.curved: # Bezier definition
 
2238
                        for item in data:
 
2239
                                #print 'deb:Spline.get_points curved_item:', item #------------------------
 
2240
                                if item[0] == 11:   # fit point
 
2241
                                        if point: points.append(point)
 
2242
                                        point = Vertex()
 
2243
                                        point.tangent = False
 
2244
                                        point.x = item[1]
 
2245
                                elif item[0] == 21: # 20 = y
 
2246
                                        point.y = item[1]
 
2247
                                elif item[0] == 31: # 30 = z
 
2248
                                        point.z = item[1]
 
2249
                                        #print 'deb:Spline.get_points fit point:', point #------------------------
 
2250
 
 
2251
                                elif item[0] == 12:   # start tangent
 
2252
                                        if point: points.append(point)
 
2253
                                        point = Vertex()
 
2254
                                        point.tangent = True
 
2255
                                        point.x = item[1]
 
2256
                                elif item[0] == 22: # = y
 
2257
                                        point.y = item[1]
 
2258
                                elif item[0] == 32: # = z
 
2259
                                        point.z = item[1]
 
2260
                                        #print 'deb:Spline.get_points fit begtangent:', point #------------------------
 
2261
 
 
2262
                                elif item[0] == 13:   # end tangent
 
2263
                                        if point: points.append(point)
 
2264
                                        pointend = Vertex()
 
2265
                                        pointend.tangent = True
 
2266
                                        pointend.x = item[1]
 
2267
                                elif item[0] == 23: # 20 = y
 
2268
                                        pointend.y = item[1]
 
2269
                                elif item[0] == 33: # 30 = z
 
2270
                                        pointend.z = item[1]
 
2271
                                        #print 'deb:Spline.get_points fit endtangent:', pointend #------------------------
 
2272
                points.append(point)
 
2273
                if self.curved and pointend:
 
2274
                        points.append(pointend)
 
2275
                #print 'deb:Spline points:\n', points #------------------------
 
2276
                return points
 
2277
 
 
2278
        def __repr__(self):
 
2279
                return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
 
2280
 
 
2281
        
 
2282
 
 
2283
class LWpolyline(Polyline):  #-------------------------------------------------------------
 
2284
        """Class for objects representing dxf LWPOLYLINEs.
 
2285
        """
 
2286
        def __init__(self, obj):
 
2287
                """Expects an entity object of type lwpolyline as input.
 
2288
                """
 
2289
                #print 'deb:LWpolyline.START:----------------' #------------------------
 
2290
                if not obj.type == 'lwpolyline':
 
2291
                        raise TypeError, "Wrong type %s for polyline object!" %obj.type
 
2292
                self.type = obj.type
 
2293
#               self.data = obj.data[:]
 
2294
 
 
2295
                # required data
 
2296
                self.num_points = obj.get_type(90)[0]
 
2297
 
 
2298
                # optional data (with defaults)
 
2299
                self.space = getit(obj, 67, 0)
 
2300
                self.elevation =  getit(obj, 38, 0)
 
2301
                self.thic =  getit(obj, 39, 0)
 
2302
                self.color_index = getit(obj, 62, BYLAYER)
 
2303
                width =  getit(obj, 43, 0)
 
2304
                self.swidth =  width # default start width
 
2305
                self.ewidth =  width # default end width
 
2306
                #print 'deb:LWpolyline width=', width #------------------------
 
2307
                #print 'deb:LWpolyline elevation=', self.elevation #------------------------
 
2308
        
 
2309
                self.flags = getit(obj, 70, 0)
 
2310
                self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen
 
2311
 
 
2312
                self.layer = getit(obj, 8, None)
 
2313
                self.extrusion = get_extrusion(obj)
 
2314
 
 
2315
                self.points = self.get_points(obj.data)
 
2316
 
 
2317
                self.pltype = 'poly2d'   # LW-polyline is a 2D-polyline
 
2318
                self.spline = False
 
2319
                self.curved = False
 
2320
 
 
2321
 
 
2322
                #print 'deb:LWpolyline.obj.data:\n', obj.data #------------------------
 
2323
                #print 'deb:LWpolyline.ENDinit:----------------' #------------------------
 
2324
 
 
2325
 
 
2326
        def get_points(self, data):
 
2327
                """Gets points for a polyline type object.
 
2328
 
 
2329
                LW-Polylines have no fixed number of verts, and
 
2330
                each vert can have a number of properties.
 
2331
                Verts should be coded as
 
2332
                10:xvalue
 
2333
                20:yvalue
 
2334
                40:startwidth or 0
 
2335
                41:endwidth or 0
 
2336
                42:bulge or 0
 
2337
                for each vert
 
2338
                """
 
2339
                num = self.num_points
 
2340
                point = None
 
2341
                points = []
 
2342
                for item in data:
 
2343
                        if item[0] == 10:   # 10 = x
 
2344
                                if point:
 
2345
                                        points.append(point)
 
2346
                                point = Vertex()
 
2347
                                point.x = item[1]
 
2348
                                point.z = self.elevation
 
2349
                        elif item[0] == 20: # 20 = y
 
2350
                                point.y = item[1]
 
2351
                        elif item[0] == 40: # 40 = start width
 
2352
                                point.swidth = item[1]
 
2353
                        elif item[0] == 41: # 41 = end width
 
2354
                                point.ewidth = item[1]
 
2355
                        elif item[0] == 42: # 42 = bulge
 
2356
                                point.bulge = item[1]
 
2357
                points.append(point)
 
2358
                return points
 
2359
 
 
2360
 
 
2361
        def __repr__(self):
 
2362
                return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
 
2363
 
 
2364
 
 
2365
class Text:  #-----------------------------------------------------------------
 
2366
        """Class for objects representing dxf TEXT.
 
2367
        """
 
2368
        def __init__(self, obj):
 
2369
                """Expects an entity object of type text as input.
 
2370
                """
 
2371
                if not obj.type == 'text':
 
2372
                        raise TypeError, "Wrong type %s for text object!" %obj.type
 
2373
                self.type = obj.type
 
2374
#               self.data = obj.data[:]
 
2375
 
 
2376
                # required data
 
2377
                self.height = 1.7 * obj.get_type(40)[0]  #text.height
 
2378
                self.value = obj.get_type(1)[0]   #The text string value
 
2379
 
 
2380
                # optional data (with defaults)
 
2381
                self.space = getit(obj, 67, 0)
 
2382
                self.color_index = getit(obj, 62, BYLAYER)
 
2383
                self.thic =  getit(obj, 39, 0)
 
2384
 
 
2385
                self.rotation = getit(obj, 50, 0)  # radians
 
2386
                self.width_factor = getit(obj, 41, 1) # Scaling factor along local x axis
 
2387
                self.oblique = getit(obj, 51, 0) # oblique angle: skew in degrees -90 <= oblique <= 90
 
2388
 
 
2389
                #self.style = getit(obj, 7, 'STANDARD') # --todo---- Text style name (optional, default = STANDARD)
 
2390
 
 
2391
                #Text generation flags (optional, default = 0):
 
2392
                #2 = backward (mirrored in X),
 
2393
                #4 = upside down (mirrored in Y)
 
2394
                self.flags = getit(obj, 71, 0)
 
2395
                self.mirrorX, self.mirrorY = 1.0, 1.0
 
2396
                if self.flags&2: self.mirrorX = - 1.0
 
2397
                if self.flags&4: self.mirrorY = - 1.0
 
2398
 
 
2399
                # vertical.alignment: 0=baseline, 1=bottom, 2=middle, 3=top
 
2400
                self.valignment = getit(obj, 73, 0)
 
2401
                #Horizontal text justification type (optional, default = 0) integer codes (not bit-coded)
 
2402
                #0=left, 1=center, 2=right
 
2403
                #3=aligned, 4=middle, 5=fit
 
2404
                self.halignment = getit(obj, 72, 0)
 
2405
 
 
2406
                self.layer = getit(obj, 8, None)
 
2407
                self.loc1, self.loc2 = self.get_loc(obj)
 
2408
                if self.loc2[0] != None and self.halignment != 5: 
 
2409
                        self.loc = self.loc2
 
2410
                else:
 
2411
                        self.loc = self.loc1
 
2412
                self.extrusion = get_extrusion(obj)
 
2413
 
 
2414
 
 
2415
        def get_loc(self, data):
 
2416
                """Gets adjusted location for text type objects.
 
2417
 
 
2418
                If group 72 and/or 73 values are nonzero then the first alignment point values
 
2419
                are ignored and AutoCAD calculates new values based on the second alignment
 
2420
                point and the length and height of the text string itself (after applying the
 
2421
                text style). If the 72 and 73 values are zero or missing, then the second
 
2422
                alignment point is meaningless.
 
2423
                I don't know how to calc text size...
 
2424
                """
 
2425
                # bottom left x, y, z and justification x, y, z = 0
 
2426
                #x, y, z, jx, jy, jz = 0, 0, 0, 0, 0, 0
 
2427
                x  = getit(data, 10, None) #First alignment point (in OCS). 
 
2428
                y  = getit(data, 20, None)
 
2429
                z  = getit(data, 30, 0.0)
 
2430
                jx = getit(data, 11, None) #Second alignment point (in OCS). 
 
2431
                jy = getit(data, 21, None)
 
2432
                jz = getit(data, 31, 0.0)
 
2433
                return [x, y, z],[jx, jy, jz]
 
2434
 
 
2435
 
 
2436
        def __repr__(self):
 
2437
                return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
 
2438
 
 
2439
 
 
2440
        def draw(self, settings):
 
2441
                """for TEXTs: generate Blender_geometry.
 
2442
                """
 
2443
                obname = 'tx_%s' %self.layer  # create object name from layer name
 
2444
                obname = obname[:MAX_NAMELENGTH]
 
2445
                txt = Text3d.New(obname)
 
2446
                ob = SCENE.objects.new(txt) # create a new text_object
 
2447
 
 
2448
                txt.setText(self.value)
 
2449
                txt.setSize(1.0) #Blender<2.45 accepts only (0.0 - 5.0)
 
2450
                #txt.setSize(self.height)
 
2451
                #txt.setWidth(self.bold)
 
2452
                #setLineSeparation(sep)
 
2453
                txt.setShear(self.oblique/90)
 
2454
 
 
2455
                thic = set_thick(self.thic, settings)
 
2456
                if thic != 0.0:
 
2457
                        thic = self.thic * 0.5
 
2458
                        self.loc[2] += thic
 
2459
                        txt.setExtrudeDepth(1.0)  #Blender<2.45 accepts only (0.1 - 10.0)
 
2460
                if self.halignment == 0:
 
2461
                        align = Text3d.LEFT
 
2462
                elif self.halignment == 1:
 
2463
                        align = Text3d.MIDDLE
 
2464
                elif self.halignment == 2:
 
2465
                        align = Text3d.RIGHT
 
2466
                else:
 
2467
                        align = Text3d.LEFT
 
2468
                txt.setAlignment(align)
 
2469
 
 
2470
                if self.valignment == 1:
 
2471
                        txt.setYoffset(0.0)
 
2472
                elif self.valignment == 2:
 
2473
                        txt.setYoffset(- self.height * 0.5)
 
2474
                elif self.valignment == 3:
 
2475
                        txt.setYoffset(- self.height)
 
2476
 
 
2477
                # move the object center to the text location
 
2478
                ob.loc = tuple(self.loc)
 
2479
                transform(self.extrusion, self.rotation, ob)
 
2480
 
 
2481
                # flip it and scale it to the text width
 
2482
                ob.SizeX *= self.height * self.width_factor * self.mirrorX
 
2483
                ob.SizeY *= self.height * self.mirrorY
 
2484
                if thic != 0.0: ob.SizeZ *= abs(thic)
 
2485
                return ob
 
2486
 
 
2487
 
 
2488
        
 
2489
def set_thick(thickness, settings):
 
2490
        """Set thickness relative to settings variables.
 
2491
        
 
2492
        Set thickness relative to settings variables:
 
2493
        'thick_on','thick_force','thick_min'.
 
2494
        Accepted also minus values of thickness
 
2495
        python trick: sign(x)=cmp(x,0)
 
2496
        """
 
2497
        if settings.var['thick_force']:
 
2498
                if settings.var['thick_on']:
 
2499
                        if abs(thickness) <  settings.var['thick_min']:
 
2500
                                thic = settings.var['thick_min'] * cmp(thickness,0)
 
2501
                        else: thic = thickness
 
2502
                else: thic = settings.var['thick_min']
 
2503
        else: 
 
2504
                if settings.var['thick_on']: thic = thickness
 
2505
                else: thic = 0.0
 
2506
        return thic
 
2507
 
 
2508
 
 
2509
 
 
2510
 
 
2511
class Mtext:  #-----------------------------------------------------------------
 
2512
        """Class for objects representing dxf MTEXT.
 
2513
        """
 
2514
 
 
2515
        def __init__(self, obj):
 
2516
                """Expects an entity object of type mtext as input.
 
2517
                """
 
2518
                if not obj.type == 'mtext':
 
2519
                        raise TypeError, "Wrong type %s for mtext object!" %obj.type
 
2520
                self.type = obj.type
 
2521
#               self.data = obj.data[:]
 
2522
 
 
2523
                # required data
 
2524
                self.height = obj.get_type(40)[0]
 
2525
                self.width = obj.get_type(41)[0]
 
2526
                self.alignment = obj.get_type(71)[0] # alignment 1=TL, 2=TC, 3=TR, 4=ML, 5=MC, 6=MR, 7=BL, 8=BC, 9=BR
 
2527
                self.value = self.get_text(obj) # The text string value
 
2528
 
 
2529
                # optional data (with defaults)
 
2530
                self.space = getit(obj, 67, 0)
 
2531
                self.color_index = getit(obj, 62, BYLAYER)
 
2532
                self.rotation = getit(obj, 50, 0)  # radians
 
2533
 
 
2534
                self.width_factor = getit(obj, 42, 1) # Scaling factor along local x axis
 
2535
                self.line_space = getit(obj, 44, 1) # percentage of default
 
2536
 
 
2537
                self.layer = getit(obj, 8, None)
 
2538
                self.loc = self.get_loc(obj)
 
2539
                self.extrusion = get_extrusion(obj)
 
2540
 
 
2541
 
 
2542
        def get_text(self, data):
 
2543
                """Reconstructs mtext data from dxf codes.
 
2544
                """
 
2545
                primary = ''
 
2546
                secondary = []
 
2547
                for item in data:
 
2548
                        if item[0] == 1: # There should be only one primary...
 
2549
                                primary = item[1]
 
2550
                        elif item[0] == 3: # There may be any number of extra strings (in order)
 
2551
                                secondary.append(item[1])
 
2552
                if not primary:
 
2553
                        #raise ValueError, "Empty Mtext Object!"
 
2554
                        string = "Empty Mtext Object!"
 
2555
                if not secondary:
 
2556
                        string = primary.replace(r'\P', '\n')
 
2557
                else:
 
2558
                        string = ''.join(secondary)+primary
 
2559
                        string = string.replace(r'\P', '\n')
 
2560
                return string
 
2561
 
 
2562
 
 
2563
        def get_loc(self, data):
 
2564
                """Gets location for a mtext type objects.
 
2565
 
 
2566
                Mtext objects have only one point indicating 
 
2567
                """      
 
2568
                loc = [0, 0, 0]
 
2569
                loc[0] = getit(data, 10, None)
 
2570
                loc[1] = getit(data, 20, None)
 
2571
                loc[2] = getit(data, 30, 0.0)
 
2572
                return loc
 
2573
 
 
2574
 
 
2575
        def __repr__(self):
 
2576
                return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
 
2577
 
 
2578
 
 
2579
        def draw(self, settings):
 
2580
                """for MTEXTs: generate Blender_geometry.
 
2581
                """
 
2582
                # Now Create an object
 
2583
                obname = 'tm_%s' %self.layer  # create object name from layer name
 
2584
                obname = obname[:MAX_NAMELENGTH]
 
2585
                txt = Text3d.New(obname)
 
2586
                ob = SCENE.objects.new(txt) # create a new text_object
 
2587
 
 
2588
                txt.setSize(1)
 
2589
                # Blender doesn't give access to its text object width currently
 
2590
                # only to the text3d's curve width...
 
2591
                #txt.setWidth(text.width/10)
 
2592
                txt.setLineSeparation(self.line_space)
 
2593
                txt.setExtrudeDepth(0.5)
 
2594
                txt.setText(self.value)
 
2595
 
 
2596
                # scale it to the text size
 
2597
                ob.SizeX = self.height * self.width_factor
 
2598
                ob.SizeY = self.height
 
2599
                ob.SizeZ = self.height
 
2600
 
 
2601
                # move the object center to the text location
 
2602
                ob.loc = tuple(self.loc)
 
2603
                transform(self.extrusion, self.rotation, ob)
 
2604
 
 
2605
                return ob
 
2606
 
 
2607
 
 
2608
class Circle:  #-----------------------------------------------------------------
 
2609
        """Class for objects representing dxf CIRCLEs.
 
2610
        """
 
2611
 
 
2612
        def __init__(self, obj):
 
2613
                """Expects an entity object of type circle as input.
 
2614
                """
 
2615
                if not obj.type == 'circle':
 
2616
                        raise TypeError, "Wrong type %s for circle object!" %obj.type
 
2617
                self.type = obj.type
 
2618
#               self.data = obj.data[:]
 
2619
 
 
2620
                # required data
 
2621
                self.radius = obj.get_type(40)[0]
 
2622
 
 
2623
                # optional data (with defaults)
 
2624
                self.space = getit(obj, 67, 0)
 
2625
                self.thic =  getit(obj, 39, 0)
 
2626
                self.color_index = getit(obj, 62, BYLAYER)
 
2627
 
 
2628
                self.layer = getit(obj, 8, None)
 
2629
                self.loc = self.get_loc(obj)
 
2630
                self.extrusion = get_extrusion(obj)
 
2631
 
 
2632
 
 
2633
 
 
2634
        def get_loc(self, data):
 
2635
                """Gets the center location for circle type objects.
 
2636
 
 
2637
                Circles have a single coord location.
 
2638
                """
 
2639
                loc = [0, 0, 0]
 
2640
                loc[0] = getit(data, 10, None)
 
2641
                loc[1] = getit(data, 20, None)
 
2642
                loc[2] = getit(data, 30, 0.0)
 
2643
                return loc
 
2644
 
 
2645
 
 
2646
 
 
2647
        def __repr__(self):
 
2648
                return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
 
2649
 
 
2650
 
 
2651
        def draw(self, settings):
 
2652
                """for CIRCLE: generate Blender_geometry.
 
2653
                """
 
2654
                obname = 'ci_%s' %self.layer  # create object name from layer name
 
2655
                obname = obname[:MAX_NAMELENGTH]
 
2656
                radius = self.radius
 
2657
 
 
2658
                thic = set_thick(self.thic, settings)
 
2659
                width = 0.0
 
2660
                if settings.var['lines_as'] == 4: # as thin_box
 
2661
                        thic = settings.var['thick_min']
 
2662
                        width = settings.var['width_min']
 
2663
                if settings.var['lines_as'] == 3: # as thin cylinder
 
2664
                        cyl_rad = 0.5 * settings.var['width_min']
 
2665
 
 
2666
                if settings.var['lines_as'] == 5:  # draw CIRCLE as curve -------------
 
2667
                        if True:  # universal version
 
2668
                                arc_res = settings.var['curve_arc']
 
2669
                                #arc_res = 3
 
2670
                                start, end = 0.0, 360.0
 
2671
                                VectorTriples = calcArc(None, radius, start, end, arc_res, True)
 
2672
                                c = Curve.New(obname) # create new curve data
 
2673
                                curve = c.appendNurb(BezTriple.New(VectorTriples[0]))
 
2674
                                for p in VectorTriples[1:-1]:
 
2675
                                        curve.append(BezTriple.New(p))
 
2676
                                for point in curve:
 
2677
                                        point.handleTypes = [FREE, FREE]
 
2678
                        else:   # standard version
 
2679
                                c = Curve.New(obname)   # create new curve data
 
2680
                                p1 = (0, -radius, 0)
 
2681
                                p2 = (radius, 0, 0)
 
2682
                                p3 = (0, radius, 0)
 
2683
                                p4 = (-radius, 0, 0)
 
2684
        
 
2685
                                p1 = BezTriple.New(p1)
 
2686
                                p2 = BezTriple.New(p2)
 
2687
                                p3 = BezTriple.New(p3)
 
2688
                                p4 = BezTriple.New(p4)
 
2689
        
 
2690
                                curve = c.appendNurb(p1)
 
2691
                                curve.append(p2)
 
2692
                                curve.append(p3)
 
2693
                                curve.append(p4)
 
2694
                                for point in curve:
 
2695
                                        point.handleTypes = [AUTO, AUTO]
 
2696
 
 
2697
                        curve.flagU = 1  # 1 sets the curve cyclic=closed
 
2698
                        if settings.var['fill_on']:
 
2699
                                c.setFlag(6) # 2+4 set top and button caps
 
2700
                        else:
 
2701
                                c.setFlag(c.getFlag() & ~6) # dont set top and button caps
 
2702
 
 
2703
                        c.setResolu(settings.var['curve_res'])
 
2704
                        c.update()
 
2705
 
 
2706
                        #--todo-----to check---------------------------
 
2707
                        ob = SCENE.objects.new(c) # create a new curve_object
 
2708
                        ob.loc = tuple(self.loc)
 
2709
                        if thic != 0.0: #hack: Blender<2.45 curve-extrusion
 
2710
                                thic = thic * 0.5
 
2711
                                c.setExt1(1.0)  # curve-extrusion accepts only (0.0 - 2.0)
 
2712
                                ob.LocZ = thic + self.loc[2]
 
2713
                        transform(self.extrusion, 0, ob)
 
2714
                        if thic != 0.0:
 
2715
                                ob.SizeZ *= abs(thic)
 
2716
                        return ob
 
2717
 
 
2718
                elif False: # create a new mesh_object with buildin_circle_primitive
 
2719
                        verts_num = settings.var['arc_res'] * sqrt(radius / settings.var['arc_rad'])
 
2720
                        if verts_num > 100: verts_num = 100 # Blender accepts only values [3:500]
 
2721
                        if verts_num < 4: verts_num = 4 # Blender accepts only values [3:500]
 
2722
                        if thic != 0:
 
2723
                                loc2 = thic * 0.5   #-----blenderAPI draw Cylinder with 2*thickness
 
2724
                                self.loc[2] += loc2  #---new location for the basis of cylinder
 
2725
                                #print 'deb:circleDraw:self.loc2:', self.loc  #-----------------------
 
2726
                                c = Mesh.Primitives.Cylinder(int(verts_num), radius*2, abs(thic))
 
2727
                        else:
 
2728
                                c = Mesh.Primitives.Circle(int(verts_num), radius*2)
 
2729
 
 
2730
                        #c.update()
 
2731
                        ob = SCENE.objects.new(c, obname) # create a new circle_mesh_object
 
2732
                        ob.loc = tuple(self.loc)
 
2733
                        transform(self.extrusion, 0, ob)
 
2734
                        return ob
 
2735
 
 
2736
                else:  # draw CIRCLE as mesh -----------------------------------------------
 
2737
                        if M_OBJ: obname, me, ob = makeNewObject()
 
2738
                        else: 
 
2739
                                me = Mesh.New(obname)           # create a new mesh
 
2740
                                ob = SCENE.objects.new(me) # create a new mesh_object
 
2741
                        # set a number of segments in entire circle
 
2742
                        arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
 
2743
                        start, end = 0.0 , 360.0
 
2744
                        verts = calcArc(None, radius, start, end, arc_res, False)
 
2745
                        verts = verts[:-1] #list without last point/edge (cause by circle it is equal to the first point)
 
2746
                        #print 'deb:circleDraw: verts:', verts  #--------------- 
 
2747
 
 
2748
                        if thic != 0:
 
2749
                                len1 = len(verts)
 
2750
                                thic_verts = []
 
2751
                                thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
 
2752
                                if thic < 0.0:
 
2753
                                        thic_verts.extend(verts)
 
2754
                                        verts = thic_verts
 
2755
                                else:
 
2756
                                        verts.extend(thic_verts)
 
2757
                                faces = []
 
2758
                                f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
 
2759
                                #f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1)]
 
2760
                                f_band.append([len1 - 1, 0, len1, len1 + len1 -1])
 
2761
                                faces = f_band
 
2762
                                smooth_len = len(f_band)
 
2763
                                if settings.var['fill_on']:
 
2764
                                        if thic < 0.0:
 
2765
                                                verts.append([0,0,thic])  #center of top side
 
2766
                                                verts.append([0,0,0])  #center of bottom side
 
2767
                                        else:
 
2768
                                                verts.append([0,0,0])  #center of bottom side
 
2769
                                                verts.append([0,0,thic])  #center of top side
 
2770
                                        center1 = len(verts)-2
 
2771
                                        center2 = len(verts)-1
 
2772
                                        f_bottom = [[num+1, num, center1] for num in xrange(len1 - 1)]
 
2773
                                        f_bottom.append([0, len1 - 1, center1])
 
2774
                                        f_top = [[num+len1, num+1+len1, center2] for num in xrange(len1 - 1)]
 
2775
                                        f_top.append([len1-1+len1, 0+len1, center2])
 
2776
                                        #print 'deb:circleDraw:verts:', verts  #---------------
 
2777
                                        faces = f_band + f_bottom + f_top
 
2778
                                        #print 'deb:circleDraw:faces:', faces  #---------------
 
2779
                                me.verts.extend(verts) # add vertices to mesh
 
2780
                                me.faces.extend(faces)  # add faces to the mesh
 
2781
 
 
2782
                                if settings.var['meshSmooth_on']:  # left and right side become smooth ----------------------
 
2783
                                        for i in xrange(smooth_len):
 
2784
                                                me.faces[i].smooth = True
 
2785
                                # each MeshSide becomes vertexGroup for easier material assignment ---------------------
 
2786
                                if settings.var['vGroup_on'] and not M_OBJ:
 
2787
                                        # each MeshSide becomes vertexGroup for easier material assignment ---------------------
 
2788
                                        replace = Blender.Mesh.AssignModes.REPLACE  #or .AssignModes.ADD
 
2789
                                        vg_band, vg_top, vg_bottom = [], [], []
 
2790
                                        for v in f_band: vg_band.extend(v)
 
2791
                                        me.addVertGroup('side.band')  ; me.assignVertsToGroup('side.band',  list(set(vg_band)), 1.0, replace)
 
2792
                                        if settings.var['fill_on']:
 
2793
                                                for v in f_top: vg_top.extend(v)
 
2794
                                                for v in f_bottom: vg_bottom.extend(v)
 
2795
                                                me.addVertGroup('side.top')   ; me.assignVertsToGroup('side.top',   list(set(vg_top)), 1.0, replace)
 
2796
                                                me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
 
2797
 
 
2798
                        else: # if thic == 0
 
2799
                                if settings.var['fill_on']:
 
2800
                                        len1 = len(verts)
 
2801
                                        verts.append([0,0,0])  #center of circle
 
2802
                                        center1 = len1
 
2803
                                        faces = []
 
2804
                                        faces.extend([[num, num+1, center1] for num in xrange(len1)])
 
2805
                                        faces.append([len1-1, 0, center1])
 
2806
                                        #print 'deb:circleDraw:verts:', verts  #---------------
 
2807
                                        #print 'deb:circleDraw:faces:', faces  #---------------
 
2808
                                        me.verts.extend(verts) # add vertices to mesh
 
2809
                                        me.faces.extend(faces)  # add faces to the mesh
 
2810
                                else:
 
2811
                                        me.verts.extend(verts) # add vertices to mesh
 
2812
                                        edges = [[num, num+1] for num in xrange(len(verts))]
 
2813
                                        edges[-1][1] = 0   # it points the "new" last edge to the first vertex
 
2814
                                        me.edges.extend(edges)  # add edges to the mesh
 
2815
 
 
2816
                        ob.loc = tuple(self.loc)
 
2817
                        transform(self.extrusion, 0, ob)
 
2818
                        return ob
 
2819
                        
 
2820
 
 
2821
class Arc:  #-----------------------------------------------------------------
 
2822
        """Class for objects representing dxf ARCs.
 
2823
        """
 
2824
 
 
2825
        def __init__(self, obj):
 
2826
                """Expects an entity object of type arc as input.
 
2827
                """
 
2828
                if not obj.type == 'arc':
 
2829
                        raise TypeError, "Wrong type %s for arc object!" %obj.type
 
2830
                self.type = obj.type
 
2831
#               self.data = obj.data[:]
 
2832
 
 
2833
                # required data
 
2834
                self.radius = obj.get_type(40)[0]
 
2835
                self.start_angle = obj.get_type(50)[0]
 
2836
                self.end_angle = obj.get_type(51)[0]
 
2837
 
 
2838
                # optional data (with defaults)
 
2839
                self.space = getit(obj, 67, 0)
 
2840
                self.thic =  getit(obj, 39, 0)
 
2841
                self.color_index = getit(obj, 62, BYLAYER)
 
2842
 
 
2843
                self.layer = getit(obj, 8, None)
 
2844
                self.loc = self.get_loc(obj)
 
2845
                self.extrusion = get_extrusion(obj)
 
2846
                #print 'deb:Arc__init__: center, radius, start, end:\n', self.loc, self.radius, self.start_angle, self.end_angle  #---------
 
2847
 
 
2848
 
 
2849
 
 
2850
        def get_loc(self, data):
 
2851
                """Gets the center location for arc type objects.
 
2852
 
 
2853
                Arcs have a single coord location.
 
2854
                """
 
2855
                loc = [0, 0, 0]
 
2856
                loc[0] = getit(data, 10, None)
 
2857
                loc[1] = getit(data, 20, None)
 
2858
                loc[2] = getit(data, 30, 0.0)
 
2859
                return loc
 
2860
 
 
2861
 
 
2862
 
 
2863
        def __repr__(self):
 
2864
                return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
 
2865
 
 
2866
 
 
2867
        def draw(self, settings):
 
2868
                """for ARC: generate Blender_geometry.
 
2869
                """
 
2870
                obname = 'ar_%s' %self.layer  # create object name from layer name
 
2871
                obname = obname[:MAX_NAMELENGTH]
 
2872
 
 
2873
                center = self.loc
 
2874
                radius = self.radius
 
2875
                start = self.start_angle
 
2876
                end = self.end_angle
 
2877
                #print 'deb:calcArcPoints:\n center, radius, start, end:\n', center, radius, start, end  #---------
 
2878
                thic = set_thick(self.thic, settings)
 
2879
                width = 0.0
 
2880
                if settings.var['lines_as'] == 4: # as thin_box
 
2881
                        thic = settings.var['thick_min']
 
2882
                        width = settings.var['width_min']
 
2883
                if settings.var['lines_as'] == 3: # as thin cylinder
 
2884
                        cyl_rad = 0.5 * settings.var['width_min']
 
2885
 
 
2886
                if settings.var['lines_as'] == 5:  # draw ARC as curve -------------
 
2887
                        arc_res = settings.var['curve_arc']
 
2888
                        triples = True
 
2889
                        VectorTriples = calcArc(None, radius, start, end, arc_res, triples)
 
2890
                        arc = Curve.New(obname) # create new curve data
 
2891
                        curve = arc.appendNurb(BezTriple.New(VectorTriples[0]))
 
2892
                        for p in VectorTriples[1:]:
 
2893
                                curve.append(BezTriple.New(p))
 
2894
                        for point in curve:
 
2895
                                point.handleTypes = [FREE, FREE]
 
2896
                        curve.flagU = 0 # 0 sets the curve not cyclic=open
 
2897
                        arc.setResolu(settings.var['curve_res'])
 
2898
 
 
2899
                        arc.update() #important for handles calculation
 
2900
 
 
2901
                        ob = SCENE.objects.new(arc) # create a new curve_object
 
2902
                        ob.loc = tuple(self.loc)
 
2903
                        if thic != 0.0: #hack: Blender<2.45 curve-extrusion
 
2904
                                thic = thic * 0.5
 
2905
                                arc.setExt1(1.0)  # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
 
2906
                                ob.LocZ = thic + self.loc[2]
 
2907
                        transform(self.extrusion, 0, ob)
 
2908
                        if thic != 0.0:
 
2909
                                ob.SizeZ *= abs(thic)
 
2910
                        return ob
 
2911
 
 
2912
                else:  # draw ARC as mesh --------------------
 
2913
                        if M_OBJ: obname, me, ob = makeNewObject()
 
2914
                        else: 
 
2915
                                me = Mesh.New(obname)           # create a new mesh
 
2916
                                ob = SCENE.objects.new(me) # create a new mesh_object
 
2917
                        # set a number of segments in entire circle
 
2918
                        arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
 
2919
 
 
2920
                        verts = calcArc(None, radius, start, end, arc_res, False)
 
2921
                        #verts = [list(point) for point in verts]
 
2922
                        len1 = len(verts)
 
2923
                        #print 'deb:len1:', len1  #-----------------------
 
2924
                        if width != 0:
 
2925
                                radius_out = radius + (0.5 * width)
 
2926
                                radius_in  = radius - (0.5 * width)
 
2927
                                if radius_in <= 0.0:
 
2928
                                        radius_in = settings.var['dist_min']
 
2929
                                        #radius_in = 0.0
 
2930
                                verts_in = []
 
2931
                                verts_out = []
 
2932
                                for point in verts:
 
2933
                                        pointVec = Mathutils.Vector(point)
 
2934
                                        pointVec = pointVec.normalize()
 
2935
                                        verts_in.append(list(radius_in * pointVec))   #vertex inside
 
2936
                                        verts_out.append(list(radius_out * pointVec)) #vertex outside
 
2937
                                verts = verts_in + verts_out
 
2938
 
 
2939
                                #print 'deb:verts:', verts  #---------------------
 
2940
                                if thic != 0:
 
2941
                                        thic_verts = []
 
2942
                                        thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
 
2943
                                        if thic < 0.0:
 
2944
                                                thic_verts.extend(verts)
 
2945
                                                verts = thic_verts
 
2946
                                        else:
 
2947
                                                verts.extend(thic_verts)
 
2948
                                        f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
 
2949
                                        f_top   = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
 
2950
                                        f_left   = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
 
2951
                                        f_right  = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
 
2952
                                        f_start = [[0, len1, len1+len1+len1, len1+len1]]
 
2953
                                        f_end   = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
 
2954
                                        faces = f_left + f_right + f_bottom + f_top + f_start + f_end
 
2955
        
 
2956
                                        me.verts.extend(verts) # add vertices to mesh
 
2957
                                        me.faces.extend(faces)  # add faces to the mesh
 
2958
 
 
2959
                                        if settings.var['meshSmooth_on']:  # left and right side become smooth ----------------------
 
2960
                                                smooth_len = len(f_left) + len(f_right)
 
2961
                                                for i in xrange(smooth_len):
 
2962
                                                        me.faces[i].smooth = True
 
2963
                                        # each MeshSide becomes vertexGroup for easier material assignment ---------------------
 
2964
                                        if settings.var['vGroup_on'] and not M_OBJ:
 
2965
                                                # each MeshSide becomes vertexGroup for easier material assignment ---------------------
 
2966
                                                replace = Blender.Mesh.AssignModes.REPLACE  #or .AssignModes.ADD
 
2967
                                                vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
 
2968
                                                for v in f_left: vg_left.extend(v)
 
2969
                                                for v in f_right: vg_right.extend(v)
 
2970
                                                for v in f_top: vg_top.extend(v)
 
2971
                                                for v in f_bottom: vg_bottom.extend(v)
 
2972
                                                me.addVertGroup('side.left')  ; me.assignVertsToGroup('side.left',  list(set(vg_left)), 1.0, replace)
 
2973
                                                me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
 
2974
                                                me.addVertGroup('side.top')   ; me.assignVertsToGroup('side.top',   list(set(vg_top)), 1.0, replace)
 
2975
                                                me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
 
2976
                                                me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
 
2977
                                                me.addVertGroup('side.end')  ; me.assignVertsToGroup('side.end',   f_end[0],   1.0, replace)
 
2978
                                        
 
2979
 
 
2980
                                else:  # if thick=0 - draw only flat ring
 
2981
                                        faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
 
2982
                                        me.verts.extend(verts) # add vertices to mesh
 
2983
                                        me.faces.extend(faces)  # add faces to the mesh
 
2984
        
 
2985
                        elif thic != 0:
 
2986
                                thic_verts = []
 
2987
                                thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
 
2988
                                if thic < 0.0:
 
2989
                                        thic_verts.extend(verts)
 
2990
                                        verts = thic_verts
 
2991
                                else:
 
2992
                                        verts.extend(thic_verts)
 
2993
                                faces = []
 
2994
                                #print 'deb:len1:', len1  #-----------------------
 
2995
                                #print 'deb:verts:', verts  #---------------------
 
2996
                                faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
 
2997
 
 
2998
                                me.verts.extend(verts) # add vertices to mesh
 
2999
                                me.faces.extend(faces)  # add faces to the mesh
 
3000
                                if settings.var['meshSmooth_on']:  # left and right side become smooth ----------------------
 
3001
                                        for i in xrange(len(faces)):
 
3002
                                                me.faces[i].smooth = True
 
3003
 
 
3004
                        else:
 
3005
                                edges = [[num, num+1] for num in xrange(len(verts)-1)]
 
3006
                                me.verts.extend(verts) # add vertices to mesh
 
3007
                                me.edges.extend(edges)  # add edges to the mesh
 
3008
 
 
3009
                        #me.update()
 
3010
                        #ob = SCENE.objects.new(me) # create a new arc_object
 
3011
                        #ob.link(me)
 
3012
                        ob.loc = tuple(center)
 
3013
                        #ob.loc = Mathutils.Vector(ob.loc)
 
3014
                        transform(self.extrusion, 0, ob)
 
3015
                        #ob.size = (1,1,1)
 
3016
                        return ob
 
3017
 
 
3018
 
 
3019
class BlockRecord:  #-----------------------------------------------------------------
 
3020
        """Class for objects representing dxf block_records.
 
3021
        """
 
3022
 
 
3023
        def __init__(self, obj):
 
3024
                """Expects an entity object of type block_record as input.
 
3025
                """
 
3026
                if not obj.type == 'block_record':
 
3027
                        raise TypeError, "Wrong type %s for block_record object!" %obj.type
 
3028
                self.type = obj.type
 
3029
#               self.data = obj.data[:]
 
3030
 
 
3031
                # required data
 
3032
                self.name =  getit(obj, 2, None)
 
3033
 
 
3034
                # optional data (with defaults)
 
3035
                self.insertion_units =  getit(obj, 70, None)
 
3036
                self.insert_units = getit(obj, 1070, None)
 
3037
                """code 1070 Einfuegeeinheiten:
 
3038
                0 = Keine Einheiten; 1 = Zoll; 2 = Fuss; 3 = Meilen; 4 = Millimeter;
 
3039
                5 = Zentimeter; 6 = Meter; 7 = Kilometer; 8 = Mikrozoll;
 
3040
                9 = Mils; 10 = Yard; 11 = Angstrom; 12 = Nanometer;
 
3041
                13 = Mikrons; 14 = Dezimeter; 15 = Dekameter;
 
3042
                16 = Hektometer; 17 = Gigameter; 18 = Astronomische Einheiten;
 
3043
                19 = Lichtjahre; 20 = Parsecs
 
3044
                """
 
3045
 
 
3046
 
 
3047
        def __repr__(self):
 
3048
                return "%s: name - %s, insert units - %s" %(self.__class__.__name__, self.name, self.insertion_units)
 
3049
 
 
3050
 
 
3051
 
 
3052
 
 
3053
class Block:  #-----------------------------------------------------------------
 
3054
        """Class for objects representing dxf BLOCKs.
 
3055
        """
 
3056
 
 
3057
        def __init__(self, obj):
 
3058
                """Expects an entity object of type block as input.
 
3059
                """
 
3060
                if not obj.type == 'block':
 
3061
                        raise TypeError, "Wrong type %s for block object!" %obj.type
 
3062
 
 
3063
                self.type = obj.type
 
3064
                self.name = obj.name
 
3065
                self.data = obj.data[:]
 
3066
 
 
3067
                # required data
 
3068
                self.flags = getit(obj, 70, 0)
 
3069
                self.anonim = self.flags & 1 #anonymous block generated by hatching, associative dimensioning, other
 
3070
                self.atrib  = self.flags & 2 # has attribute definitions
 
3071
                self.xref = self.flags & 4 # is an external reference (xref)
 
3072
                self.xref_lay = self.flags & 8 # is an xref overlay 
 
3073
                self.dep_ext = self.flags & 16 #  is externally dependent
 
3074
                self.dep_res = self.flags & 32 # resolved external reference
 
3075
                self.xref_ext = self.flags & 64 # is a referenced external reference xref
 
3076
                #--todo--- if self.flag > 4: self.xref = True
 
3077
 
 
3078
                # optional data (with defaults)
 
3079
                self.path = getit(obj, 1, '') # Xref path name
 
3080
                self.discription = getit(obj, 4, '')
 
3081
 
 
3082
                self.entities = dxfObject('block_contents') #creates empty entities_container for this block
 
3083
                self.entities.data = objectify([ent for ent in obj.data if type(ent) != list])
 
3084
 
 
3085
                self.layer = getit(obj, 8, None)
 
3086
                self.loc = self.get_loc(obj)
 
3087
 
 
3088
                #print 'deb:Block %s data:\n%s' %(self.name, self.data) #------------
 
3089
                #print 'deb:Block %s self.entities.data:\n%s' %(self.name, self.entities.data) #------------
 
3090
                        
 
3091
                        
 
3092
 
 
3093
        def get_loc(self, data):
 
3094
                """Gets the insert point of the block.
 
3095
                """
 
3096
                loc = [0, 0, 0]
 
3097
                loc[0] = getit(data, 10, 0.0) # 10 = x
 
3098
                loc[1] = getit(data, 20, 0.0) # 20 = y
 
3099
                loc[2] = getit(data, 30, 0.0) # 30 = z
 
3100
                return loc
 
3101
 
 
3102
 
 
3103
        def __repr__(self):
 
3104
                return "%s: name - %s, description - %s, xref-path - %s" %(self.__class__.__name__, self.name, self.discription, self.path)
 
3105
 
 
3106
 
 
3107
 
 
3108
 
 
3109
class Insert:  #-----------------------------------------------------------------
 
3110
        """Class for objects representing dxf INSERTs.
 
3111
        """
 
3112
 
 
3113
        def __init__(self, obj):
 
3114
                """Expects an entity object of type insert as input.
 
3115
                """
 
3116
                if not obj.type == 'insert':
 
3117
                        raise TypeError, "Wrong type %s for insert object!" %obj.type
 
3118
                self.type = obj.type
 
3119
                self.data = obj.data[:]
 
3120
                #print 'deb:Insert_init_ self.data:\n', self.data #-----------
 
3121
 
 
3122
                # required data
 
3123
                self.name = obj.get_type(2)[0]
 
3124
 
 
3125
                # optional data (with defaults)
 
3126
                self.rotation =  getit(obj, 50, 0)
 
3127
                self.space = getit(obj, 67, 0)
 
3128
                self.color_index = getit(obj, 62, BYLAYER)
 
3129
 
 
3130
                self.layer = getit(obj, 8, None)
 
3131
                self.loc = self.get_loc(obj)
 
3132
                self.scale = self.get_scale(obj)
 
3133
                self.rows, self.columns = self.get_array(obj)
 
3134
                self.extrusion = get_extrusion(obj)
 
3135
 
 
3136
                #self.flags = getit(obj.data, 66, 0) #
 
3137
                #self.attrib = self.flags & 1
 
3138
 
 
3139
 
 
3140
        def get_loc(self, data):
 
3141
                """Gets the origin location of the insert.
 
3142
                """
 
3143
                loc = [0, 0, 0]
 
3144
                loc[0] = getit(data, 10, 0.0)
 
3145
                loc[1] = getit(data, 20, 0.0)
 
3146
                loc[2] = getit(data, 30, 0.0)
 
3147
                return loc
 
3148
 
 
3149
 
 
3150
        def get_scale(self, data):
 
3151
                """Gets the x/y/z scale factors of the insert.
 
3152
                """
 
3153
                scale = [1, 1, 1]
 
3154
                scale[0] = getit(data, 41, 1.0)
 
3155
                scale[1] = getit(data, 42, 1.0)
 
3156
                scale[2] = getit(data, 43, 1.0)
 
3157
                return scale
 
3158
 
 
3159
 
 
3160
        def get_array(self, data):
 
3161
                """Returns the pair (row number, row spacing), (column number, column spacing).
 
3162
                """
 
3163
                columns = getit(data, 70, 1)
 
3164
                rows    = getit(data, 71, 1)
 
3165
                cspace  = getit(data, 44, 0.0)
 
3166
                rspace  = getit(data, 45, 0.0)
 
3167
                return (rows, rspace), (columns, cspace)
 
3168
 
 
3169
 
 
3170
        def get_target(self, data):
 
3171
                """Gets the origin location of the insert.
 
3172
                """
 
3173
                loc = [0, 0, 0]
 
3174
                loc[0] = getit(data, 1011, 0.0)
 
3175
                loc[1] = getit(data, 1021, 0.0)
 
3176
                loc[2] = getit(data, 1031, 0.0)
 
3177
                return loc
 
3178
 
 
3179
 
 
3180
        def get_color(self, data):
 
3181
                """Gets the origin location of the insert.
 
3182
                """
 
3183
                loc = [0, 0, 0]
 
3184
                loc[0] = getit(data, 1010, 0.0)
 
3185
                loc[1] = getit(data, 1020, 0.0)
 
3186
                loc[2] = getit(data, 1030, 0.0)
 
3187
                return loc
 
3188
 
 
3189
 
 
3190
        def get_ave_render(self, data):
 
3191
                """Gets the origin location of the insert.
 
3192
                """
 
3193
                loc = [0, 0, 0]
 
3194
                loc[0] = getit(data, 1010, 0.0)
 
3195
                loc[1] = getit(data, 1020, 0.0)
 
3196
                loc[2] = getit(data, 1030, 0.0)
 
3197
                return loc
 
3198
 
 
3199
 
 
3200
        def __repr__(self):
 
3201
                return "%s: layer - %s, name - %s" %(self.__class__.__name__, self.layer, self.name)
 
3202
 
 
3203
 
 
3204
        def draw(self, settings, deltaloc):
 
3205
                """for INSERT(block): draw empty-marker for duplicated Blender_Group.
 
3206
 
 
3207
                Blocks are made of three objects:
 
3208
                        the block_record in the tables section
 
3209
                        the block in the blocks section
 
3210
                        the insert object (one or more) in the entities section
 
3211
                block_record gives the insert units,
 
3212
                block provides the objects drawn in the block,
 
3213
                insert object gives the location/scale/rotation of the block instances.
 
3214
                """
 
3215
 
 
3216
                name = self.name.lower()
 
3217
                if name == 'ave_render':
 
3218
                        if settings.var['lights_on']:  #if lights support activated
 
3219
                                a_data = get_ave_data(self.data)
 
3220
                                # AVE_RENDER objects:
 
3221
                                # 7:'Pref', 0:'Full Opt', 0:'Quick Opt', 1:'Scanl Opt', 2:'Raytr Opt', 0:'RFile Opt'
 
3222
                                # 0:'Fog Opt', 0:'BG Opt', 0:'SCENE1','','','','','','','','','',
 
3223
                                # '','','','','','','','','','','','',
 
3224
 
 
3225
                                if a_data.key == 'SCENE': # define set of lights as blender group
 
3226
                                        scene_lights = 1
 
3227
                                elif False: # define set of lights as blender group
 
3228
                                        scene_lights = 1
 
3229
                                return
 
3230
                elif name == 'ave_global':
 
3231
                        if settings.var['lights_on']:  #if lights support activated
 
3232
                                return
 
3233
                elif name == 'sh_spot':
 
3234
                        if settings.var['lights_on']:  #if lights support activated
 
3235
                                obname = settings.blocknamesmap[self.name]
 
3236
                                obname = 'sp_%s' %obname  # create object name from block name
 
3237
                                #obname = obname[:MAX_NAMELENGTH]
 
3238
                                # blender: 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', or 'Photon'
 
3239
                                li = Lamp.New('Spot', obname)
 
3240
                                ob = SCENE.objects.new(li)
 
3241
                                intensity = 2.0 #--todo-- -----------
 
3242
                                li.setEnergy(intensity)
 
3243
                                target = self.get_target(self.data)
 
3244
                                color = self.get_color(self.data)
 
3245
                                li.R = color[0]
 
3246
                                li.G = color[1]
 
3247
                                li.B = color[2]
 
3248
 
 
3249
                                ob.loc = tuple(self.loc)
 
3250
                                transform(self.extrusion, 0, ob)
 
3251
                                return ob
 
3252
 
 
3253
                elif name == 'overhead':
 
3254
                        if settings.var['lights_on']:  #if lights support activated
 
3255
                                obname = settings.blocknamesmap[self.name]
 
3256
                                obname = 'la_%s' %obname  # create object name from block name
 
3257
                                #obname = obname[:MAX_NAMELENGTH]
 
3258
                                # blender: 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', or 'Photon'
 
3259
                                li = Lamp.New('Lamp', obname)
 
3260
                                ob = SCENE.objects.new(li)
 
3261
                                intensity = 2.0 #--todo-- -----------
 
3262
                                li.setEnergy(intensity)
 
3263
                                target = self.get_target(self.data)
 
3264
                                color = self.get_color(self.data)
 
3265
                                li.R = color[0]
 
3266
                                li.G = color[1]
 
3267
                                li.B = color[2]
 
3268
 
 
3269
                                ob.loc = tuple(self.loc)
 
3270
                                transform(self.extrusion, 0, ob)
 
3271
                                return ob
 
3272
 
 
3273
                elif name == 'direct':
 
3274
                        if settings.var['lights_on']:  #if lights support activated
 
3275
                                obname = settings.blocknamesmap[self.name]
 
3276
                                obname = 'su_%s' %obname  # create object name from block name
 
3277
                                #obname = obname[:MAX_NAMELENGTH]
 
3278
                                # blender: 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', or 'Photon'
 
3279
                                li = Lamp.New('Sun', obname)
 
3280
                                ob = SCENE.objects.new(li)
 
3281
                                intensity = 2.0 #--todo-- -----------
 
3282
                                li.setEnergy(intensity)
 
3283
                                color = self.get_color(self.data)
 
3284
                                li.R = color[0]
 
3285
                                li.G = color[1]
 
3286
                                li.B = color[2]
 
3287
 
 
3288
                                ob.loc = tuple(self.loc)
 
3289
                                transform(self.extrusion, 0, ob)
 
3290
                                return ob
 
3291
 
 
3292
                elif settings.drawTypes['insert']:  #if insert_drawType activated
 
3293
                        #print 'deb:draw.  settings.blocknamesmap:', settings.blocknamesmap #--------------------
 
3294
                        obname = settings.blocknamesmap[self.name]
 
3295
                        obname = 'in_%s' %obname  # create object name from block name
 
3296
                        #obname = obname[:MAX_NAMELENGTH]
 
3297
 
 
3298
                        # if material BYBLOCK def needed: use as placeholder a mesh-vertex instead of empty
 
3299
                        ob = SCENE.objects.new('Empty', obname) # create a new empty_object
 
3300
                        empty_size = 1.0 * settings.var['g_scale']
 
3301
                        if   empty_size < 0.01:  empty_size = 0.01 #Blender limits (0.01-10.0)
 
3302
                        elif empty_size > 10.0:  empty_size = 10.0
 
3303
                        ob.drawSize = empty_size
 
3304
 
 
3305
                        # get our block_def-group
 
3306
                        block = settings.blocks(self.name)
 
3307
                        ob.DupGroup = block
 
3308
                        ob.enableDupGroup = True
 
3309
 
 
3310
                        if block.name.startswith('xr_'):
 
3311
                                ob.name = 'xb_' + ob.name[3:]
 
3312
                
 
3313
                        #print 'deb:draw.block.deltaloc:', deltaloc #--------------------
 
3314
                        ob.loc = tuple(self.loc)
 
3315
                        if deltaloc:
 
3316
                                deltaloc = rotXY_Vec(self.rotation, deltaloc)
 
3317
                                #print 'deb:draw.block.loc:', deltaloc  #--------------------
 
3318
                                ob.loc = [ob.loc[0]+deltaloc[0], ob.loc[1]+deltaloc[1], ob.loc[2]+deltaloc[2]]
 
3319
                        transform(self.extrusion, self.rotation, ob)
 
3320
                        ob.size = tuple(self.scale)
 
3321
                        return ob
 
3322
 
 
3323
 
 
3324
 
 
3325
 
 
3326
class Ellipse:  #-----------------------------------------------------------------
 
3327
        """Class for objects representing dxf ELLIPSEs.
 
3328
        """
 
3329
 
 
3330
        def __init__(self, obj):
 
3331
                """Expects an entity object of type ellipse as input.
 
3332
                """
 
3333
                if not obj.type == 'ellipse':
 
3334
                        raise TypeError, "Wrong type %s for ellipse object!" %obj.type
 
3335
                self.type = obj.type
 
3336
#               self.data = obj.data[:]
 
3337
 
 
3338
                # required data
 
3339
                self.ratio = obj.get_type(40)[0] # Ratio of minor axis to major axis
 
3340
                self.start_angle = obj.get_type(41)[0]  # in radians
 
3341
                self.end_angle = obj.get_type(42)[0]
 
3342
 
 
3343
                # optional data (with defaults)
 
3344
                self.space = getit(obj, 67, 0)
 
3345
                self.thic =  getit(obj, 39, 0.0)
 
3346
                self.color_index = getit(obj, 62, BYLAYER)
 
3347
 
 
3348
                self.layer = getit(obj, 8, None)
 
3349
                self.loc = self.get_loc(obj)
 
3350
                self.major = self.get_major(obj)
 
3351
                self.extrusion = get_extrusion(obj)
 
3352
 
 
3353
 
 
3354
        def get_loc(self, data):
 
3355
                """Gets the center location for arc type objects.
 
3356
 
 
3357
                Arcs have a single coord location.
 
3358
                """
 
3359
                loc = [0.0, 0.0, 0.0]
 
3360
                loc[0] = getit(data, 10, 0.0)
 
3361
                loc[1] = getit(data, 20, 0.0)
 
3362
                loc[2] = getit(data, 30, 0.0)
 
3363
                return loc
 
3364
 
 
3365
 
 
3366
        def get_major(self, data):
 
3367
                """Gets the major axis for ellipse type objects.
 
3368
 
 
3369
                The ellipse major axis defines the rotation of the ellipse and its radius.
 
3370
                """
 
3371
                loc = [0.0, 0.0, 0.0]
 
3372
                loc[0] = getit(data, 11, 0.0)
 
3373
                loc[1] = getit(data, 21, 0.0)
 
3374
                loc[2] = getit(data, 31, 0.0)
 
3375
                return loc
 
3376
 
 
3377
 
 
3378
        def __repr__(self):
 
3379
                return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
 
3380
 
 
3381
 
 
3382
        def draw(self, settings):
 
3383
                """for ELLIPSE: generate Blender_geometry.
 
3384
                """
 
3385
                obname = 'el_%s' %self.layer  # create object name from layer name
 
3386
                obname = obname[:MAX_NAMELENGTH]
 
3387
 
 
3388
                center = self.loc
 
3389
                if True:
 
3390
                        start = degrees(self.start_angle)
 
3391
                        end = degrees(self.end_angle)
 
3392
                        if abs(end - 360.0) < 0.00001: end = 360.0
 
3393
                        ellipse_closed = False
 
3394
                        if end - start == 360.0: ellipse_closed = True
 
3395
        
 
3396
                else: # bug in AutoCAD_2002 dxf-exporter into r12 for ELLIPSE->POLYLINE_ARC
 
3397
                        #print 'deb:calcEllipse---------:\n start=%s\n   end=%s' %(self.start_angle, self.end_angle)  #---------
 
3398
                        if self.start_angle > pi+pi: self.start_angle %= pi+pi
 
3399
                        if self.end_angle > pi+pi: self.end_angle %= pi+pi
 
3400
                        if abs(self.end_angle - pi - pi) < 0.00001: self.end_angle = pi + pi
 
3401
                        ellipse_closed = False
 
3402
                        if abs(self.end_angle - self.start_angle) == pi + pi: ellipse_closed = True
 
3403
                        test = self.start_angle % pi
 
3404
                        if  test < 0.001 or pi - test < 0.001: start = self.start_angle
 
3405
                        else:
 
3406
                                start = atan(tan(self.start_angle) * self.ratio)
 
3407
                                if start < 0.0: start += pi
 
3408
                                if self.start_angle > pi: start += pi
 
3409
                        test = self.end_angle % pi
 
3410
                        if test < 0.001 or pi - test < 0.001: end = self.end_angle
 
3411
                        else:
 
3412
                                end = atan(tan(self.end_angle) * self.ratio)
 
3413
                                if end < 0.0: end += pi
 
3414
                                if self.end_angle > pi: end += pi
 
3415
                        start = degrees(start)
 
3416
                        end = degrees(end)
 
3417
 
 
3418
                # rotation = Angle between major and WORLDX
 
3419
                # doesnt work, couse produces always positive value: rotation = Mathutils.AngleBetweenVecs(major, WORLDX)
 
3420
                if self.major[0] == 0:
 
3421
                        rotation = 90.0
 
3422
                        if self.major[1] < 0: rotation += 180
 
3423
                else:
 
3424
                        rotation = degrees(atan(self.major[1] / self.major[0]))
 
3425
                        if self.major[0] < 0:
 
3426
                                rotation += 180.0
 
3427
 
 
3428
                major = Mathutils.Vector(self.major)
 
3429
                #radius = sqrt(self.major[0]**2 + self.major[1]**2 + self.major[2]**2)
 
3430
                radius = major.length
 
3431
                #print 'deb:calcEllipse:\n center, radius, start, end:\n', center, radius, start, end  #---------
 
3432
 
 
3433
                thic = set_thick(self.thic, settings)
 
3434
                width = 0.0
 
3435
                if settings.var['lines_as'] == 4: # as thin_box
 
3436
                        thic = settings.var['thick_min']
 
3437
                        width = settings.var['width_min']
 
3438
                elif settings.var['lines_as'] == 3: # as thin cylinder
 
3439
                        cyl_rad = 0.5 * settings.var['width_min']
 
3440
 
 
3441
                elif settings.var['lines_as'] == 5:  # draw ELLIPSE as curve -------------
 
3442
                        arc_res = settings.var['curve_arc']
 
3443
                        triples = True
 
3444
                        VectorTriples = calcArc(None, radius, start, end, arc_res, triples)
 
3445
                        arc = Curve.New(obname) # create new curve data
 
3446
                        curve = arc.appendNurb(BezTriple.New(VectorTriples[0]))
 
3447
                        if ellipse_closed:
 
3448
                                for p in VectorTriples[1:-1]:
 
3449
                                        curve.append(BezTriple.New(p))
 
3450
                                for point in curve:
 
3451
                                        point.handleTypes = [FREE, FREE]
 
3452
                                curve.flagU = 1 # 0 sets the curve not cyclic=open
 
3453
                                if settings.var['fill_on']:
 
3454
                                        arc.setFlag(6) # 2+4 set top and button caps
 
3455
                                else:
 
3456
                                        arc.setFlag(arc.getFlag() & ~6) # dont set top and button caps
 
3457
                        else:
 
3458
                                for p in VectorTriples[1:]:
 
3459
                                        curve.append(BezTriple.New(p))
 
3460
                                for point in curve:
 
3461
                                        point.handleTypes = [FREE, FREE]
 
3462
                                curve.flagU = 0 # 0 sets the curve not cyclic=open
 
3463
 
 
3464
                        arc.setResolu(settings.var['curve_res'])
 
3465
                        arc.update() #important for handles calculation
 
3466
 
 
3467
                        ob = SCENE.objects.new(arc) # create a new curve_object
 
3468
                        ob.loc = tuple(self.loc)
 
3469
                        if thic != 0.0: #hack: Blender<2.45 curve-extrusion
 
3470
                                thic = thic * 0.5
 
3471
                                arc.setExt1(1.0)  # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
 
3472
                                ob.LocZ = thic + self.loc[2]
 
3473
                        transform(self.extrusion, rotation, ob)
 
3474
                        ob.SizeY *= self.ratio
 
3475
                        if thic != 0.0:
 
3476
                                ob.SizeZ *= abs(thic)
 
3477
                        return ob
 
3478
 
 
3479
 
 
3480
                else: # draw ELLIPSE as mesh --------------------------------------
 
3481
                        if M_OBJ: obname, me, ob = makeNewObject()
 
3482
                        else: 
 
3483
                                me = Mesh.New(obname)           # create a new mesh
 
3484
                                ob = SCENE.objects.new(me) # create a new mesh_object
 
3485
                        # set a number of segments in entire circle
 
3486
                        arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
 
3487
 
 
3488
                        verts = calcArc(None, radius, start, end, arc_res, False)
 
3489
                        #verts = [list(point) for point in verts]
 
3490
                        if False: #--todo--: if ellipse_closed:
 
3491
                                verts = verts[:-1] #list without last point/edge (cause closed curve)
 
3492
                        len1 = len(verts)
 
3493
                        #print 'deb:len1:', len1  #-----------------------
 
3494
                        if width != 0:
 
3495
                                radius_out = radius + (0.5 * width)
 
3496
                                radius_in  = radius - (0.5 * width)
 
3497
                                if radius_in <= 0.0:
 
3498
                                        radius_in = settings.var['dist_min']
 
3499
                                        #radius_in = 0.0
 
3500
                                verts_in = []
 
3501
                                verts_out = []
 
3502
                                for point in verts:
 
3503
                                        pointVec = Mathutils.Vector(point)
 
3504
                                        pointVec = pointVec.normalize()
 
3505
                                        verts_in.append(list(radius_in * pointVec))   #vertex inside
 
3506
                                        verts_out.append(list(radius_out * pointVec)) #vertex outside
 
3507
                                verts = verts_in + verts_out
 
3508
 
 
3509
                                #print 'deb:verts:', verts  #---------------------
 
3510
                                if thic != 0:
 
3511
                                        thic_verts = []
 
3512
                                        thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
 
3513
                                        if thic < 0.0:
 
3514
                                                thic_verts.extend(verts)
 
3515
                                                verts = thic_verts
 
3516
                                        else:
 
3517
                                                verts.extend(thic_verts)
 
3518
                                        f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
 
3519
                                        f_top   = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
 
3520
                                        f_left   = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
 
3521
                                        f_right  = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
 
3522
                                        f_start = [[0, len1, len1+len1+len1, len1+len1]]
 
3523
                                        f_end   = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
 
3524
                                        faces = f_left + f_right + f_bottom + f_top + f_start + f_end
 
3525
        
 
3526
                                        me.verts.extend(verts) # add vertices to mesh
 
3527
                                        me.faces.extend(faces)  # add faces to the mesh
 
3528
 
 
3529
                                        if settings.var['meshSmooth_on']:  # left and right side become smooth ----------------------
 
3530
                                                smooth_len = len(f_left) + len(f_right)
 
3531
                                                for i in xrange(smooth_len):
 
3532
                                                        me.faces[i].smooth = True
 
3533
                                        if settings.var['vGroup_on'] and not M_OBJ:
 
3534
                                                # each MeshSide becomes vertexGroup for easier material assignment ---------------------
 
3535
                                                replace = Blender.Mesh.AssignModes.REPLACE  #or .AssignModes.ADD
 
3536
                                                vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
 
3537
                                                for v in f_left: vg_left.extend(v)
 
3538
                                                for v in f_right: vg_right.extend(v)
 
3539
                                                for v in f_top: vg_top.extend(v)
 
3540
                                                for v in f_bottom: vg_bottom.extend(v)
 
3541
                                                me.addVertGroup('side.left')  ; me.assignVertsToGroup('side.left',  list(set(vg_left)), 1.0, replace)
 
3542
                                                me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
 
3543
                                                me.addVertGroup('side.top')   ; me.assignVertsToGroup('side.top',   list(set(vg_top)), 1.0, replace)
 
3544
                                                me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
 
3545
                                                me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
 
3546
                                                me.addVertGroup('side.end')  ; me.assignVertsToGroup('side.end',   f_end[0],   1.0, replace)
 
3547
                                        
 
3548
 
 
3549
                                else:  # if thick=0 - draw only flat ring
 
3550
                                        faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
 
3551
                                        me.verts.extend(verts) # add vertices to mesh
 
3552
                                        me.faces.extend(faces)  # add faces to the mesh
 
3553
        
 
3554
                        elif thic != 0:
 
3555
                                thic_verts = []
 
3556
                                thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
 
3557
                                if thic < 0.0:
 
3558
                                        thic_verts.extend(verts)
 
3559
                                        verts = thic_verts
 
3560
                                else:
 
3561
                                        verts.extend(thic_verts)
 
3562
                                faces = []
 
3563
                                #print 'deb:len1:', len1  #-----------------------
 
3564
                                #print 'deb:verts:', verts  #---------------------
 
3565
                                faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
 
3566
 
 
3567
                                me.verts.extend(verts) # add vertices to mesh
 
3568
                                me.faces.extend(faces)  # add faces to the mesh
 
3569
                                if settings.var['meshSmooth_on']:  # left and right side become smooth ----------------------
 
3570
                                        for i in xrange(len(faces)):
 
3571
                                                me.faces[i].smooth = True
 
3572
 
 
3573
                        else:
 
3574
                                edges = [[num, num+1] for num in xrange(len(verts)-1)]
 
3575
                                me.verts.extend(verts) # add vertices to mesh
 
3576
                                me.edges.extend(edges)  # add edges to the mesh
 
3577
 
 
3578
                        #print 'deb:calcEllipse transform rotation: ', rotation  #---------
 
3579
                        ob.loc = tuple(center)
 
3580
                        #old ob.SizeY = self.ratio
 
3581
                        transform(self.extrusion, rotation, ob)
 
3582
                        #old transform(self.extrusion, 0, ob)
 
3583
                        ob.SizeY *= self.ratio
 
3584
        
 
3585
                        return ob
 
3586
 
 
3587
 
 
3588
 
 
3589
class Face:  #-----------------------------------------------------------------
 
3590
        """Class for objects representing dxf 3DFACEs.
 
3591
        """
 
3592
 
 
3593
        def __init__(self, obj):
 
3594
                """Expects an entity object of type 3dfaceplot as input.
 
3595
                """
 
3596
                if not obj.type == '3dface':
 
3597
                        raise TypeError, "Wrong type %s for 3dface object!" %obj.type
 
3598
                self.type = obj.type
 
3599
#               self.data = obj.data[:]
 
3600
 
 
3601
                # optional data (with defaults)
 
3602
                self.space = getit(obj, 67, 0)
 
3603
                self.color_index = getit(obj, 62, BYLAYER)
 
3604
 
 
3605
                self.layer = getit(obj, 8, None)
 
3606
                self.points = self.get_points(obj)
 
3607
 
 
3608
 
 
3609
        def get_points(self, data):
 
3610
                """Gets 3-4 points for a 3d face type object.
 
3611
 
 
3612
                Faces have three or optionally four verts.
 
3613
                """
 
3614
                a = [0, 0, 0]
 
3615
                b = [0, 0, 0]
 
3616
                c = [0, 0, 0]
 
3617
                d = [0, 0, 0]
 
3618
                a[0] = getit(data, 10, None) # 10 = x
 
3619
                a[1] = getit(data, 20, None) # 20 = y
 
3620
                a[2] = getit(data, 30,  0.0) # 30 = z
 
3621
                b[0] = getit(data, 11, None)
 
3622
                b[1] = getit(data, 21, None)
 
3623
                b[2] = getit(data, 31,  0.0)
 
3624
                c[0] = getit(data, 12, None)
 
3625
                c[1] = getit(data, 22, None)
 
3626
                c[2] = getit(data, 32,  0.0)
 
3627
                out = [a,b,c]
 
3628
 
 
3629
                d[0] =  getit(data, 13, None)
 
3630
                if d[0] != None:
 
3631
                        d[1] = getit(data, 23, None)
 
3632
                        d[2] = getit(data, 33,  0.0)
 
3633
                        out.append(d)
 
3634
 
 
3635
                #if len(out) < 4: print '3dface with only 3 vertices:\n',a,b,c,d #-----------------
 
3636
                return out
 
3637
 
 
3638
 
 
3639
        def __repr__(self):
 
3640
                return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
 
3641
 
 
3642
 
 
3643
        def draw(self, settings):
 
3644
                """for 3DFACE: generate Blender_geometry.
 
3645
                """
 
3646
                # Generate the geometery
 
3647
                points = self.points
 
3648
 
 
3649
                global activObjectLayer
 
3650
                global activObjectName
 
3651
                #print 'deb:draw:face.ob IN activObjectName: ', activObjectName #---------------------
 
3652
 
 
3653
                if M_OBJ: obname, me, ob = makeNewObject()
 
3654
                else: 
 
3655
                        if activObjectLayer == self.layer and settings.var['one_mesh_on']:
 
3656
                                obname = activObjectName
 
3657
                                #print 'deb:face.draw obname from activObjectName: ', obname #---------------------
 
3658
                                ob = getSceneChild(obname)  # open an existing mesh_object
 
3659
                                #ob = SCENE.getChildren(obname)  # open an existing mesh_object
 
3660
                                me = ob.getData(name_only=False, mesh=True)
 
3661
                        else:
 
3662
                                obname = 'fa_%s' %self.layer  # create object name from layer name
 
3663
                                obname = obname[:MAX_NAMELENGTH]
 
3664
                                me = Mesh.New(obname)             # create a new mesh
 
3665
                                ob = SCENE.objects.new(me) # create a new mesh_object
 
3666
                                activObjectName = ob.name
 
3667
                                activObjectLayer = self.layer
 
3668
                                #print ('deb:except. new face.ob+mesh:"%s" created!' %ob.name) #---------------------
 
3669
        
 
3670
                #me = Mesh.Get(ob.name)   # open objects mesh data
 
3671
                faces, edges = [], []
 
3672
                n = len(me.verts)
 
3673
                if len(self.points) == 4:
 
3674
                        faces = [[0+n,1+n,2+n,3+n]]
 
3675
                elif len(self.points) == 3:
 
3676
                        faces = [[0+n,1+n,2+n]]
 
3677
                elif len(self.points) == 2:
 
3678
                        edges = [[0+n,1+n]]
 
3679
 
 
3680
                me.verts.extend(points) # add vertices to mesh
 
3681
                if faces: me.faces.extend(faces)           # add faces to the mesh
 
3682
                if edges: me.edges.extend(edges)           # add faces to the mesh
 
3683
                if settings.var['vGroup_on'] and not M_OBJ:
 
3684
                        # entities with the same color build one vertexGroup for easier material assignment ---------------------
 
3685
                        ob.link(me) # link mesh to that object
 
3686
                        vG_name = 'color_%s' %self.color_index
 
3687
                        if edges: faces = edges
 
3688
                        replace = Blender.Mesh.AssignModes.ADD  #or .AssignModes.REPLACE or ADD
 
3689
                        try:
 
3690
                                me.assignVertsToGroup(vG_name,  faces[0], 1.0, replace)
 
3691
                                #print 'deb: existed vGroup:', vG_name #---------------------
 
3692
                        except:
 
3693
                                me.addVertGroup(vG_name)
 
3694
                                me.assignVertsToGroup(vG_name,  faces[0], 1.0, replace)
 
3695
                                #print 'deb: create new vGroup:', vG_name #--------------------
 
3696
 
 
3697
                #print 'deb:draw:face.ob OUT activObjectName: ', activObjectName #---------------------
 
3698
                return ob
 
3699
 
 
3700
 
 
3701
#---------------------------------------------------------------------------------------
 
3702
# type to object maping (sorted-dictionary for f_obiectify ONLY!, format={'key':Class} )
 
3703
type_map = {
 
3704
        'vport':Vport,
 
3705
        'view':View,
 
3706
        'layer':Layer,
 
3707
        'block_record':BlockRecord,
 
3708
        'block':Block,
 
3709
        'insert':Insert,
 
3710
        'point':Point,
 
3711
        '3dface':Face,
 
3712
        'line':Line,
 
3713
#       'mline':MLine,
 
3714
        'polyline':Polyline,
 
3715
        'lwpolyline':LWpolyline,
 
3716
        'spline':Spline,
 
3717
#       'region':Region,
 
3718
        'trace':Solid,
 
3719
        'solid':Solid,
 
3720
        'text':Text,
 
3721
        'mtext':Mtext,
 
3722
        'circle':Circle,
 
3723
        'ellipse':Ellipse,
 
3724
        'arc':Arc
 
3725
}
 
3726
 
 
3727
 
 
3728
 
 
3729
def objectify(data):  #-----------------------------------------------------------------
 
3730
        """Expects a section type object's data as input.
 
3731
 
 
3732
        Maps object data to the correct object type.
 
3733
        """
 
3734
        #print 'deb:objectify start %%%%%%%%%%%' #---------------
 
3735
        objects = [] # colector for finished objects
 
3736
        known_types = type_map.keys() # so we don't have to call foo.keys() every iteration
 
3737
        curves_on = GUI_A['curves_on'].val
 
3738
        index = 0
 
3739
        while index < len(data):
 
3740
                item = data[index]
 
3741
                #print 'deb:objectify item: \n', item #------------
 
3742
                if type(item) != list and item.type == 'table':
 
3743
                        item.data = objectify(item.data) # tables have sub-objects
 
3744
                        objects.append(item)
 
3745
                elif type(item) != list and item.type == 'polyline': #remi --todo-----------
 
3746
                        #print 'deb:gosub Polyline\n' #-------------
 
3747
                        pline = Polyline(item)
 
3748
                        while 1:
 
3749
                                index += 1
 
3750
                                item = data[index]
 
3751
                                if item.type == 'vertex':
 
3752
                                        #print 'deb:objectify gosub Vertex--------' #-------------
 
3753
                                        v = Vertex(item)
 
3754
                                        if pline.spline: # if NURBSpline-curve
 
3755
                                                # then for Blender-mesh  filter only additional_vertices
 
3756
                                                # OR
 
3757
                                                # then for Blender-curve filter only spline_control_vertices
 
3758
                                                if (v.spline and not curves_on) or (curves_on and v.spline_c): #correct for real NURBS-import
 
3759
                                                #if (v.spline and not curves_on) or (curves_on and not v.spline_c): #fake for Bezier-emulation of NURBS-import
 
3760
                                                        pline.points.append(v)
 
3761
                                        elif pline.curved:  # if Bezier-curve
 
3762
                                                # then for Blender-mesh filter only curve_additional_vertices
 
3763
                                                # OR
 
3764
                                                # then for Blender-curve filter curve_control_vertices
 
3765
                                                if not curves_on or (curves_on and not v.curved):
 
3766
                                                        pline.points.append(v)
 
3767
                                        else:
 
3768
                                                pline.points.append(v)
 
3769
                                elif item.type == 'seqend':
 
3770
                                        #print 'deb:objectify it is seqEND ---------\n' #-------------
 
3771
                                        break
 
3772
                                else:
 
3773
                                        print "Error: non-vertex found before seqend!"
 
3774
                                        index -= 1  #so go back one step
 
3775
                                        break
 
3776
                        objects.append(pline)
 
3777
                elif type(item) != list and item.type in ['block', 'insert']:
 
3778
                        if not settings.var['block_nn'] and item.name.startswith('*X'):
 
3779
                                #print 'deb:objectify item.type:"%s", item.name:"%s"' %(item.type, item.name) #------------
 
3780
                                pass
 
3781
                        elif settings.var['blockFilter_on'] and not settings.accepted_block(item.name):
 
3782
                                pass
 
3783
                        else:
 
3784
                                try:
 
3785
                                        objects.append(type_map[item.type](item))
 
3786
                                except TypeError:
 
3787
                                        pass
 
3788
                elif type(item) != list and item.type in known_types:
 
3789
                        # proccess the object and append the resulting object
 
3790
                        try:
 
3791
                                objects.append(type_map[item.type](item))
 
3792
                        except TypeError:
 
3793
                                pass
 
3794
                else:
 
3795
                        #we will just let the data pass un-harrased
 
3796
                        #objects.append(item)
 
3797
                        pass
 
3798
                index += 1
 
3799
        #print 'deb:objectify objects:\n', objects #------------
 
3800
        #print 'deb:objectify END %%%%%%%%' #------------
 
3801
        return objects
 
3802
 
 
3803
 
 
3804
 
 
3805
class MatColors:  #-----------------------------------------------------------------
 
3806
        """A smart container for dxf-color based materials.
 
3807
 
 
3808
        This class is a wrapper around a dictionary mapping dxf-color indicies to materials.
 
3809
        When called with a color_index
 
3810
        it returns a material corresponding to that index.
 
3811
        Behind the scenes it checks if that index is in its keys, and if not it creates
 
3812
        a new material.  It then adds the new index:material pair to its dict and returns
 
3813
        the material.
 
3814
        """
 
3815
 
 
3816
        def __init__(self):
 
3817
                """Expects a map - a dictionary mapping layer names to layers.
 
3818
                """
 
3819
                #self.layersmap = layersmap  # a dictionary of layername:layerobject
 
3820
                self.colMaterials = {}  # a dictionary of color_index:blender_material
 
3821
                #print 'deb:init_MatColors argument.map: ', map #------------------
 
3822
 
 
3823
 
 
3824
        def __call__(self, color=None):
 
3825
                """Return the material associated with color.
 
3826
 
 
3827
                If a layer name is provided, the color of that layer is used.
 
3828
                """
 
3829
                if color == None: color = 256  # color 256=BYLAYER
 
3830
                if type(color) == str: # looking for color of LAYER named "color"
 
3831
                        #--todo---bug with ARC from ARC-T0.DXF layer="T-3DARC-1"-----
 
3832
                        #print 'deb:color is string:--------: ', color
 
3833
                        #try:
 
3834
                                #color = layersmap[color].color
 
3835
                                #print 'deb:color=self.map[color].color:', color #------------------
 
3836
                        #except KeyError:
 
3837
                                #layer = Layer(name=color, color=256, frozen=False)
 
3838
                                #layersmap[color] = layer
 
3839
                                #color = 0
 
3840
                        if color in layersmap.keys():
 
3841
                                color = layersmap[color].color
 
3842
                if color == 256:  # color 256 = BYLAYER
 
3843
                        #--todo-- should looking for color of LAYER
 
3844
                        #if layersmap: color = layersmap[color].color
 
3845
                        color = 3
 
3846
                if color == 0:  # color 0 = BYBLOCK
 
3847
                        #--todo-- should looking for color of paret-BLOCK
 
3848
                        #if layersmap: color = layersmap[color].color
 
3849
                        color = 3
 
3850
                color = abs(color)  # cause the value could be nagative = means the layer is turned off
 
3851
 
 
3852
                if color not in self.colMaterials.keys():
 
3853
                        self.add(color)
 
3854
                return self.colMaterials[color]
 
3855
 
 
3856
 
 
3857
        def add(self, color):
 
3858
                """Create a new material 'ColorNr-N' using the provided color index-N.
 
3859
                """
 
3860
                #global color_map    #--todo-- has not to be global?
 
3861
                mat = Material.New('ColorNr-%s' %color)
 
3862
                mat.setRGBCol(color_map[color])
 
3863
                #mat.mode |= Material.Modes.SHADELESS  #--todo--
 
3864
                #mat.mode |= Material.Modes.WIRE
 
3865
#               try: mat.setMode('Shadeless', 'Wire') #work-around for 2.45rc-bug
 
3866
#               except: pass
 
3867
                self.colMaterials[color] = mat
 
3868
 
 
3869
 
 
3870
 
 
3871
class MatLayers:  #-----------------------------------------------------------------
 
3872
        """A smart container for dxf-layer based materials.
 
3873
 
 
3874
        This class is a wrapper around a dictionary mapping dxf-layer names to materials.
 
3875
        When called with a layer name it returns a material corrisponding to that.
 
3876
        Behind the scenes it checks if that layername is in its keys, and if not it creates
 
3877
        a new material.  It then adds the new layername:material pair to its dict and returns
 
3878
        the material.
 
3879
        """
 
3880
 
 
3881
        def __init__(self):
 
3882
                """Expects a map - a dictionary mapping layer names to layers.
 
3883
                """
 
3884
                #self.layersmap = layersmap  # a dictionary of layername:layer
 
3885
                self.layMaterials = {}  # a dictionary of layer_name:blender_material
 
3886
                #print 'deb:init_MatLayers argument.map: ', map #------------------
 
3887
 
 
3888
 
 
3889
        def __call__(self, layername=None, color=None):
 
3890
                """Return the material associated with dxf-layer.
 
3891
 
 
3892
                If a dxf-layername is not provided, create a new material
 
3893
                """
 
3894
                #global layernamesmap
 
3895
                layername_short = layername
 
3896
                if layername in layernamesmap.keys():
 
3897
                        layername_short = layernamesmap[layername]
 
3898
                colorlayername = layername_short
 
3899
                if color: colorlayername = str(color) + colorlayername
 
3900
                if colorlayername not in self.layMaterials.keys():
 
3901
                        self.add(layername, color, colorlayername)
 
3902
                return self.layMaterials[colorlayername]
 
3903
 
 
3904
 
 
3905
        def add(self, layername, color, colorlayername):
 
3906
                """Create a new material 'layername'.
 
3907
                """
 
3908
                try: mat = Material.Get('L-%s' %colorlayername)
 
3909
                except: mat = Material.New('L-%s' %colorlayername)
 
3910
                #print 'deb:MatLayers material: ', mat  #----------
 
3911
                #global settings
 
3912
                #print 'deb:MatLayers material_from: ', settings.var['material_from']  #----------
 
3913
                if settings.var['material_from'] == 3 and color:
 
3914
                        if color == 0 or color == 256: mat_color = 3
 
3915
                        else: mat_color = color
 
3916
                elif layersmap and layername:
 
3917
                        mat_color = layersmap[layername].color
 
3918
                else: mat_color = 3
 
3919
                #print 'deb:MatLayers color: ', color  #-----------
 
3920
                #print 'deb:MatLayers mat_color: ', mat_color  #-----------
 
3921
                mat.setRGBCol(color_map[abs(mat_color)])
 
3922
                #mat.mode |= Material.Modes.SHADELESS
 
3923
                #mat.mode |= Material.Modes.WIRE
 
3924
#               try: mat.setMode('Shadeless', 'Wire') #work-around for 2.45rc-bug
 
3925
#               except: pass
 
3926
                self.layMaterials[colorlayername] = mat
 
3927
 
 
3928
 
 
3929
 
 
3930
 
 
3931
class Blocks:  #-----------------------------------------------------------------
 
3932
        """A smart container for blocks.
 
3933
 
 
3934
        This class is a wrapper around a dictionary mapping block names to Blender data blocks.
 
3935
        When called with a name string it returns a block corresponding to that name.
 
3936
        Behind the scenes it checks if that name is in its keys, and if not it creates
 
3937
        a new data block.  It then adds the new name:block_data pair to its dict and returns
 
3938
        the block.
 
3939
        """
 
3940
 
 
3941
        def __init__(self, blocksmap, settings):
 
3942
                """Expects a dictionary mapping block_name:block_data.
 
3943
                """
 
3944
                self.blocksmap = blocksmap       #a dictionary mapping block_name:block_data
 
3945
                self.settings = settings
 
3946
                self.blocks = {}   #container for blender groups representing blocks
 
3947
 
 
3948
 
 
3949
        def __call__(self, name=None):
 
3950
                """Return the data block associated with that block_name.
 
3951
 
 
3952
                If that name is not in its keys, it creates a new data block.
 
3953
                If no name is provided return entire self.blocks container.
 
3954
                """
 
3955
                if name == None:
 
3956
                        return self.blocks
 
3957
                if name not in self.blocks.keys():
 
3958
                        self.addBlock(name)
 
3959
                return self.blocks[name]
 
3960
 
 
3961
 
 
3962
        def addBlock(self, name):
 
3963
                """Create a new 'block group' for the block name.
 
3964
                """
 
3965
                block = self.blocksmap[name]
 
3966
                prefix = 'bl'
 
3967
                if block.xref: prefix = 'xr'
 
3968
                blender_group = Group.New('%s_%s' %(prefix,name))  # Blender groupObject contains definition of BLOCK
 
3969
                block_def = [blender_group, block.loc]
 
3970
                self.settings.write("\nDrawing block:\'%s\' ..." % name)
 
3971
 
 
3972
                if block.xref:
 
3973
                        obname = 'xr_%s' %name  # create object name from xref block name
 
3974
                        #obname = obname[:MAX_NAMELENGTH]
 
3975
                        # if material BYBLOCK def needed: use as placeholder a mesh-vertex instead of empty
 
3976
                        ob = SCENE.objects.new('Empty', obname) # create a new empty_object
 
3977
                        empty_size = 1.0 * settings.var['g_scale']
 
3978
                        if   empty_size < 0.01:  empty_size = 0.01 #Blender limits (0.01-10.0)
 
3979
                        elif empty_size > 10.0:  empty_size = 10.0
 
3980
                        ob.drawSize = empty_size
 
3981
                        ob.loc = tuple(block.loc)
 
3982
                        ob.properties['xref_path'] = block.path
 
3983
                        ob.layers = [19]
 
3984
                        insertFlag=True; blockFlag=True
 
3985
                        global oblist
 
3986
                        oblist.append((ob, insertFlag, blockFlag))
 
3987
                else:           
 
3988
                        if M_OBJ:
 
3989
                                car_end()
 
3990
                                car_start()
 
3991
                        drawEntities(block.entities, self.settings, block_def)
 
3992
                        if M_OBJ: car_end()
 
3993
                self.settings.write("Drawing block:\'%s\' done!" %name)
 
3994
                self.blocks[name] = blender_group
 
3995
 
 
3996
 
 
3997
 
 
3998
 
 
3999
 
 
4000
class Settings:  #-----------------------------------------------------------------
 
4001
        """A container for all the import settings and objects used by the draw functions.
 
4002
 
 
4003
        This is like a collection of globally accessable persistant properties and functions.
 
4004
        """
 
4005
        # Optimization constants
 
4006
        MIN = 0
 
4007
        MID = 1
 
4008
        PRO = 2
 
4009
        MAX = 3
 
4010
 
 
4011
        def __init__(self, keywords, drawTypes):
 
4012
                """initialize all the important settings used by the draw functions.
 
4013
                """
 
4014
                self.obj_number = 1 #global object_number for progress_bar
 
4015
 
 
4016
                self.var = dict(keywords)         #a dictionary of (key_variable:Value) control parameter
 
4017
                self.drawTypes = dict(drawTypes) #a dictionary of (entity_type:True/False) = import on/off for this entity_type
 
4018
 
 
4019
                self.var['colorFilter_on'] = False   #deb:remi------------
 
4020
                self.acceptedColors = [0,2,3,4,5,6,7,8,9,
 
4021
                                                           10 ]
 
4022
 
 
4023
                self.var['layerFilter_on'] = False   #deb:remi------------
 
4024
                self.acceptedLayers = ['3',
 
4025
                                                   '0'
 
4026
                                                  ]
 
4027
 
 
4028
                self.var['groupFilter_on'] = False   #deb:remi------------
 
4029
                self.acceptedLayers = ['3',
 
4030
                                                   '0'
 
4031
                                                  ]
 
4032
 
 
4033
                #self.var['blockFilter_on'] = 0   #deb:remi------------
 
4034
                self.acceptedBlocks = ['WALL_1871',
 
4035
                                                   'BOX02'
 
4036
                                                  ]
 
4037
                self.unwantedBlocks = ['BOX05',
 
4038
                                                   'BOX04'
 
4039
                                                  ]
 
4040
 
 
4041
 
 
4042
        def update(self, keywords, drawTypes):
 
4043
                """update all the important settings used by the draw functions.
 
4044
                mostly used after loading parameters from INI-file
 
4045
                """
 
4046
 
 
4047
                for k, v in keywords.iteritems():
 
4048
                        self.var[k] = v
 
4049
                        #print 'deb:settings_update var %s= %s' %(k, self.var[k]) #--------------
 
4050
                for t, v in drawTypes.iteritems():
 
4051
                        self.drawTypes[t] = v
 
4052
                        #print 'deb:settings_update drawType %s= %s' %(t, self.drawTypes[t]) #--------------
 
4053
 
 
4054
                self.drawTypes['arc'] = self.drawTypes['line']
 
4055
                self.drawTypes['circle'] = self.drawTypes['line']
 
4056
                self.drawTypes['ellipse'] = self.drawTypes['line']
 
4057
                self.drawTypes['trace'] = self.drawTypes['solid']
 
4058
                self.drawTypes['insert'] = self.drawTypes['block']
 
4059
                #self.drawTypes['vport'] = self.drawTypes['view']
 
4060
 
 
4061
                #print 'deb:self.drawTypes', self.drawTypes #---------------
 
4062
 
 
4063
 
 
4064
        def validate(self, drawing):
 
4065
                """Given the drawing, build dictionaries of Layers, Colors and Blocks.
 
4066
                """
 
4067
 
 
4068
                global oblist
 
4069
                #adjust the distance parameter to globalScale
 
4070
                if self.var['g_scale'] != 1.0:
 
4071
                        self.var['dist_min']  = self.var['dist_min'] / self.var['g_scale']
 
4072
                        self.var['thick_min'] = self.var['thick_min'] / self.var['g_scale']
 
4073
                        self.var['width_min'] = self.var['width_min'] / self.var['g_scale']
 
4074
                        self.var['arc_rad'] =  self.var['arc_rad'] / self.var['g_scale']
 
4075
 
 
4076
                self.g_origin = Mathutils.Vector(self.var['g_originX'], self.var['g_originY'], self.var['g_originZ'])
 
4077
 
 
4078
                # First sort out all the section_items
 
4079
                sections = dict([(item.name, item) for item in drawing.data])
 
4080
 
 
4081
                # The section:header may be omited
 
4082
                if 'header' in sections.keys():
 
4083
                        self.write("found section:header")
 
4084
                else:
 
4085
                        self.write("File contains no section:header!")
 
4086
 
 
4087
                if self.var['optimization'] == 0: self.var['one_mesh_on'] = 0
 
4088
                # The section:tables may be partialy or completely missing.
 
4089
                self.layersTable = False
 
4090
                self.colMaterials = MatColors() #A container for dxf-color based materials
 
4091
                self.layMaterials = MatLayers() #A container for dxf-layer based materials
 
4092
                #self.collayMaterials = MatColLayers({}) #A container for dxf-color+layer based materials
 
4093
                global layersmap, layernamesmap
 
4094
                layersmap, layernamesmap = {}, {}
 
4095
                if 'tables' in sections.keys():
 
4096
                        self.write("found section:tables")
 
4097
                        views, vports, layers = False, False, False
 
4098
                        for table in drawing.tables.data:
 
4099
                                if table.name == 'layer':
 
4100
                                        self.write("found table:layers")
 
4101
                                        layers = table
 
4102
                                elif table.name == 'view':
 
4103
                                        print "found table:view"
 
4104
                                        views = table
 
4105
                                elif table.name == 'vport':
 
4106
                                        print "found table:vport"
 
4107
                                        vports = table
 
4108
                        if layers: #----------------------------------
 
4109
                                # Read the layers table and get the layer colors
 
4110
                                layersmap, layernamesmap = getLayersmap(layers)
 
4111
                                #self.colMaterials = MatColors()
 
4112
                                #self.layMaterials = MatLayers()
 
4113
                        else:
 
4114
                                self.write("File contains no table:layers!")
 
4115
 
 
4116
 
 
4117
                        if views: #----------------------------------
 
4118
                                if self.var['views_on']:
 
4119
                                        for item in views.data:
 
4120
                                                if type(item) != list and item.type == 'view':
 
4121
                                                        #print 'deb:settings_valid views dir(item)=', dir(item) #-------------
 
4122
                                                        #print 'deb:settings_valid views item=', item #-------------
 
4123
                                                        ob = item.draw(self)
 
4124
                                                        #viewsmap[item.name] = [item.length]
 
4125
                                                        #--todo-- add to obj_list for global.Scaling
 
4126
                                                        insertFlag, blockFlag = False, False
 
4127
                                                        oblist.append((ob, insertFlag, blockFlag))
 
4128
 
 
4129
                        else:
 
4130
                                self.write("File contains no table:views!")
 
4131
 
 
4132
 
 
4133
                        if vports: #----------------------------------
 
4134
                                if self.var['views_on']:
 
4135
                                        for item in vports.data:
 
4136
                                                if type(item) != list and item.type == 'vport':
 
4137
                                                        #print 'deb:settings_valid views dir(item)=', dir(item) #-------------
 
4138
                                                        #print 'deb:settings_valid views item=', item #-------------
 
4139
                                                        ob = item.draw(self)
 
4140
                                                        #viewsmap[item.name] = [item.length]
 
4141
                                                        #--todo-- add to obj_list for global.Scaling
 
4142
                                                        insertFlag, blockFlag = False, False
 
4143
                                                        oblist.append((ob, insertFlag, blockFlag))
 
4144
                        else:
 
4145
                                self.write("File contains no table:vports!")
 
4146
 
 
4147
 
 
4148
                else:
 
4149
                        self.write("File contains no section:tables!")
 
4150
                        self.write("File contains no table:layers!")
 
4151
 
 
4152
 
 
4153
                # The section:blocks may be omited
 
4154
                if 'blocks' in sections.keys():
 
4155
                        self.write("found section:blocks")
 
4156
                        # Read the block definitions and build our block object
 
4157
                        if self.drawTypes['insert']: #if support for entity type 'Insert' is activated
 
4158
                                #Build a dictionary of blockname:block_data pairs
 
4159
                                blocksmap, obj_number = getBlocksmap(drawing, layersmap, self.var['layFrozen_on'])
 
4160
                                self.obj_number += obj_number
 
4161
                                self.blocknamesmap = getBlocknamesmap(blocksmap)
 
4162
                                self.blocks = Blocks(blocksmap, self) # initiates container for blocks_data
 
4163
                                self.usedBlocks = blocksmap.keys()
 
4164
                                #print 'deb:settings_valid self.usedBlocks', self.usedBlocks #----------
 
4165
                        else:
 
4166
                                self.write("ignored, because support for BLOCKs is turn off!")
 
4167
                        #print 'deb:settings_valid self.obj_number', self.obj_number #----------
 
4168
                else:
 
4169
                        self.write("File contains no section:blocks!")
 
4170
                        self.drawTypes['insert'] = False
 
4171
 
 
4172
                # The section:entities
 
4173
                if 'entities' in sections.keys():
 
4174
                        self.write("found section:entities")
 
4175
                        self.obj_number += len(drawing.entities.data)
 
4176
                        self.obj_number = 1.0 / self.obj_number
 
4177
 
 
4178
 
 
4179
        def accepted_block(self, name):
 
4180
                if name not in self.usedBlocks: return False
 
4181
                if name in self.unwantedBlocks: return False
 
4182
                elif name in self.acceptedBlocks: return True
 
4183
                #elif (name.find('*X')+1): return False
 
4184
                #elif name.startswith('3'): return True
 
4185
                #elif name.endswith('H'): return False
 
4186
                return True
 
4187
 
 
4188
 
 
4189
        def write(self, text, newline=True):
 
4190
                """Wraps the built-in print command in a optimization check.
 
4191
                """
 
4192
                if self.var['optimization'] <= self.MID:
 
4193
                        if newline:
 
4194
                                print text
 
4195
                        else:
 
4196
                                print text,
 
4197
 
 
4198
 
 
4199
        def redraw(self):
 
4200
                """Update Blender if optimization level is low enough.
 
4201
                """
 
4202
                if self.var['optimization'] <= self.MIN:
 
4203
                        Blender.Redraw()
 
4204
 
 
4205
 
 
4206
        def progress(self, done, text):
 
4207
                """Wrapper for Blender.Window.DrawProgressBar.
 
4208
                """
 
4209
                if self.var['optimization'] <= self.PRO:
 
4210
                        progressbar = done * self.obj_number
 
4211
                        Window.DrawProgressBar(progressbar, text)
 
4212
                        #print 'deb:drawer done, progressbar: ', done, progressbar  #-----------------------
 
4213
 
 
4214
        def layer_isOff(self, layername):  # no more used -------
 
4215
                """Given a layer name, and return its visible status.
 
4216
                """
 
4217
                # if layer is off then color_index is negative 
 
4218
                if layersmap and layersmap[layername].color < 0: return True
 
4219
                #print 'deb:layer_isOff: layer is ON' #---------------
 
4220
                return False
 
4221
 
 
4222
 
 
4223
        def layer_isFrozen(self, layername):  # no more used -------
 
4224
                """Given a layer name, and return its frozen status.
 
4225
                """
 
4226
                if layersmap and layersmap[layername].frozen: return True
 
4227
                #print 'deb:layer_isFrozen: layer is not FROZEN' #---------------
 
4228
                return False
 
4229
 
 
4230
 
 
4231
 
 
4232
def     analyzeDXF(dxfFile): #---------------------------------------
 
4233
        """list statistics about LAYER and BLOCK dependences into textfile.INF
 
4234
        
 
4235
        """
 
4236
        Window.WaitCursor(True)   # Let the user know we are thinking
 
4237
        print 'reading DXF file: %s.' % dxfFile
 
4238
        time1 = Blender.sys.time()  #time marker1
 
4239
        drawing = readDXF(dxfFile, objectify)
 
4240
        print 'finish reading in %.4f sec.' % (Blender.sys.time()-time1)
 
4241
 
 
4242
        # First sort out all the section_items
 
4243
        sections = dict([(item.name, item) for item in drawing.data])
 
4244
 
 
4245
        # The section:header may be omited
 
4246
        if 'header' in sections.keys(): print "found section:header"
 
4247
        else: print "File contains no section:header!"
 
4248
 
 
4249
        # The section:tables may be partialy or completely missing.
 
4250
        layersTable = False
 
4251
        global layersmap
 
4252
        layersmap = {}
 
4253
        viewsmap = {}
 
4254
        vportsmap = {}
 
4255
        layersmap_str = '#File contains no table:layers!'
 
4256
        viewsmap_str = '#File contains no table:views!'
 
4257
        vportsmap_str = '#File contains no table:vports!'
 
4258
        if 'tables' in sections.keys():
 
4259
                print "found section:tables"
 
4260
                views, vports, layers = False, False, False
 
4261
                for table in drawing.tables.data:
 
4262
                        if table.name == 'layer':
 
4263
                                print "found table:layers"
 
4264
                                layers = table
 
4265
                        elif table.name == 'view':
 
4266
                                print "found table:view"
 
4267
                                views = table
 
4268
                        elif table.name == 'vport':
 
4269
                                print "found table:vport"
 
4270
                                vports = table
 
4271
                if layers: #----------------------------------
 
4272
                        for item in layers.data:
 
4273
                                if type(item) != list and item.type == 'layer':
 
4274
                                        #print dir(item)
 
4275
                                        layersmap[item.name] = [item.color, item.frozen]
 
4276
                        #print 'deb:analyzeDXF: layersmap=' , layersmap #-------------
 
4277
                        layersmap_str = '#list of LAYERs: name, color, frozen_status  ---------------------------\n'
 
4278
                        key_list = layersmap.keys()
 
4279
                        key_list.sort()
 
4280
                        for key in key_list:
 
4281
                        #for layer_name, layer_data in layersmap.iteritems():
 
4282
                                layer_name, layer_data = key, layersmap[key]
 
4283
                                layer_str = '\'%s\': col=%s' %(layer_name,layer_data[0])#-------------
 
4284
                                if layer_data[1]: layer_str += ', frozen'
 
4285
                                layersmap_str += layer_str + '\n'
 
4286
                        #print 'deb:analyzeDXF: layersmap_str=\n' , layersmap_str #-------------
 
4287
                else:
 
4288
                        print "File contains no table:layers!"
 
4289
 
 
4290
                if views: #----------------------------------
 
4291
                        for item in views.data:
 
4292
                                if type(item) != list and item.type == 'view':
 
4293
                                        #print dir(item)
 
4294
                                        viewsmap[item.name] = [item.length]
 
4295
                        #print 'deb:analyzeDXF: viewsmap=' , viewsmap #-------------
 
4296
                        viewsmap_str = '#list of VIEWs: name, focus_length  ------------------------------------\n'
 
4297
                        key_list = viewsmap.keys()
 
4298
                        key_list.sort()
 
4299
                        for key in key_list:
 
4300
                        #for view_name, view_data in viewsmap.iteritems():
 
4301
                                view_name, view_data = key, viewsmap[key]
 
4302
                                view_str = '\'%s\': length=%s' %(view_name,view_data[0])#-------------
 
4303
                                #if view_data[1]: view_str += ', something'
 
4304
                                viewsmap_str += view_str + '\n'
 
4305
                        #print 'deb:analyzeDXF: layersmap_str=\n' , layersmap_str #-------------
 
4306
                else:
 
4307
                        print "File contains no table:views!"
 
4308
 
 
4309
                if vports: #----------------------------------
 
4310
                        for item in vports.data:
 
4311
                                if type(item) != list and item.type == 'vport':
 
4312
                                        #print dir(item)
 
4313
                                        vportsmap[item.name] = [item.length]
 
4314
                        #print 'deb:analyzeDXF: vportsmap=' , vportsmap #-------------
 
4315
                        vportsmap_str = '#list of VPORTs: name, focus_length  -----------------------------------\n'
 
4316
                        key_list = vportsmap.keys()
 
4317
                        key_list.sort()
 
4318
                        for key in key_list:
 
4319
                        #for vport_name, vport_data in vportsmap.iteritems():
 
4320
                                vport_name, vport_data = key, vportsmap[key]
 
4321
                                vport_str = '\'%s\': length=%s' %(vport_name,vport_data[0])#-------------
 
4322
                                #if vport_data[1]: vport_str += ', something'
 
4323
                                vportsmap_str += vport_str + '\n'
 
4324
                        #print 'deb:analyzeDXF: vportsmap_str=\n' , vportsmap_str #-------------
 
4325
                else:
 
4326
                        print "File contains no table:vports!"
 
4327
 
 
4328
        else:
 
4329
                print "File contains no section:tables!"
 
4330
                print "File contains no tables:layers,views,vports!"
 
4331
 
 
4332
        # The section:blocks may be omited
 
4333
        if 'blocks' in sections.keys():
 
4334
                print "found section:blocks"
 
4335
                blocksmap = {}
 
4336
                for item in drawing.blocks.data:
 
4337
                        #print 'deb:getBlocksmap item=' ,item #--------
 
4338
                        #print 'deb:getBlocksmap item.entities=' ,item.entities #--------
 
4339
                        #print 'deb:getBlocksmap item.entities.data=' ,item.entities.data #--------
 
4340
                        if type(item) != list and item.type == 'block':
 
4341
                                xref = False
 
4342
                                if item.xref: xref = True
 
4343
                                childList = []
 
4344
                                used = False
 
4345
                                for item2 in item.entities.data:
 
4346
                                        if type(item2) != list and item2.type == 'insert':
 
4347
                                                #print 'deb:getBlocksmap dir(item2)=', dir(item2) #----------
 
4348
                                                item2str = [item2.name, item2.layer, item2.color_index, item2.scale, item2.space]
 
4349
                                                childList.append(item2str)
 
4350
                                try: blocksmap[item.name] = [used, childList, xref]
 
4351
                                except KeyError: print 'Cannot map "%s" - "%s" as Block!' %(item.name, item)
 
4352
                #print 'deb:analyzeDXF: blocksmap=' , blocksmap #-------------
 
4353
 
 
4354
                for item2 in drawing.entities.data:
 
4355
                        if type(item2) != list and item2.type == 'insert':
 
4356
                                if not layersmap or (layersmap and not layersmap[item2.layer][1]): #if insert_layer is not frozen
 
4357
                                        blocksmap[item2.name][0] = True # marked as world used BLOCK
 
4358
 
 
4359
                key_list = blocksmap.keys()
 
4360
                key_list.reverse()
 
4361
                for key in key_list:
 
4362
                        if blocksmap[key][0]: #if used
 
4363
                                for child in blocksmap[key][1]:
 
4364
                                        if not layersmap or (layersmap and not layersmap[child[1]][1]): #if insert_layer is not frozen
 
4365
                                                blocksmap[child[0]][0] = True # marked as used BLOCK
 
4366
 
 
4367
                blocksmap_str = '#list of BLOCKs: name:(unused)(xref) -[child_name, layer, color, scale, space]-------\n'
 
4368
                key_list = blocksmap.keys()
 
4369
                key_list.sort()
 
4370
                for key in key_list:
 
4371
                #for block_name, block_data in blocksmap.iteritems():
 
4372
                        block_name, block_data = key, blocksmap[key]
 
4373
                        block_str = '\'%s\': ' %(block_name) #-------------
 
4374
                        used = '(unused)'
 
4375
                        if block_data[0]: used = ''
 
4376
#                       else: used = '(unused)'
 
4377
                        xref = ''
 
4378
                        if block_data[2]: xref = '(xref)'
 
4379
                        blocksmap_str += block_str + used + xref +'\n'
 
4380
                        if block_data:
 
4381
                                for block_item in block_data[1]:
 
4382
                                        block_data_str = ' - %s\n' %block_item
 
4383
                                        blocksmap_str += block_data_str
 
4384
                #print 'deb:analyzeDXF: blocksmap_str=\n' , blocksmap_str #-------------
 
4385
        else:
 
4386
                blocksmap_str = '#File contains no section:blocks!'
 
4387
                print "File contains no section:blocks!"
 
4388
 
 
4389
        Window.WaitCursor(False)
 
4390
        output_str = '%s\n%s\n%s\n%s' %(viewsmap_str, vportsmap_str, layersmap_str, blocksmap_str)
 
4391
        infFile = dxfFile[:-4] + '_DXF.INF'  # replace last char:'.dxf' with '_DXF.inf'
 
4392
        try:
 
4393
                f = file(infFile, 'w')
 
4394
                f.write(INFFILE_HEADER + '\n# this is a comment line\n\n')
 
4395
                f.write(output_str)
 
4396
                f.close()
 
4397
                Draw.PupMenu('DXF importer: report saved in INF-file:%t|' + '\'%s\'' %infFile)
 
4398
        except:
 
4399
                Draw.PupMenu('DXF importer: ERROR by writing report in INF-file:%t|' + '\'%s\'' %infFile)
 
4400
        finally:
 
4401
                f.close()
 
4402
 
 
4403
 
 
4404
 
 
4405
 
 
4406
def main(dxfFile):  #---------------#############################-----------
 
4407
        #print 'deb:filename:', filename #--------------
 
4408
        global SCENE
 
4409
        global oblist
 
4410
        editmode = Window.EditMode()    # are we in edit mode?  If so ...
 
4411
        if editmode:
 
4412
                Window.EditMode(0) # leave edit mode before
 
4413
 
 
4414
        #SCENE = bpy.data.scenes.active
 
4415
        #SCENE.objects.selected = [] # deselect all
 
4416
        
 
4417
        global cur_COUNTER  #counter for progress_bar
 
4418
        cur_COUNTER = 0
 
4419
 
 
4420
        try:
 
4421
                #print "Getting settings..."
 
4422
                global GUI_A, GUI_B, g_scale_as
 
4423
                if not GUI_A['g_scale_on'].val:
 
4424
                        GUI_A['g_scale'].val = 1.0
 
4425
 
 
4426
                keywords = {}
 
4427
                drawTypes = {}
 
4428
                for k, v in GUI_A.iteritems():
 
4429
                        keywords[k] = v.val
 
4430
                for k, v in GUI_B.iteritems():
 
4431
                        drawTypes[k] = v.val
 
4432
                #print 'deb:startUInew keywords: ', keywords #--------------
 
4433
                #print 'deb:startUInew drawTypes: ', drawTypes #--------------
 
4434
 
 
4435
                # The settings object controls how dxf entities are drawn
 
4436
                settings.update(keywords, drawTypes)
 
4437
                #print 'deb:settings.var:\n', settings.var  #-----------------------
 
4438
 
 
4439
                if not settings:
 
4440
                        #Draw.PupMenu('DXF importer:  EXIT!%t')
 
4441
                        #print '\nDXF Import: terminated by user!'
 
4442
                        print '\nDXF Import: terminated, cause settings failure!'
 
4443
                        Window.WaitCursor(False)
 
4444
                        if editmode: Window.EditMode(1) # and put things back how we fond them
 
4445
                        return None
 
4446
 
 
4447
                #no more used dxfFile = dxfFileName.val
 
4448
                #print 'deb: dxfFile file: ', dxfFile #----------------------
 
4449
                if dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile):
 
4450
                        Window.WaitCursor(True)   # Let the user know we are thinking
 
4451
                        print 'reading file: %s.' % dxfFile
 
4452
                        time1 = Blender.sys.time()  #time marker1
 
4453
                        drawing = readDXF(dxfFile, objectify)
 
4454
                        print 'reading finished in %.4f sec.' % (Blender.sys.time()-time1)
 
4455
                        Window.WaitCursor(False)
 
4456
                else:
 
4457
                        if UI_MODE: Draw.PupMenu('DXF importer:  Alert!%t| no valid DXF-file selected!')
 
4458
                        print "DXF importer: Alert! - no valid DXF-file selected."
 
4459
                        Window.WaitCursor(False)
 
4460
                        if editmode: Window.EditMode(1) # and put things back how we fond them
 
4461
                        return None
 
4462
 
 
4463
                # Draw all the know entity types in the current scene
 
4464
                oblist = []  # a list of all created AND linked objects for final f_globalScale
 
4465
                time2 = Blender.sys.time()  #time marker2
 
4466
 
 
4467
                Window.WaitCursor(True)   # Let the user know we are thinking
 
4468
                settings.write("\n\nDrawing entities...")
 
4469
 
 
4470
                settings.validate(drawing)
 
4471
 
 
4472
                global activObjectLayer, activObjectName
 
4473
                activObjectLayer, activObjectName = None, None
 
4474
 
 
4475
                if M_OBJ: car_init()
 
4476
 
 
4477
                drawEntities(drawing.entities, settings)
 
4478
 
 
4479
                #print 'deb:drawEntities after: oblist:', oblist #-----------------------
 
4480
                if M_OBJ: car_end()
 
4481
                if oblist: # and settings.var['g_scale'] != 1:
 
4482
                        globalScale(oblist, settings.var['g_scale'])
 
4483
 
 
4484
                # Set visibility for all layers on all View3d
 
4485
                #Window.ViewLayers([i+1 for i in range(18)]) # for 2.45
 
4486
                SCENE.setLayers([i+1 for i in range(18)])
 
4487
                SCENE.update(1)
 
4488
                SCENE.objects.selected = [i[0] for i in oblist] #select only the imported objects                  
 
4489
                #SCENE.objects.selected = SCENE.objects   #select all objects in current scene            
 
4490
                Blender.Redraw()
 
4491
 
 
4492
                time_text = Blender.sys.time() - time2
 
4493
                Window.WaitCursor(False)
 
4494
                if settings.var['paper_space_on']: space = 'from paper space'
 
4495
                else: space = 'from model space'
 
4496
                ob_len = len(oblist)
 
4497
                message = '  %s objects imported %s in %.4f sec.  -----DONE-----' % (ob_len, space, time_text)
 
4498
                settings.progress(1.0/settings.obj_number, 'DXF import done!')
 
4499
                print message
 
4500
                #settings.write(message)
 
4501
                if UI_MODE: Draw.PupMenu('DXF importer: Done!|finished in %.4f sec.' % time_text)
 
4502
 
 
4503
        finally:
 
4504
                # restore state even if things didn't work
 
4505
                #print 'deb:drawEntities finally!' #-----------------------
 
4506
                Window.WaitCursor(False)
 
4507
                if editmode: Window.EditMode(1) # and put things back how we fond them
 
4508
 
 
4509
 
 
4510
 
 
4511
def getOCS(az):  #-----------------------------------------------------------------
 
4512
        """An implimentation of the Arbitrary Axis Algorithm.
 
4513
        """
 
4514
        #decide if we need to transform our coords
 
4515
        #if az[0] == 0 and az[1] == 0: 
 
4516
        if abs(az[0]) < 0.00001 and abs(az[1]) < 0.00001:
 
4517
                if az[2] > 0.0:
 
4518
                        return False
 
4519
                elif az[2] < 0.0:
 
4520
                        ax = Mathutils.Vector(-1.0, 0, 0)
 
4521
                        ay = Mathutils.Vector(0, 1.0, 0)
 
4522
                        az = Mathutils.Vector(0, 0, -1.0)
 
4523
                        return ax, ay, az 
 
4524
 
 
4525
        az = Mathutils.Vector(az)
 
4526
 
 
4527
        cap = 0.015625 # square polar cap value (1/64.0)
 
4528
        if abs(az.x) < cap and abs(az.y) < cap:
 
4529
                ax = Mathutils.CrossVecs(WORLDY, az)
 
4530
        else:
 
4531
                ax = Mathutils.CrossVecs(WORLDZ, az)
 
4532
        ax = ax.normalize()
 
4533
        ay = Mathutils.CrossVecs(az, ax)
 
4534
        ay = ay.normalize()
 
4535
        return ax, ay, az
 
4536
 
 
4537
 
 
4538
 
 
4539
def transform(normal, rotation, obj):  #--------------------------------------------
 
4540
        """Use the calculated ocs to determine the objects location/orientation in space.
 
4541
 
 
4542
        Quote from dxf docs:
 
4543
                The elevation value stored with an entity and output in DXF files is a sum
 
4544
        of the Z-coordinate difference between the UCS XY plane and the OCS XY
 
4545
        plane, and the elevation value that the user specified at the time the entity
 
4546
        was drawn.
 
4547
        """
 
4548
        ma = Mathutils.Matrix([1,0,0],[0,1,0],[0,0,1])
 
4549
        o = Mathutils.Vector(obj.loc)
 
4550
        ocs = getOCS(normal)
 
4551
        if ocs:
 
4552
                ma = Mathutils.Matrix(ocs[0], ocs[1], ocs[2])
 
4553
                o = ma.invert() * o
 
4554
                ma = Mathutils.Matrix(ocs[0], ocs[1], ocs[2])
 
4555
 
 
4556
        if rotation != 0:
 
4557
                g = radians(-rotation)
 
4558
                rmat = Mathutils.Matrix([cos(g), -sin(g), 0], [sin(g), cos(g), 0], [0, 0, 1])
 
4559
                ma = rmat * ma
 
4560
 
 
4561
        obj.setMatrix(ma)
 
4562
        obj.loc = o
 
4563
        #print 'deb:new obj.matrix:\n', obj.getMatrix()   #--------------------
 
4564
 
 
4565
 
 
4566
 
 
4567
def rotXY_Vec(rotation, vec):  #----------------------------------------------------
 
4568
        """Rotate vector vec in XY-plane. vec must be in radians
 
4569
        """
 
4570
        if rotation != 0:
 
4571
                o = Mathutils.Vector(vec)
 
4572
                g = radians(-rotation)
 
4573
                vec = o * Mathutils.Matrix([cos(g), -sin(g), 0], [sin(g), cos(g), 0], [0, 0, 1])
 
4574
        return vec
 
4575
 
 
4576
 
 
4577
 
 
4578
def getLayersmap(dxflayers):  #------------------------------------------------------
 
4579
        """Build two dictionaries: 1.layername:layer object, and 2.layername:layername_short
 
4580
        gets set of layers from TABLES SECTION LAYERS
 
4581
        """
 
4582
        layersmap = {}
 
4583
        layernamesmap = {}
 
4584
        for item in dxflayers.data:
 
4585
                if type(item) != list and item.type == 'layer':
 
4586
                        layersmap[item.name] = item
 
4587
                        layername_short = item.name[:MAX_NAMELENGTH-1]
 
4588
                        i = 0  #sufix for layernames cause Blender-objectnames-limits
 
4589
                        while layername_short in layernamesmap.keys():
 
4590
                                i += 1
 
4591
                                suffix = str(i) #--todo--set zero-leading number format
 
4592
                                layername_short = layername_short[:-2] + suffix
 
4593
                        layernamesmap[item.name] = layername_short
 
4594
 
 
4595
        #print 'deb:getLayersmap layersmap:\n', layersmap #------------
 
4596
        #print 'deb:getLayersmap layernamesmap:\n', layernamesmap #------------
 
4597
        return layersmap, layernamesmap
 
4598
 
 
4599
 
 
4600
        
 
4601
def getBlocksmap(drawing, layersmap, layFrozen_on=False):  #--------------------------------------------------------
 
4602
        """Build a dictionary of blockname:block_data pairs
 
4603
        """
 
4604
        usedblocks = {}
 
4605
        for item in drawing.blocks.data:
 
4606
                #print 'deb:getBlocksmap item=%s\n i.entities=%s\n i.data=%s' %(item,item.entities,item.entities.data)
 
4607
                if type(item) != list and item.type == 'block':
 
4608
                        childList = []
 
4609
                        used = False
 
4610
                        for item2 in item.entities.data:
 
4611
                                if type(item2) != list and item2.type == 'insert':
 
4612
                                        #print 'deb:getBlocksmap dir(item2)=', dir(item2) #----------
 
4613
                                        item2str = [item2.name, item2.layer]
 
4614
                                        childList.append(item2str)
 
4615
                        try: usedblocks[item.name] = [used, childList]
 
4616
                        except KeyError: print 'Cannot map "%s" - "%s" as Block!' %(item.name, item)
 
4617
        #print 'deb:getBlocksmap: usedblocks=' , usedblocks #-------------
 
4618
        #print 'deb:getBlocksmap:  layersmap=' , layersmap #-------------
 
4619
 
 
4620
        for item in drawing.entities.data:
 
4621
                if type(item) != list and item.type == 'insert':
 
4622
                        if not layersmap or (not layersmap[item.layer].frozen or layFrozen_on): #if insert_layer is not frozen
 
4623
                                try: usedblocks[item.name][0] = True 
 
4624
                                except: pass
 
4625
                                
 
4626
        key_list = usedblocks.keys()
 
4627
        key_list.reverse()
 
4628
        for key in key_list:
 
4629
                if usedblocks[key][0]: #if parent used, then set used also all child blocks
 
4630
                        for child in usedblocks[key][1]:
 
4631
                                if not layersmap or (layersmap and not layersmap[child[1]].frozen): #if insert_layer is not frozen
 
4632
                                        usedblocks[child[0]][0] = True # marked as used BLOCK
 
4633
 
 
4634
        usedblocks = [i for i in usedblocks.keys() if usedblocks[i][0]]
 
4635
        #print 'deb:getBlocksmap: usedblocks=' , usedblocks #-------------
 
4636
        obj_number = 0
 
4637
        blocksmap = {}
 
4638
        for item in drawing.blocks.data:
 
4639
                if type(item) != list and item.type == 'block' and item.name in usedblocks:
 
4640
                        #if item.name.startswith('*X'): #--todo--
 
4641
                        obj_number += len(item.entities.data)
 
4642
                        try: blocksmap[item.name] = item
 
4643
                        except KeyError: print 'Cannot map "%s" - "%s" as Block!' %(item.name, item)
 
4644
        
 
4645
 
 
4646
        #print 'deb:getBlocksmap: blocksmap:\n', blocksmap #------------
 
4647
        return blocksmap, obj_number
 
4648
 
 
4649
 
 
4650
def getBlocknamesmap(blocksmap):  #--------------------------------------------------------
 
4651
        """Build a dictionary of blockname:blockname_short pairs
 
4652
        """
 
4653
        #print 'deb:getBlocknamesmap blocksmap:\n', blocksmap #------------
 
4654
        blocknamesmap = {}
 
4655
        for n in blocksmap.keys():
 
4656
                blockname_short = n[:MAX_NAMELENGTH-1]
 
4657
                i = 0  #sufix for blockname cause Blender-objectnamelength-limit
 
4658
                while blockname_short in blocknamesmap.keys():
 
4659
                        i += 1
 
4660
                        suffix = str(i)
 
4661
                        blockname_short = blockname_short[:-2] + suffix
 
4662
                blocknamesmap[n] = blockname_short
 
4663
        #print 'deb:getBlocknamesmap blocknamesmap:\n', blocknamesmap #------------
 
4664
        return blocknamesmap
 
4665
 
 
4666
 
 
4667
def drawEntities(entities, settings, block_def=None):  #----------------------------------------
 
4668
        """Draw every kind of thing in the entity list.
 
4669
 
 
4670
        If provided 'block_def': the entities are to be added to the Blender 'group'.
 
4671
        """
 
4672
        for _type in type_map.keys():
 
4673
                #print 'deb:drawEntities_type:', _type #------------------
 
4674
                # for each known type get a list of that type and call the associated draw function
 
4675
                entities_type = entities.get_type(_type)
 
4676
                if entities_type: drawer(_type, entities_type, settings, block_def)
 
4677
 
 
4678
 
 
4679
def drawer(_type, entities, settings, block_def):  #------------------------------------------
 
4680
        """Call with a list of entities and a settings object to generate Blender geometry.
 
4681
 
 
4682
        If 'block_def': the entities are to be added to the Blender 'group'.
 
4683
        """
 
4684
        global layersmap, layersmapshort
 
4685
        #print 'deb:drawer _type, entities:\n ', _type, entities  #-----------------------
 
4686
 
 
4687
        if entities:
 
4688
                # Break out early if settings says we aren't drawing the current dxf-type
 
4689
                global cur_COUNTER  #counter for progress_bar
 
4690
                group = None
 
4691
                #print 'deb:drawer.check:_type: ', _type  #--------------------
 
4692
                if _type == '3dface':_type = 'face' # hack, while python_variable_name can not beginn with a nummber
 
4693
                if not settings.drawTypes[_type] or _type == 'block_record':
 
4694
                        message = 'Skipping dxf\'%ss\' entities' %_type
 
4695
                        settings.write(message, True)
 
4696
                        cur_COUNTER += len(entities)
 
4697
                        settings.progress(cur_COUNTER, message)
 
4698
                        return
 
4699
                #print 'deb:drawer.todo:_type:', _type  #-----------------------
 
4700
                #print 'deb:drawer entities:\n ', entities  #-----------------------
 
4701
 
 
4702
                len_temp = len(entities)
 
4703
                # filtering only model-space enitities (no paper-space enitities)
 
4704
                if settings.var['paper_space_on']:
 
4705
                        entities = [entity for entity in entities if entity.space != 0]
 
4706
                else:
 
4707
                        entities = [entity for entity in entities if entity.space == 0]
 
4708
 
 
4709
                # filtering only objects with color from acceptedColorsList
 
4710
                if settings.var['colorFilter_on']:
 
4711
                        entities = [entity for entity in entities if entity.color in settings.acceptedColors]
 
4712
 
 
4713
                # filtering only objects on layers from acceptedLayersList
 
4714
                if settings.var['layerFilter_on']:
 
4715
                        #entities = [entity for entity in entities if entity.layer[0] in ['M','3','0'] and not entity.layer.endswith('H')]
 
4716
                        entities = [entity for entity in entities if entity.layer in settings.acceptedLayers]
 
4717
 
 
4718
                # patch for incomplete layer table in HL2-DXF-files 
 
4719
                if layersmap:
 
4720
                        for entity in entities:
 
4721
                                oblayer = entity.layer
 
4722
                                if oblayer not in layersmap.keys():
 
4723
                                        layer_obj = Layer(None, name=oblayer)
 
4724
                                        layersmap[oblayer] = layer_obj
 
4725
                                        layername_short = oblayer[:MAX_NAMELENGTH-1]
 
4726
                                        i = 0  #sufix for layernames cause Blender-objectnames-limits
 
4727
                                        while layername_short in layernamesmap.keys():
 
4728
                                                i += 1
 
4729
                                                suffix = str(i) #--todo--set zero-leading number format
 
4730
                                                layername_short = layername_short[:-2] + suffix
 
4731
                                        layernamesmap[oblayer] = layername_short
 
4732
 
 
4733
                # filtering only objects on not-frozen layers
 
4734
                if layersmap and not settings.var['layFrozen_on']:
 
4735
                        entities = [entity for entity in entities if not layersmap[entity.layer].frozen]
 
4736
 
 
4737
                global activObjectLayer, activObjectName
 
4738
                activObjectLayer = ''
 
4739
                activObjectName = ''
 
4740
 
 
4741
                message = "Drawing dxf\'%ss\'..." %_type
 
4742
                cur_COUNTER += len_temp - len(entities)
 
4743
                settings.write(message, False)
 
4744
                settings.progress(cur_COUNTER, message)
 
4745
                if len(entities) > 0.1 / settings.obj_number:
 
4746
                        show_progress = int(0.03 / settings.obj_number)
 
4747
                else: show_progress = 0
 
4748
                cur_temp = 0
 
4749
 
 
4750
                #print 'deb:drawer cur_COUNTER: ', cur_COUNTER  #-----------------------
 
4751
 
 
4752
                for entity in entities:   #----loop-------------------------------------
 
4753
                        settings.write('\b.', False)
 
4754
                        cur_COUNTER += 1
 
4755
                        if show_progress:
 
4756
                                cur_temp += 1
 
4757
                                if cur_temp == show_progress:
 
4758
                                        settings.progress(cur_COUNTER, message)
 
4759
                                        cur_temp = 0
 
4760
                                        #print 'deb:drawer show_progress=',show_progress  #----------------
 
4761
                                
 
4762
                        # get the layer group (just to make things a little cleaner)
 
4763
                        if settings.var['group_bylayer_on'] and not block_def:
 
4764
                                group = getGroup('l:%s' % layernamesmap[entity.layer])
 
4765
 
 
4766
                        if _type == 'insert':   #---- INSERT and MINSERT=array --------------------
 
4767
                                if not settings.var['block_nn'] and entity.name.startswith('*X'):   #---- support for noname BLOCKs
 
4768
                                        #print 'deb:drawer entity.name:', entity.name #------------
 
4769
                                        continue
 
4770
                                elif settings.var['blockFilter_on'] and not settings.accepted_block(entity.name):
 
4771
                                        continue
 
4772
 
 
4773
                                #print 'deb:insert entity.loc:', entity.loc #----------------
 
4774
                                insertFlag = True
 
4775
                                columns = entity.columns[0]
 
4776
                                coldist = entity.columns[1]
 
4777
                                rows    = entity.rows[0]
 
4778
                                rowdist = entity.rows[1]
 
4779
                                deltaloc = [0,0,0]
 
4780
                                #print 'deb:insert columns, rows:', columns, rows   #-----------
 
4781
                                for col in xrange(columns):
 
4782
                                        deltaloc[0] =  col * coldist
 
4783
                                        for row in xrange(rows):
 
4784
                                                deltaloc[1] =  row * rowdist
 
4785
                                                #print 'deb:insert col=%s, row=%s,deltaloc=%s' %(col, row, deltaloc) #------
 
4786
                                                ob = entity.draw(settings, deltaloc)   #-----draw BLOCK----------
 
4787
                                                if block_def:
 
4788
                                                        blockFlag = True
 
4789
                                                        bl_loc = block_def[1]
 
4790
                                                        ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]]
 
4791
                                                else: blockFlag = False
 
4792
                                                setObjectProperties(ob, group, entity, settings, block_def)
 
4793
                                                if ob:
 
4794
                                                        if settings.var['optimization'] <= settings.MIN:
 
4795
                                                                #if settings.var['g_origin_on'] and not block_def: ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin
 
4796
                                                                if settings.var['g_scale_on']: globalScaleOne(ob, insertFlag, blockFlag, settings.var['g_scale'])
 
4797
                                                                settings.redraw()
 
4798
                                                        else: oblist.append((ob, insertFlag, blockFlag))
 
4799
                                        
 
4800
                        else:   #---draw entities except BLOCKs/INSERTs---------------------
 
4801
                                insertFlag = False
 
4802
                                alt_obname = activObjectName
 
4803
                                ob = entity.draw(settings)
 
4804
                                if ob:
 
4805
                                        if M_OBJ and ob.type=='Mesh': #'Curve', 'Text'
 
4806
                                                if block_def:
 
4807
                                                        blockFlag = True
 
4808
                                                        bl_loc = block_def[1]
 
4809
                                                        ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]]
 
4810
                                                car_nr()
 
4811
        
 
4812
                                        elif ob.name != alt_obname:
 
4813
                                                if block_def:
 
4814
                                                        blockFlag = True
 
4815
                                                        bl_loc = block_def[1]
 
4816
                                                        ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]]
 
4817
                                                else: blockFlag = False
 
4818
                                                setObjectProperties(ob, group, entity, settings, block_def)
 
4819
                                                if settings.var['optimization'] <= settings.MIN:
 
4820
                                                        #if settings.var['g_origin_on'] and not block_def: ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin
 
4821
                                                        if settings.var['g_scale_on']: globalScaleOne(ob, insertFlag, blockFlag, settings.var['g_scale'])
 
4822
                                                        settings.redraw()
 
4823
                                                else: oblist.append((ob, insertFlag, blockFlag))
 
4824
        
 
4825
                #print 'deb:Finished drawing:', entities[0].type   #------------------------
 
4826
                message = "\nDrawing dxf\'%ss\' done!" % _type
 
4827
                settings.write(message, True)
 
4828
 
 
4829
 
 
4830
 
 
4831
def globalScale(oblist, SCALE):  #---------------------------------------------------------
 
4832
        """Global_scale for list of all imported objects.
 
4833
 
 
4834
        oblist is a list of pairs (ob, insertFlag), where insertFlag=True/False
 
4835
        """
 
4836
        #print 'deb:globalScale.oblist: ---------%\n', oblist #---------------------
 
4837
        for l in oblist:
 
4838
                ob, insertFlag, blockFlag  = l[0], l[1], l[2]
 
4839
                globalScaleOne(ob, insertFlag, blockFlag, SCALE)
 
4840
 
 
4841
 
 
4842
def globalScaleOne(ob, insertFlag, blockFlag, SCALE):  #---------------------------------------------------------
 
4843
        """Global_scale imported object.
 
4844
        """
 
4845
        #print 'deb:globalScaleOne  ob: ', ob #---------------------
 
4846
        if settings.var['g_origin_on'] and not blockFlag:
 
4847
                ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin
 
4848
 
 
4849
        SCALE_MAT= Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1])
 
4850
        if insertFlag:  # by BLOCKs/INSERTs only insert-point coords must be scaled------------
 
4851
                ob.loc = Mathutils.Vector(ob.loc) * SCALE_MAT
 
4852
        else:   # entire scaling for all other imported objects ------------
 
4853
                if ob.type == 'Mesh':           
 
4854
                        me = ob.getData(name_only=False, mesh=True)
 
4855
                        #me = Mesh.Get(ob.name)
 
4856
                        # set centers of all objects in (0,0,0)
 
4857
                        #me.transform(ob.matrixWorld*SCALE_MAT) 
 
4858
                        #ob.loc = Mathutils.Vector([0,0,0])
 
4859
                        # preseve centers of all objects
 
4860
                        me.transform(SCALE_MAT) 
 
4861
                        ob.loc = Mathutils.Vector(ob.loc) * SCALE_MAT
 
4862
                else: #--todo-- also for curves: neutral scale factor after import
 
4863
                        ob.setMatrix(ob.matrixWorld*SCALE_MAT)
 
4864
 
 
4865
 
 
4866
def setObjectProperties(ob, group, entity, settings, block_def):  #-----------------------
 
4867
        """Link object to scene.
 
4868
        """
 
4869
 
 
4870
        if not ob:  #remi--todo-----------------------
 
4871
                message = "\nObject \'%s\' not found!" %entity
 
4872
                settings.write(message)
 
4873
                return
 
4874
 
 
4875
        if group:
 
4876
                setGroup(group, ob)  # if object belongs to group
 
4877
 
 
4878
        if block_def:   # if object belongs to BLOCK_def - Move it to layer nr19
 
4879
                setGroup(block_def[0], ob)
 
4880
                #print 'deb:setObjectProperties  \'%s\' set to block_def_group!' %ob.name #---------
 
4881
                ob.layers = [19]
 
4882
        else:
 
4883
                #ob.layers = [i+1 for i in xrange(20)] #remi--todo------------
 
4884
                ob.layers = [settings.var['target_layer']]
 
4885
 
 
4886
        # Set material for any objects except empties
 
4887
        if ob.type != 'Empty' and settings.var['material_on']:
 
4888
                setMaterial_from(entity, ob, settings, block_def)
 
4889
 
 
4890
        # Set the visibility
 
4891
        #if settings.layer_isOff(entity.layer):
 
4892
        if layersmap and layersmap[entity.layer].color < 0: # color is negative if layer is off
 
4893
                #ob.layers = [20]  #remi--todo-------------
 
4894
                ob.restrictDisplay = True
 
4895
                ob.restrictRender = True
 
4896
 
 
4897
        #print 'deb:\n---------linking Object %s!' %ob.name #----------
 
4898
 
 
4899
 
 
4900
 
 
4901
def getGroup(name):  #-----------------------------------------------------------------
 
4902
        """Returns a Blender group-object.
 
4903
        """
 
4904
        try:
 
4905
                group = Group.Get(name)
 
4906
        except: # What is the exception?
 
4907
                group = Group.New(name)
 
4908
        return group
 
4909
 
 
4910
 
 
4911
def setGroup(group, ob):  #------------------------------------------------------------
 
4912
        """Assigns object to Blender group.
 
4913
        """
 
4914
        try:
 
4915
                group.objects.link(ob)
 
4916
        except:
 
4917
                group.objects.append(ob)  #remi?---------------
 
4918
 
 
4919
 
 
4920
 
 
4921
def setMaterial_from(entity, ob, settings, block_def):  #------------------------------------------------
 
4922
        """ Set Blender-material for the object controled by item.
 
4923
 
 
4924
        Set Blender-material for the object
 
4925
         - controlled by settings.var['material_from']
 
4926
        """
 
4927
        if settings.var['material_from'] == 1: # 1= material from color
 
4928
                if entity.color_index == BYLAYER or entity.color_index == 256:
 
4929
                        mat = settings.colMaterials(entity.layer)
 
4930
                elif entity.color_index == BYBLOCK or entity.color_index == 0:
 
4931
                        #--todo-- looking for block.color_index
 
4932
                        #mat = settings.colMaterials(block.color_index)
 
4933
                        #if block_def: mat = settings.colMaterials(block_def[2])
 
4934
                        mat = settings.colMaterials(3)
 
4935
                else:
 
4936
                        mat = settings.colMaterials(entity.color_index)
 
4937
 
 
4938
        elif settings.var['material_from'] == 2: # 2= material from layer_name
 
4939
                mat = settings.layMaterials(layername=entity.layer)
 
4940
 
 
4941
        elif settings.var['material_from'] == 3: # 3= material from layer+color
 
4942
                mat = settings.layMaterials(layername=entity.layer, color=entity.color_index)
 
4943
 
 
4944
#       elif settings.var['material_from'] == 4: # 4= material from block_name
 
4945
 
 
4946
#       elif settings.var['material_from'] == 5: # 5= material from XDATA
 
4947
 
 
4948
#       elif settings.var['material_from'] == 6: # 6= material from INI-file
 
4949
 
 
4950
        else:                                      # set neutral material
 
4951
                try:
 
4952
                        mat = Material.Get('dxf-neutral')
 
4953
                except:
 
4954
                        mat = Material.New('dxf-neutral')
 
4955
                        mat.setRGBCol(color_map[3])
 
4956
                        try:mat.setMode('Shadeless', 'Wire') #work-around for 2.45rc1-bug
 
4957
                        except:
 
4958
                         mat.mode |= Material.Modes.SHADELESS #
 
4959
                         mat.mode |= Material.Modes.WIRE
 
4960
        try:
 
4961
                #print 'deb:material mat:', mat #-----------
 
4962
                ob.setMaterials([mat])  #assigns Blender-material to object
 
4963
        except ValueError:
 
4964
                settings.write("material error - \'%s\'!" %mat)
 
4965
        ob.colbits = 0x01 # Set OB materials.
 
4966
 
 
4967
 
 
4968
 
 
4969
def calcBulge(p1, p2, arc_res, triples=False):   #-------------------------------------------------
 
4970
        """given startpoint, endpoint and bulge of arc, returns points/segments of its representation.
 
4971
 
 
4972
        Needs to take into account bulge sign.
 
4973
        negative = clockwise
 
4974
        positive = counter-clockwise
 
4975
 
 
4976
        to find center given two points, and arc angle
 
4977
        calculate radius
 
4978
                Cord = sqrt(start^2 + end^2)
 
4979
                S = (bulge*Cord)/2
 
4980
                radius = ((Cord/2)^2+S^2)/2*S
 
4981
        angle of arc = 4*atan( bulge )
 
4982
        angle from p1 to center is (180-angle)/2
 
4983
        get vector pointing from p1 to p2 (p2 - p1)
 
4984
        normalize it and multiply by radius
 
4985
        rotate around p1 by angle to center, point to center.
 
4986
        start angle = angle between (center - p1) and worldX
 
4987
        end angle = angle between (center - p2) and worldX
 
4988
 
 
4989
        calculate the center, radius, start angle, and end angle
 
4990
        returns points/segments of its mesh representation
 
4991
        incl.startpoint, without endpoint
 
4992
        """
 
4993
 
 
4994
        bulge = p1.bulge
 
4995
        p1 = Mathutils.Vector(p1.loc)
 
4996
        p2 = Mathutils.Vector(p2.loc)
 
4997
        cord = p2 - p1 # vector from p1 to p2
 
4998
        clength = cord.length
 
4999
        s = (bulge * clength)/2.0 # sagitta (height)
 
5000
        radius = abs(((clength/2.0)**2.0 + s**2.0)/(2.0*s)) # magic formula
 
5001
        angle = (degrees(4.0*atan(bulge))) # theta (included angle)
 
5002
        radial = cord.normalize() * radius # a radius length vector aligned with cord
 
5003
        delta = (180.0 - abs(angle))/2.0 # the angle from cord to center
 
5004
        if bulge < 0: delta = -delta
 
5005
        rmat = Mathutils.RotationMatrix(-delta, 3, 'Z')
 
5006
        center = p1 + (rmat * radial) # rotate radial by delta degrees, then add to p1 to find center
 
5007
        #length = radians(abs(angle)) * radius
 
5008
        #print 'deb:calcBulge:\n angle, delta: ', angle, delta  #----------------
 
5009
        #print 'deb:center, radius: ', center, radius  #----------------------
 
5010
        startpoint = p1 - center
 
5011
        endpoint = p2 - center
 
5012
        #print 'deb:calcBulg: startpoint:', startpoint  #---------
 
5013
        #print 'deb:calcBulg: endpoint:', endpoint  #---------
 
5014
 
 
5015
        if not triples: #IF mesh-representation -----------
 
5016
                if arc_res > 1024: arc_res = 1024 
 
5017
                elif arc_res < 4: arc_res = 4 
 
5018
                pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION
 
5019
                if pieces < 3: pieces = 3
 
5020
        else:  #IF curve-representation -------------------------------
 
5021
                if arc_res > 32: arc_res = 32
 
5022
                elif arc_res < 3: arc_res = 3 
 
5023
                pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION
 
5024
                if pieces < 2: pieces = 2
 
5025
 
 
5026
        step = angle/pieces  # set step so pieces * step = degrees in arc
 
5027
        stepmatrix = Mathutils.RotationMatrix(-step, 3, "Z")
 
5028
 
 
5029
        if not triples: #IF mesh-representation -----------
 
5030
                points = [startpoint]
 
5031
                point = startpoint
 
5032
                for i in xrange(int(pieces)-1):  #fast (but not so acurate as: vector * RotMatrix(-step*i,3,"Z")
 
5033
                        point = stepmatrix * point
 
5034
                        points.append(point)
 
5035
                points = [ point+center for point in points]
 
5036
                # vector to point convertion:
 
5037
                points = [list(point) for point in points]
 
5038
                return points, list(center)
 
5039
 
 
5040
        else:  #IF curve-representation -------------------------------
 
5041
                # correct Bezier curves representation for free segmented circles/arcs
 
5042
                step2 = radians(step * 0.5)
 
5043
                bulg = radius * (1 - cos(step2))
 
5044
                deltaY = 4.0 * bulg / (3.0 * sin(step2) )
 
5045
                #print 'deb:calcArcCurve: bulg, deltaY:\n',  bulg, deltaY  #---------
 
5046
                #print 'deb:calcArcCurve: step:\n',  step  #---------
 
5047
 
 
5048
                #org handler0 = Mathutils.Vector(0.0, -deltaY, 0.0)
 
5049
                #handler = startmatrix * handler0
 
5050
                #endhandler = endmatrix * handler0
 
5051
                rotMatr90 = Mathutils.Matrix([0, -1, 0], [1, 0, 0], [0, 0, 1])
 
5052
                handler = rotMatr90 * startpoint
 
5053
                handler = - deltaY * handler.normalize()
 
5054
                endhandler = rotMatr90 * endpoint
 
5055
                endhandler = - deltaY * endhandler.normalize()
 
5056
        
 
5057
                points = [startpoint]
 
5058
                handlers1 = [startpoint + handler]
 
5059
                handlers2 = [startpoint - handler]
 
5060
                point = Mathutils.Vector(startpoint)
 
5061
                for i in xrange(int(pieces)-1):
 
5062
                        point = stepmatrix * point
 
5063
                        handler = stepmatrix * handler
 
5064
                        handler1 = point + handler
 
5065
                        handler2 = point - handler
 
5066
                        points.append(point)
 
5067
                        handlers1.append(handler1)
 
5068
                        handlers2.append(handler2)
 
5069
                points.append(endpoint)
 
5070
                handlers1.append(endpoint + endhandler)
 
5071
                handlers2.append(endpoint - endhandler)
 
5072
 
 
5073
                points = [point + center for point in points]
 
5074
                handlers1 = [point + center for point in handlers1]
 
5075
                handlers2 = [point + center for point in handlers2]
 
5076
 
 
5077
                VectorTriples = [list(h1)+list(p)+list(h2) for h1,p,h2 in zip(handlers1, points, handlers2)]
 
5078
                #print 'deb:calcBulgCurve: handlers1:\n', handlers1  #---------
 
5079
                #print 'deb:calcBulgCurve: points:\n', points  #---------
 
5080
                #print 'deb:calcBulgCurve: handlers2:\n', handlers2  #---------
 
5081
                #print 'deb:calcBulgCurve: VectorTriples:\n', VectorTriples  #---------
 
5082
                return VectorTriples
 
5083
 
 
5084
 
 
5085
        
 
5086
 
 
5087
def calcArc(center, radius, start, end, arc_res, triples):  #-----------------------------------------
 
5088
        """calculate Points (or BezierTriples) for ARC/CIRCLEs representation.
 
5089
        
 
5090
        Given parameters of the ARC/CIRCLE,
 
5091
        returns points/segments (or BezierTriples) and centerPoint
 
5092
        """
 
5093
        # center is currently set by object
 
5094
        # if start > end: start = start - 360
 
5095
        if end > 360: end = end % 360.0
 
5096
 
 
5097
        startmatrix = Mathutils.RotationMatrix(-start, 3, "Z")
 
5098
        startpoint = startmatrix * Mathutils.Vector(radius, 0, 0)
 
5099
        endmatrix = Mathutils.RotationMatrix(-end, 3, "Z")
 
5100
        endpoint = endmatrix * Mathutils.Vector(radius, 0, 0)
 
5101
 
 
5102
        if end < start: end +=360.0
 
5103
        angle = end - start
 
5104
        #length = radians(angle) * radius
 
5105
 
 
5106
        if not triples: #IF mesh-representation -----------
 
5107
                if arc_res > 1024: arc_res = 1024 
 
5108
                elif arc_res < 4: arc_res = 4 
 
5109
                pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION
 
5110
                if pieces < 3: pieces = 3
 
5111
                step = angle/pieces # set step so pieces * step = degrees in arc
 
5112
                stepmatrix = Mathutils.RotationMatrix(-step, 3, "Z")
 
5113
 
 
5114
                points = [startpoint]
 
5115
                point = startpoint
 
5116
                for i in xrange(int(pieces)-1):
 
5117
                        point = stepmatrix * point
 
5118
                        points.append(point)
 
5119
                points.append(endpoint)
 
5120
        
 
5121
                if center:
 
5122
                        centerVec = Mathutils.Vector(center)
 
5123
                        #points = [point + centerVec for point in points()]
 
5124
                        points = [point + centerVec for point in points]
 
5125
                # vector to point convertion:
 
5126
                points = [list(point) for point in points]
 
5127
                return points
 
5128
 
 
5129
        else:  #IF curve-representation ---------------
 
5130
                if arc_res > 32: arc_res = 32
 
5131
                elif arc_res < 3: arc_res = 3 
 
5132
                pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION
 
5133
                if pieces < 2: pieces = 2
 
5134
                step = angle/pieces # set step so pieces * step = degrees in arc
 
5135
                stepmatrix = Mathutils.RotationMatrix(-step, 3, "Z")
 
5136
 
 
5137
                # correct Bezier curves representation for free segmented circles/arcs
 
5138
                step2 = radians(step * 0.5)
 
5139
                bulg = radius * (1 - cos(step2))
 
5140
                deltaY = 4.0 * bulg / (3.0 * sin(step2) )
 
5141
                #print 'deb:calcArcCurve: bulg, deltaY:\n',  bulg, deltaY  #---------
 
5142
                #print 'deb:calcArcCurve: step:\n',  step  #---------
 
5143
                handler0 = Mathutils.Vector(0.0, -deltaY, 0.0)
 
5144
        
 
5145
                points = [startpoint]
 
5146
                handler = startmatrix * handler0
 
5147
                endhandler = endmatrix * handler0
 
5148
                handlers1 = [startpoint + handler]
 
5149
                handlers2 = [startpoint - handler]
 
5150
                point = Mathutils.Vector(startpoint)
 
5151
                for i in xrange(int(pieces)-1):
 
5152
                        point = stepmatrix * point
 
5153
                        handler = stepmatrix * handler
 
5154
                        handler1 = point + handler
 
5155
                        handler2 = point - handler
 
5156
                        points.append(point)
 
5157
                        handlers1.append(handler1)
 
5158
                        handlers2.append(handler2)
 
5159
                points.append(endpoint)
 
5160
                handlers1.append(endpoint + endhandler)
 
5161
                handlers2.append(endpoint - endhandler)
 
5162
                VectorTriples = [list(h1)+list(p)+list(h2) for h1,p,h2 in zip(handlers1, points, handlers2)]
 
5163
                #print 'deb:calcArcCurve: handlers1:\n', handlers1  #---------
 
5164
                #print 'deb:calcArcCurve: points:\n', points  #---------
 
5165
                #print 'deb:calcArcCurve: handlers2:\n', handlers2  #---------
 
5166
                #print 'deb:calcArcCurve: VectorTriples:\n', VectorTriples  #---------
 
5167
                return VectorTriples
 
5168
 
 
5169
 
 
5170
def drawCurveCircle(circle):  #--- no more used --------------------------------------------
 
5171
        """Given a dxf circle object return a blender circle object using curves.
 
5172
        """
 
5173
        c = Curve.New('circle') # create new  curve data
 
5174
        center = circle.loc
 
5175
        radius = circle.radius
 
5176
 
 
5177
        p1 = (0, -radius, 0)
 
5178
        p2 = (radius, 0, 0)
 
5179
        p3 = (0, radius, 0)
 
5180
        p4 = (-radius, 0, 0)
 
5181
 
 
5182
        p1 = BezTriple.New(p1)
 
5183
        p2 = BezTriple.New(p2)
 
5184
        p3 = BezTriple.New(p3)
 
5185
        p4 = BezTriple.New(p4)
 
5186
 
 
5187
        curve = c.appendNurb(p1)
 
5188
        curve.append(p2)
 
5189
        curve.append(p3)
 
5190
        curve.append(p4)
 
5191
        for point in curve:
 
5192
                point.handleTypes = [AUTO, AUTO]
 
5193
        curve.flagU = 1 # Set curve cyclic
 
5194
        c.update()
 
5195
 
 
5196
        ob = Object.New('Curve', 'circle')  # make curve object
 
5197
        return ob
 
5198
 
 
5199
 
 
5200
def drawCurveArc(self):  #---- only for ELLIPSE -------------------------------------------------------------
 
5201
        """Given a dxf ELLIPSE object return a blender_curve.
 
5202
        """
 
5203
        center = self.loc
 
5204
        radius = self.radius
 
5205
        start = self.start_angle
 
5206
        end = self.end_angle
 
5207
 
 
5208
        if start > end:
 
5209
                start = start - 360.0
 
5210
        startmatrix = Mathutils.RotationMatrix(start, 3, "Z")
 
5211
        startpoint = startmatrix * Mathutils.Vector((radius, 0, 0))
 
5212
        endmatrix = Mathutils.RotationMatrix(end, 3, "Z")
 
5213
        endpoint = endmatrix * Mathutils.Vector((radius, 0, 0))
 
5214
        # Note: handles must be tangent to arc and of correct length...
 
5215
 
 
5216
        a = Curve.New('arc')                     # create new  curve data
 
5217
 
 
5218
        p1 = (0, -radius, 0)
 
5219
        p2 = (radius, 0, 0)
 
5220
        p3 = (0, radius, 0)
 
5221
        p4 = (-radius, 0, 0)
 
5222
 
 
5223
        p1 = BezTriple.New(p1)
 
5224
        p2 = BezTriple.New(p2)
 
5225
        p3 = BezTriple.New(p3)
 
5226
        p4 = BezTriple.New(p4)
 
5227
 
 
5228
        curve = a.appendNurb(p1)
 
5229
        curve.append(p2)
 
5230
        curve.append(p3)
 
5231
        curve.append(p4)
 
5232
        for point in curve:
 
5233
                point.handleTypes = [AUTO, AUTO]
 
5234
        curve.flagU = 1 # Set curve cyclic
 
5235
        a.update()
 
5236
 
 
5237
        ob = Object.New('Curve', 'arc') # make curve object
 
5238
        return ob
 
5239
 
 
5240
 
 
5241
 
 
5242
 
 
5243
# GUI STUFF -----#################################################-----------------
 
5244
from Blender.BGL import *
 
5245
 
 
5246
EVENT_NONE = 1
 
5247
EVENT_START = 2
 
5248
EVENT_REDRAW = 3
 
5249
EVENT_LOAD_INI = 4
 
5250
EVENT_SAVE_INI = 5
 
5251
EVENT_RESET = 6
 
5252
EVENT_CHOOSE_INI = 7
 
5253
EVENT_CHOOSE_DXF = 8
 
5254
EVENT_HELP = 9
 
5255
EVENT_PRESETCURV = 10
 
5256
EVENT_PRESETS = 11
 
5257
EVENT_DXF_DIR = 12
 
5258
#         = 13
 
5259
EVENT_LIST = 14
 
5260
EVENT_ORIGIN = 15
 
5261
EVENT_SCALE = 16
 
5262
EVENT_PRESET2D = 20
 
5263
EVENT_PRESET3D = 21
 
5264
EVENT_EXIT = 100
 
5265
GUI_EVENT = EVENT_NONE
 
5266
 
 
5267
GUI_A = {}  # GUI-buttons dictionary for parameter
 
5268
GUI_B = {}  # GUI-buttons dictionary for drawingTypes
 
5269
 
 
5270
# settings default, initialize ------------------------
 
5271
 
 
5272
points_as_menu  = "convert to: %t|empty %x1|mesh.vertex %x2|thin sphere %x3|thin box %x4|*curve.vertex %x5"
 
5273
lines_as_menu   = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|thin box %x4|Bezier-curve %x5|NURBS-curve %x6"
 
5274
mlines_as_menu  = "convert to: %t|*edge %x1|*mesh %x2|*thin cylinder %x3|*thin box %x|*curve %x5"
 
5275
plines_as_menu  = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|*thin box %x4|Bezier-curve %x5|NURBS-curve %x6"
 
5276
splines_as_menu = "convert to: %t|mesh %x2|*thin cylinder %x3|*thin box %x4|Bezier-curve %x5|NURBS-curve %x6"
 
5277
plines3_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|*thin box %x4|Bezier-curve %x5|NURBS-curve %x6"
 
5278
plmesh_as_menu  = "convert to: %t|*edge %x1|mesh %x2|NURBS-surface %x6"
 
5279
solids_as_menu  = "convert to: %t|*edge %x1|mesh %x2"
 
5280
blocks_as_menu  = "convert to: %t|dupliGroup %x1|*real.Group %x2|*exploded %x3"
 
5281
texts_as_menu   = "convert to: %t|text %x1|*mesh %x2|*curve %x5"
 
5282
material_from_menu= "material from: %t|*LINESTYLE %x7|COLOR %x1|LAYER %x2|*LAYER+COLOR %x3|*BLOCK %x4|*XDATA %x5|*INI-File %x6"
 
5283
g_scale_list    = ''.join((
 
5284
        'scale factor: %t',
 
5285
        '|user def. %x12',
 
5286
        '|yard to m %x8',
 
5287
        '|feet to m %x7',
 
5288
        '|inch to m %x6',
 
5289
        '|  x  1000 %x3',
 
5290
        '|  x  100 %x2',
 
5291
        '|  x  10 %x1',
 
5292
        '|  x  1 %x0',
 
5293
        '|  x  0.1 %x-1',
 
5294
        '|  x  0.01 %x-2',
 
5295
        '|  x  0.001 %x-3',
 
5296
        '|  x  0.0001 %x-4',
 
5297
        '|  x  0.00001 %x-5'))
 
5298
 
 
5299
#print 'deb:  g_scale_list', g_scale_list #-----------
 
5300
 
 
5301
dxfFileName = Draw.Create("")
 
5302
iniFileName = Draw.Create(INIFILE_DEFAULT_NAME + INIFILE_EXTENSION)
 
5303
user_preset = 0
 
5304
config_UI = Draw.Create(0)   #switch_on/off extended config_UI
 
5305
g_scale_as = Draw.Create(int(log10(G_SCALE)))
 
5306
 
 
5307
 
 
5308
keywords_org = {
 
5309
        'curves_on' : 0,
 
5310
        'optimization': 2,
 
5311
        'one_mesh_on': 1,
 
5312
        'vGroup_on' : 1,
 
5313
        'dummy_on' : 0,
 
5314
        'views_on' : 0,
 
5315
        'cams_on'  : 0,
 
5316
        'lights_on' : 0,
 
5317
        'xref_on' : 1,
 
5318
        'block_nn': 0,
 
5319
        'blockFilter_on': 0,
 
5320
        'layerFilter_on': 0,
 
5321
        'colorFilter_on': 0,
 
5322
        'groupFilter_on': 0,
 
5323
        'newScene_on' : 1,
 
5324
        'target_layer' : TARGET_LAYER,
 
5325
        'group_bylayer_on' : GROUP_BYLAYER,
 
5326
        'g_originX'   : G_ORIGIN_X,
 
5327
        'g_originY'   : G_ORIGIN_Y,
 
5328
        'g_originZ'   : G_ORIGIN_Z,
 
5329
        'g_origin_on': 0,
 
5330
        'g_scale'   : float(G_SCALE),
 
5331
#       'g_scale_as': int(log10(G_SCALE)), #   0,
 
5332
        'g_scale_on': 0,
 
5333
        'thick_on'  : 1,
 
5334
        'thick_min' : float(MIN_THICK),
 
5335
        'thick_force': 0,
 
5336
        'width_on'  : 1,
 
5337
        'width_min' : float(MIN_WIDTH),
 
5338
        'width_force': 0,
 
5339
        'dist_on'   : 1,
 
5340
        'dist_min'  : float(MIN_DIST),
 
5341
        'dist_force': 0,
 
5342
        'material_on': 1,
 
5343
        'material_from': 2,
 
5344
        'fill_on'       : 1,
 
5345
        'meshSmooth_on': 1,
 
5346
        'curve_res' : CURV_RESOLUTION,
 
5347
        'curve_arc' : CURVARC_RESOLUTION,
 
5348
        'arc_res'   : ARC_RESOLUTION,
 
5349
        'arc_rad'   : ARC_RADIUS,
 
5350
        'thin_res'  : THIN_RESOLUTION,
 
5351
        'pl_trim_max' : TRIM_LIMIT,
 
5352
        'pl_trim_on': 1,
 
5353
        'plmesh_flip': 0,
 
5354
        'normals_out': 0,
 
5355
        'paper_space_on': 0,
 
5356
        'layFrozen_on': 0,
 
5357
        'Z_force_on': 0,
 
5358
        'Z_elev': float(ELEVATION),
 
5359
        'points_as' : 2,
 
5360
        'lines_as'  : 2,
 
5361
        'mlines_as' : 2,
 
5362
        'plines_as' : 2,
 
5363
        'splines_as' : 5,
 
5364
        'plines3_as': 2,
 
5365
        'plmesh_as' : 2,
 
5366
        'solids_as' : 2,
 
5367
        'blocks_as' : 1,
 
5368
        'texts_as'  : 1
 
5369
        }
 
5370
 
 
5371
drawTypes_org = {
 
5372
        'point' : 1,
 
5373
        'line'  : 1,
 
5374
        'arc'   : 1,
 
5375
        'circle': 1,
 
5376
        'ellipse': 1,
 
5377
        'mline' : 0,
 
5378
        'polyline': 1,
 
5379
        'spline': 1,
 
5380
        'plmesh': 1,
 
5381
        'pline3': 1,
 
5382
        'lwpolyline': 1,
 
5383
        'text'  : 1,
 
5384
        'mtext' : 0,
 
5385
        'block' : 1,
 
5386
        'insert': 1,
 
5387
        'solid' : 1,
 
5388
        'trace' : 1,
 
5389
        'face'  : 1,
 
5390
#       'view' : 0,
 
5391
        }
 
5392
 
 
5393
# creating of GUI-buttons
 
5394
# GUI_A - GUI-buttons dictionary for parameter
 
5395
# GUI_B - GUI-buttons dictionary for drawingTypes
 
5396
for k, v in keywords_org.iteritems():
 
5397
        GUI_A[k] = Draw.Create(v)
 
5398
for k, v in drawTypes_org.iteritems():
 
5399
        GUI_B[k] = Draw.Create(v)
 
5400
#print 'deb:init GUI_A: ', GUI_A #---------------
 
5401
#print 'deb:init GUI_B: ', GUI_B #---------------
 
5402
 
 
5403
model_space_on = Draw.Create(1)
 
5404
 
 
5405
# initialize settings-object controls how dxf entities are drawn
 
5406
settings = Settings(keywords_org, drawTypes_org)
 
5407
 
 
5408
 
 
5409
def update_RegistryKey(key, item): #
 
5410
        """updates key in Blender.Registry
 
5411
        """
 
5412
        cache = True # data is also saved to a file
 
5413
        rdict = Registry.GetKey('DXF_Importer', cache)
 
5414
        if not rdict: rdict = {}
 
5415
        if item:
 
5416
                rdict[key] = item
 
5417
                Registry.SetKey('DXF_Importer', rdict, cache)
 
5418
                #print  'deb:update_RegistryKey rdict', rdict #---------------
 
5419
 
 
5420
 
 
5421
def check_RegistryKey(key):
 
5422
        """ check if the key is already there (saved on a previous execution of this script)
 
5423
        """
 
5424
        cache = True # data is also saved to a file
 
5425
        rdict = Registry.GetKey('DXF_Importer', cache)
 
5426
        #print 'deb:check_RegistryKey  rdict:', rdict #----------------
 
5427
        if rdict: # if found, get the values saved there
 
5428
                try:
 
5429
                        item = rdict[key]
 
5430
                        return item
 
5431
                except:
 
5432
                        #update_RegistryKey() # if data isn't valid rewrite it
 
5433
                        pass
 
5434
 
 
5435
def saveConfig():  #--todo-----------------------------------------------
 
5436
        """Save settings/config/materials from GUI to INI-file.
 
5437
 
 
5438
        Write all config data to INI-file.
 
5439
        """
 
5440
        global iniFileName
 
5441
 
 
5442
        iniFile = iniFileName.val
 
5443
        #print 'deb:saveConfig inifFile: ', inifFile #----------------------
 
5444
        if iniFile.lower().endswith(INIFILE_EXTENSION):
 
5445
 
 
5446
                #--todo-- sort key.list for output
 
5447
                #key_list = GUI_A.keys().val
 
5448
                #key_list.sort()
 
5449
                #for key in key_list:
 
5450
                #       l_name, l_data = key, GUI_A[key].val
 
5451
                #       list_A
 
5452
 
 
5453
                output_str = '[%s,%s]' %(GUI_A, GUI_B)
 
5454
                if output_str =='None':
 
5455
                        Draw.PupMenu('DXF importer: INI-file:  Alert!%t|no config-data present to save!')
 
5456
                else:
 
5457
                        #if BPyMessages.Warning_SaveOver(iniFile): #<- remi find it too abstarct
 
5458
                        if sys.exists(iniFile):
 
5459
                                try:
 
5460
                                        f = file(iniFile, 'r')
 
5461
                                        try: header_str = f.readline()
 
5462
                                        finally: f.close()
 
5463
                                except: pass
 
5464
                                if header_str.startswith(INIFILE_HEADER[0:13]):
 
5465
                                        if Draw.PupMenu('  OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile) == 1:
 
5466
                                                save_ok = True
 
5467
                                        else: save_ok = False
 
5468
                                elif Draw.PupMenu('  OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile +
 
5469
                                         '|Alert: this file has no valid ImportDXF-header| ! it may belong to another aplication !') == 1:
 
5470
                                        save_ok = True
 
5471
                                else: save_ok = False
 
5472
                        else: save_ok = True
 
5473
 
 
5474
                        if save_ok:
 
5475
                                # replace: ',' -> ',\n'
 
5476
                                # replace: '{' -> '\n{\n'
 
5477
                                # replace: '}' -> '\n}\n'
 
5478
                                output_str = ',\n'.join(output_str.split(','))
 
5479
                                output_str = '\n}'.join(output_str.split('}'))
 
5480
                                output_str = '{\n'.join(output_str.split('{'))
 
5481
                                try:
 
5482
                                        f = file(iniFile, 'w')
 
5483
                                        try:
 
5484
                                                f.write(INIFILE_HEADER + '\n# this is a comment line\n')
 
5485
                                                f.write(output_str)
 
5486
                                        finally: f.close()
 
5487
                                        #Draw.PupMenu('DXF importer: INI-file: Done!%t|config-data saved in ' + '\'%s\'' %iniFile)
 
5488
                                except:
 
5489
                                        Draw.PupMenu('DXF importer: INI-file: Error!%t|failure by writing to ' + '\'%s\'|no config-data saved!' %iniFile)
 
5490
 
 
5491
        else:
 
5492
                Draw.PupMenu('DXF importer: INI-file:  Alert!%t|no valid name/extension for INI-file selected!')
 
5493
                print "DXF importer: Alert!: no valid INI-file selected."
 
5494
                if not iniFile:
 
5495
                        if dxfFileName.val.lower().endswith('.dxf'):
 
5496
                                iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
 
5497
 
 
5498
 
 
5499
def loadConfig():  #remi--todo-----------------------------------------------
 
5500
        """Load settings/config/materials from INI-file.
 
5501
 
 
5502
        Read material-assignements from config-file.
 
5503
        """
 
5504
        #070724 buggy Window.FileSelector(loadConfigFile, 'Load config data from INI-file', inifilename)
 
5505
        global iniFileName, GUI_A, GUI_B
 
5506
 
 
5507
        iniFile = iniFileName.val
 
5508
        update_RegistryKey('iniFileName', iniFile)
 
5509
        #print 'deb:loadConfig iniFile: ', iniFile #----------------------
 
5510
        if iniFile.lower().endswith(INIFILE_EXTENSION) and sys.exists(iniFile):
 
5511
                try:
 
5512
                        f = file(iniFile, 'r')
 
5513
                        try:
 
5514
                                header_str = f.readline()
 
5515
                                if header_str.startswith(INIFILE_HEADER):
 
5516
                                        data_str = f.read()
 
5517
                                        f.close()
 
5518
                                        #print 'deb:loadConfig data_str from %s: \n' %iniFile , data_str #-----------------
 
5519
                                        data = eval(data_str)
 
5520
                                        for k, v in data[0].iteritems():
 
5521
                                                try: GUI_A[k].val = v
 
5522
                                                except: GUI_A[k] = Draw.Create(v)
 
5523
                                        for k, v in data[1].iteritems():
 
5524
                                                try: GUI_B[k].val = v
 
5525
                                                except: GUI_B[k] = Draw.Create(v)
 
5526
                                else:
 
5527
                                        Draw.PupMenu('DXF importer: INI-file:  Alert!%t|no valid header in INI-file: ' + '\'%s\'' %iniFile)
 
5528
                        finally: f.close()
 
5529
                except: pass
 
5530
        else:
 
5531
                Draw.PupMenu('DXF importer: INI-file:  Alert!%t|no valid INI-file selected!')
 
5532
                print "DXF importer: Alert!: no valid INI-file selected."
 
5533
                if not iniFileName:
 
5534
                        if dxfFileName.val.lower().endswith('.dxf'):
 
5535
                                iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
 
5536
 
 
5537
 
 
5538
 
 
5539
def updateConfig(keywords, drawTypes):  #-----------------------------------------------
 
5540
        """updates GUI_settings with given dictionaries
 
5541
 
 
5542
        """
 
5543
        global GUI_A, GUI_B
 
5544
        #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
 
5545
        for k, v in keywords.iteritems():
 
5546
                GUI_A[k].val = v
 
5547
        for k, v in drawTypes.iteritems():
 
5548
                GUI_B[k].val = v
 
5549
 
 
5550
def resetDefaultConfig():  #-----------------------------------------------
 
5551
        """Resets settings/config/materials to defaults.
 
5552
 
 
5553
        """
 
5554
        #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
 
5555
        updateConfig(keywords_org, drawTypes_org)
 
5556
 
 
5557
 
 
5558
def presetConfig_curv(activate):  #-----------------------------------------------
 
5559
        """Sets settings/config/materials for curve representation.
 
5560
 
 
5561
        """
 
5562
        global GUI_A
 
5563
        if activate:
 
5564
                GUI_A['curves_on'].val = 1
 
5565
                GUI_A['points_as'].val = 5
 
5566
                GUI_A['lines_as'].val  = 5
 
5567
                GUI_A['mlines_as'].val = 5
 
5568
                GUI_A['plines_as'].val = 5
 
5569
                GUI_A['splines_as'].val = 5
 
5570
                GUI_A['plines3_as'].val = 5
 
5571
        else:
 
5572
                GUI_A['curves_on'].val = 0
 
5573
                GUI_A['points_as'].val = 2
 
5574
                GUI_A['lines_as'].val  = 2
 
5575
                GUI_A['mlines_as'].val = 2
 
5576
                GUI_A['plines_as'].val = 2
 
5577
                GUI_A['splines_as'].val = 6
 
5578
                GUI_A['plines3_as'].val = 2
 
5579
 
 
5580
        
 
5581
def resetDefaultConfig_2D():  #-----------------------------------------------
 
5582
        """Sets settings/config/materials to defaults 2D.
 
5583
 
 
5584
        """
 
5585
        presetConfig_curv(1)
 
5586
        keywords2d = {
 
5587
                'views_on' : 0,
 
5588
                'cams_on'  : 0,
 
5589
                'lights_on' : 0,
 
5590
                'vGroup_on' : 1,
 
5591
                'thick_on'  : 0,
 
5592
                'thick_force': 0,
 
5593
                'width_on'  : 1,
 
5594
                'width_force': 0,
 
5595
                'dist_on'   : 1,
 
5596
                'dist_force': 0,
 
5597
                'fill_on'       : 0,
 
5598
                'pl_trim_on': 1,
 
5599
                'Z_force_on': 0,
 
5600
                'meshSmooth_on': 0,
 
5601
                'solids_as' : 2,
 
5602
                'blocks_as' : 1,
 
5603
                'texts_as'  : 1
 
5604
                }
 
5605
 
 
5606
        drawTypes2d = {
 
5607
                'point' : 1,
 
5608
                'line'  : 1,
 
5609
                'arc'   : 1,
 
5610
                'circle': 1,
 
5611
                'ellipse': 1,
 
5612
                'mline' : 0,
 
5613
                'polyline': 1,
 
5614
                'spline': 1,
 
5615
                'plmesh': 0,
 
5616
                'pline3': 1,
 
5617
                'lwpolyline': 1,
 
5618
                'text'  : 1,
 
5619
                'mtext' : 0,
 
5620
                'block' : 1,
 
5621
                'insert': 1,
 
5622
                'solid' : 1,
 
5623
                'trace' : 1,
 
5624
                'face'  : 0,
 
5625
#               'view' : 0,
 
5626
                }
 
5627
 
 
5628
        updateConfig(keywords2d, drawTypes2d)
 
5629
 
 
5630
def resetDefaultConfig_3D():  #-----------------------------------------------
 
5631
        """Sets settings/config/materials to defaults 3D.
 
5632
 
 
5633
        """
 
5634
        presetConfig_curv(0)
 
5635
        keywords3d = {
 
5636
#               'views_on' : 1,
 
5637
#               'cams_on'  : 1,
 
5638
#               'lights_on' : 1,
 
5639
                'vGroup_on' : 1,
 
5640
                'thick_on'  : 1,
 
5641
                'thick_force': 0,
 
5642
                'width_on'  : 1,
 
5643
                'width_force': 0,
 
5644
                'dist_on'   : 1,
 
5645
                'dist_force': 0,
 
5646
                'fill_on'       : 1,
 
5647
                'pl_trim_on': 1,
 
5648
                'Z_force_on': 0,
 
5649
                'meshSmooth_on': 1,
 
5650
                'solids_as' : 2,
 
5651
                'blocks_as' : 1,
 
5652
                'texts_as'  : 1
 
5653
                }
 
5654
 
 
5655
        drawTypes3d = {
 
5656
                'point' : 1,
 
5657
                'line'  : 1,
 
5658
                'arc'   : 1,
 
5659
                'circle': 1,
 
5660
                'ellipse': 1,
 
5661
                'mline' : 0,
 
5662
                'polyline': 1,
 
5663
                'spline': 1,
 
5664
                'plmesh': 1,
 
5665
                'pline3': 1,
 
5666
                'lwpolyline': 1,
 
5667
                'text'  : 0,
 
5668
                'mtext' : 0,
 
5669
                'block' : 1,
 
5670
                'insert': 1,
 
5671
                'solid' : 1,
 
5672
                'trace' : 1,
 
5673
                'face'  : 1,
 
5674
#               'view' : 0,
 
5675
                }
 
5676
 
 
5677
        updateConfig(keywords3d, drawTypes3d)
 
5678
 
 
5679
 
 
5680
def     inputGlobalScale():
 
5681
        """Pop-up UI-Block for global scale factor
 
5682
        """
 
5683
        global GUI_A
 
5684
        #print 'deb:inputGlobalScale ##########' #------------
 
5685
        x_scale = Draw.Create(GUI_A['g_scale'].val)
 
5686
        block = []
 
5687
        #block.append("global translation vector:")
 
5688
        block.append(("", x_scale, 0.0, 10000000.0))
 
5689
 
 
5690
        retval = Draw.PupBlock("set global scale factor:", block)
 
5691
 
 
5692
        GUI_A['g_scale'].val = float(x_scale.val)
 
5693
 
 
5694
        
 
5695
def     inputOriginVector():
 
5696
        """Pop-up UI-Block for global translation vector
 
5697
        """
 
5698
        global GUI_A
 
5699
        #print 'deb:inputOriginVector ##########' #------------
 
5700
        x_origin = Draw.Create(GUI_A['g_originX'].val)
 
5701
        y_origin = Draw.Create(GUI_A['g_originY'].val)
 
5702
        z_origin = Draw.Create(GUI_A['g_originZ'].val)
 
5703
        block = []
 
5704
        #block.append("global translation vector:")
 
5705
        block.append(("X: ", x_origin, -100000000.0, 100000000.0))
 
5706
        block.append(("Y: ", y_origin, -100000000.0, 100000000.0))
 
5707
        block.append(("Z: ", z_origin, -100000000.0, 100000000.0))
 
5708
 
 
5709
        retval = Draw.PupBlock("set global translation vector:", block)
 
5710
 
 
5711
        GUI_A['g_originX'].val = x_origin.val
 
5712
        GUI_A['g_originY'].val = y_origin.val
 
5713
        GUI_A['g_originZ'].val = z_origin.val
 
5714
 
 
5715
 
 
5716
def draw_UI():  #-----------------------------------------------------------------
 
5717
        """ Draw startUI and setup Settings.
 
5718
        """
 
5719
        global GUI_A, GUI_B #__version__
 
5720
        global user_preset, iniFileName, dxfFileName, config_UI, g_scale_as
 
5721
        global model_space_on
 
5722
 
 
5723
        # This is for easy layout changes
 
5724
        but_0c = 70  #button 1.column width
 
5725
        but_1c = 70  #button 1.column width
 
5726
        but_2c = 70  #button 2.column
 
5727
        but_3c = 70  #button 3.column
 
5728
        menu_margin = 10
 
5729
        butt_margin = 10
 
5730
        menu_w = (3 * butt_margin) + but_0c + but_1c + but_2c + but_3c  #menu width
 
5731
 
 
5732
        simple_menu_h = 100
 
5733
        extend_menu_h = 350
 
5734
        y = simple_menu_h                # y is menu upper.y
 
5735
        if config_UI.val: y += extend_menu_h
 
5736
        x = 20 #menu left.x
 
5737
        but0c = x + menu_margin  #buttons 0.column position.x
 
5738
        but1c = but0c + but_0c + butt_margin
 
5739
        but2c = but1c + but_1c + butt_margin
 
5740
        but3c = but2c + but_2c + butt_margin
 
5741
        but4c = but3c + but_3c
 
5742
 
 
5743
        # Here starts menu -----------------------------------------------------
 
5744
        #glClear(GL_COLOR_BUFFER_BIT)
 
5745
        #glRasterPos2d(8, 125)
 
5746
 
 
5747
        y += 30
 
5748
        colorbox(x, y+20, x+menu_w+menu_margin*2, menu_margin)
 
5749
        Draw.Label("DXF-Importer  v" + __version__, but0c, y, menu_w, 20)
 
5750
 
 
5751
        if config_UI.val:
 
5752
                b0, b0_ = but0c, but_0c + butt_margin
 
5753
                b1, b1_ = but1c, but_1c
 
5754
                y_top = y
 
5755
 
 
5756
                y -= 10
 
5757
                y -= 20
 
5758
                Draw.BeginAlign()
 
5759
                GUI_B['point'] = Draw.Toggle('POINT', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['point'].val, "support dxf-POINT on/off")
 
5760
                if GUI_B['point'].val:
 
5761
                        GUI_A['points_as'] = Draw.Menu(points_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['points_as'].val, "select target Blender-object")
 
5762
#               Draw.Label('-->', but2c, y, but_2c, 20)
 
5763
                Draw.EndAlign()
 
5764
 
 
5765
                y -= 20
 
5766
                Draw.BeginAlign()
 
5767
                GUI_B['line'] = Draw.Toggle('LINE...etc', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['line'].val, "support dxf-LINE,ARC,CIRCLE,ELLIPSE on/off")
 
5768
                if GUI_B['line'].val:
 
5769
                        GUI_A['lines_as'] = Draw.Menu(lines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['lines_as'].val, "select target Blender-object")
 
5770
                Draw.EndAlign()
 
5771
 
 
5772
                y -= 20
 
5773
                Draw.BeginAlign()
 
5774
                GUI_B['mline'] = Draw.Toggle('*MLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['mline'].val, "(*wip)support dxf-MLINE on/off")
 
5775
                if GUI_B['mline'].val:
 
5776
                        GUI_A['mlines_as'] = Draw.Menu(mlines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['mlines_as'].val, "select target Blender-object")
 
5777
                Draw.EndAlign()
 
5778
 
 
5779
                y -= 20
 
5780
                Draw.BeginAlign()
 
5781
                GUI_B['spline'] = Draw.Toggle('SPLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['spline'].val, "support dxf-SPLINE on/off")
 
5782
                if GUI_B['spline'].val:
 
5783
                        GUI_A['splines_as'] = Draw.Menu(splines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['splines_as'].val, "select target Blender-object")
 
5784
                Draw.EndAlign()
 
5785
 
 
5786
                y -= 20
 
5787
                Draw.BeginAlign()
 
5788
                GUI_B['polyline'] = Draw.Toggle('2D/LWPLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['polyline'].val, "support dxf-2D-POLYLINE on/off")
 
5789
                if GUI_B['polyline'].val:
 
5790
                        GUI_A['plines_as'] = Draw.Menu(plines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plines_as'].val, "select target Blender-object")
 
5791
                Draw.EndAlign()
 
5792
 
 
5793
                y -= 20
 
5794
                Draw.BeginAlign()
 
5795
                GUI_B['pline3'] = Draw.Toggle('3D-PLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['pline3'].val, "support dxf-3D-POLYLINE on/off")
 
5796
                if GUI_B['pline3'].val:
 
5797
                        GUI_A['plines3_as'] = Draw.Menu(plines3_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plines3_as'].val, "select target Blender-object")
 
5798
                Draw.EndAlign()
 
5799
 
 
5800
                y_down = y
 
5801
                # -----------------------------------------------
 
5802
 
 
5803
                y = y_top
 
5804
                b0, b0_ = but2c, but_2c + butt_margin
 
5805
                b1, b1_ = but3c, but_3c
 
5806
 
 
5807
                y -= 10
 
5808
                y -= 20
 
5809
                Draw.BeginAlign()
 
5810
                GUI_B['plmesh'] = Draw.Toggle('PL-MESH/FACE', EVENT_NONE, b0, y, b0_+b1_-40, 20, GUI_B['plmesh'].val, "support dxf-POLYMESH/POLYFACE on/off")
 
5811
#               GUI_A['plmesh_as'] = Draw.Menu(plmesh_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plmesh_as'].val, "select target Blender-object")
 
5812
                GUI_A['plmesh_flip'] = Draw.Toggle('N', EVENT_NONE, b1+b1_-40, y, 20, 20, GUI_A['plmesh_flip'].val, "flip DXF normals on/off")
 
5813
                GUI_A['normals_out'] = Draw.Toggle('N', EVENT_NONE, b1+b1_-20, y, 20, 20, GUI_A['normals_out'].val, "force Blender normals to outside on/off")
 
5814
                Draw.EndAlign()
 
5815
 
 
5816
                y -= 20
 
5817
                GUI_B['solid'] = Draw.Toggle('SOLID', EVENT_NONE, b0, y, b0_, 20, GUI_B['solid'].val, "support dxf-SOLID and TRACE on/off")
 
5818
                GUI_B['face'] = Draw.Toggle('3DFACE', EVENT_NONE, b1, y, b1_, 20, GUI_B['face'].val, "support dxf-3DFACE on/off")
 
5819
#               GUI_A['solids_as'] = Draw.Menu(solids_as_menu, EVENT_NONE, but3c, y, but_3c, 20, GUI_A['solids_as'].val, "select target Blender-object")
 
5820
                #print 'deb:support solid, trace', GUI_B['trace'].val, GUI_B['solid'].val # ------------
 
5821
 
 
5822
 
 
5823
                y -= 20
 
5824
                GUI_B['text'] = Draw.Toggle('TEXT', EVENT_NONE, b0, y, b0_, 20, GUI_B['text'].val, "support dxf-TEXT on/off")
 
5825
                GUI_B['mtext'] = Draw.Toggle('*MTEXT', EVENT_NONE, b1, y, b1_, 20, GUI_B['mtext'].val, "(*wip)support dxf-MTEXT on/off")
 
5826
#               GUI_A['texts_as'] = Draw.Menu(texts_as_menu, EVENT_NONE, but3c, y, but_3c, 20, GUI_A['texts_as'].val, "select target Blender-object")
 
5827
 
 
5828
                y -= 20
 
5829
                Draw.BeginAlign()
 
5830
                GUI_B['block'] = Draw.Toggle('BLOCK', EVENT_REDRAW, b0, y, b0_-30, 20, GUI_B['block'].val, "support dxf-BLOCK and ARRAY on/off")
 
5831
                GUI_B['insert'].val = GUI_B['block'].val
 
5832
                if GUI_B['block'].val:
 
5833
                        GUI_A['block_nn'] = Draw.Toggle('n', EVENT_NONE, b1-30, y, 15, 20, GUI_A['block_nn'].val, "support hatch/noname BLOCKs *X... on/off")
 
5834
                        GUI_A['xref_on'] = Draw.Toggle('Xref', EVENT_NONE, b1-15, y, 35, 20, GUI_A['xref_on'].val, "support for XREF-BLOCKs (place holders) on/off")
 
5835
                        GUI_A['blocks_as'] = Draw.Menu(blocks_as_menu, EVENT_NONE, b1+20, y, b1_-20, 20, GUI_A['blocks_as'].val, "select target representation for imported BLOCKs")
 
5836
                Draw.EndAlign()
 
5837
 
 
5838
 
 
5839
                y -= 20
 
5840
                y -= 20
 
5841
                
 
5842
                Draw.BeginAlign()
 
5843
                GUI_A['views_on'] = Draw.Toggle('views', EVENT_NONE, b0, y, b0_-25, 20, GUI_A['views_on'].val, "imports VIEWs and VIEWPORTs as cameras on/off")
 
5844
                GUI_A['cams_on'] = Draw.Toggle('*cams', EVENT_NONE, b1-25, y, b1_-25, 20, GUI_A['cams_on'].val, "(*wip) support ASHADE cameras on/off")
 
5845
                GUI_A['lights_on'] = Draw.Toggle('*lights', EVENT_NONE, b1+25, y, b1_-25, 20, GUI_A['lights_on'].val, "(*wip) support AVE_RENDER lights on/off")
 
5846
                Draw.EndAlign()
 
5847
 
 
5848
 
 
5849
                if y < y_down: y_down = y
 
5850
                # -----end supported objects--------------------------------------
 
5851
 
 
5852
                y_top = y_down
 
5853
                y = y_top
 
5854
                y -= 10
 
5855
                y -= 20
 
5856
                but_ = menu_w / 6
 
5857
                b0 = but0c + (menu_w - but_*6)/2
 
5858
                Draw.BeginAlign()
 
5859
                GUI_A['paper_space_on'] = Draw.Toggle('paper', EVENT_NONE, b0+but_*0, y, but_, 20, GUI_A['paper_space_on'].val, "import only from Paper-Space on/off")
 
5860
                GUI_A['layFrozen_on'] = Draw.Toggle ('frozen', EVENT_NONE, b0+but_*1, y, but_, 20, GUI_A['layFrozen_on'].val, "import also from frozen LAYERs on/off")
 
5861
                GUI_A['layerFilter_on'] = Draw.Toggle('layer', EVENT_NONE, b0+but_*2, y, but_, 20, GUI_A['layerFilter_on'].val, "(*wip) LAYER filtering on/off")
 
5862
                GUI_A['colorFilter_on'] = Draw.Toggle('color', EVENT_NONE, b0+but_*3, y, but_, 20, GUI_A['colorFilter_on'].val, "(*wip) COLOR filtering on/off")
 
5863
                GUI_A['groupFilter_on'] = Draw.Toggle('group', EVENT_NONE, b0+but_*4, y, but_, 20, GUI_A['groupFilter_on'].val, "(*wip) GROUP filtering on/off")
 
5864
                GUI_A['blockFilter_on'] = Draw.Toggle('block', EVENT_NONE, b0+but_*5, y, but_, 20, GUI_A['blockFilter_on'].val, "(*wip) BLOCK filtering on/off")
 
5865
                #GUI_A['dummy_on'] = Draw.Toggle('-', EVENT_NONE, but3c, y, but_3c, 20, GUI_A['dummy_on'].val, "dummy on/off")
 
5866
                Draw.EndAlign()
 
5867
 
 
5868
                # -----end filters--------------------------------------
 
5869
 
 
5870
                b0, b0_ = but0c, but_0c + butt_margin
 
5871
                b1, b1_ = but1c, but_1c
 
5872
 
 
5873
                y -= 10
 
5874
                y -= 20
 
5875
                Draw.BeginAlign()
 
5876
                GUI_A['g_origin_on'] = Draw.Toggle('glob.reLoc', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_origin_on'].val, "global relocate all DXF objects on/off")
 
5877
                if GUI_A['g_origin_on'].val:
 
5878
                        tmp = Draw.PushButton('=', EVENT_ORIGIN, b1, y, 20, 20, "edit relocation-vector (x,y,z in DXF units)")
 
5879
                        origin_str = '(%.4f, %.4f, %.4f)'  % (
 
5880
                                GUI_A['g_originX'].val,
 
5881
                                GUI_A['g_originY'].val,
 
5882
                                GUI_A['g_originZ'].val
 
5883
                                )
 
5884
                        tmp = Draw.Label(origin_str, b1+20, y, 300, 20)
 
5885
                        #GUI_A['g_origin'] = Draw.String('', EVENT_ORIGIN, b1, y, b1_, 20, GUI_A['g_origin'].val, "global translation-vector (x,y,z) in DXF units")
 
5886
                Draw.EndAlign()
 
5887
 
 
5888
                y -= 20
 
5889
                Draw.BeginAlign()
 
5890
                GUI_A['g_scale_on'] = Draw.Toggle('glob.Scale', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_scale_on'].val, "global scale all DXF objects on/off")
 
5891
                if GUI_A['g_scale_on'].val:
 
5892
                        g_scale_as = Draw.Menu(g_scale_list, EVENT_SCALE, b1, y, 45, 20, g_scale_as.val, "factor for scaling the DXFdata")
 
5893
                        if g_scale_as.val == 12:
 
5894
                                pass
 
5895
                        else:
 
5896
                                if g_scale_as.val == 6: #scale inches to meters
 
5897
                                        GUI_A['g_scale'].val = 0.0254000
 
5898
                                elif g_scale_as.val == 7: #scale feets to meters
 
5899
                                        GUI_A['g_scale'].val = 0.3048000
 
5900
                                elif g_scale_as.val == 8: #scale yards to meters
 
5901
                                        GUI_A['g_scale'].val = 0.9144000
 
5902
                                else:
 
5903
                                        GUI_A['g_scale'].val = 10.0 ** int(g_scale_as.val)
 
5904
                        scale_float = GUI_A['g_scale'].val
 
5905
                        if scale_float < 0.000001 or scale_float > 1000000:
 
5906
                                scale_str = ' = %s' % GUI_A['g_scale'].val
 
5907
                        else:   
 
5908
                                scale_str = ' = %.6f' % GUI_A['g_scale'].val
 
5909
                        Draw.Label(scale_str, b1+45, y, 200, 20)
 
5910
                Draw.EndAlign()
 
5911
 
 
5912
                y_down = y
 
5913
                # -----end material,translate,scale------------------------------------------
 
5914
 
 
5915
                b0, b0_ = but0c, but_0c + butt_margin
 
5916
                b1, b1_ = but1c, but_1c
 
5917
 
 
5918
                y_top = y_down
 
5919
                y = y_top
 
5920
                y -= 10
 
5921
                y -= 20
 
5922
                Draw.BeginAlign()
 
5923
                GUI_A['meshSmooth_on'] = Draw.Toggle('smooth', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['meshSmooth_on'].val, "mesh smooth for circles/arc-segments on/off")
 
5924
                GUI_A['pl_trim_on'] = Draw.Toggle('trim', EVENT_NONE, b1-20, y, 32, 20, GUI_A['pl_trim_on'].val, "clean intersection of POLYLINE-wide-segments on/off")
 
5925
                GUI_A['pl_trim_max'] = Draw.Number('', EVENT_NONE, b1+12, y,  b1_-12, 20, GUI_A['pl_trim_max'].val, 0, 5, "threshold intersection of POLYLINE-wide-segments: 0.0-5.0")
 
5926
                Draw.EndAlign()
 
5927
 
 
5928
                y -= 20
 
5929
                Draw.BeginAlign()
 
5930
#               GUI_A['thin_res'] = Draw.Number('thin:', EVENT_NONE, but0c, y, but_0c, 20, GUI_A['thin_res'].val, 4, 64, "thin cylinder resolution - number of segments (4-64)")
 
5931
                GUI_A['arc_rad'] = Draw.Number('bR:', EVENT_NONE, b0, y, b0_, 20, GUI_A['arc_rad'].val, 0.01, 100, "basis radius for arc/circle resolution (0.01-100)")
 
5932
                GUI_A['arc_res'] = Draw.Number('', EVENT_NONE, b1, y, b1_/2, 20, GUI_A['arc_res'].val, 3, 500, "arc/circle resolution - number of segments (3-500)")
 
5933
                GUI_A['fill_on'] = Draw.Toggle('caps', EVENT_NONE, b1+b1_/2, y, b1_/2, 20, GUI_A['fill_on'].val, "draws top and bottom caps of CYLINDERs/closed curves on/off")
 
5934
                Draw.EndAlign()
 
5935
 
 
5936
                y -= 20
 
5937
                Draw.BeginAlign()
 
5938
                GUI_A['curve_arc'] = Draw.Number('', EVENT_NONE, b0, y, b0_/2, 20, GUI_A['curve_arc'].val, 3, 32, "Bezier circle: amount of segments: 3-32")
 
5939
                GUI_A['curve_res'] = Draw.Number('', EVENT_NONE, b0+b0_/2, y,  b0_/2, 20, GUI_A['curve_res'].val, 1, 128, "Set the Curve's U-resolution value: 1-128")
 
5940
                GUI_A['curves_on'] = Draw.Toggle('to Curves', EVENT_PRESETCURV, b1, y, b1_, 20, GUI_A['curves_on'].val, "set Curve as target object type on/off")
 
5941
                Draw.EndAlign()
 
5942
 
 
5943
                y -= 20
 
5944
                GUI_A['group_bylayer_on'] = Draw.Toggle('Layer', EVENT_NONE, b0, y, 30, 20, GUI_A['group_bylayer_on'].val, "DXF-entities group by layer on/off")
 
5945
                GUI_A['vGroup_on'] = Draw.Toggle('vGroups', EVENT_NONE, b0+30, y, b1_-10, 20, GUI_A['vGroup_on'].val, "sort faces into VertexGroups on/off")
 
5946
                GUI_A['one_mesh_on'] = Draw.Toggle('oneMesh', EVENT_NONE, b1+10, y, b1_-10, 20, GUI_A['one_mesh_on'].val, "draw DXF-entities into one mesh-object. Recommended for big DXF-files. on/off")
 
5947
 
 
5948
                y -= 30
 
5949
                Draw.BeginAlign()
 
5950
                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")
 
5951
                if GUI_A['material_on'].val:
 
5952
                        GUI_A['material_from'] = Draw.Menu(material_from_menu,   EVENT_NONE, b1-20, y, b1_+20, 20, GUI_A['material_from'].val, "material assignment from?")
 
5953
                Draw.EndAlign()
 
5954
 
 
5955
                y_down = y
 
5956
                # -----------------------------------------------
 
5957
 
 
5958
                b0, b0_ = but2c, but_2c + butt_margin
 
5959
                b1, b1_ = but3c, but_3c
 
5960
 
 
5961
                y = y_top
 
5962
                y -= 10
 
5963
                y -= 20
 
5964
                Draw.BeginAlign()
 
5965
                GUI_A['Z_force_on'] = Draw.Toggle('*elevation', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['Z_force_on'].val, "*set objects Z-coordinates to elevation on/off")
 
5966
                if GUI_A['Z_force_on'].val:
 
5967
                        GUI_A['Z_elev'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['Z_elev'].val, -1000, 1000, "set default elevation(Z-coordinate)")
 
5968
                Draw.EndAlign()
 
5969
 
 
5970
                y -= 20
 
5971
                Draw.BeginAlign()
 
5972
                GUI_A['dist_on'] = Draw.Toggle('dist.:', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['dist_on'].val, "support distance on/off")
 
5973
                GUI_A['dist_force'] = Draw.Toggle('F', EVENT_NONE, b0+b0_-20, y,  20, 20, GUI_A['dist_force'].val, "force minimal distance on/off")
 
5974
                GUI_A['dist_min'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['dist_min'].val, 0, 10, "minimal length/distance (double.vertex removing)")
 
5975
                Draw.EndAlign()
 
5976
 
 
5977
                y -= 20
 
5978
                Draw.BeginAlign()
 
5979
                GUI_A['thick_on'] = Draw.Toggle('thick:', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['thick_on'].val, "support thickness on/off")
 
5980
                GUI_A['thick_force'] = Draw.Toggle('F', EVENT_REDRAW, b0+b0_-20, y,  20, 20, GUI_A['thick_force'].val, "force for thickness at least limiter value on/off")
 
5981
                if GUI_A['thick_force'].val:
 
5982
                        GUI_A['thick_min'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['thick_min'].val, 0, 10, "minimal value for thickness")
 
5983
                Draw.EndAlign()
 
5984
 
 
5985
                y -= 20
 
5986
                Draw.BeginAlign()
 
5987
                GUI_A['width_on'] = Draw.Toggle('width:', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['width_on'].val, "support width on/off")
 
5988
                GUI_A['width_force'] = Draw.Toggle('F', EVENT_REDRAW, b0+b0_-20, y, 20, 20, GUI_A['width_force'].val, "force for width at least limiter value on/off")
 
5989
                if GUI_A['width_force'].val:
 
5990
                        GUI_A['width_min'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['width_min'].val, 0, 10, "minimal value for width")
 
5991
                Draw.EndAlign()
 
5992
 
 
5993
                y -= 30
 
5994
                but, but_ = but2c, 25
 
5995
                Draw.BeginAlign()
 
5996
                Draw.EndAlign()
 
5997
 
 
5998
                if y < y_down: y_down = y
 
5999
                # -----end options --------------------------------------
 
6000
 
 
6001
 
 
6002
                #--------------------------------------
 
6003
                y_top = y_down
 
6004
                y = y_top
 
6005
                #GUI_A['dummy_on'] = Draw.Toggle(' - ', EVENT_NONE, but0c, y, but_0c, 20, GUI_A['dummy_on'].val, "reserved")
 
6006
                y -= 30
 
6007
                Draw.BeginAlign()
 
6008
                Draw.PushButton('INI file >', EVENT_CHOOSE_INI, but0c, y, but_0c, 20, 'Select INI-file from project directory')
 
6009
                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")
 
6010
                but = but4c-60
 
6011
                Draw.PushButton('#', EVENT_PRESETS, but, y, 20, 20, "toggle Preset-INI-files")
 
6012
                Draw.PushButton('L', EVENT_LOAD_INI, but+20, y, 20, 20, 'Loads configuration from ini-file: %s' % iniFileName.val)
 
6013
                Draw.PushButton('S', EVENT_SAVE_INI, but+40, y, 20, 20, 'Saves configuration to ini-file: %s' % iniFileName.val)
 
6014
                Draw.EndAlign()
 
6015
 
 
6016
 
 
6017
        b0, b0_ = but2c, but_2c + butt_margin
 
6018
        b1, b1_ = but3c, but_3c
 
6019
 
 
6020
        y =     simple_menu_h
 
6021
        bm = butt_margin/2
 
6022
 
 
6023
        #y -= 10
 
6024
        Draw.BeginAlign()
 
6025
        Draw.PushButton('DXFfile >', EVENT_CHOOSE_DXF, but0c, y, but_0c, 20, 'Select DXF-file from project directory')
 
6026
        dxfFileName = Draw.String(' :', EVENT_NONE, but1c, y, but_1c+but_2c+but_3c-20, 20, dxfFileName.val, FILENAME_MAX, "type the name of DXF-file or type *.dxf for multi-import")
 
6027
        Draw.PushButton('*.*', EVENT_DXF_DIR, but3c+but_3c-20, y, 20, 20, 'import all dxf files from this directory')
 
6028
        Draw.EndAlign()
 
6029
 
 
6030
        y -= 30
 
6031
        config_UI = Draw.Toggle('CONFIG', EVENT_REDRAW, but0c, y, but_0c+bm, 20, config_UI.val, 'Advanced configuration on/off' )
 
6032
        Draw.BeginAlign()
 
6033
        but, but_ = but1c, but_1c+bm
 
6034
        but_ /= 3
 
6035
        Draw.PushButton('X', EVENT_RESET, but, y, 15, 20, "reset configuration to defaults")
 
6036
        Draw.PushButton('2D', EVENT_PRESET2D, but+but_, y, but_, 20, 'set configuration for 2D import')
 
6037
        Draw.PushButton('3D', EVENT_PRESET3D, but+(but_*2), y, but_, 20, 'set configuration for 3D import')
 
6038
        Draw.EndAlign()
 
6039
 
 
6040
        Draw.BeginAlign()
 
6041
        GUI_A['newScene_on'] = Draw.Toggle('newScene', EVENT_NONE, but2c, y, but_2c, 20, GUI_A['newScene_on'].val, "create new Scene for each imported dxf file on/off")
 
6042
        GUI_A['target_layer'] = Draw.Number('layer', EVENT_NONE, but3c, y, but_3c, 20, GUI_A['target_layer'].val, 1, 18, "target Blender-layer (<19> reserved for block_definitions)")
 
6043
        Draw.EndAlign()
 
6044
 
 
6045
        y -= 40
 
6046
        Draw.PushButton('EXIT', EVENT_EXIT, but0c, y, but_0c+bm, 20, '' )
 
6047
        Draw.PushButton('HELP', EVENT_HELP, but1c, y, but_1c+bm, 20, 'calls DXF-Importer Manual Page on Wiki.Blender.org')
 
6048
        Draw.BeginAlign()
 
6049
        GUI_A['optimization'] = Draw.Number('', EVENT_NONE, but2c, y+20, 40, 20, GUI_A['optimization'].val, 0, 3, "Optimization Level: 0=Debug/directDrawing, 1=Verbose, 2=ProgressBar, 3=SilentMode")
 
6050
        Draw.EndAlign()
 
6051
        Draw.BeginAlign()
 
6052
        Draw.PushButton('TEST', EVENT_LIST, but2c, y, 40, 20, 'DXF-Analyze-Tool: reads data from selected dxf file and writes report in project_directory/dxf_blendname.INF')
 
6053
        Draw.PushButton('START IMPORT', EVENT_START, but2c+40, y, but_2c-40+but_3c+butt_margin, 40, 'Start the import process. For Cancel go to console and hit Ctrl-C')
 
6054
        Draw.EndAlign()
 
6055
 
 
6056
 
 
6057
 
 
6058
 
 
6059
        y -= 20
 
6060
        Draw.BeginAlign()
 
6061
        Draw.Label(' ', but0c-menu_margin, y, menu_margin, 20)
 
6062
        Draw.Label(LAB, but0c, y, menu_w, 20)
 
6063
        Draw.Label(' ', but0c+menu_w, y, menu_margin, 20)
 
6064
        Draw.EndAlign()
 
6065
 
 
6066
#-- END GUI Stuf-----------------------------------------------------
 
6067
 
 
6068
def colorbox(x,y,xright,bottom):
 
6069
   glColor3f(0.75, 0.75, 0.75)
 
6070
   glRecti(x + 1, y + 1, xright - 1, bottom - 1)
 
6071
 
 
6072
def dxf_callback(input_filename):
 
6073
        global dxfFileName
 
6074
        dxfFileName.val=input_filename
 
6075
#       dirname == Blender.sys.dirname(Blender.Get('filename'))
 
6076
#       update_RegistryKey('DirName', dirname)
 
6077
#       update_RegistryKey('dxfFileName', input_filename)
 
6078
        
 
6079
def ini_callback(input_filename):
 
6080
        global iniFileName
 
6081
        iniFileName.val=input_filename
 
6082
 
 
6083
def event(evt, val):
 
6084
        if evt in (Draw.QKEY, Draw.ESCKEY) and not val:
 
6085
                Blender.Draw.Exit()
 
6086
 
 
6087
def bevent(evt):
 
6088
#   global EVENT_NONE,EVENT_LOAD_DXF,EVENT_LOAD_INI,EVENT_SAVE_INI,EVENT_EXIT
 
6089
        global config_UI, user_preset
 
6090
        global GUI_A
 
6091
 
 
6092
        ######### Manages GUI events
 
6093
        if (evt==EVENT_EXIT):
 
6094
                Blender.Draw.Exit()
 
6095
                print 'DXF-Importer  *** exit ***'   #---------------------
 
6096
        elif (evt==EVENT_CHOOSE_INI):
 
6097
                Window.FileSelector(ini_callback, "INI-file Selection", '*.ini')
 
6098
        elif (evt==EVENT_REDRAW):
 
6099
                Draw.Redraw()
 
6100
        elif (evt==EVENT_RESET):
 
6101
                resetDefaultConfig()
 
6102
                Draw.Redraw()
 
6103
        elif (evt==EVENT_PRESET2D):
 
6104
                resetDefaultConfig_2D()
 
6105
                Draw.Redraw()
 
6106
        elif (evt==EVENT_SCALE):
 
6107
                if g_scale_as.val == 12:
 
6108
                        inputGlobalScale()
 
6109
                if GUI_A['g_scale'].val < 0.00000001:
 
6110
                        GUI_A['g_scale'].val = 0.00000001
 
6111
                Draw.Redraw()
 
6112
        elif (evt==EVENT_ORIGIN):
 
6113
                inputOriginVector()
 
6114
                Draw.Redraw()
 
6115
        elif (evt==EVENT_PRESET3D):
 
6116
                resetDefaultConfig_3D()
 
6117
                Draw.Redraw()
 
6118
        elif (evt==EVENT_PRESETCURV):
 
6119
                presetConfig_curv(GUI_A['curves_on'].val)
 
6120
                Draw.Redraw()
 
6121
        elif (evt==EVENT_PRESETS):
 
6122
                user_preset += 1
 
6123
                index = str(user_preset)
 
6124
                if user_preset > 5: user_preset = 0; index = ''
 
6125
                iniFileName.val = INIFILE_DEFAULT_NAME + index + INIFILE_EXTENSION
 
6126
                Draw.Redraw()
 
6127
        elif (evt==EVENT_LIST):
 
6128
                dxfFile = dxfFileName.val
 
6129
                update_RegistryKey('dxfFileName', dxfFileName.val)
 
6130
                if dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile):
 
6131
                        analyzeDXF(dxfFile)
 
6132
                else:
 
6133
                        Draw.PupMenu('DXF importer:  Alert!%t|no valid DXF-file selected!')
 
6134
                        print "DXF importer: error, no valid DXF-file selected! try again"
 
6135
                Draw.Redraw()
 
6136
        elif (evt==EVENT_HELP):
 
6137
                try:
 
6138
                        import webbrowser
 
6139
                        webbrowser.open('http://wiki.blender.org/index.php?title=Scripts/Manual/Import/DXF-3D')
 
6140
                except:
 
6141
                        Draw.PupMenu('DXF importer: HELP Alert!%t|no connection to manual-page on Blender-Wiki! try:|\
 
6142
http://wiki.blender.org/index.php?title=Scripts/Manual/Import/DXF-3D')
 
6143
                Draw.Redraw()
 
6144
        elif (evt==EVENT_LOAD_INI):
 
6145
                loadConfig()
 
6146
                Draw.Redraw()
 
6147
        elif (evt==EVENT_SAVE_INI):
 
6148
                saveConfig()
 
6149
                Draw.Redraw()
 
6150
        elif (evt==EVENT_DXF_DIR):
 
6151
                dxfFile = dxfFileName.val
 
6152
                dxfPathName = ''
 
6153
                if '/' in dxfFile:
 
6154
                        dxfPathName = '/'.join(dxfFile.split('/')[:-1]) + '/'
 
6155
                elif '\\' in dxfFile:
 
6156
                        dxfPathName = '\\'.join(dxfFile.split('\\')[:-1]) + '\\'
 
6157
                dxfFileName.val = dxfPathName + '*.dxf'
 
6158
#               dirname == Blender.sys.dirname(Blender.Get('filename'))
 
6159
#               update_RegistryKey('DirName', dirname)
 
6160
#               update_RegistryKey('dxfFileName', dxfFileName.val)
 
6161
                GUI_A['newScene_on'].val = 1
 
6162
                Draw.Redraw()
 
6163
        elif (evt==EVENT_CHOOSE_DXF):
 
6164
                filename = '' # '*.dxf'
 
6165
                if dxfFileName.val:     filename = dxfFileName.val
 
6166
                Window.FileSelector(dxf_callback, "DXF-file Selection", filename)
 
6167
        elif (evt==EVENT_START):
 
6168
                dxfFile = dxfFileName.val
 
6169
                #print 'deb: dxfFile file: ', dxfFile #----------------------
 
6170
                if E_M: dxfFileName.val, dxfFile = e_mode(dxfFile) #evaluation mode
 
6171
                update_RegistryKey('dxfFileName', dxfFileName.val)
 
6172
                if dxfFile.lower().endswith('*.dxf'):
 
6173
                        if Draw.PupMenu('DXF importer:  OK?|will import all DXF-files from:|%s' % dxfFile) == 1:
 
6174
                                global UI_MODE
 
6175
                                UI_MODE = False
 
6176
                                multi_import(dxfFile[:-5])  # cut last 5 characters '*.dxf'
 
6177
                                Draw.Redraw()
 
6178
                                #Draw.Exit()
 
6179
                        else:
 
6180
                                Draw.Redraw()
 
6181
                elif dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile):
 
6182
                        print '\nStandard Mode: active'
 
6183
                        if GUI_A['newScene_on'].val:
 
6184
                                _dxf_file = dxfFile.split('/')[-1].split('\\')[-1]
 
6185
                                _dxf_file = _dxf_file[:-4]  # cut last char:'.dxf'
 
6186
                                _dxf_file = _dxf_file[:MAX_NAMELENGTH]  #? [-MAX_NAMELENGTH:])
 
6187
                                global SCENE
 
6188
                                SCENE = Blender.Scene.New(_dxf_file)
 
6189
                                SCENE.makeCurrent()
 
6190
                                Blender.Redraw()
 
6191
                                #or so? Blender.Scene.makeCurrent(_dxf_file)
 
6192
                                #sce = bpy.data.scenes.new(_dxf_file)
 
6193
                                #bpy.data.scenes.active = sce
 
6194
                        else:
 
6195
                                SCENE = Blender.Scene.GetCurrent()
 
6196
                                SCENE.objects.selected = [] # deselect all
 
6197
                        main(dxfFile)
 
6198
                        #SCENE.objects.selected = SCENE.objects          
 
6199
                        #Window.RedrawAll()
 
6200
                        #Blender.Redraw()
 
6201
                        #Draw.Redraw()
 
6202
                else:
 
6203
                        Draw.PupMenu('DXF importer:  Alert!%t|no valid DXF-file selected!')
 
6204
                        print "DXF importer: error, no valid DXF-file selected! try again"
 
6205
                        Draw.Redraw()
 
6206
 
 
6207
 
 
6208
 
 
6209
 
 
6210
def multi_import(DIR):
 
6211
        """Imports all DXF-files from directory DIR.
 
6212
        
 
6213
        """
 
6214
        global SCENE
 
6215
        batchTIME = Blender.sys.time()
 
6216
        #if #DIR == "": DIR = os.path.curdir
 
6217
        if DIR == "": DIR = Blender.sys.dirname(Blender.Get('filename'))
 
6218
        print 'Multifiles Import from %s' %DIR
 
6219
        files = \
 
6220
                [sys.join(DIR, f) for f in os.listdir(DIR) if f.lower().endswith('.dxf')] 
 
6221
        if not files:
 
6222
                print '...None DXF-files found. Abort!'
 
6223
                return
 
6224
        
 
6225
        i = 0
 
6226
        for dxfFile in files:
 
6227
                i += 1
 
6228
                print '\nDXF-file', i, 'of', len(files) #,'\nImporting', dxfFile
 
6229
                if GUI_A['newScene_on'].val:
 
6230
                        _dxf_file = dxfFile.split('/')[-1].split('\\')[-1]
 
6231
                        _dxf_file = _dxf_file[:-4]  # cut last char:'.dxf'
 
6232
                        _dxf_file = _dxf_file[:MAX_NAMELENGTH]  #? [-MAX_NAMELENGTH:])
 
6233
                        SCENE = Blender.Scene.New(_dxf_file)
 
6234
                        SCENE.makeCurrent()
 
6235
                        #or so? Blender.Scene.makeCurrent(_dxf_file)
 
6236
                        #sce = bpy.data.scenes.new(_dxf_file)
 
6237
                        #bpy.data.scenes.active = sce
 
6238
                else:
 
6239
                        SCENE = Blender.Scene.GetCurrent()
 
6240
                        SCENE.objects.selected = [] # deselect all
 
6241
                main(dxfFile)
 
6242
                #Blender.Redraw()
 
6243
 
 
6244
        print 'TOTAL TIME: %.6f' % (Blender.sys.time() - batchTIME)
 
6245
        print '\a\r', # beep when done
 
6246
 
 
6247
 
 
6248
 
 
6249
UI_MODE = True
 
6250
 
 
6251
if __name__ == "__main__":
 
6252
        UI_MODE = True
 
6253
        # recall last used DXF-file and INI-file names
 
6254
        dxffilename = check_RegistryKey('dxfFileName')
 
6255
        #print 'deb:start dxffilename:', dxffilename #----------------
 
6256
        if dxffilename: dxfFileName.val = dxffilename
 
6257
        else:
 
6258
                dirname = Blender.sys.dirname(Blender.Get('filename'))
 
6259
                #print 'deb:start dirname:', dirname #----------------
 
6260
                dxfFileName.val = sys.join(dirname, '')
 
6261
        inifilename = check_RegistryKey('iniFileName')
 
6262
        if inifilename: iniFileName.val = inifilename
 
6263
 
 
6264
        Draw.Register(draw_UI, event, bevent)
 
6265
 
 
6266
 
 
6267
"""
 
6268
if 1:
 
6269
        # DEBUG ONLY
 
6270
        UI_MODE = False
 
6271
        TIME= Blender.sys.time()
 
6272
        #DIR = '/dxf_r12_testfiles/'
 
6273
        DIR = '/metavr/'
 
6274
        import os
 
6275
        print 'Searching for files'
 
6276
        os.system('find %s -iname "*.dxf" > /tmp/tempdxf_list' % DIR)
 
6277
        # os.system('find /storage/ -iname "*.dxf" > /tmp/tempdxf_list')
 
6278
        print '...Done'
 
6279
        file= open('/tmp/tempdxf_list', 'r')
 
6280
        lines= file.readlines()
 
6281
        file.close()
 
6282
        # sort by filesize for faster testing
 
6283
        lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines]
 
6284
        lines_size.sort()
 
6285
        lines = [f[1] for f in lines_size]
 
6286
 
 
6287
        for i, _dxf in enumerate(lines):
 
6288
                if i >= 70:
 
6289
                        #if 1:
 
6290
                        print 'Importing', _dxf, '\nNUMBER', i, 'of', len(lines)
 
6291
                        if True:
 
6292
                                _dxf_file= _dxf.split('/')[-1].split('\\')[-1]
 
6293
                                _dxf_file = _dxf_file[:-4]  # cut last char:'.dxf'
 
6294
                                _dxf_file = _dxf_file[:MAX_NAMELENGTH]  #? [-MAX_NAMELENGTH:])
 
6295
                                sce = bpy.data.scenes.new(_dxf_file)
 
6296
                                bpy.data.scenes.active = sce
 
6297
                        dxfFileName.val = _dxf
 
6298
                        main(_dxf)
 
6299
 
 
6300
        print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
 
6301
"""
 
 
b'\\ No newline at end of file'