2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r17434...
[blender-staging.git] / release / scripts / import_dxf.py
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.11.16 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.11.16 by migius
115  d1 remove try_finally: cause not supported in python <2.5
116  d1 add Bezier curves bevel radius support (default 1.0)
117  v1.12 - 2008.08.03 by migius
118  c2 warningfix: relocating of globals: layersmap, oblist 
119  c2 modif UI: buttons newScene+targetLayer moved to start panel
120  v1.12 - 2008.07.04 by migius
121  c1 added control Curve's OrderU parameter
122  c1 modif UI: preset buttons X-2D-3D moved to start panel
123  b6 added handling exception of not registered LAYERs (Hammer-HL-editor DXF output)
124  b5 rebuild UI: global preset 2D for Curve-Import
125  b5 added UI-options: PL-MESH N+N plmesh_flip and normals_out 
126  b5 added support for SPLINEs, added control OrderU parameter
127  b5 rewrote draw module for NURBS_curve and Bezier_curve
128  v1.12 - 2008.06.22 by migius
129  b4 change versioning system 1.0.12 -> 1.12
130  b4 print at start version-info to console
131  b3 bugfix: ob.name conflict with existing meshes (different ob.name/mesh.name)
132  v1.0.12: 2008.05.24 by migius
133  b2 added support for LWPOLYLINEs
134  b2 added support for ProE in readerDXF.py
135  v1.0.12: 2008.02.08 by migius
136  b1 update: object = Object.Get(obname) -> f_getSceChild().getChildren()
137  a9 bugfix by non-existing tables views, vports, layers (Kai reported)
138  v1.0.12: 2008.01.17 by migius
139  a8 lately used INI-dir/filename persistently stored in Registry
140  a8 lately used DXF-dir/filename persistently stored in Registry
141  a7 fix missing layersmap{} for dxf-files without "section:layer"
142  a6 added support for XREF external referenced BLOCKs
143  a6 check for bug in AutoCAD2002:DXFr12export: ELLIPSE->POLYLINE_ARC fault angles
144  a6 support VIEWs and VPORTs as cameras: ortho and perspective mode
145  a6 save resources through ignoring unused BLOCKs (not-inserted or on frozen/blocked layers)
146  a6 added try_finally: f.close() for all IO-files
147  a6 added handling for TypeError raise
148  a5 bugfix f_getOCS for (0,0,z!=1.0) (ellipse in Kai's dxf)
149  a4 added to analyzeTool: report about VIEWs, VPORTs, unused/xref BLOCKs
150  a4 bugfix: individual support for 2D/3DPOLYLINE/POLYMESH
151  a4 added to UI: (*wip)BLOCK-(F): name filtering for BLOCKs
152  a4 added to UI: BLOCK-(n): filter anoname/hatch BLOCKs *X...
153  a2 g_scale_as is no more GUI_A-variable
154  a2 bugfix "material": negative sign color_index
155  a2 added support for BLOCKs defined with origin !=(0,0,0)
156  a1 added 'global.reLocation-vector' option
157
158  v1.0.11: 2007.11.24 by migius
159  c8 added 'curve_resolution_U' option 
160  c8 added context_sensitivity for some UI-buttons
161  c8 bugfix ELLIPSE rotation, added closed_variant and caps
162  c7 rebuild UI: new layout, grouping and meta-buttons
163  c6 rewritten support for ELLIPSE mesh & curve representation
164  c6 restore selector-buttons for DXF-drawTypes: LINE & Co
165  c6 change header of INI/INF-files: # at begin
166  c6 apply scale(1,1,1) after glob.Scale for all mesh objects, not for curve objects.
167  c5 fixing 'material_on' option
168  c4 added "analyze DXF-file" UI-option: print LAYER/BLOCK-dependences into a textfile
169  c3 human-formating of data in INI-Files
170  c2 added "caps" for closed Bezier-curves
171  c2 added "set elevation" UI-option
172  c1 rewrite POLYLINE2d-arc-segments Bezier-interpreter
173  b9 many bugs fixed
174  b9 rewrite POLYLINE2d-arc-segments trimming (clean-trim)
175  b8 added "import from frozen layers" UI-option
176  b8 added "import from paper space" UI-option
177  b8 support Bezier curves for LINEs incl.thickness(0.0-10.0)
178  b8 added meshSmooth_on for circle/arc/polyline 
179  b8 added vertexGroups for circle/arc 
180  b7 added width_force for ARCs/CIRCLEs = "thin_box" option
181  b3 cleanup code, rename f_drawArc/Bulg->f_calcArc/Bulg
182  b2 fixing material assignment by LAYER+COLOR
183  b1 fixing Bezier curves representation of POLYLINEs-arc-segments
184  b0 added global_scale_presets: "yard/feet/inch to meter"
185
186  v1.0.10: 2007.10.18 by migius
187  a6 bugfix CircleDrawCaps for OSX 
188  a5 added two "curve_res" UI-buttons for Bezier curves representation
189  a5 improved Bezier curves representation of circles/arcs: correct handlers
190  a4 try to fix malformed endpoints of Blender curves of ARC/POLYLINE-arc segments. 
191  a3 bugfix: open-POLYLINEs with end_point.loc==start_point.loc
192  a2 bugfix: f_transform for OCS=(0,0,-1) oriented objects
193  a1 added "fill_on=caps" option to draw top and bottom sides of CIRCLEs and ELLIPSEs
194  a1 rewrite f_CIRCLE.Draw: from Mesh.Primitive to Mesh
195  a1 bugfix "newScene"-mode: all Cylinders/Arcs were drawn at <0,0,0>location
196
197  v1.0.beta09: 2007.09.02 by migius
198  g5 redesign UI: grouping of buttons
199  g3 update multi-import-mode: <*.*> button
200  g- added multi-import-mode: (path/*) for importing many dxf-files at once
201  g- added import into newScene
202  g- redesign UI: user presets, into newScene-import  
203  f- cleanup code
204  f- bugfix: thickness for Bezier/Bsplines into Blender-curves
205  f- BlenderWiki documentation, on-line Manual
206  f- added import POLYLINE-Bsplines into Blender-NURBSCurves
207  f- added import POLYLINE-arc-segments into Blender-BezierCurves
208  f- added import POLYLINE-Bezier-curves into Blender-Curves
209  d5 rewrite: Optimization Levels, added 'directDrawing'
210  d4 added: f_set_thick(controlled by ini-parameters)
211  d4 bugfix: face-normals in objects with minus thickness
212  d4 added: placeholder'Empty'-size in f_Insert.draw
213  d3 rewrite f_Text.Draw: added support for all Text's parameters
214  d2 redesign: progressbar 
215  e- tuning by ideasman42: better use of the Py API.
216  c- tuning by ideasman42
217  b- rewrite f_Text.Draw rotation/transform
218  b- bugfix: POLYLINE-segment-intersection more reliable now
219  b- bugfix: circle:_thic, 'Empties':no material_assignment
220  b- added material assignment (from layer and/or color)
221  a- added empty, cylinder and UVsphere for POINTs
222  a- added support for 2d-POLYLINE: splines, fitted curves, fitted surfaces
223  a- redesign f_Drawer for block_definitions
224  a- rewrite import into Blender-Curve-Object
225
226  v1.0.beta08 - 2007.07.27 by migius: "full 3d"-release
227  l- bugfix: solid_vgroups, clean:scene.objects.new()
228  l- redesign UI to standard Draw.Register+FileSelector, advanced_config_option
229  k- bugfix UI:fileSelect() for MacOSX os.listdir()
230  k- added reset/save/load for config-data
231  k- redesign keywords/drawTypes/Draw.Create_Buttons
232  j- new UI using UIBlock() with own FileSelector, cause problem Window.FileSelector()
233  i- rewritten Class:Settings for better config-parameter management
234  h- bugfix: face-normals in objects with minus thickness
235  h- added Vertex-Groups in POLYLINE and SOLID meshes, for easy material assignment
236  h- beautify code, whitespace->tabs
237  h- added settings.thic_force switch for forcing thickness
238  h- added "one Mesh" option for all entities from the same Layer, sorted in<br>
239  Vertex-Groups(color_name)  (fewer objects = better import performance)
240  g- rewrote: insert-point-handle-object is a small tetrahedron
241  e- bugfix: closed-polymesh3d
242  - rewrote: UI, type_map.keys, f_drawer, all class_f_draw(added "settings" as attribut)
243  - added 2d/3d-support for Polyline_Width incl. angle intersection
244  beta07: 2007.06.19 by migius
245  - added 3d-support for LWPolylines
246  - added 2d/3d-support for Points
247  beta06: 2007.06.15 by migius
248  - cleanup code
249  - added 2d/3d-support for MINSERT=BlockArray in f_drawer, added f_rotXY_Vec
250  beta05: 2007.06.14 by migius
251  - added 2d/3d-support for 3d-PolyLine, PolyMesh and PolyFace
252  - added Global-Scale for size control of imported scenes
253  beta04: 2007.06.12 by migius
254  - rewrote the f_drawBulge for correct import the arc-segments of Polylines
255  beta03: 2007.06.10 by migius
256  - rewrote interface
257  beta02: 2007.06.09 by migius
258  - added 3d-support for Arcs and Circles
259  - added support for Object_Thickness(=height)
260  beta01: 2007.06.08 by migius
261  - added 3d-support for Blocks/Inserts within nested-structures
262  - rewrote f_transform for correct 3d-location/3d-rotation
263  - added 3d-support Lines, 3dFaces
264  - added 2d+3d-support for Solids and Traces
265
266  v0.9 - 2007.01 by kitsu: (for 2.43)
267  - first draft of true POLYLINE import
268  -
269
270  v0.8 - 2006.12 by kitsu:
271  - first draft of object space coordinates OCS import
272  -
273
274  v0.5b - 2006.10 by kitsu: (for 2.42a)
275  - dxfReader.py
276  - color_map.py
277
278 """
279
280 # --------------------------------------------------------------------------
281 # DXF Import v1.0 by Ed Blake (AKA kitsu) and Remigiusz Fiedler (AKA migius)
282 # --------------------------------------------------------------------------
283 # ***** BEGIN GPL LICENSE BLOCK *****
284 #
285 # This program is free software; you can redistribute it and/or
286 # modify it under the terms of the GNU General Public License
287 # as published by the Free Software Foundation; either version 2
288 # of the License, or (at your option) any later version.
289 #
290 # This program is distributed in the hope that it will be useful,
291 # but WITHOUT ANY WARRANTY; without even the implied warranty of
292 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
293 # GNU General Public License for more details.
294 #
295 # You should have received a copy of the GNU General Public License
296 # along with this program; if not, write to the Free Software Foundation,
297 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
298 #
299 # ***** END GPL LICENCE BLOCK *****
300 # --------------------------------------------------------------------------
301
302 import Blender
303 from Blender import *
304 #from Blender.Mathutils import Vector, Matrix
305 #import bpy #not used yet
306 #import BPyMessages
307
308 from dxfReader import readDXF
309 #from dxfReader import get_name, get_layer
310 from dxfReader import Object as dxfObject
311 from dxfColorMap import color_map
312
313 from math import *
314
315 try:
316         import os
317         if os.name != 'mac':
318                 import psyco
319                 psyco.log(Blender.Get('tempdir')+"/blender.log-psyco")
320                 #psyco.log()
321                 psyco.full(memory=100)
322                 psyco.profile(0.05, memory=100)
323                 psyco.profile(0.2)
324                 #print 'psyco imported'
325 except ImportError:
326         print 'psyco not imported'
327         pass
328
329 #try: Curve.orderU
330
331 print '\n\n\n'
332 print 'DXF-Importer v%s *** start ***' %(__version__)   #---------------------
333
334 SCENE = None
335 WORLDX = Mathutils.Vector((1,0,0))
336 WORLDY = Mathutils.Vector((1,1,0))
337 WORLDZ = Mathutils.Vector((0,0,1))
338
339 G_SCALE = 1.0      #(0.0001-1000) global scaling factor for all dxf data
340 G_ORIGIN_X = 0.0   #global translation-vector (x,y,z) in DXF units
341 G_ORIGIN_Y = 0.0
342 G_ORIGIN_Z = 0.0
343 MIN_DIST = 0.001        #cut-off value for sort out short-distance polyline-"duoble_vertex"
344 ARC_RESOLUTION = 64   #(4-500) arc/circle resolution - number of segments
345 ARC_RADIUS = 1.0   #(0.01-100) arc/circle radius for number of segments algorithm
346 CURV_RESOLUTION = 12 #(1-128) Bezier curves U-resolution
347 CURVARC_RESOLUTION = 4 #(3-32) resolution of circle represented as Bezier curve 
348 THIN_RESOLUTION = 8   #(4-64) thin_cylinder arc_resolution - number of segments
349 MIN_THICK = MIN_DIST * 10.0  #minimal thickness by forced thickness
350 MIN_WIDTH = MIN_DIST * 10.0  #minimal width by forced width
351 TRIM_LIMIT = 3.0         #limit for triming of polylines-wide-segments (values:0.0 - 5.0)
352 ELEVATION = 0.0 #standard elevation = coordinate Z value
353
354 BYBLOCK = 0
355 BYLAYER = 256
356 TARGET_LAYER = 3        #target blender_layer
357 GROUP_BYLAYER = 0   #(0/1) all entities from same layer import into one blender-group
358 LAYER_DEF_NAME = 'AAAA' #default layer name
359 LAYER_DEF_COLOR = 4 #default layer color
360 E_M = 0
361 LAB = "*) parts under construction"
362 M_OBJ = 0
363
364 FILENAME_MAX = 180      #max length of path+file_name string  (FILE_MAXDIR + FILE_MAXFILE)
365 MAX_NAMELENGTH = 17   #max_effective_obnamelength in blender =21=17+(.001)
366 INIFILE_DEFAULT_NAME = 'importDXF'
367 INIFILE_EXTENSION = '.ini'
368 INIFILE_HEADER = '#ImportDXF.py ver.1.0 config data'
369 INFFILE_HEADER = '#ImportDXF.py ver.1.0 analyze of DXF-data'
370
371 AUTO = BezTriple.HandleTypes.AUTO
372 FREE = BezTriple.HandleTypes.FREE
373 VECT = BezTriple.HandleTypes.VECT
374 ALIGN = BezTriple.HandleTypes.ALIGN
375
376
377 class View:  #-----------------------------------------------------------------
378         """Class for objects representing dxf VIEWs.
379         """
380         def __init__(self, obj, active=None):
381                 """Expects an object of type VIEW as input.
382                 """
383                 if not obj.type == 'view':
384                         raise TypeError, "Wrong type %s for VIEW object!" %obj.type
385
386                 self.type = obj.type
387                 self.name = obj.get_type(2)[0]
388 #               self.data = obj.data[:]
389
390
391                 self.centerX = getit(obj, 10, 0.0) #view center pointX (in DCS)
392                 self.centerY = getit(obj, 20, 0.0) #view center pointY (in DCS)
393                 self.height = obj.get_type(40)[0] #view height (in DCS)
394                 self.width = obj.get_type(41)[0] #view width (in DCS)
395
396                 self.dir = [0,0,0]
397                 self.dir[0] = getit(obj, 11, 0.0) #view directionX from target (in WCS)
398                 self.dir[1] = getit(obj, 21, 0.0) #
399                 self.dir[2] = getit(obj, 31, 0.0) #
400
401                 self.target = [0,0,0]
402                 self.target[0] = getit(obj, 12, 0.0) #target pointX(in WCS)
403                 self.target[1] = getit(obj, 22, 0.0) #
404                 self.target[2] = getit(obj, 32, 0.0) #
405
406                 self.length = obj.get_type(42)[0] #Lens length
407                 self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
408                 self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
409                 self.twist  = obj.get_type(50)[0] #view twist angle in degrees
410
411                 self.flags = getit(obj, 70, 0)
412                 self.paperspace = self.flags & 1 #
413
414                 self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
415
416         def __repr__(self):
417                 return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
418
419
420         def draw(self, settings):
421                 """for VIEW: generate Blender_camera.
422                 """
423                 obname = 'vw_%s' %self.name  # create camera object name
424                 #obname = 'ca_%s' %self.name  # create camera object name
425                 obname = obname[:MAX_NAMELENGTH]
426
427                 if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
428                         cam= Camera.New('ortho', obname)
429                         ob= SCENE.objects.new(cam)
430                         cam.type = 'ortho'
431                         cam.scale = 1.0  # for ortho cameras
432                 else:
433                         cam= Camera.New('persp', obname)
434                         ob= SCENE.objects.new(cam)
435                         cam.type = 'persp'
436                         cam.angle = 60.0  # for persp cameras
437                         if self.length:
438                                 #cam.angle = 2 * atan(17.5/self.length) * 180/pi
439                                 cam.lens = self.length #for persp cameras
440                         # hack to update Camera>Lens setting (inaccurate as a focal length) 
441                         #curLens = cam.lens; cam.lens = curLens
442                         # AutoCAD gets clip distance from target:
443                         dist = Mathutils.Vector(self.dir).length
444                         cam.clipEnd = dist - self.clip_back
445                         cam.clipStart = dist - self.clip_front
446         
447                 cam.drawLimits = 1 
448                 cam.drawSize = 10
449                 
450                 v = Mathutils.Vector(self.dir)
451 #               print 'deb:view cam:', cam #------------
452 #               print 'deb:view self.target:', self.target #------------
453 #               print 'deb:view self.dir:', self.dir #------------
454 #               print 'deb:view self.twist:', self.twist #------------
455 #               print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
456                 transform(v.normalize(), -self.twist, ob)
457                 ob.loc =  Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
458                 return ob
459
460
461 class Vport:  #-----------------------------------------------------------------
462         """Class for objects representing dxf VPORTs.
463         """
464         def __init__(self, obj, active=None):
465                 """Expects an object of type VPORT as input.
466                 """
467                 if not obj.type == 'vport':
468                         raise TypeError, "Wrong type %s for VPORT object!" %obj.type
469
470                 self.type = obj.type
471                 self.name = obj.get_type(2)[0]
472 #               self.data = obj.data[:]
473                 #print 'deb:vport name, data:', self.name #-------
474                 #print 'deb:vport data:', self.data #-------
475
476                 self.height = obj.get_type(40)[0] #vport height (in DCS)
477                 self.centerX = getit(obj, 12, 0.0) #vport center pointX (in DCS)
478                 self.centerY = getit(obj, 22, 0.0) #vport center pointY (in DCS)
479                 self.width = self.height * obj.get_type(41)[0] #vport aspect ratio - width (in DCS)
480
481                 self.dir = [0,0,0]
482                 self.dir[0] = getit(obj, 16, 0.0) #vport directionX from target (in WCS)
483                 self.dir[1] = getit(obj, 26, 0.0) #
484                 self.dir[2] = getit(obj, 36, 0.0) #
485
486                 self.target = [0,0,0]
487                 self.target[0] = getit(obj, 17, 0.0) #target pointX(in WCS)
488                 self.target[1] = getit(obj, 27, 0.0) #
489                 self.target[2] = getit(obj, 37, 0.0) #
490
491                 self.length = obj.get_type(42)[0] #Lens length
492                 self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
493                 self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
494                 self.twist  = obj.get_type(51)[0] #view twist angle
495
496                 self.flags = getit(obj, 70, 0)
497                 self.paperspace = self.flags & 1 #
498
499                 self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
500
501         def __repr__(self):
502                 return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
503
504         def draw(self, settings):
505                 """for VPORT: generate Blender_camera.
506                 """
507                 obname = 'vp_%s' %self.name  # create camera object name
508                 #obname = 'ca_%s' %self.name  # create camera object name
509                 obname = obname[:MAX_NAMELENGTH]
510
511                 if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
512                         cam= Camera.New('ortho', obname)
513                         ob= SCENE.objects.new(cam)
514                         cam.type = 'ortho'
515                         cam.scale = 1.0  # for ortho cameras
516                 else:
517                         cam= Camera.New('persp', obname)
518                         ob= SCENE.objects.new(cam)
519                         cam.type = 'persp'
520                         cam.angle = 60.0  # for persp cameras
521                         if self.length:
522                                 #cam.angle = 2 * atan(17.5/self.length) * 180/pi
523                                 cam.lens = self.length #for persp cameras
524                         # hack to update Camera>Lens setting (inaccurate as a focal length) 
525                         #curLens = cam.lens; cam.lens = curLens
526                         # AutoCAD gets clip distance from target:
527                         dist = Mathutils.Vector(self.dir).length
528                         cam.clipEnd = dist - self.clip_back
529                         cam.clipStart = dist - self.clip_front
530         
531                 cam.drawLimits = 1 
532                 cam.drawSize = 10
533                 
534                 v = Mathutils.Vector(self.dir)
535 #               print 'deb:view cam:', cam #------------
536 #               print 'deb:view self.target:', self.target #------------
537 #               print 'deb:view self.dir:', self.dir #------------
538 #               print 'deb:view self.twist:', self.twist #------------
539 #               print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
540                 transform(v.normalize(), -self.twist, ob)
541                 ob.loc =  Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
542                 return ob
543
544
545
546 class Layer:  #-----------------------------------------------------------------
547         """Class for objects representing dxf LAYERs.
548         """
549         def __init__(self, obj, name=None, color=None, frozen=None):
550                 """Expects an dxfobject of type layer as input.
551                         if no dxfobject - creates surogate layer with default parameters
552                 """
553
554                 if obj==None:
555                         self.type = 'layer'
556                         if name: self.name = name
557                         else: self.name = LAYER_DEF_NAME
558
559                         if color: self.color = color
560                         else: self.color = LAYER_DEF_COLOR
561
562                         if frozen!=None: self.frozen = frozen
563                         else: self.frozen = 0
564                 else:   
565                         if obj.type=='layer':
566                                 self.type = obj.type
567                                 #self.data = obj.data[:]
568                                 if name: self.name = name
569                                         #self.bfname = name  #--todo---see layernamesmap in f_getLayersmap ---
570                                 else: self.name = obj.get_type(2)[0] #layer name of object
571                 
572                                 if color: self.color = color
573                                 else: self.color = obj.get_type(62)[0]  #color of object
574                 
575                                 if frozen!=None: self.frozen = frozen
576                                 else:
577                                         self.flags = obj.get_type(70)[0]
578                                         self.frozen = self.flags & 1
579         
580         def __repr__(self):
581                 return "%s: name - %s, color - %s" %(self.__class__.__name__, self.name, self.color)
582
583
584
585 def getit(obj, typ, default=None):  #------------------------------------------
586         """Universal procedure for geting data from list/objects.
587         """
588         it = default
589         if type(obj) == list:  #if obj is a list, then searching in a list
590                 for item in obj:
591                         #print 'deb:getit item, type(item)', item, type(item)
592                         try:
593                                 if item[0] == typ:
594                                         it = item[1]
595                                         break  #as soon as the first found
596                         except:
597                                 # --todo-- I found one case where item was a text instance
598                                 # that failed with no __getitem__
599                                 pass
600         else:   #else searching in Object with get_type-Methode
601                 item = obj.get_type(typ)
602                 if item:
603                         it = item[0]
604         #print 'deb:getit:typ, it', typ, it #----------
605         return it
606
607
608
609 def get_extrusion(data):         #-------------------------------------------------
610         """Find the axis of extrusion.
611
612         Used to get from object_data the objects Object_Coordinate_System (ocs).
613         """
614         #print 'deb:get_extrusion: data: \n', data  #---------------
615         vec = [0,0,1]
616         vec[0] = getit(data, 210, 0) # 210 = x
617         vec[1] = getit(data, 220, 0) # 220 = y
618         vec[2] = getit(data, 230, 1) # 230 = z
619         #print 'deb:get_extrusion: vec: ', vec  #---------------
620         return vec
621
622
623 #------------------------------------------
624 def getSceneChild(name):
625         dudu = [i for i in SCENE.objects if i.name==name]
626 #       dudu = [i for i in SCENE.getChildren() if i.name==name]
627         #print 'deb:getSceneChild %s -result: %s:' %(name,dudu) #-----------------
628         if dudu!=[]: return dudu[0]
629         return None
630
631
632 class Solid:  #-----------------------------------------------------------------
633         """Class for objects representing dxf SOLID or TRACE.
634         """
635         def __init__(self, obj):
636                 """Expects an entity object of type solid or trace as input.
637                 """
638                 if obj.type == 'trace':
639                         obj.type = 'solid'
640                 if not obj.type == 'solid':
641                         raise TypeError, "Wrong type \'%s\' for solid/trace object!" %obj.type
642
643                 self.type = obj.type
644 #               self.data = obj.data[:]
645
646                 self.space = getit(obj, 67, 0)
647                 self.thic =  getit(obj, 39, 0)
648                 self.color_index = getit(obj, 62, BYLAYER)
649
650                 self.layer = getit(obj, 8, None)
651                 self.extrusion = get_extrusion(obj)
652                 self.points = self.get_points(obj)
653
654
655
656         def get_points(self, data):
657                 """Gets start and end points for a solid type object.
658
659                 Solids have 3 or 4 points and fixed codes for each value.
660                 """
661
662                 # start x, y, z and end x, y, z = 0
663                 a = [0, 0, 0]
664                 b = [0, 0, 0]
665                 c = [0, 0, 0]
666                 d = [0, 0, 0]
667                 a[0] = getit(data, 10, None) # 10 = x
668                 a[1] = getit(data, 20, None) # 20 = y
669                 a[2] = getit(data, 30,  0)   # 30 = z
670                 b[0] = getit(data, 11, None)
671                 b[1] = getit(data, 21, None)
672                 b[2] = getit(data, 31,  0)
673                 c[0] = getit(data, 12, None)
674                 c[1] = getit(data, 22, None)
675                 c[2] = getit(data, 32,  0)
676                 out = [a,b,c]
677
678                 d[0] =  getit(data, 13, None)
679                 if d[0] != None:
680                         d[1] = getit(data, 23, None)
681                         d[2] = getit(data, 33,  0)
682                         out.append(d)
683                 #print 'deb:solid.vertices:---------\n', out  #-----------------------
684                 return out
685
686
687         def __repr__(self):
688                 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
689
690
691         def draw(self, settings):
692                 """for SOLID: generate Blender_geometry.
693                 """
694                 points = self.points
695                 if not points: return
696                 edges, faces = [], []
697                 l = len(self.points)
698
699                 obname = 'so_%s' %self.layer  # create object name from layer name
700                 obname = obname[:MAX_NAMELENGTH]
701
702                 vg_left, vg_right, vg_top, vg_bottom, vg_start, vg_end = [], [], [], [], [], []
703                 thic = set_thick(self.thic, settings)
704                 if thic != 0:
705                         thic_points = [[v[0], v[1], v[2] + thic] for v in points[:]]
706                         if thic < 0.0:
707                                 thic_points.extend(points)
708                                 points = thic_points
709                         else:
710                                 points.extend(thic_points)
711
712                         if   l == 4:
713                                 faces = [[0,1,3,2], [4,6,7,5], [0,4,5,1],
714                                                  [1,5,7,3], [3,7,6,2], [2,6,4,0]]
715                                 vg_left = [2,6,4,0]
716                                 vg_right = [1,5,7,3]
717                                 vg_top = [4,6,7,5]
718                                 vg_bottom = [0,1,3,2]
719                                 vg_start = [0,4,5,1]
720                                 vg_end = [3,7,6,2]
721                         elif l == 3:
722                                 faces = [[0,1,2], [3,5,4], [0,3,4,1], [1,4,5,2], [2,5,3,0]]
723                                 vg_top = [3,4,5]
724                                 vg_bottom = [0,1,2]
725                                 vg_left = [2,5,3,0]
726                                 vg_right = [1,4,5,2]
727                                 vg_start = [0,3,4,1]
728                         elif l == 2: faces = [[0,1,3,2]]
729                 else:
730                         if   l == 4: faces = [[0,1,3,2]]
731                         elif l == 3: faces = [[0,1,2]]
732                         elif l == 2: edges = [[0,1]]
733                 
734                 if M_OBJ: obname, me, ob = makeNewObject()
735                 else: 
736                         me = Mesh.New(obname)           # create a new mesh
737                         ob = SCENE.objects.new(me) # create a new mesh_object
738                 me.verts.extend(points)         # add vertices to mesh
739                 if faces: me.faces.extend(faces)                   # add faces to the mesh
740                 if edges: me.edges.extend(edges)                   # add faces to the mesh
741
742                 if settings.var['vGroup_on'] and not M_OBJ:
743                         # each MeshSide becomes vertexGroup for easier material assignment ---------------------
744                         replace = Blender.Mesh.AssignModes.ADD  #or .AssignModes.ADD/REPLACE
745                         if vg_left: me.addVertGroup('side.left')  ; me.assignVertsToGroup('side.left',  vg_left, 1.0, replace)
746                         if vg_right:me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
747                         if vg_top:  me.addVertGroup('side.top')   ; me.assignVertsToGroup('side.top',   vg_top, 1.0, replace)
748                         if vg_bottom:me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
749                         if vg_start:me.addVertGroup('side.start') ; me.assignVertsToGroup('side.start', vg_start, 1.0, replace)
750                         if vg_end:  me.addVertGroup('side.end')   ; me.assignVertsToGroup('side.end',   vg_end,   1.0, replace)
751
752                 transform(self.extrusion, 0, ob)
753
754                 return ob
755
756 class Line:  #-----------------------------------------------------------------
757         """Class for objects representing dxf LINEs.
758         """
759         def __init__(self, obj):
760                 """Expects an entity object of type line as input.
761                 """
762                 if not obj.type == 'line':
763                         raise TypeError, "Wrong type \'%s\' for line object!" %obj.type
764                 self.type = obj.type
765 #               self.data = obj.data[:]
766
767                 self.space = getit(obj, 67, 0)
768                 self.thic =  getit(obj, 39, 0)
769                 #print 'deb:self.thic: ', self.thic #---------------------
770                 self.color_index = getit(obj, 62, BYLAYER)
771
772                 self.layer = getit(obj, 8, None)
773                 self.extrusion = get_extrusion(obj)
774                 self.points = self.get_points(obj)
775
776
777         def get_points(self, data):
778                 """Gets start and end points for a line type object.
779
780                 Lines have a fixed number of points (two) and fixed codes for each value.
781                 """
782                 # start x,y,z and end x,y,z = 0
783                 a = [0, 0, 0]
784                 b = [0, 0, 0]
785                 a[0] = getit(data, 10, None) # 10 = x
786                 a[1] = getit(data, 20, None) # 20 = y
787                 a[2] = getit(data, 30,  0) # 30 = z
788                 b[0] = getit(data, 11, None)
789                 b[1] = getit(data, 21, None)
790                 b[2] = getit(data, 31,  0)
791                 out = [a,b]
792                 return out
793
794
795         def __repr__(self):
796                 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
797
798
799         def draw(self, settings):
800                 """for LINE: generate Blender_geometry.
801                 """
802                 # Generate the geometery
803                 #settings.var['curves_on']=False
804
805                 points = self.points
806                 thic = set_thick(self.thic, settings)
807                 width = 0.0
808                 if settings.var['lines_as'] == 4: # as thin_box
809                         thic = settings.var['thick_min']
810                         width = settings.var['width_min']
811                 elif settings.var['lines_as'] == 3: # as thin cylinder
812                         cyl_rad = 0.5 * settings.var['width_min']
813
814                 elif settings.var['lines_as'] == 5: # LINE curve representation-------------------------
815                         obname = 'li_%s' %self.layer  # create object name from layer name
816                         obname = obname[:MAX_NAMELENGTH]
817
818                         c = Curve.New(obname) # create new curve data
819                         curve = c.appendNurb(BezTriple.New(points[0]))
820                         curve.append(BezTriple.New(points[1]))
821                         for point in curve:
822                                 point.handleTypes = [VECT, VECT]
823                                 point.radius = 1.0
824                         curve.flagU = 0 # 0 sets the curve not cyclic=open
825                         c.setResolu(settings.var['curve_res'])
826                         c.update() #important for handles calculation
827
828                         ob = SCENE.objects.new(c) # create a new curve_object
829
830                         #if False:  # --todo-- better support for 210-group
831                         if thic != 0.0: #hack: Blender2.45 curve-extrusion
832                                 t = thic * 0.5
833                                 if abs(t) > 5.0: t = 5.0 * cmp(t,0) # Blender2.45 accepts only (0.0 - 5.0)
834                                 e = self.extrusion
835                                 c.setExt1(abs(t))  # curve-extrusion
836                                 ob.LocX += t * e[0]
837                                 ob.LocY += t * e[1]
838                                 ob.LocZ += t * e[2]
839                                 #c.setExt1(1.0)  # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
840                                 #ob.LocZ = t + self.loc[2]
841                                 #ob.SizeZ *= abs(t)
842                         return ob
843
844                 else:  # LINE mesh representation ------------------------------
845                         global activObjectLayer
846                         global activObjectName
847                         #print 'deb:draw:line.ob IN activObjectName: ', activObjectName #---------------------
848         
849                         if M_OBJ: obname, me, ob = makeNewObject()
850                         else: 
851                                 if activObjectLayer == self.layer and settings.var['one_mesh_on']:
852                                         obname = activObjectName
853                                         #print 'deb:line.draw obname from activObjectName: ', obname #---------------------
854                                         ob = getSceneChild(obname)  # open an existing mesh_object
855                                         #ob = SCENE.getChildren(obname)  # open an existing mesh_object
856                                         #me = Mesh.Get(ob.name)   # open objects mesh data
857                                         me = ob.getData(name_only=False, mesh=True)
858                                 else:
859                                         obname = 'li_%s' %self.layer  # create object name from layer name
860                                         obname = obname[:MAX_NAMELENGTH]
861                                         me = Mesh.New(obname)             # create a new mesh
862                                         ob = SCENE.objects.new(me) # create a new mesh_object
863                                         activObjectName = ob.name
864                                         activObjectLayer = self.layer
865                                         #print ('deb:line.draw new line.ob+mesh:"%s" created!' %ob.name) #---------------------
866         
867                         faces, edges = [], []
868                         n = len(me.verts)
869
870                         #if settings.var['width_force']: #--todo-----------
871
872                         if thic != 0:
873                                 t, e = thic, self.extrusion
874                                 #print 'deb:thic, extr: ', t, e #---------------------
875                                 points.extend([[v[0]+t*e[0], v[1]+t*e[1], v[2]+t*e[2]] for v in points[:]])
876                                 faces = [[0+n, 1+n, 3+n, 2+n]]
877                         else:
878                                 edges = [[0+n, 1+n]]
879         
880                         me.verts.extend(points) # adds vertices to global mesh
881                         if faces: me.faces.extend(faces)           # add faces to the mesh
882                         if edges: me.edges.extend(edges)           # add faces to the mesh
883         
884                         if settings.var['vGroup_on'] and not M_OBJ:
885                                 # entities with the same color build one vertexGroup for easier material assignment ----
886                                 ob.link(me) # link mesh to that object
887                                 vG_name = 'color_%s' %self.color_index
888                                 if edges: faces = edges
889                                 replace = Blender.Mesh.AssignModes.ADD  #or .AssignModes.REPLACE or ADD
890                                 try:
891                                         me.assignVertsToGroup(vG_name,  faces[0], 1.0, replace)
892                                         #print 'deb: existed vGroup:', vG_name #---------------------
893                                 except:
894                                         me.addVertGroup(vG_name)
895                                         me.assignVertsToGroup(vG_name,  faces[0], 1.0, replace)
896                                         #print 'deb: create new vGroup:', vG_name #---------------------
897         
898         
899                         #print 'deb:draw:line.ob OUT activObjectName: ', activObjectName #---------------------
900                         return ob
901         
902
903
904 class Point:  #-----------------------------------------------------------------
905         """Class for objects representing dxf POINTs.
906         """
907         def __init__(self, obj):
908                 """Expects an entity object of type point as input.
909                 """
910                 if not obj.type == 'point':
911                         raise TypeError, "Wrong type %s for point object!" %obj.type
912                 self.type = obj.type
913 #               self.data = obj.data[:]
914
915                 self.space = getit(obj, 67, 0)
916                 self.thic =  getit(obj, 39, 0)
917                 #print 'deb:self.thic: ', self.thic #---------------------
918                 self.color_index = getit(obj, 62, BYLAYER)
919
920                 self.layer = getit(obj, 8, None)
921                 self.extrusion = get_extrusion(obj)
922                 self.points = self.get_points(obj)
923
924
925         def get_points(self, data):
926                 """Gets coordinates for a point type object.
927
928                 Points have fixed codes for each value.
929                 """
930                 a = [0, 0, 0]
931                 a[0] = getit(data, 10, None) # 10 = x
932                 a[1] = getit(data, 20, None) # 20 = y
933                 a[2] = getit(data, 30,  0) # 30 = z
934                 out = [a]
935                 return out
936
937
938         def __repr__(self):
939                 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
940
941
942         def draw(self, settings):
943                 """for POINT: generate Blender_geometry.
944                 """
945                 points = self.points
946                 obname = 'po_%s' %self.layer  # create object name from layer name
947                 obname = obname[:MAX_NAMELENGTH]
948                 points_as = settings.var['points_as']
949                 thic = settings.var['thick_min']
950                 if thic < settings.var['dist_min']: thic = settings.var['dist_min']
951
952                 if points_as in [1,3,4,5]:
953                         if True: # points_as in [1,5]: # as 'empty'
954                                 c = 'Empty'
955                         elif points_as == 3: # as 'thin sphere'
956                                 res = settings.var['thin_res']
957                                 c = Mesh.Primitives.UVsphere(res,res,thic)
958                         elif points_as == 4: # as 'thin box'
959                                 c = Mesh.Primitives.Cube(thic)
960                         ob = SCENE.objects.new(c, obname) # create a new object
961                         transform(self.extrusion, 0, ob)
962                         ob.loc = tuple(points[0])
963
964                 elif points_as == 2: # as 'vertex'
965                         global activObjectLayer
966                         global activObjectName
967                         #print 'deb:draw:point.ob IN activObjectName: ', activObjectName #---------------------
968                         if M_OBJ: obname, me, ob = makeNewObject()
969                         else: 
970                                 if activObjectLayer == self.layer and settings.var['one_mesh_on']:
971                                         obname = activObjectName
972                                         #print 'deb:draw:point.ob obname from activObjectName: ', obname #---------------------
973                                         ob = getSceneChild(obname)  # open an existing mesh_object
974                                         #ob = SCENE.getChildren(obname)  # open an existing mesh_object
975                                         me = ob.getData(name_only=False, mesh=True)
976                                         #me = Mesh.Get(ob.name)   # open objects mesh data
977                                 else:
978                                         me = Mesh.New(obname)             # create a new mesh
979                                         ob = SCENE.objects.new(me) # create a new mesh_object
980                                         activObjectName = ob.name
981                                         activObjectLayer = self.layer
982                                         #print ('deb:draw:point new point.ob+mesh:"%s" created!' %ob.name) #---------------------
983                         me.verts.extend(points) # add vertices to mesh
984
985                 return ob
986
987
988
989 class Polyline:  #-----------------------------------------------------------------
990         """Class for objects representing dxf POLYLINEs.
991         """
992         def __init__(self, obj):
993                 """Expects an entity object of type polyline as input.
994                 """
995                 #print 'deb:polyline.init.START:----------------' #------------------------
996                 if not obj.type == 'polyline':
997                         raise TypeError, "Wrong type %s for polyline object!" %obj.type
998                 self.type = obj.type
999 #               self.data = obj.data[:]
1000
1001                 self.space = getit(obj, 67, 0)
1002                 self.elevation =  getit(obj, 30, 0)
1003                 #print 'deb:elevation: ', self.elevation #---------------
1004                 self.thic =  getit(obj, 39, 0)
1005                 self.color_index = getit(obj, 62, BYLAYER)
1006
1007                 self.flags = getit(obj, 70, 0)
1008                 self.closed = self.flags & 1   # closed in the M direction
1009                 self.curved = self.flags & 2   # Bezier-curve-fit vertices have been added
1010                 self.spline = self.flags & 4   # NURBS-curve-fit vertices have been added
1011                 self.poly3d = self.flags & 8   # 3D-polyline
1012                 self.plmesh = self.flags & 16  # 3D-polygon mesh
1013                 self.closeN = self.flags & 32  # closed in the N direction
1014                 self.plface = self.flags & 64  # 3D-polyface mesh
1015                 self.contin = self.flags & 128 # the linetype pattern is generated continuously
1016
1017                 self.pltype='poly2d'   # default is a 2D-polyline
1018                 if self.poly3d: self.pltype='poly3d'
1019                 elif self.plface: self.pltype='plface'
1020                 elif self.plmesh: self.pltype='plmesh'
1021
1022                 self.swidth =  getit(obj, 40, 0) # default start width
1023                 self.ewidth =  getit(obj, 41, 0) # default end width
1024                 #self.bulge  =  getit(obj, 42, None) # bulge of the segment
1025                 self.vectorsM =  getit(obj, 71, None) # PolyMesh: expansion in M-direction / PolyFace: number of the vertices
1026                 self.vectorsN =  getit(obj, 72, None) # PolyMesh: expansion in M-direction / PolyFace: number of faces
1027                 #self.resolM =  getit(obj, 73, None) # resolution of surface in M direction
1028                 #self.resolN =  getit(obj, 74, None) # resolution of surface in N direction
1029                 self.curvNoFitted = False
1030                 self.curvQuadrati = False
1031                 self.curvCubicBsp = False
1032                 self.curvBezier = False
1033                 curvetype =  getit(obj, 75, 0) # type of curve/surface: 0=None/5=Quadric/6=Cubic/8=Bezier
1034                 if   curvetype == 0: self.curvNoFitted = True
1035                 elif curvetype == 5: self.curvQuadrati = True
1036                 elif curvetype == 6: self.curvCubicBsp = True
1037                 elif curvetype == 8: self.curvBezier = True
1038
1039                 self.layer = getit(obj, 8, None)
1040                 self.extrusion = get_extrusion(obj)
1041
1042                 self.points = []  #list with vertices coordinats
1043                 self.faces  = []  #list with vertices assigment to faces
1044                 #print 'deb:polyline.init.ENDinit:----------------' #------------
1045
1046
1047
1048         def __repr__(self):
1049                 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
1050
1051
1052
1053         def doubles_out(self, settings, d_points):
1054                 """routine to sort out of double.vertices-----------------------------
1055                 """
1056                 minimal_dist =  settings.var['dist_min'] * 0.1
1057                 dv_count = 0
1058                 temp_points = []
1059                 for i in xrange(len(d_points)-1):
1060                         point = d_points[i]
1061                         point2 = d_points[i+1]
1062                         #print 'deb:double.vertex p1,p2', point, point2 #------------------------
1063                         delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
1064                         if delta.length > minimal_dist:
1065                                  temp_points.append(point)
1066                         else:
1067                                 dv_count+=1
1068                 #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
1069                 temp_points.append(d_points[-1])  #------ incl. last vertex -------------
1070                 #if self.closed: temp_points.append(d_points[1])  #------ loop start vertex -------------
1071                 d_points = temp_points   #-----vertex.list without "double.vertices"
1072                 #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1073                 return d_points
1074
1075
1076         def tribles_out(self, settings, d_points):
1077                 """routine to sort out of three_in_place.vertices-----------------------------
1078                 """
1079                 minimal_dist = settings.var['dist_min'] * 0.1
1080                 dv_count = 0
1081                 temp_points = []
1082                 for i in xrange(len(d_points)-2):
1083                         point1 = d_points[i]
1084                         point2 = d_points[i+1]
1085                         point3 = d_points[i+2]
1086                         #print 'deb:double.vertex p1,p2', point, point2 #------------------------
1087                         delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
1088                         delta23 = Mathutils.Vector(point3.loc) - Mathutils.Vector(point2.loc)
1089                         if delta12.length < minimal_dist and delta23.length < minimal_dist:
1090                                 dv_count+=1
1091                         else:
1092                                 temp_points.append(point1)
1093                 #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
1094                 point1 = d_points[-2]
1095                 point2 = d_points[-1]
1096                 delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
1097                 if delta12.length > minimal_dist:
1098                         temp_points.append(d_points[-2])  #------ incl. 2last vertex -------------
1099                 temp_points.append(d_points[-1])  #------ incl. 1last vertex -------------
1100                 #if self.closed: temp_points.append(d_points[1])  #------ loop start vertex -------------
1101                 d_points = temp_points   #-----vertex.list without "double.vertices"
1102                 #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1103                 return d_points
1104
1105
1106         def draw(self, settings):   #-------------%%%% DRAW POLYLINE %%%---------------
1107                 """for POLYLINE: generate Blender_geometry.
1108                 """
1109                 #print 'deb:drawPOLYLINE.START:----------------' #------------------------
1110                 #print 'deb:POLYLINEdraw self.pltype:', self.pltype #------------------------
1111                 #print 'deb:POLYLINEdraw self.points:\n', self.points #------------------------
1112                 ob = []
1113                 #---- 3dPolyFace - mesh with free topology
1114                 if self.pltype=='plface' and settings.drawTypes['plmesh']:
1115                         ob = self.drawPlFace(settings)
1116                 #---- 3dPolyMesh - mesh with ortogonal topology
1117                 elif self.pltype=='plmesh' and settings.drawTypes['plmesh']:
1118                         ob = self.drawPlMesh(settings)
1119
1120                 #---- 2dPolyline - plane polyline with arc/wide/thic segments
1121                 elif self.pltype=='poly2d' and settings.drawTypes['polyline']:
1122                         if settings.var['plines_as'] in [5,6]: # and self.spline:
1123                                 ob = self.drawPolyCurve(settings)
1124                         else:
1125                                 ob = self.drawPoly2d(settings)
1126
1127                 #---- 3dPolyline - non-plane polyline (thin segments = without arc/wide/thic)
1128                 elif self.pltype=='poly3d' and settings.drawTypes['pline3']:
1129                         if settings.var['plines3_as'] in [5,6]: # and self.spline:
1130                                 ob = self.drawPolyCurve(settings)
1131                         else:
1132                                 ob = self.drawPoly2d(settings)
1133
1134                 #---- Spline - curved polyline (thin segments = without arc/wide/thic)
1135                 elif self.pltype=='spline' and settings.drawTypes['spline']:
1136                         if settings.var['splines_as'] in [5,6]:
1137                                 ob = self.drawPolyCurve(settings)
1138                         else:
1139                                 ob = self.drawPoly2d(settings)
1140                 return ob
1141
1142
1143         def drawPlFace(self, settings):  #---- 3dPolyFace - mesh with free topology
1144                 """Generate the geometery of polyface.
1145                 """
1146                 #print 'deb:drawPlFace.START:----------------' #------------------------
1147                 points = []
1148                 faces = []
1149                 #print 'deb:len of pointsList ====== ', len(self.points) #------------------------
1150                 for point in self.points:
1151                         if point.face:
1152                                 faces.append(point.face)
1153                         else:
1154                                 points.append(point.loc)
1155
1156                 if settings.var['plmesh_flip']:  # ----------------------
1157                         for face in faces:
1158                                 face.reverse()
1159                                 face = [face[-1]] + face[:-1]
1160
1161                 #print 'deb:drawPlFace: len of points_list:\n', len(points)  #-----------------------
1162                 #print 'deb:drawPlFace: len of faces_list:\n', len(faces)  #-----------------------
1163                 #print 'deb:drawPlFace: points_list:\n', points  #-----------------------
1164                 #print 'deb:drawPlFace: faces_list:\n', faces  #-----------------------
1165                 obname = 'pf_%s' %self.layer  # create object name from layer name
1166                 obname = obname[:MAX_NAMELENGTH]
1167                 me = Mesh.New(obname)             # create a new mesh
1168                 ob = SCENE.objects.new(me) # create a new mesh_object
1169                 me.verts.extend(points) # add vertices to mesh
1170                 me.faces.extend(faces)   # add faces to the mesh
1171                 if settings.var['normals_out']:  # ----------------------
1172                         #me.flipNormals()
1173                         me.recalcNormals(0)
1174                         #me.update()
1175                 #print 'deb:drawPlFace: len of me.faces:\n', len(me.faces)  #-----------------------
1176
1177                 if settings.var['meshSmooth_on']:  # ----------------------
1178                         for i in xrange(len(me.faces)):
1179                                 me.faces[i].smooth = True
1180                         #me.Mode(AUTOSMOOTH)
1181                 transform(self.extrusion, 0, ob)
1182                 #print 'deb:drawPlFace.END:----------------' #------------------------
1183                 return ob
1184
1185
1186
1187         def drawPlMesh(self, settings):  #---- 3dPolyMesh - mesh with orthogonal topology
1188                 """Generate the geometery of polymesh.
1189                 """
1190                 #print 'deb:polymesh.draw.START:----------------' #------------------------
1191                 #points = []
1192                 #print 'deb:len of pointsList ====== ', len(self.points) #------------------------
1193                 faces = []
1194                 m = self.vectorsM
1195                 n = self.vectorsN
1196                 for j in xrange(m - 1):
1197                         for i in xrange(n - 1):
1198                                 nn = j * n
1199                                 faces.append([nn+i, nn+i+1, nn+n+i+1, nn+n+i])
1200
1201                 if self.closed:   #mesh closed in N-direction
1202                         nn = (m-1)*n
1203                         for i in xrange(n - 1):
1204                                 faces.append([nn+i, nn+i+1, i+1, i])
1205
1206                 if self.closeN:   #mesh closed in M-direction
1207                         for j in xrange(m-1):
1208                                 nn = j * n
1209                                 faces.append([nn+n-1, nn, nn+n, nn+n-1+n])
1210
1211                 if self.closed and self.closeN:   #mesh closed in M/N-direction
1212                                 faces.append([ (n*m)-1, (m-1)*n, 0, n-1])
1213
1214                 #print 'deb:len of points_list:\n', len(points)  #-----------------------
1215                 #print 'deb:faces_list:\n', faces  #-----------------------
1216                 obname = 'pm_%s' %self.layer  # create object name from layer name
1217                 obname = obname[:MAX_NAMELENGTH]
1218                 me = Mesh.New(obname)             # create a new mesh
1219                 ob = SCENE.objects.new(me) # create a new mesh_object
1220                 me.verts.extend([point.loc for point in self.points]) # add vertices to mesh
1221                 me.faces.extend(faces)   # add faces to the mesh
1222                 if settings.var['normals_out']:  # ----------------------
1223                         #me.flipNormals()
1224                         me.recalcNormals(0)
1225                         #me.update()
1226                 if settings.var['meshSmooth_on']:  # ----------------------
1227                         for i in xrange(len(faces)):
1228                                 me.faces[i].smooth = True
1229                         #me.Mode(AUTOSMOOTH)
1230
1231                 transform(self.extrusion, 0, ob)
1232                 #print 'deb:polymesh.draw.END:----------------' #------------------------
1233                 return ob
1234
1235
1236         def drawPolyCurve(self, settings):  #---- Polyline - draw as Blender-curve
1237                 """Generate the geometery of polyline as Blender-curve.
1238                 """
1239                 #print 'deb:polyline2dCurve.draw.START:----------------' #---
1240                 if len(self.points) < 2:
1241                         #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
1242                         return
1243
1244                 if self.spline: pline_typ = 'ps'        # Polyline-NURBSpline
1245                 elif self.curved: pline_typ = 'pc'      # Polyline-BezierCurve
1246                 else: pline_typ = 'pl'                          # Polyline classic
1247                 obname = '%s_%s' %(pline_typ, self.layer)  # create object_name from layer name
1248                 obname = obname[:MAX_NAMELENGTH]
1249                 d_points = []
1250
1251                 if settings.var['Z_force_on']:
1252                         self.elevation = settings.var['Z_elev']
1253                         for point in self.points:
1254                                 point.loc[2] = self.elevation
1255                                 d_points.append(point)
1256                 else: #for DXFr10-format: update all points[].loc[2] == None -> 0.0 
1257                         for point in self.points:
1258                                 if point.loc[2] == None:
1259                                         point.loc[2] = self.elevation
1260                                 d_points.append(point)
1261
1262                 #d_points = self.tribles_out(settings, d_points)
1263                 #d_points = self.doubles_out(settings, d_points)
1264                 #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1265
1266                 thic = set_thick(self.thic, settings)
1267                 if thic != 0.0:   #hack: Blender<2.45 curve-extrusion
1268                         LocZ = d_points[0].loc[2]
1269                         temp_points = []
1270                         for point in d_points:
1271                                 point.loc[2] = 0.0
1272                                 temp_points.append(point)
1273                         d_points = temp_points
1274                 
1275                 #print 'deb:polyline2dCurve.draw d_points=', d_points  #---------------
1276                 pline = Curve.New(obname)   # create new curve data
1277                 #pline.setResolu(24) #--todo-----                                               
1278
1279                 if False: #old self.spline:  # NURBSplines-----OK-----
1280                         #print 'deb:polyline2dCurve.draw self.spline!' #---------------
1281                         weight1 = 0.5
1282                         weight2 = 1.0
1283                         if self.curvQuadrati:
1284                                 # Bezier-curve form simulated in NURBS-curve
1285                                 # generate middlepoints except start/end-segments ---
1286                                 #print 'deb:polyline2dCurve.draw extraQBspline!' #---------------
1287                                 temp_points = []
1288                                 point = d_points[0].loc
1289                                 point.append(weight1)
1290                                 temp_points.append(point)
1291                                 for i in xrange(1,len(d_points)-2):
1292                                         point1 = d_points[i].loc
1293                                         point2 = d_points[i+1].loc
1294                                         mpoint = list((Mathutils.Vector(point1) + Mathutils.Vector(point2)) * 0.5)
1295                                         mpoint.append(weight2)
1296                                         point1.append(weight1)
1297                                         temp_points.append(point1)
1298                                         temp_points.append(mpoint)
1299                                 point2.append(weight1)
1300                                 temp_points.append(point2)
1301                                 point = d_points[-1].loc
1302                                 point.append(weight1)
1303                                 temp_points.append(point)
1304                                 d_points = temp_points
1305                         else:
1306                                 temp_points = []
1307                                 for d in d_points:
1308                                         d = d.loc
1309                                         d.append(weight1)
1310                                         temp_points.append(d)
1311                                 d_points = temp_points
1312
1313                         if not self.closed:
1314                                 # generate extended startpoint and endpoint------
1315                                 point1 = Mathutils.Vector(d_points[0][:3])
1316                                 point2 = Mathutils.Vector(d_points[1][:3])
1317                                 startpoint = list(point1 - point2 + point1)
1318                                 startpoint.append(weight1)
1319                                 point1 = Mathutils.Vector(d_points[-1][:3])
1320                                 point2 = Mathutils.Vector(d_points[-2][:3])
1321                                 endpoint = list(point1 - point2 + point1)
1322                                 endpoint.append(weight1)
1323                                 temp_points = []
1324                                 temp_points.append(startpoint)
1325                                 temp_points.extend(d_points)
1326                                 d_points = temp_points
1327                                 d_points.append(endpoint)
1328
1329                         point = d_points[0]
1330                         curve = pline.appendNurb(point)
1331                         curve.setType(4) #NURBS curve
1332                         for point in d_points[1:]:
1333                                 curve.append(point)
1334                         if self.closed:
1335                                 curve.flagU = 1 # Set curve cyclic=close
1336                         else:
1337                                 curve.flagU = 0 # Set curve not cyclic=open
1338
1339                 if self.spline:  # NURBSplines-----OK-----
1340                         #print 'deb:polyline2dCurve.draw self.spline!' #---------------
1341                         nurbs_points = []
1342                         for d in d_points:
1343                                 pkt = d.loc
1344                                 pkt.append(d.weight)
1345                                 nurbs_points.append(pkt)
1346                         firstpoint = nurbs_points[0]
1347                         curve = pline.appendNurb(firstpoint)
1348                         curve.setType(4) # set curve_type NURBS
1349                         print 'deb: dir(curve):', dir(curve[-1]) #----------------
1350                         for point in nurbs_points[1:]:
1351                                 curve.append(point)
1352                                 #TODO: what is the trick for bevel radius? curve[-1].radius = 1.0
1353                         if self.closed:
1354                                 curve.flagU = 1+0 # Set curve cyclic=close and uni
1355                         else:
1356                                 curve.flagU = 0+2 # Set curve not cyclic=open
1357                         try: curve.orderU = 5 # works only with >2.46svn080625
1358                         except AttributeError: pass
1359                         #print 'deb: dir(curve):', dir(curve) #----------------
1360
1361                 elif  False: #orig self.curved:  #--Bezier-curves---OK-------
1362                         #print 'deb:polyline2dCurve.draw self.curved!' #---------------
1363                         curve = pline.appendNurb(BezTriple.New(d_points[0]))
1364                         for p in d_points[1:]:
1365                                 curve.append(BezTriple.New(p))
1366                         for point in curve:
1367                                 point.handleTypes = [AUTO, AUTO]
1368                                 point.radius = 1.0
1369                         if self.closed:
1370                                 curve.flagU = 1 # Set curve cyclic=close
1371                         else:
1372                                 curve.flagU = 0 # Set curve not cyclic=open
1373                                 curve[0].handleTypes = [FREE, ALIGN]   #remi--todo-----
1374                                 curve[-1].handleTypes = [ALIGN, FREE]   #remi--todo-----
1375
1376                 elif  self.curved:  #--SPLINE as Bezier-curves---wip------
1377                         #print 'deb:polyline2dCurve.draw self.curved!' #---------------
1378                         begtangent, endtangent = None, None
1379                         if d_points[0].tangent:
1380                                 begtangent = d_points[0]
1381                                 d_points = d_points[1:]
1382                         if d_points[-1].tangent:
1383                                 endtangent = d_points[-1]
1384                                 d_points = d_points[:-1]
1385                         curve = pline.appendNurb(BezTriple.New(d_points[0]))
1386                         for p in d_points[1:]:
1387                                 curve.append(BezTriple.New(p))
1388                         for point in curve:
1389                                 point.handleTypes = [AUTO, AUTO]
1390                                 point.radius = 1.0
1391                         #curve.setType(1) #Bezier curve
1392                         if self.closed:
1393                                 curve.flagU = 5 #1 # Set curve cyclic=close
1394                         else:
1395                                 curve.flagU = 4 #0 # Set curve not cyclic=open
1396                                 if begtangent:
1397                                         #print 'deb:polyline2dCurve.draw curve[0].vec:', curve[0].vec #-----
1398                                         #print 'deb:polyline2dCurve.draw begtangent:', begtangent #-----
1399                                         p0h1,p0,p0h2 = curve[0].vec 
1400                                         p0h1 = [p0h1[i]+begtangent[i] for i in range(3)]
1401                                         curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
1402                                 curve[0].handleTypes = [FREE, ALIGN]   #remi--todo-----
1403                                 curve[0].radius = 1.0
1404                                 if endtangent:
1405                                         #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
1406                                         #print 'deb:polyline2dCurve.draw endtangent:', endtangent #-----
1407                                         p0h1,p0,p0h2 = curve[-1].vec 
1408                                         p0h2 = [p0h2[i]+endtangent[i] for i in range(3)]
1409                                         #print 'deb:drawPlineCurve: p0h2:', p0h2 #----------
1410                                         curve.__setitem__(-1,BezTriple.New(p0h1+p0+p0h2))
1411                                         #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
1412                                 curve[-1].handleTypes = [ALIGN, FREE]   #remi--todo-----
1413                                 curve[-1].radius = 1.0
1414
1415
1416
1417                 else:   #-- only straight line- and arc-segments----OK------
1418                         #print 'deb:polyline2dCurve.draw curve:', curve #-----
1419                         points = []
1420                         arc_res = settings.var['curve_arc']
1421                         prevHandleType = VECT
1422                         #d_points.append(d_points[0])  #------ first vertex added at the end of list --------
1423                         #curve.setType(0) #polygon_type of Blender_curve
1424                         for i in xrange(len(d_points)):
1425                                 point1 = d_points[i]
1426                                 #point2 = d_points[i+1]
1427                                 if False: #-----outdated!- standard calculation ----------------------------------
1428                                         if point1.bulge and (i < len(d_points)-2 or self.closed):
1429                                                 verts, center = calcBulge(point1, point2, arc_res, triples=False)
1430                                                 if i == 0: curve = pline.appendNurb(BezTriple.New(verts[0]))
1431                                                 else: curve.append(BezTriple.New(verts[0]))
1432                                                 curve[-1].handleTypes = [VECT, VECT]  #--todo--calculation of bezier-tangents
1433                                                 curve[-1].radius = 1.0
1434                                                 for p in verts[1:]:
1435                                                         curve.append(BezTriple.New(p))
1436                                                         curve[-1].handleTypes = [AUTO, AUTO]
1437                                                         curve[-1].radius = 1.0
1438                                         else:
1439                                                 if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
1440                                                 else: curve.append(BezTriple.New(point1.loc))
1441                                                 curve[-1].handleTypes = [VECT, VECT]   #--todo--calculation of bezier-tangents
1442                                                 curve[-1].radius = 1.0
1443
1444                                 elif True:   #----- optimised Bezier-Handles calculation --------------------------------
1445                                         #print 'deb:drawPlineCurve: i:', i #---------
1446                                         if point1.bulge and not (i == len(d_points)-1 and point1.bulge and not self.closed):
1447                                                 if i == len(d_points)-1: point2 = d_points[0]
1448                                                 else: point2 = d_points[i+1]
1449
1450
1451                                                 # calculate additional points for bulge
1452                                                 VectorTriples = calcBulge(point1, point2, arc_res, triples=True)
1453
1454                                                 if prevHandleType == FREE:
1455                                                         #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
1456                                                         VectorTriples[0][:3] = prevHandleVect
1457                                                         #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
1458
1459                                                 if i == 0: curve = pline.appendNurb(BezTriple.New(VectorTriples[0]))
1460                                                 else: curve.append(BezTriple.New(VectorTriples[0]))
1461                                                 curve[-1].handleTypes = [prevHandleType, FREE]
1462                                                 curve[-1].radius = 1.0
1463
1464                                                 for p in VectorTriples[1:-1]:
1465                                                         curve.append(BezTriple.New(p))
1466                                                         curve[-1].handleTypes = [FREE, FREE]
1467                                                         curve[-1].radius = 1.0
1468
1469                                                 prevHandleVect = VectorTriples[-1][:3]
1470                                                 prevHandleType = FREE
1471                                                 #print 'deb:drawPlineCurve: prevHandleVect:', prevHandleVect #---------
1472                                         else:
1473                                                 #print 'deb:drawPlineCurve: else' #----------
1474                                                 if prevHandleType == FREE:
1475                                                         VectorTriples = prevHandleVect + list(point1) + list(point1)
1476                                                         #print 'deb:drawPlineCurve: VectorTriples:', VectorTriples #---------
1477                                                         curve.append(BezTriple.New(VectorTriples))
1478                                                         curve[-1].handleTypes = [FREE, VECT]
1479                                                         prevHandleType = VECT
1480                                                         curve[-1].radius = 1.0
1481                                                 else:
1482                                                         if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
1483                                                         else: curve.append(BezTriple.New(point1.loc))
1484                                                         curve[-1].handleTypes = [VECT, VECT]
1485                                                         curve[-1].radius = 1.0
1486
1487
1488
1489                                         #print 'deb:drawPlineCurve: curve[-1].vec[0]', curve[-1].vec[0] #----------
1490
1491                         if self.closed:
1492                                 curve.flagU = 1 # Set curve cyclic=close
1493                                 if prevHandleType == FREE:
1494                                         #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
1495                                         #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
1496                                         prevHandleType2 = curve[0].handleTypes[1]
1497                                         p0h1,p0,p0h2 = curve[0].vec 
1498                                         #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
1499                                         p0h1 = prevHandleVect
1500                                         #p0h1 = [0,0,0]
1501                                         #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
1502                                         #curve[0].vec = [p0h1,p0,p0h2]
1503                                         curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
1504
1505                                         curve[0].handleTypes = [FREE,prevHandleType2]
1506                                         curve[0].radius = 1.0
1507                                         #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
1508                                         #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
1509                                 else: 
1510                                         curve[0].handleTypes[0] = VECT
1511                                         curve[0].radius = 1.0
1512                         else: 
1513                                 curve.flagU = 0 # Set curve not cyclic=open
1514
1515                 if settings.var['fill_on']:
1516                         pline.setFlag(6) # 2+4 set top and button caps
1517                 else:
1518                         pline.setFlag(pline.getFlag() & ~6) # dont set top and button caps
1519
1520                 pline.setResolu(settings.var['curve_res'])
1521                 pline.update()
1522                 ob = SCENE.objects.new(pline) # create a new curve_object
1523
1524                 if thic != 0.0: #hack: Blender<2.45 curve-extrusion
1525                         thic = thic * 0.5
1526                         pline.setExt1(1.0)  # curve-extrusion accepts only (0.0 - 2.0)
1527                         ob.LocZ = thic + LocZ
1528
1529                 transform(self.extrusion, 0, ob)
1530                 if thic != 0.0:
1531                         ob.SizeZ *= abs(thic)
1532
1533                 #print 'deb:polyline2dCurve.draw.END:----------------' #-----
1534                 return ob
1535
1536
1537         def drawPoly2d(self, settings):  #---- 2dPolyline - plane lines/arcs with wide/thic
1538                 """Generate the geometery of regular polyline.
1539                 """
1540                 #print 'deb:polyline2d.draw.START:----------------' #------------------------
1541                 points = []
1542                 d_points = []
1543                 swidths = []
1544                 ewidths = []
1545                 swidth_default = self.swidth #default start width of POLYLINEs segments
1546                 ewidth_default = self.ewidth #default end width of POLYLINEs segments
1547                 #print 'deb:drawPoly2d self.swidth=', self.swidth #------------------------
1548                 thic = set_thick(self.thic, settings)
1549                 if self.spline: pline_typ = 'ps'
1550                 elif self.curved: pline_typ = 'pc'
1551                 else: pline_typ = 'pl'
1552                 obname = '%s_%s' %(pline_typ, self.layer)  # create object_name from layer name
1553                 obname = obname[:MAX_NAMELENGTH]
1554
1555                 if len(self.points) < 2:
1556                         #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
1557                         return
1558                 
1559                 if settings.var['Z_force_on']:
1560                         self.elevation = settings.var['Z_elev']
1561                         for point in self.points:
1562                                 point.loc[2] = self.elevation
1563                                 d_points.append(point)
1564                 else: #for DXFr10-format: update all non-existing LocZ points[].loc[2] == None -> 0.0 elevation
1565                         for point in self.points:
1566                                 if point.loc[2] == None:
1567                                         point.loc[2] = self.elevation
1568                                 d_points.append(point)
1569                 #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1570                 #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
1571
1572
1573                 #if closed polyline, add duplic of the first vertex at the end of pointslist
1574                 if self.closed:  #new_b8
1575                         if d_points[-1].loc != d_points[0].loc: # if not equal, then set the first at the end of pointslist
1576                                 d_points.append(d_points[0])
1577                 else:
1578                         if d_points[-1].loc == d_points[0].loc: # if equal, then set to closed, and modify the last point
1579                                 d_points[-1] = d_points[0]
1580                                 self.closed = True
1581                 #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1582                 #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
1583
1584                 d_points = self.doubles_out(settings, d_points)
1585                 #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1586
1587                 """# routine to sort out of "double.vertices" ------------------------------------
1588                 minimal_dist =  settings.var['dist_min'] * 0.1
1589                 temp_points = []
1590                 for i in xrange(len(d_points)-1):
1591                         point = d_points[i]
1592                         point2 = d_points[i+1]
1593                         #print 'deb:double.vertex p1,p2', point, point2 #------------------------
1594                         delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
1595                         if delta.length > minimal_dist:
1596                                  temp_points.append(point)
1597                         #else: print 'deb:drawPoly2d double.vertex sort out!' #------------------------
1598                 temp_points.append(d_points[-1])  #------ incl. last vertex -------------
1599                 #if self.closed: temp_points.append(d_points[1])  #------ loop start vertex -------------
1600                 d_points = temp_points   #-----vertex.list without "double.vertices"
1601                 #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1602                 """
1603
1604                 #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1605                 if len(d_points) < 2:  #if too few vertex, then return
1606                         #print 'deb:drawPoly2d corrupted Vertices' #---------
1607                         return
1608
1609                 # analyze of straight- and bulge-segments
1610                 # generation of additional points for bulge segments
1611                 arc_res = settings.var['arc_res']/sqrt(settings.var['arc_rad'])
1612                 wide_segment_exist = False
1613                 bulg_points = []  # for each point set None (or center for arc-subPoints)
1614                 for i in xrange(len(d_points)-1):
1615                         point1 = d_points[i]
1616                         point2 = d_points[i+1]
1617                         #print 'deb:drawPoly2d_bulg tocalc.point1:', point1 #------------------------
1618                         #print 'deb:drawPoly2d_bulg tocalc.point2:', point2 #------------------------
1619
1620                         swidth = point1.swidth
1621                         ewidth = point1.ewidth
1622                         #print 'deb:drawPoly2d point1.swidth=', swidth #------------------------
1623                         if swidth == None: swidth = swidth_default
1624                         if ewidth == None: ewidth = ewidth_default
1625                         if swidth != 0.0 or ewidth != 0.0: wide_segment_exist = True
1626                         #print 'deb:drawPoly2d vertex_swidth=', swidth #------------------------
1627
1628                         if settings.var['width_force']:  # force minimal width for thin segments
1629                                 width_min = settings.var['width_min']
1630                                 if swidth < width_min: swidth = width_min
1631                                 if ewidth < width_min: ewidth = width_min
1632                                 if not settings.var['width_on']:  # then force minimal width for all segments
1633                                         swidth = width_min
1634                                         ewidth = width_min
1635
1636                         #if point1.bulge and (i < (len(d_points)-1) or self.closed):
1637                         if point1.bulge and i < (len(d_points)-1): #10_b8
1638                                 verts, center = calcBulge(point1, point2, arc_res) #calculate additional points for bulge
1639                                 points.extend(verts)
1640                                 delta_width = (ewidth - swidth) / len(verts)
1641                                 width_list = [swidth + (delta_width * ii) for ii in xrange(len(verts)+1)]
1642                                 swidths.extend(width_list[:-1])
1643                                 ewidths.extend(width_list[1:])
1644                                 bulg_list = [center for ii in xrange(len(verts))]
1645                                 #the last point in bulge has index False for better indexing of bulg_end!
1646                                 bulg_list[-1] = None
1647                                 bulg_points.extend(bulg_list)
1648
1649                         else:
1650                                 points.append(point1.loc)
1651                                 swidths.append(swidth)
1652                                 ewidths.append(ewidth)
1653                                 bulg_points.append(None)
1654                 points.append(d_points[-1].loc)
1655
1656
1657                 #--calculate width_vectors: left-side- and right-side-points ----------------
1658                 # 1.level:IF width  ---------------------------------------
1659                 if (settings.var['width_on'] and wide_segment_exist) or settings.var['width_force']:
1660                         #new_b8 points.append(d_points[0].loc)  #temporarly add first vertex at the end (for better loop)
1661                         dist_min05 = 0.5 * settings.var['dist_min'] #minimal width for zero_witdh
1662                         
1663                         pointsLs = []   # list of left-start-points
1664                         pointsLe = []   # list of left-end-points
1665                         pointsRs = []   # list of right-start-points
1666                         pointsRe = []   # list of right-end-points
1667                         pointsW  = []   # list of all border-points
1668                         #rotMatr90 = Mathutils.Matrix(rotate 90 degree around Z-axis) = normalvectorXY
1669                         rotMatr90 = Mathutils.Matrix([0, -1, 0], [1, 0, 0], [0, 0, 1])
1670                         bulg_in = False
1671                         last_bulg_point = False
1672                         for i in xrange(len(points)-1):
1673                                 point1 = points[i]
1674                                 point2 = points[i+1]
1675                                 point1vec = Mathutils.Vector(point1)
1676                                 point2vec = Mathutils.Vector(point2)
1677                                 swidth05 = swidths[i] * 0.5
1678                                 ewidth05 = ewidths[i] * 0.5
1679                                 if swidth05 == 0: swidth05 = dist_min05
1680                                 if ewidth05 == 0: ewidth05 = dist_min05
1681                                 normal_vector = rotMatr90 * (point2vec-point1vec).normalize()
1682                                 if last_bulg_point:
1683                                         last_bulg_point = False
1684                                         bulg_in = True
1685                                 elif bulg_points[i] != None:
1686                                         centerVec = Mathutils.Vector(bulg_points[i])
1687                                         if bulg_points[i+1] == None: last_bulg_point = True
1688                                         bulg_in = True
1689                                 else: bulg_in = False
1690
1691                                 if bulg_in:
1692                                         #makes clean intersections for arc-segments
1693                                         radius1vec = point1vec - centerVec
1694                                         radius2vec = point2vec - centerVec
1695                                         angle = Mathutils.AngleBetweenVecs(normal_vector, radius1vec)
1696                                         if angle < 90.0:
1697                                                 normal_vector1 = radius1vec.normalize()
1698                                                 normal_vector2 = radius2vec.normalize()
1699                                         else:   
1700                                                 normal_vector1 = - radius1vec.normalize()
1701                                                 normal_vector2 = - radius2vec.normalize()
1702
1703                                         swidth05vec = swidth05 * normal_vector1
1704                                         ewidth05vec = ewidth05 * normal_vector2
1705                                         pointsLs.append(point1vec + swidth05vec) #vertex left start
1706                                         pointsRs.append(point1vec - swidth05vec) #vertex right start
1707                                         pointsLe.append(point2vec + ewidth05vec) #vertex left end
1708                                         pointsRe.append(point2vec - ewidth05vec) #vertex right end
1709
1710                                 else:
1711                                         swidth05vec = swidth05 * normal_vector
1712                                         ewidth05vec = ewidth05 * normal_vector
1713                                         pointsLs.append(point1vec + swidth05vec) #vertex left start
1714                                         pointsRs.append(point1vec - swidth05vec) #vertex right start
1715                                         pointsLe.append(point2vec + ewidth05vec) #vertex left end
1716                                         pointsRe.append(point2vec - ewidth05vec) #vertex right end
1717         
1718                         # additional last point is also calculated
1719                         #pointsLs.append(pointsLs[0])
1720                         #pointsRs.append(pointsRs[0])
1721                         #pointsLe.append(pointsLe[0])
1722                         #pointsRe.append(pointsRe[0])
1723
1724                         pointsLc, pointsRc = [], [] # lists Left/Right corners = intersection points
1725
1726                         # 2.level:IF width and corner-trim
1727                         if settings.var['pl_trim_on']:  #optional clean corner-intersections
1728                                 # loop preset
1729                                 # set STARTpoints of the first point points[0]
1730                                 if not self.closed:
1731                                         pointsLc.append(pointsLs[0])
1732                                         pointsRc.append(pointsRs[0])
1733                                 else:
1734                                         pointsLs.append(pointsLs[0])
1735                                         pointsRs.append(pointsRs[0])
1736                                         pointsLe.append(pointsLe[0])
1737                                         pointsRe.append(pointsRe[0])
1738                                         points.append(points[0])
1739                                 vecL3, vecL4 = pointsLs[0], pointsLe[0]
1740                                 vecR3, vecR4 = pointsRs[0], pointsRe[0]
1741                                 lenL = len(pointsLs)-1
1742                                 #print 'deb:drawPoly2d pointsLs():\n',  pointsLs  #----------------
1743                                 #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs)  #----------------
1744                                 bulg_in = False
1745                                 last_bulg_point = False
1746
1747                                 # LOOP: makes (ENDpoints[i],STARTpoints[i+1])
1748                                 for i in xrange(lenL):
1749                                         if bulg_points[i] != None:
1750                                                 if bulg_points[i+1] == None: #makes clean intersections for arc-segments
1751                                                         last_bulg_point = True
1752                                                 if not bulg_in:
1753                                                         bulg_in = True
1754                                                         #pointsLc.extend((points[i], pointsLs[i]))
1755                                                         #pointsRc.extend((points[i], pointsRs[i]))
1756                                         vecL1, vecL2 = vecL3, vecL4
1757                                         vecR1, vecR2 = vecR3, vecR4
1758                                         vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
1759                                         vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
1760                                         #compute left- and right-cornerpoints
1761                                         #cornerpointL = Geometry.LineIntersect2D(vec1, vec2, vec3, vec4)
1762                                         cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
1763                                         cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
1764                                         #print 'deb:drawPoly2d cornerpointL: ', cornerpointL  #-------------
1765                                         #print 'deb:drawPoly2d cornerpointR: ', cornerpointR  #-------------
1766
1767                                         # IF not cornerpoint THEN check if identic start-endpoints (=collinear segments)
1768                                         if cornerpointL == None or cornerpointR == None:
1769                                                 if vecL2 == vecL3 and vecR2 == vecR3:
1770                                                         #print 'deb:drawPoly2d pointVec: ####### identic ##########' #----------------
1771                                                         pointsLc.append(pointsLe[i])
1772                                                         pointsRc.append(pointsRe[i])
1773                                                 else:
1774                                                         pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1775                                                         pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1776                                         else:
1777                                                 cornerpointL = cornerpointL[0] # because Mathutils.LineIntersect() -> (pkt1,pkt2)
1778                                                 cornerpointR = cornerpointR[0]
1779                                                 #print 'deb:drawPoly2d cornerpointL: ', cornerpointL  #-------------
1780                                                 #print 'deb:drawPoly2d cornerpointR: ', cornerpointR  #-------------
1781                                                 pointVec0 = Mathutils.Vector(points[i])
1782                                                 pointVec = Mathutils.Vector(points[i+1])
1783                                                 pointVec2 = Mathutils.Vector(points[i+2])
1784                                                 #print 'deb:drawPoly2d pointVec0: ', pointVec0  #-------------
1785                                                 #print 'deb:drawPoly2d pointVec: ', pointVec  #-------------
1786                                                 #print 'deb:drawPoly2d pointVec2: ', pointVec2  #-------------
1787                                                 # if diststance(cornerL-center-cornerR) < limiter * (seg1_endWidth + seg2_startWidth)
1788                                                 max_cornerDist = (vecL2 - vecR2).length + (vecL3 - vecR3).length
1789                                                 is_cornerDist = (cornerpointL - pointVec).length + (cornerpointR - pointVec).length
1790                                                 #corner_angle = Mathutils.AngleBetweenVecs((pointVec0 - pointVec),(pointVec - pointVec2))
1791                                                 #print 'deb:drawPoly2d corner_angle: ', corner_angle  #-------------
1792                                                 #print 'deb:drawPoly2d max_cornerDist, is_cornerDist: ', max_cornerDist, is_cornerDist  #-------------
1793                                                 #if abs(corner_angle) < 90.0:
1794                                                 # intersection --------- limited by TRIM_LIMIT (1.0 - 5.0)
1795                                                 if is_cornerDist < max_cornerDist * settings.var['pl_trim_max']:
1796                                                         # clean corner intersection
1797                                                         pointsLc.append(cornerpointL)
1798                                                         pointsRc.append(cornerpointR)
1799                                                 elif False: # the standard no-intersection
1800                                                         # --todo-- not optimal, because produces X-face
1801                                                         pointsLc.extend((pointsLe[i],pointsLs[i+1]))
1802                                                         pointsRc.extend((pointsRe[i],pointsRs[i+1]))
1803                                                 elif False: # --todo-- the optimised non-intersection
1804                                                         if (cornerpointL - vecL1).length < (cornerpointR - vecR1).length:
1805                                                                 left_angle = True
1806                                                         else:
1807                                                                 left_angle = False
1808                                                         limit_dist = settings.var['dist_min']
1809                                                         if left_angle:  # if left turning angle
1810                                                                 #print 'deb:drawPoly2d it is left turning angle' #-------------
1811                                                                 # to avoid triangelface/doubleVertex
1812                                                                 delta1 = (cornerpointL - vecL1).normalize() * limit_dist
1813                                                                 delta4 = (cornerpointL - vecL4).normalize() * limit_dist
1814                                                                 pointsLc.extend((cornerpointL - delta1, cornerpointL - delta4))
1815                                                                 pointsRc.extend((pointsRe[i],pointsRs[i+1]))
1816                                                         else:  # if right turning angle
1817                                                                 #print 'deb:drawPoly2d right turning angle' #-------------
1818                                                                 delta1 = (cornerpointR - vecR1).normalize() * limit_dist
1819                                                                 delta4 = (cornerpointR - vecR4).normalize() * limit_dist
1820                                                                 pointsRc.extend((cornerpointR - delta1, cornerpointR - delta4))
1821                                                                 pointsLc.extend((pointsLe[i],pointsLs[i+1]))
1822                                                 else:
1823                                                         pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1824                                                         pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1825                                 if not self.closed:
1826                                         pointsLc.append(pointsLe[-1])
1827                                         pointsRc.append(pointsRe[-1])
1828
1829                         # 2.level:IF width but no-trim
1830                         else:
1831                                 # loop preset
1832                                 # set STARTpoints of the first point points[0]
1833                                 if not self.closed:
1834                                         pointsLc.append(pointsLs[0])
1835                                         pointsRc.append(pointsRs[0])
1836                                 else:
1837                                         pointsLs.append(pointsLs[0])
1838                                         pointsRs.append(pointsRs[0])
1839                                         pointsLe.append(pointsLe[0])
1840                                         pointsRe.append(pointsRe[0])
1841                                         points.append(points[0])
1842                                 vecL3, vecL4 = pointsLs[0], pointsLe[0]
1843                                 vecR3, vecR4 = pointsRs[0], pointsRe[0]
1844                                 lenL = len(pointsLs)-1
1845                                 #print 'deb:drawPoly2d pointsLs():\n',  pointsLs  #----------------
1846                                 #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs)  #----------------
1847                                 bulg_in = False
1848                                 last_bulg_point = False
1849
1850                                 # LOOP: makes (ENDpoints[i],STARTpoints[i+1])
1851                                 for i in xrange(lenL):
1852                                         vecL1, vecL2 = vecL3, vecL4
1853                                         vecR1, vecR2 = vecR3, vecR4
1854                                         vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
1855                                         vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
1856                                         if bulg_points[i] != None:
1857                                                 #compute left- and right-cornerpoints
1858                                                 if True:
1859                                                         cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
1860                                                         cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
1861                                                         pointsLc.append(cornerpointL[0])
1862                                                         pointsRc.append(cornerpointR[0])
1863                                                 else:
1864                                                         pointVec = Mathutils.Vector(point[i])
1865
1866                                         else: # IF non-bulg
1867                                                 pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1868                                                 pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1869                                 if not self.closed:
1870                                         pointsLc.append(pointsLe[-1])
1871                                         pointsRc.append(pointsRe[-1])
1872
1873                         len1 = len(pointsLc)
1874                         #print 'deb:drawPoly2d len1:', len1  #-----------------------
1875                         #print 'deb:drawPoly2d len1 len(pointsLc),len(pointsRc):', len(pointsLc),len(pointsRc)  #-----------------------
1876                         pointsW = pointsLc + pointsRc  # all_points_List = left_side + right_side
1877                         #print 'deb:drawPoly2d pointsW():\n',  pointsW  #----------------
1878
1879                         # 2.level:IF width and thickness  ---------------------
1880                         if thic != 0:
1881                                 thic_pointsW = []
1882                                 thic_pointsW.extend([[point[0], point[1], point[2]+thic] for point in pointsW])
1883                                 if thic < 0.0:
1884                                         thic_pointsW.extend(pointsW)
1885                                         pointsW = thic_pointsW
1886                                 else:
1887                                         pointsW.extend(thic_pointsW)
1888                                 faces = []
1889                                 f_start, f_end = [], []
1890                                 f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
1891                                 f_top   = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
1892                                 f_left   = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
1893                                 f_right  = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
1894
1895                                 if self.closed:
1896                                         f_bottom.append([len1-1, 0, len1, len1+len1-1])  #bottom face
1897                                         f_top.append(   [len1+len1+len1-1, len1+len1+len1+len1-1, len1+len1+len1, len1+len1+0])  #top face
1898                                         f_left.append(  [0, len1-1, len1+len1+len1-1, len1+len1])  #left face
1899                                         f_right.append( [len1, len1+len1+len1, len1+len1+len1+len1-1, len1+len1-1])  #right face
1900                                 else:
1901                                         f_start = [[0, len1, len1+len1+len1, len1+len1]]
1902                                         f_end   = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
1903
1904                                 faces = f_left + f_right + f_bottom + f_top + f_start + f_end
1905                                 #faces = f_bottom + f_top
1906                                 #faces = f_left + f_right + f_start + f_end
1907                                 #print 'deb:faces_list:\n', faces  #-----------------------
1908                                 if M_OBJ: obname, me, ob = makeNewObject()
1909                                 else: 
1910                                         me = Mesh.New(obname)           # create a new mesh
1911                                         ob = SCENE.objects.new(me) # create a new mesh_object
1912                                 me.verts.extend(pointsW)                # add vertices to mesh
1913                                 me.faces.extend(faces)  # add faces to the mesh
1914
1915                                 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
1916                                 # The mesh must first be linked to an object so the method knows which object to update.
1917                                 # This is because vertex groups in Blender are stored in the object -- not in the mesh,
1918                                 # which may be linked to more than one object.
1919                                 if settings.var['vGroup_on'] and not M_OBJ:
1920                                         # each MeshSide becomes vertexGroup for easier material assignment ---------------------
1921                                         replace = Blender.Mesh.AssignModes.REPLACE  #or .AssignModes.ADD
1922                                         vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
1923                                         for v in f_left: vg_left.extend(v)
1924                                         for v in f_right: vg_right.extend(v)
1925                                         for v in f_top: vg_top.extend(v)
1926                                         for v in f_bottom: vg_bottom.extend(v)
1927                                         me.addVertGroup('side.left')  ; me.assignVertsToGroup('side.left',  list(set(vg_left)), 1.0, replace)
1928                                         me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
1929                                         me.addVertGroup('side.top')   ; me.assignVertsToGroup('side.top',   list(set(vg_top)), 1.0, replace)
1930                                         me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
1931                                         if not self.closed:
1932                                                 me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
1933                                                 me.addVertGroup('side.end')  ; me.assignVertsToGroup('side.end',   f_end[0],   1.0, replace)
1934
1935                                 if settings.var['meshSmooth_on']:  # left and right side become smooth ----------------------
1936                                         #if self.spline or self.curved:
1937                                         if True:
1938                                                 smooth_len = len(f_left) + len(f_right)
1939                                                 for i in xrange(smooth_len):
1940                                                         me.faces[i].smooth = True
1941                                                 #me.Modes(AUTOSMOOTH)
1942
1943                         # 2.level:IF width, but no-thickness  ---------------------
1944                         else:
1945                                 faces = []
1946                                 faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
1947                                 if self.closed:
1948                                         faces.append([len1, 0, len1-1, len1+len1-1])
1949                                 if M_OBJ: obname, me, ob = makeNewObject()
1950                                 else: 
1951                                         me = Mesh.New(obname)           # create a new mesh
1952                                         ob = SCENE.objects.new(me) # create a new mesh_object
1953                                 me.verts.extend(pointsW)                # add vertices to mesh
1954                                 me.faces.extend(faces)  # add faces to the mesh
1955
1956
1957                 # 1.level:IF no-width, but thickness ---------------------
1958                 elif thic != 0:
1959                         len1 = len(points)
1960                         thic_points = []
1961                         thic_points.extend([[point[0], point[1], point[2]+thic] for point in points])
1962                         if thic < 0.0:
1963                                 thic_points.extend(points)
1964                                 points = thic_points
1965                         else:
1966                                 points.extend(thic_points)
1967                         faces = []
1968                         faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
1969                         if self.closed:
1970                                 faces.append([len1-1, 0, len1, 2*len1-1])
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.faces.extend(faces)  # add faces to the mesh
1977
1978                         if settings.var['meshSmooth_on']:  # left and right side become smooth ----------------------
1979                                 #if self.spline or self.curved:
1980                                 if True:
1981                                         for i in xrange(len(faces)):
1982                                                 me.faces[i].smooth = True
1983                                         #me.Modes(AUTOSMOOTH)
1984
1985                 # 1.level:IF no-width and no-thickness  ---------------------
1986                 else:
1987                         edges = [[num, num+1] for num in xrange(len(points)-1)]
1988                         if self.closed:
1989                                 edges.append([len(points)-1, 0])
1990                         if M_OBJ: obname, me, ob = makeNewObject()
1991                         else: 
1992                                 me = Mesh.New(obname)           # create a new mesh
1993                                 ob = SCENE.objects.new(me) # create a new mesh_object
1994                         me.verts.extend(points)   # add vertices to mesh
1995                         me.edges.extend(edges)  # add edges to the mesh
1996
1997                 transform(self.extrusion, 0, ob)
1998                 #print 'deb:polyline.draw.END:----------------' #-----------------------
1999                 return ob
2000
2001
2002
2003
2004 class Vertex(object):  #-----------------------------------------------------------------
2005         """Generic vertex object used by POLYLINEs, (and maybe others).
2006         also used by class_LWPOLYLINEs but without obj-parameter
2007         """
2008
2009         def __init__(self, obj=None):
2010                 """Initializes vertex data.
2011
2012                 The optional obj arg is an entity object of type vertex.
2013                 """
2014                 #print 'deb:Vertex.init.START:----------------' #-----------------------
2015                 self.loc = [0,0,0]
2016                 self.face = []
2017                 self.swidth = None #0
2018                 self.ewidth = None #0
2019                 self.bulge = 0
2020                 self.tangent = False
2021                 self.weight =  1.0
2022                 if obj is not None:
2023                         if not obj.type == 'vertex':
2024                                 raise TypeError, "Wrong type %s for vertex object!" %obj.type
2025                         self.type = obj.type
2026 #                       self.data = obj.data[:]
2027                         self.get_props(obj)
2028                 else:
2029                         pass
2030                 #print 'deb:Vertex.init.END:----------------' #------------------------
2031
2032
2033         def get_props(self, data):
2034                 """Gets coords for a VERTEX type object.
2035
2036                 Each vert can have a number of properties.
2037                 Verts should be coded as
2038                 10:xvalue
2039                 20:yvalue
2040                 40:startwidth or 0
2041                 41:endwidth or 0
2042                 42:bulge or 0
2043                 """
2044                 self.x = getit(data, 10, None)
2045                 self.y = getit(data, 20, None)
2046                 self.z = getit(data, 30, None)
2047
2048                 self.flags  = getit(data, 70, 0) # flags
2049                 self.curved = self.flags&1   # Bezier-curve-fit:additional-vertex
2050                 self.curved_t = self.flags&2   # Bezier-curve-fit:tangent exists
2051                 self.spline = self.flags&8   # NURBSpline-fit:additional-vertex
2052                 self.spline_c = self.flags&16  # NURBSpline-fit:control-vertex
2053                 self.poly3d = self.flags&32  # polyline3d:control-vertex
2054                 self.plmesh = self.flags&64  # polymesh3d:control-vertex
2055                 self.plface = self.flags&128 # polyface
2056
2057                 # if PolyFace.Vertex with Face_definition
2058                 if self.curved_t:
2059                         self.curve_tangent =  getit(data, 50, None) # curve_tangent
2060                         if not self.curve_tangent==None:
2061                                 self.tangent = True
2062                 #elif self.spline_c: # NURBSpline:control-vertex
2063                 #       self.weight =  getit(data, 41, 1.0) # weight od control point
2064
2065                 elif self.plface and not self.plmesh:
2066                         v1 = getit(data, 71, 0) # polyface:Face.vertex 1.
2067                         v2 = getit(data, 72, 0) # polyface:Face.vertex 2.
2068                         v3 = getit(data, 73, 0) # polyface:Face.vertex 3.
2069                         v4 = getit(data, 74, None) # polyface:Face.vertex 4.
2070                         self.face = [abs(v1)-1,abs(v2)-1,abs(v3)-1]
2071                         if v4 != None:
2072                                 if abs(v4) != abs(v1):
2073                                         self.face.append(abs(v4)-1)
2074                 else:   #--parameter for polyline2d
2075                         self.swidth = getit(data, 40, None) # start width
2076                         self.ewidth = getit(data, 41, None) # end width
2077                         self.bulge  = getit(data, 42, 0) # bulge of segment
2078
2079
2080         def __len__(self):
2081                 return 3
2082
2083
2084         def __getitem__(self, key):
2085                 return self.loc[key]
2086
2087
2088         def __setitem__(self, key, value):
2089                 if key in [0,1,2]:
2090                         self.loc[key]
2091
2092
2093         def __iter__(self):
2094                 return self.loc.__iter__()
2095
2096
2097         def __str__(self):
2098                 return str(self.loc)
2099
2100
2101         def __repr__(self):
2102                 return "Vertex %s, swidth=%s, ewidth=%s, bulge=%s, face=%s" %(self.loc, self.swidth, self.ewidth, self.bulge, self.face)
2103
2104
2105         def getx(self):
2106                 return self.loc[0]
2107         def setx(self, value):
2108                 self.loc[0] = value
2109         x = property(getx, setx)
2110
2111
2112         def gety(self):
2113                 return self.loc[1]
2114         def sety(self, value):
2115                 self.loc[1] = value
2116         y = property(gety, sety)
2117
2118
2119         def getz(self):
2120                 return self.loc[2]
2121         def setz(self, value):
2122                 self.loc[2] = value
2123         z = property(getz, setz)
2124
2125
2126
2127 class Spline(Polyline):  #-----------------------------------------------------------------
2128         """Class for objects representing dxf SPLINEs.
2129         """
2130         """Expects an entity object of type spline as input.
2131 100 - Subclass marker (AcDbSpline)
2132 210,220, 230  - Normal vector (omitted if the spline is nonplanar) X,Y,Z values of normal vector
2133 70 - Spline flag (bit coded):
2134   1 = Closed spline
2135   2 = Periodic spline
2136   4 = Rational spline
2137   8 = Planar
2138  16 = Linear (planar bit is also set)
2139 71 - Degree of the spline curve
2140 72 - Number of knots
2141 73 - Number of control points
2142 74 - Number of fit points (if any)
2143 42 - Knot tolerance (default = 0.0000001)
2144 43 - Control-point tolerance (default = 0.0000001)
2145 44 - Fit tolerance (default = 0.0000000001)
2146 12,22,32 - Start tangent--may be omitted (in WCS). X,Y,Z values of start tangent--may be omitted (in WCS).
2147 13,23, 33 - End tangent--may be omitted (in WCS). X,Y,Z values of end tangent--may be omitted (in WCS)
2148 40 - Knot value (one entry per knot)
2149 41 - Weight (if not 1); with multiple group pairs, are present if all are not 1
2150 10,20, 30  - Control points (in WCS) one entry per control point.
2151 DXF: X value; APP: 3D point, Y and Z values of control points (in WCS) (one entry per control point)
2152 11,21, 31 - Fit points (in WCS) one entry per fit point.
2153  X,Y,Z values of fit points (in WCS) (one entry per fit point)
2154         """
2155         def __init__(self, obj):
2156                 #print 'deb:Spline.START:----------------' #------------------------
2157                 if not obj.type == 'spline':
2158                         raise TypeError, "Wrong type %s for spline object!" %obj.type
2159                 self.type = obj.type
2160 #               self.data = obj.data[:]
2161
2162                 # required data
2163                 self.num_points = obj.get_type(73)[0]
2164
2165                 # optional data (with defaults)
2166                 self.space = getit(obj, 67, 0)
2167
2168                 self.color_index = getit(obj, 62, BYLAYER)
2169
2170                 #self.elevation =  getit(obj, 30, 0)
2171                 self.thic = 0 # getit(obj, 39, 0)
2172
2173                 width = 0
2174                 self.swidth =  width # default start width
2175                 self.ewidth =  width # default end width
2176
2177                 self.flags = getit(obj, 70, 0)
2178                 self.closed = self.flags & 1   # closed spline
2179                 self.period = self.flags & 2   # Periodic spline
2180                 self.ration = self.flags & 4   # Rational spline
2181                 self.planar = self.flags & 8   # Planar
2182                 self.linear = self.flags & 16  # Linear (and Planar)
2183
2184                 self.curvNoFitted = False
2185                 self.curvQuadrati = False
2186                 self.curvCubicBsp = False
2187                 self.curvBezier = False
2188                 self.degree = getit(obj, 71, 0) # Degree of the spline curve
2189                 if   self.degree == 0: self.curvNoFitted = True
2190                 elif self.degree == 1: self.curvQuadrati = True
2191                 elif self.degree == 2: self.curvCubicBsp = True
2192                 #elif self.degree == 3: self.curvBezier = True
2193                 #elif self.degree == 3: self.spline = True
2194         
2195                 self.knotpk_len = getit(obj, 72, 0) # Number of knots
2196                 self.ctrlpk_len = getit(obj, 73, 0) # Number of control points
2197                 self.fit_pk_len = getit(obj, 74, 0) # Number of fit points (if any)
2198
2199                 #TODO: import SPLINE as Bezier curve directly, possible?
2200                 #print 'deb:Spline self.fit_pk_len=', self.fit_pk_len #------------------------
2201                 #self.fit_pk_len = 0 # temp for debug
2202                 if self.fit_pk_len and settings.var['splines_as']==5:
2203                         self.spline = False
2204                         self.curved = True
2205                 else:
2206                         self.spline = True
2207                         self.curved = False
2208
2209                 self.knotpk_tol = getit(obj, 42, 0.0000001) # Knot tolerance (default = 0.0000001)
2210                 self.ctrlpk_tol = getit(obj, 43, 0.0000001) # Control-point tolerance (default = 0.0000001)
2211                 self.fit_pk_tol = getit(obj, 44, 0.0000000001) # Fit tolerance (default = 0.0000000001)
2212
2213                 self.layer = getit(obj, 8, None)
2214                 self.extrusion = get_extrusion(obj)
2215
2216                 self.pltype = 'spline'   # spline is a 2D- or 3D-polyline
2217
2218                 self.points = self.get_points(obj.data)
2219                 #self.knots_val = self.get_knots_val(obj.data) # 40 - Knot value (one entry per knot)
2220                 #self.knots_wgh = self.get_knots_wgh(obj.data) # 41 - Weight (default 1)
2221
2222                 #print 'deb:Spline obj.data:\n', obj.data #------------------------
2223                 #print 'deb:Spline self.points:\n', self.points #------------------------
2224                 #print 'deb:Spline.ENDinit:----------------' #------------------------
2225
2226
2227         def get_points(self, data):
2228                 """Gets points for a spline type object.
2229
2230                 Splines have fixed number of verts, and
2231                 each vert can have a number of properties.
2232                 Verts should be coded as
2233                 10:xvalue
2234                 20:yvalue
2235                 for each vert
2236                 """
2237                 point = None
2238                 points = []
2239                 pointend = None
2240                 #point = Vertex()
2241                 if self.spline: # NURBSpline definition
2242                         for item in data:
2243                                 #print 'deb:Spline.get_points spilne_item:', item #------------------------
2244                                 if item[0] == 10:   # control point
2245                                         if point: points.append(point)
2246                                         point = Vertex()
2247                                         point.curved = True
2248                                         point.x = item[1]
2249                                 elif item[0] == 20: # 20 = y
2250                                         point.y = item[1]
2251                                 elif item[0] == 30: # 30 = z
2252                                         point.z = item[1]
2253                                 elif item[0] == 41: # 41 = weight
2254                                         point.weight = item[1]
2255                                         #print 'deb:Spline.get_points control point:', point #------------------------
2256
2257                 elif self.curved: # Bezier definition
2258                         for item in data:
2259                                 #print 'deb:Spline.get_points curved_item:', item #------------------------
2260                                 if item[0] == 11:   # fit point
2261                                         if point: points.append(point)
2262                                         point = Vertex()
2263                                         point.tangent = False
2264                                         point.x = item[1]
2265                                 elif item[0] == 21: # 20 = y
2266                                         point.y = item[1]
2267                                 elif item[0] == 31: # 30 = z
2268                                         point.z = item[1]
2269                                         #print 'deb:Spline.get_points fit point:', point #------------------------
2270
2271                                 elif item[0] == 12:   # start tangent
2272                                         if point: points.append(point)
2273                                         point = Vertex()
2274                                         point.tangent = True
2275                                         point.x = item[1]
2276                                 elif item[0] == 22: # = y
2277                                         point.y = item[1]
2278                                 elif item[0] == 32: # = z
2279                                         point.z = item[1]
2280                                         #print 'deb:Spline.get_points fit begtangent:', point #------------------------
2281
2282                                 elif item[0] == 13:   # end tangent
2283                                         if point: points.append(point)
2284                                         pointend = Vertex()
2285                                         pointend.tangent = True
2286                                         pointend.x = item[1]
2287                                 elif item[0] == 23: # 20 = y
2288                                         pointend.y = item[1]
2289                                 elif item[0] == 33: # 30 = z
2290                                         pointend.z = item[1]
2291                                         #print 'deb:Spline.get_points fit endtangent:', pointend #------------------------
2292                 points.append(point)
2293                 if self.curved and pointend:
2294                         points.append(pointend)
2295                 #print 'deb:Spline points:\n', points #------------------------
2296                 return points
2297
2298         def __repr__(self):
2299                 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
2300
2301         
2302
2303 class LWpolyline(Polyline):  #-------------------------------------------------------------
2304         """Class for objects representing dxf LWPOLYLINEs.
2305         """
2306         def __init__(self, obj):
2307                 """Expects an entity object of type lwpolyline as input.
2308                 """
2309                 #print 'deb:LWpolyline.START:----------------' #------------------------
2310                 if not obj.type == 'lwpolyline':
2311                         raise TypeError, "Wrong type %s for polyline object!" %obj.type
2312                 self.type = obj.type
2313 #               self.data = obj.data[:]
2314
2315                 # required data
2316                 self.num_points = obj.get_type(90)[0]
2317
2318                 # optional data (with defaults)
2319                 self.space = getit(obj, 67, 0)
2320                 self.elevation =  getit(obj, 38, 0)
2321                 self.thic =  getit(obj, 39, 0)
2322                 self.color_index = getit(obj, 62, BYLAYER)
2323                 width =  getit(obj, 43, 0)
2324                 self.swidth =  width # default start width
2325                 self.ewidth =  width # default end width
2326                 #print 'deb:LWpolyline width=', width #------------------------
2327                 #print 'deb:LWpolyline elevation=', self.elevation #------------------------
2328         
2329                 self.flags = getit(obj, 70, 0)
2330                 self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen
2331
2332                 self.layer = getit(obj, 8, None)
2333                 self.extrusion = get_extrusion(obj)
2334
2335                 self.points = self.get_points(obj.data)
2336
2337                 self.pltype = 'poly2d'   # LW-polyline is a 2D-polyline
2338                 self.spline = False
2339                 self.curved = False
2340
2341
2342                 #print 'deb:LWpolyline.obj.data:\n', obj.data #------------------------
2343                 #print 'deb:LWpolyline.ENDinit:----------------' #------------------------
2344
2345
2346         def get_points(self, data):
2347                 """Gets points for a polyline type object.
2348
2349                 LW-Polylines have no fixed number of verts, and
2350                 each vert can have a number of properties.
2351                 Verts should be coded as
2352                 10:xvalue
2353                 20:yvalue
2354                 40:startwidth or 0
2355                 41:endwidth or 0
2356                 42:bulge or 0
2357                 for each vert
2358                 """
2359                 num = self.num_points
2360                 point = None
2361                 points = []
2362                 for item in data:
2363                         if item[0] == 10:   # 10 = x
2364                                 if point:
2365                                         points.append(point)
2366                                 point = Vertex()
2367                                 point.x = item[1]
2368                                 point.z = self.elevation
2369                         elif item[0] == 20: # 20 = y
2370                                 point.y = item[1]
2371                         elif item[0] == 40: # 40 = start width
2372                                 point.swidth = item[1]
2373                         elif item[0] == 41: # 41 = end width
2374                                 point.ewidth = item[1]
2375                         elif item[0] == 42: # 42 = bulge
2376                                 point.bulge = item[1]
2377                 points.append(point)
2378                 return points
2379
2380
2381         def __repr__(self):
2382                 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
2383
2384
2385 class Text:  #-----------------------------------------------------------------
2386         """Class for objects representing dxf TEXT.
2387         """
2388         def __init__(self, obj):
2389                 """Expects an entity object of type text as input.
2390                 """
2391                 if not obj.type == 'text':
2392                         raise TypeError, "Wrong type %s for text object!" %obj.type
2393                 self.type = obj.type
2394 #               self.data = obj.data[:]
2395
2396                 # required data
2397                 self.height = 1.7 * obj.get_type(40)[0]  #text.height
2398                 self.value = obj.get_type(1)[0]   #The text string value
2399
2400                 # optional data (with defaults)
2401                 self.space = getit(obj, 67, 0)
2402                 self.color_index = getit(obj, 62, BYLAYER)
2403                 self.thic =  getit(obj, 39, 0)
2404
2405                 self.rotation = getit(obj, 50, 0)  # radians
2406                 self.width_factor = getit(obj, 41, 1) # Scaling factor along local x axis
2407                 self.oblique = getit(obj, 51, 0) # oblique angle: skew in degrees -90 <= oblique <= 90
2408
2409                 #self.style = getit(obj, 7, 'STANDARD') # --todo---- Text style name (optional, default = STANDARD)
2410
2411                 #Text generation flags (optional, default = 0):
2412                 #2 = backward (mirrored in X),
2413                 #4 = upside down (mirrored in Y)
2414                 self.flags = getit(obj, 71, 0)
2415                 self.mirrorX, self.mirrorY = 1.0, 1.0
2416                 if self.flags&2: self.mirrorX = - 1.0
2417                 if self.flags&4: self.mirrorY = - 1.0
2418
2419                 # vertical.alignment: 0=baseline, 1=bottom, 2=middle, 3=top
2420                 self.valignment = getit(obj, 73, 0)
2421                 #Horizontal text justification type (optional, default = 0) integer codes (not bit-coded)
2422                 #0=left, 1=center, 2=right
2423                 #3=aligned, 4=middle, 5=fit
2424                 self.halignment = getit(obj, 72, 0)
2425
2426                 self.layer = getit(obj, 8, None)
2427                 self.loc1, self.loc2 = self.get_loc(obj)
2428                 if self.loc2[0] != None and self.halignment != 5: 
2429                         self.loc = self.loc2
2430                 else:
2431                         self.loc = self.loc1
2432                 self.extrusion = get_extrusion(obj)
2433
2434
2435         def get_loc(self, data):
2436                 """Gets adjusted location for text type objects.
2437
2438                 If group 72 and/or 73 values are nonzero then the first alignment point values
2439                 are ignored and AutoCAD calculates new values based on the second alignment
2440                 point and the length and height of the text string itself (after applying the
2441                 text style). If the 72 and 73 values are zero or missing, then the second
2442                 alignment point is meaningless.
2443                 I don't know how to calc text size...
2444                 """
2445                 # bottom left x, y, z and justification x, y, z = 0
2446                 #x, y, z, jx, jy, jz = 0, 0, 0, 0, 0, 0
2447                 x  = getit(data, 10, None) #First alignment point (in OCS). 
2448                 y  = getit(data, 20, None)
2449                 z  = getit(data, 30, 0.0)
2450                 jx = getit(data, 11, None) #Second alignment point (in OCS). 
2451                 jy = getit(data, 21, None)
2452                 jz = getit(data, 31, 0.0)
2453                 return [x, y, z],[jx, jy, jz]
2454
2455
2456         def __repr__(self):
2457                 return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
2458
2459
2460         def draw(self, settings):
2461                 """for TEXTs: generate Blender_geometry.
2462                 """
2463                 obname = 'tx_%s' %self.layer  # create object name from layer name
2464                 obname = obname[:MAX_NAMELENGTH]
2465                 txt = Text3d.New(obname)
2466                 ob = SCENE.objects.new(txt) # create a new text_object
2467
2468                 txt.setText(self.value)
2469                 txt.setSize(1.0) #Blender<2.45 accepts only (0.0 - 5.0)
2470                 #txt.setSize(self.height)
2471                 #txt.setWidth(self.bold)
2472                 #setLineSeparation(sep)
2473                 txt.setShear(self.oblique/90)
2474
2475                 thic = set_thick(self.thic, settings)
2476                 if thic != 0.0:
2477                         thic = self.thic * 0.5
2478                         self.loc[2] += thic
2479                         txt.setExtrudeDepth(1.0)  #Blender<2.45 accepts only (0.1 - 10.0)
2480                 if self.halignment == 0:
2481                         align = Text3d.LEFT
2482                 elif self.halignment == 1:
2483                         align = Text3d.MIDDLE
2484                 elif self.halignment == 2:
2485                         align = Text3d.RIGHT
2486                 else:
2487                         align = Text3d.LEFT
2488                 txt.setAlignment(align)
2489
2490                 if self.valignment == 1:
2491                         txt.setYoffset(0.0)
2492                 elif self.valignment == 2:
2493                         txt.setYoffset(- self.height * 0.5)
2494                 elif self.valignment == 3:
2495                         txt.setYoffset(- self.height)
2496
2497                 # move the object center to the text location
2498                 ob.loc = tuple(self.loc)
2499                 transform(self.extrusion, self.rotation, ob)
2500
2501                 # flip it and scale it to the text width
2502                 ob.SizeX *= self.height * self.width_factor * self.mirrorX
2503                 ob.SizeY *= self.height * self.mirrorY
2504                 if thic != 0.0: ob.SizeZ *= abs(thic)
2505                 return ob
2506
2507
2508         
2509 def set_thick(thickness, settings):
2510         """Set thickness relative to settings variables.
2511         
2512         Set thickness relative to settings variables:
2513         'thick_on','thick_force','thick_min'.
2514         Accepted also minus values of thickness
2515         python trick: sign(x)=cmp(x,0)
2516         """
2517         if settings.var['thick_force']:
2518                 if settings.var['thick_on']:
2519                         if abs(thickness) <  settings.var['thick_min']:
2520                                 thic = settings.var['thick_min'] * cmp(thickness,0)
2521                         else: thic = thickness
2522                 else: thic = settings.var['thick_min']
2523         else: 
2524                 if settings.var['thick_on']: thic = thickness
2525                 else: thic = 0.0
2526         return thic
2527
2528
2529
2530
2531 class Mtext:  #-----------------------------------------------------------------
2532         """Class for objects representing dxf MTEXT.
2533         """
2534
2535         def __init__(self, obj):
2536                 """Expects an entity object of type mtext as input.
2537                 """
2538                 if not obj.type == 'mtext':
2539                         raise TypeError, "Wrong type %s for mtext object!" %obj.type
2540                 self.type = obj.type
2541 #               self.data = obj.data[:]
2542
2543                 # required data
2544                 self.height = obj.get_type(40)[0]
2545                 self.width = obj.get_type(41)[0]
2546                 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
2547                 self.value = self.get_text(obj) # The text string value
2548
2549                 # optional data (with defaults)
2550                 self.space = getit(obj, 67, 0)
2551                 self.color_index = getit(obj, 62, BYLAYER)
2552                 self.rotation = getit(obj, 50, 0)  # radians
2553
2554                 self.width_factor = getit(obj, 42, 1) # Scaling factor along local x axis
2555                 self.line_space = getit(obj, 44, 1) # percentage of default
2556
2557                 self.layer = getit(obj, 8, None)
2558                 self.loc = self.get_loc(obj)
2559                 self.extrusion = get_extrusion(obj)
2560
2561
2562         def get_text(self, data):
2563                 """Reconstructs mtext data from dxf codes.
2564                 """
2565                 primary = ''
2566                 secondary = []
2567                 for item in data:
2568                         if item[0] == 1: # There should be only one primary...
2569                                 primary = item[1]
2570                         elif item[0] == 3: # There may be any number of extra strings (in order)
2571                                 secondary.append(item[1])
2572                 if not primary:
2573                         #raise ValueError, "Empty Mtext Object!"
2574                         string = "Empty Mtext Object!"
2575                 if not secondary:
2576                         string = primary.replace(r'\P', '\n')
2577                 else:
2578                         string = ''.join(secondary)+primary
2579                         string = string.replace(r'\P', '\n')
2580                 return string
2581
2582
2583         def get_loc(self, data):
2584                 """Gets location for a mtext type objects.
2585
2586                 Mtext objects have only one point indicating 
2587                 """      
2588                 loc = [0, 0, 0]
2589                 loc[0] = getit(data, 10, None)
2590                 loc[1] = getit(data, 20, None)
2591                 loc[2] = getit(data, 30, 0.0)
2592                 return loc
2593
2594
2595         def __repr__(self):
2596                 return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
2597
2598
2599         def draw(self, settings):
2600                 """for MTEXTs: generate Blender_geometry.
2601                 """
2602                 # Now Create an object
2603                 obname = 'tm_%s' %self.layer  # create object name from layer name
2604                 obname = obname[:MAX_NAMELENGTH]
2605                 txt = Text3d.New(obname)
2606                 ob = SCENE.objects.new(txt) # create a new text_object
2607
2608                 txt.setSize(1)
2609                 # Blender doesn't give access to its text object width currently
2610                 # only to the text3d's curve width...
2611                 #txt.setWidth(text.width/10)
2612                 txt.setLineSeparation(self.line_space)
2613                 txt.setExtrudeDepth(0.5)
2614                 txt.setText(self.value)
2615
2616                 # scale it to the text size
2617                 ob.SizeX = self.height * self.width_factor
2618                 ob.SizeY = self.height
2619                 ob.SizeZ = self.height
2620
2621                 # move the object center to the text location
2622                 ob.loc = tuple(self.loc)
2623                 transform(self.extrusion, self.rotation, ob)
2624
2625                 return ob
2626
2627
2628 class Circle:  #-----------------------------------------------------------------
2629         """Class for objects representing dxf CIRCLEs.
2630         """
2631
2632         def __init__(self, obj):
2633                 """Expects an entity object of type circle as input.
2634                 """
2635                 if not obj.type == 'circle':
2636                         raise TypeError, "Wrong type %s for circle object!" %obj.type
2637                 self.type = obj.type
2638 #               self.data = obj.data[:]
2639
2640                 # required data
2641                 self.radius = obj.get_type(40)[0]
2642
2643                 # optional data (with defaults)
2644                 self.space = getit(obj, 67, 0)
2645                 self.thic =  getit(obj, 39, 0)
2646                 self.color_index = getit(obj, 62, BYLAYER)
2647
2648                 self.layer = getit(obj, 8, None)
2649                 self.loc = self.get_loc(obj)
2650                 self.extrusion = get_extrusion(obj)
2651
2652
2653
2654         def get_loc(self, data):
2655                 """Gets the center location for circle type objects.
2656
2657                 Circles have a single coord location.
2658                 """
2659                 loc = [0, 0, 0]
2660                 loc[0] = getit(data, 10, None)
2661                 loc[1] = getit(data, 20, None)
2662                 loc[2] = getit(data, 30, 0.0)
2663                 return loc
2664
2665
2666
2667         def __repr__(self):
2668                 return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
2669
2670
2671         def draw(self, settings):
2672                 """for CIRCLE: generate Blender_geometry.
2673                 """
2674                 obname = 'ci_%s' %self.layer  # create object name from layer name
2675                 obname = obname[:MAX_NAMELENGTH]
2676                 radius = self.radius
2677
2678                 thic = set_thick(self.thic, settings)
2679                 width = 0.0
2680                 if settings.var['lines_as'] == 4: # as thin_box
2681                         thic = settings.var['thick_min']
2682                         width = settings.var['width_min']
2683                 if settings.var['lines_as'] == 3: # as thin cylinder
2684                         cyl_rad = 0.5 * settings.var['width_min']
2685
2686                 if settings.var['lines_as'] == 5:  # draw CIRCLE as curve -------------
2687                         if True:  # universal version
2688                                 arc_res = settings.var['curve_arc']
2689                                 #arc_res = 3
2690                                 start, end = 0.0, 360.0
2691                                 VectorTriples = calcArc(None, radius, start, end, arc_res, True)
2692                                 c = Curve.New(obname) # create new curve data
2693                                 curve = c.appendNurb(BezTriple.New(VectorTriples[0]))
2694                                 for p in VectorTriples[1:-1]:
2695                                         curve.append(BezTriple.New(p))
2696                                 for point in curve:
2697                                         point.handleTypes = [FREE, FREE]
2698                                         point.radius = 1.0
2699                         else:   # standard version
2700                                 c = Curve.New(obname)   # create new curve data
2701                                 p1 = (0, -radius, 0)
2702                                 p2 = (radius, 0, 0)
2703                                 p3 = (0, radius, 0)
2704                                 p4 = (-radius, 0, 0)
2705         
2706                                 p1 = BezTriple.New(p1)
2707                                 p2 = BezTriple.New(p2)
2708                                 p3 = BezTriple.New(p3)
2709                                 p4 = BezTriple.New(p4)
2710         
2711                                 curve = c.appendNurb(p1)
2712                                 curve.append(p2)
2713                                 curve.append(p3)
2714                                 curve.append(p4)
2715                                 for point in curve:
2716                                         point.handleTypes = [AUTO, AUTO]
2717                                         point.radius = 1.0
2718
2719                         curve.flagU = 1  # 1 sets the curve cyclic=closed
2720                         if settings.var['fill_on']:
2721                                 c.setFlag(6) # 2+4 set top and button caps
2722                         else:
2723                                 c.setFlag(c.getFlag() & ~6) # dont set top and button caps
2724
2725                         c.setResolu(settings.var['curve_res'])
2726                         c.update()
2727
2728                         #--todo-----to check---------------------------
2729                         ob = SCENE.objects.new(c) # create a new curve_object
2730                         ob.loc = tuple(self.loc)
2731                         if thic != 0.0: #hack: Blender<2.45 curve-extrusion
2732                                 thic = thic * 0.5
2733                                 c.setExt1(1.0)  # curve-extrusion accepts only (0.0 - 2.0)
2734                                 ob.LocZ = thic + self.loc[2]
2735                         transform(self.extrusion, 0, ob)
2736                         if thic != 0.0:
2737                                 ob.SizeZ *= abs(thic)
2738                         return ob
2739
2740                 elif False: # create a new mesh_object with buildin_circle_primitive
2741                         verts_num = settings.var['arc_res'] * sqrt(radius / settings.var['arc_rad'])
2742                         if verts_num > 100: verts_num = 100 # Blender accepts only values [3:500]
2743                         if verts_num < 4: verts_num = 4 # Blender accepts only values [3:500]
2744                         if thic != 0:
2745                                 loc2 = thic * 0.5   #-----blenderAPI draw Cylinder with 2*thickness
2746                                 self.loc[2] += loc2  #---new location for the basis of cylinder
2747                                 #print 'deb:circleDraw:self.loc2:', self.loc  #-----------------------
2748                                 c = Mesh.Primitives.Cylinder(int(verts_num), radius*2, abs(thic))
2749                         else:
2750                                 c = Mesh.Primitives.Circle(int(verts_num), radius*2)
2751
2752                         #c.update()
2753                         ob = SCENE.objects.new(c, obname) # create a new circle_mesh_object
2754                         ob.loc = tuple(self.loc)
2755                         transform(self.extrusion, 0, ob)
2756                         return ob
2757
2758                 else:  # draw CIRCLE as mesh -----------------------------------------------
2759                         if M_OBJ: obname, me, ob = makeNewObject()
2760                         else: 
2761                                 me = Mesh.New(obname)           # create a new mesh
2762                                 ob = SCENE.objects.new(me) # create a new mesh_object
2763                         # set a number of segments in entire circle
2764                         arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
2765                         start, end = 0.0 , 360.0
2766                         verts = calcArc(None, radius, start, end, arc_res, False)
2767                         verts = verts[:-1] #list without last point/edge (cause by circle it is equal to the first point)
2768                         #print 'deb:circleDraw: verts:', verts  #--------------- 
2769
2770                         if thic != 0:
2771                                 len1 = len(verts)
2772                                 thic_verts = []
2773                                 thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
2774                                 if thic < 0.0:
2775                                         thic_verts.extend(verts)
2776                                         verts = thic_verts
2777                                 else:
2778                                         verts.extend(thic_verts)
2779                                 faces = []
2780                                 f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
2781                                 #f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1)]
2782               &