4
Name: 'Autodesk DXF (.dxf)'
7
Tooltip: 'Import for DXF geometry data (Drawing eXchange Format).'
9
__author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)'
10
__version__ = '1.12 - 2008.08.03 by migius'
11
__url__ = ["http://blenderartists.org/forum/showthread.php?t=84319",
12
"http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"]
13
__email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"]
15
This script imports objects from DXF (2d/3d) into Blender.
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.
24
Supported DXF r12 objects:
31
MINSERT (=array of blocks),
35
2d-POLYLINE (=plane, incl. arc, variable-width, curve, spline),
36
3d-POLYLINE (=non-plane),
40
XREF (External Reference).
42
Supported DXF>r12 objects:
44
LWPOLYLINE (LightWeight Polyline),
51
DXF>r12: GROUP, RAY/XLINE, LEADER, 3DSOLID, BODY, REGION, dynamic BLOCK
53
Supported geometry: 2d and 3d DXF-objects.
54
Curves imported as Blender curves or meshes optionally.
56
Supported layout modes:
57
"model space" is default,
58
"paper space" as option (= "layout views")
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)
66
Entire DXF BLOCK hierarchy is preserved after import into Blender
67
(BLOCKs as groups on layer19, INSERTs as dupliGroups on target layer).
76
(wip v1.13: XDATA, grouped status)
77
It is recommended to use DXF-object properties for assign Blender materials.
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.
91
v1.0 - 2007/2008 by migius
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
114
v1.12 - 2008.08.03 by migius
115
c2 warningfix: relocating of globals: layersmap, oblist
116
c2 modif UI: buttons newScene+targetLayer moved to start panel
117
v1.12 - 2008.07.04 by migius
118
c1 added control Curve's OrderU parameter
119
c1 modif UI: preset buttons X-2D-3D moved to start panel
120
b6 added handling exception of not registered LAYERs (Hammer-HL-editor DXF output)
121
b5 rebuild UI: global preset 2D for Curve-Import
122
b5 added UI-options: PL-MESH N+N plmesh_flip and normals_out
123
b5 added support for SPLINEs, added control OrderU parameter
124
b5 rewrote draw module for NURBS_curve and Bezier_curve
125
v1.12 - 2008.06.22 by migius
126
b4 change versioning system 1.0.12 -> 1.12
127
b4 print at start version-info to console
128
b3 bugfix: ob.name conflict with existing meshes (different ob.name/mesh.name)
129
v1.0.12: 2008.05.24 by migius
130
b2 added support for LWPOLYLINEs
131
b2 added support for ProE in readerDXF.py
132
v1.0.12: 2008.02.08 by migius
133
b1 update: object = Object.Get(obname) -> f_getSceChild().getChildren()
134
a9 bugfix by non-existing tables views, vports, layers (Kai reported)
135
v1.0.12: 2008.01.17 by migius
136
a8 lately used INI-dir/filename persistently stored in Registry
137
a8 lately used DXF-dir/filename persistently stored in Registry
138
a7 fix missing layersmap{} for dxf-files without "section:layer"
139
a6 added support for XREF external referenced BLOCKs
140
a6 check for bug in AutoCAD2002:DXFr12export: ELLIPSE->POLYLINE_ARC fault angles
141
a6 support VIEWs and VPORTs as cameras: ortho and perspective mode
142
a6 save resources through ignoring unused BLOCKs (not-inserted or on frozen/blocked layers)
143
a6 added try_finally: f.close() for all IO-files
144
a6 added handling for TypeError raise
145
a5 bugfix f_getOCS for (0,0,z!=1.0) (ellipse in Kai's dxf)
146
a4 added to analyzeTool: report about VIEWs, VPORTs, unused/xref BLOCKs
147
a4 bugfix: individual support for 2D/3DPOLYLINE/POLYMESH
148
a4 added to UI: (*wip)BLOCK-(F): name filtering for BLOCKs
149
a4 added to UI: BLOCK-(n): filter anoname/hatch BLOCKs *X...
150
a2 g_scale_as is no more GUI_A-variable
151
a2 bugfix "material": negative sign color_index
152
a2 added support for BLOCKs defined with origin !=(0,0,0)
153
a1 added 'global.reLocation-vector' option
155
v1.0.11: 2007.11.24 by migius
156
c8 added 'curve_resolution_U' option
157
c8 added context_sensitivity for some UI-buttons
158
c8 bugfix ELLIPSE rotation, added closed_variant and caps
159
c7 rebuild UI: new layout, grouping and meta-buttons
160
c6 rewritten support for ELLIPSE mesh & curve representation
161
c6 restore selector-buttons for DXF-drawTypes: LINE & Co
162
c6 change header of INI/INF-files: # at begin
163
c6 apply scale(1,1,1) after glob.Scale for all mesh objects, not for curve objects.
164
c5 fixing 'material_on' option
165
c4 added "analyze DXF-file" UI-option: print LAYER/BLOCK-dependences into a textfile
166
c3 human-formating of data in INI-Files
167
c2 added "caps" for closed Bezier-curves
168
c2 added "set elevation" UI-option
169
c1 rewrite POLYLINE2d-arc-segments Bezier-interpreter
171
b9 rewrite POLYLINE2d-arc-segments trimming (clean-trim)
172
b8 added "import from frozen layers" UI-option
173
b8 added "import from paper space" UI-option
174
b8 support Bezier curves for LINEs incl.thickness(0.0-10.0)
175
b8 added meshSmooth_on for circle/arc/polyline
176
b8 added vertexGroups for circle/arc
177
b7 added width_force for ARCs/CIRCLEs = "thin_box" option
178
b3 cleanup code, rename f_drawArc/Bulg->f_calcArc/Bulg
179
b2 fixing material assignment by LAYER+COLOR
180
b1 fixing Bezier curves representation of POLYLINEs-arc-segments
181
b0 added global_scale_presets: "yard/feet/inch to meter"
183
v1.0.10: 2007.10.18 by migius
184
a6 bugfix CircleDrawCaps for OSX
185
a5 added two "curve_res" UI-buttons for Bezier curves representation
186
a5 improved Bezier curves representation of circles/arcs: correct handlers
187
a4 try to fix malformed endpoints of Blender curves of ARC/POLYLINE-arc segments.
188
a3 bugfix: open-POLYLINEs with end_point.loc==start_point.loc
189
a2 bugfix: f_transform for OCS=(0,0,-1) oriented objects
190
a1 added "fill_on=caps" option to draw top and bottom sides of CIRCLEs and ELLIPSEs
191
a1 rewrite f_CIRCLE.Draw: from Mesh.Primitive to Mesh
192
a1 bugfix "newScene"-mode: all Cylinders/Arcs were drawn at <0,0,0>location
194
v1.0.beta09: 2007.09.02 by migius
195
g5 redesign UI: grouping of buttons
196
g3 update multi-import-mode: <*.*> button
197
g- added multi-import-mode: (path/*) for importing many dxf-files at once
198
g- added import into newScene
199
g- redesign UI: user presets, into newScene-import
201
f- bugfix: thickness for Bezier/Bsplines into Blender-curves
202
f- BlenderWiki documentation, on-line Manual
203
f- added import POLYLINE-Bsplines into Blender-NURBSCurves
204
f- added import POLYLINE-arc-segments into Blender-BezierCurves
205
f- added import POLYLINE-Bezier-curves into Blender-Curves
206
d5 rewrite: Optimization Levels, added 'directDrawing'
207
d4 added: f_set_thick(controlled by ini-parameters)
208
d4 bugfix: face-normals in objects with minus thickness
209
d4 added: placeholder'Empty'-size in f_Insert.draw
210
d3 rewrite f_Text.Draw: added support for all Text's parameters
211
d2 redesign: progressbar
212
e- tuning by ideasman42: better use of the Py API.
213
c- tuning by ideasman42
214
b- rewrite f_Text.Draw rotation/transform
215
b- bugfix: POLYLINE-segment-intersection more reliable now
216
b- bugfix: circle:_thic, 'Empties':no material_assignment
217
b- added material assignment (from layer and/or color)
218
a- added empty, cylinder and UVsphere for POINTs
219
a- added support for 2d-POLYLINE: splines, fitted curves, fitted surfaces
220
a- redesign f_Drawer for block_definitions
221
a- rewrite import into Blender-Curve-Object
223
v1.0.beta08 - 2007.07.27 by migius: "full 3d"-release
224
l- bugfix: solid_vgroups, clean:scene.objects.new()
225
l- redesign UI to standard Draw.Register+FileSelector, advanced_config_option
226
k- bugfix UI:fileSelect() for MacOSX os.listdir()
227
k- added reset/save/load for config-data
228
k- redesign keywords/drawTypes/Draw.Create_Buttons
229
j- new UI using UIBlock() with own FileSelector, cause problem Window.FileSelector()
230
i- rewritten Class:Settings for better config-parameter management
231
h- bugfix: face-normals in objects with minus thickness
232
h- added Vertex-Groups in POLYLINE and SOLID meshes, for easy material assignment
233
h- beautify code, whitespace->tabs
234
h- added settings.thic_force switch for forcing thickness
235
h- added "one Mesh" option for all entities from the same Layer, sorted in<br>
236
Vertex-Groups(color_name) (fewer objects = better import performance)
237
g- rewrote: insert-point-handle-object is a small tetrahedron
238
e- bugfix: closed-polymesh3d
239
- rewrote: UI, type_map.keys, f_drawer, all class_f_draw(added "settings" as attribut)
240
- added 2d/3d-support for Polyline_Width incl. angle intersection
241
beta07: 2007.06.19 by migius
242
- added 3d-support for LWPolylines
243
- added 2d/3d-support for Points
244
beta06: 2007.06.15 by migius
246
- added 2d/3d-support for MINSERT=BlockArray in f_drawer, added f_rotXY_Vec
247
beta05: 2007.06.14 by migius
248
- added 2d/3d-support for 3d-PolyLine, PolyMesh and PolyFace
249
- added Global-Scale for size control of imported scenes
250
beta04: 2007.06.12 by migius
251
- rewrote the f_drawBulge for correct import the arc-segments of Polylines
252
beta03: 2007.06.10 by migius
254
beta02: 2007.06.09 by migius
255
- added 3d-support for Arcs and Circles
256
- added support for Object_Thickness(=height)
257
beta01: 2007.06.08 by migius
258
- added 3d-support for Blocks/Inserts within nested-structures
259
- rewrote f_transform for correct 3d-location/3d-rotation
260
- added 3d-support Lines, 3dFaces
261
- added 2d+3d-support for Solids and Traces
263
v0.9 - 2007.01 by kitsu: (for 2.43)
264
- first draft of true POLYLINE import
267
v0.8 - 2006.12 by kitsu:
268
- first draft of object space coordinates OCS import
271
v0.5b - 2006.10 by kitsu: (for 2.42a)
277
# --------------------------------------------------------------------------
278
# DXF Import v1.0 by Ed Blake (AKA kitsu) and Remigiusz Fiedler (AKA migius)
279
# --------------------------------------------------------------------------
280
# ***** BEGIN GPL LICENSE BLOCK *****
282
# This program is free software; you can redistribute it and/or
283
# modify it under the terms of the GNU General Public License
284
# as published by the Free Software Foundation; either version 2
285
# of the License, or (at your option) any later version.
287
# This program is distributed in the hope that it will be useful,
288
# but WITHOUT ANY WARRANTY; without even the implied warranty of
289
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
290
# GNU General Public License for more details.
292
# You should have received a copy of the GNU General Public License
293
# along with this program; if not, write to the Free Software Foundation,
294
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
296
# ***** END GPL LICENCE BLOCK *****
297
# --------------------------------------------------------------------------
300
from Blender import *
301
#from Blender.Mathutils import Vector, Matrix
305
from dxfReader import readDXF
306
#from dxfReader import get_name, get_layer
307
from dxfReader import Object as dxfObject
308
from dxfColorMap import color_map
314
if os.name:# != 'mac':
316
psyco.log(Blender.Get('tempdir')+"/blender.log-psyco")
318
psyco.full(memory=100)
319
psyco.profile(0.05, memory=100)
321
#print 'psyco imported'
323
#print 'psyco not imported'
329
print 'DXF-Importer v%s *** start ***' %(__version__) #---------------------
332
WORLDX = Mathutils.Vector((1,0,0))
333
WORLDY = Mathutils.Vector((1,1,0))
334
WORLDZ = Mathutils.Vector((0,0,1))
336
G_SCALE = 1.0 #(0.0001-1000) global scaling factor for all dxf data
337
G_ORIGIN_X = 0.0 #global translation-vector (x,y,z) in DXF units
340
MIN_DIST = 0.001 #cut-off value for sort out short-distance polyline-"duoble_vertex"
341
ARC_RESOLUTION = 64 #(4-500) arc/circle resolution - number of segments
342
ARC_RADIUS = 1.0 #(0.01-100) arc/circle radius for number of segments algorithm
343
CURV_RESOLUTION = 12 #(1-128) Bezier curves U-resolution
344
CURVARC_RESOLUTION = 4 #(3-32) resolution of circle represented as Bezier curve
345
THIN_RESOLUTION = 8 #(4-64) thin_cylinder arc_resolution - number of segments
346
MIN_THICK = MIN_DIST * 10.0 #minimal thickness by forced thickness
347
MIN_WIDTH = MIN_DIST * 10.0 #minimal width by forced width
348
TRIM_LIMIT = 3.0 #limit for triming of polylines-wide-segments (values:0.0 - 5.0)
349
ELEVATION = 0.0 #standard elevation = coordinate Z
353
TARGET_LAYER = 3 #target blender_layer
354
GROUP_BYLAYER = 0 #(0/1) all entities from same layer import into one blender-group
355
LAYER_DEF_NAME = 'AAAA' #default layer name
356
LAYER_DEF_COLOR = 4 #default layer color
358
LAB = "*) parts under construction"
361
FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE)
362
MAX_NAMELENGTH = 17 #max_effective_obnamelength in blender =21=17+(.001)
363
INIFILE_DEFAULT_NAME = 'importDXF'
364
INIFILE_EXTENSION = '.ini'
365
INIFILE_HEADER = '#ImportDXF.py ver.1.0 config data'
366
INFFILE_HEADER = '#ImportDXF.py ver.1.0 analyze of DXF-data'
368
AUTO = BezTriple.HandleTypes.AUTO
369
FREE = BezTriple.HandleTypes.FREE
370
VECT = BezTriple.HandleTypes.VECT
371
ALIGN = BezTriple.HandleTypes.ALIGN
374
class View: #-----------------------------------------------------------------
375
"""Class for objects representing dxf VIEWs.
377
def __init__(self, obj, active=None):
378
"""Expects an object of type VIEW as input.
380
if not obj.type == 'view':
381
raise TypeError, "Wrong type %s for VIEW object!" %obj.type
384
self.name = obj.get_type(2)[0]
385
# self.data = obj.data[:]
388
self.centerX = getit(obj, 10, 0.0) #view center pointX (in DCS)
389
self.centerY = getit(obj, 20, 0.0) #view center pointY (in DCS)
390
self.height = obj.get_type(40)[0] #view height (in DCS)
391
self.width = obj.get_type(41)[0] #view width (in DCS)
394
self.dir[0] = getit(obj, 11, 0.0) #view directionX from target (in WCS)
395
self.dir[1] = getit(obj, 21, 0.0) #
396
self.dir[2] = getit(obj, 31, 0.0) #
398
self.target = [0,0,0]
399
self.target[0] = getit(obj, 12, 0.0) #target pointX(in WCS)
400
self.target[1] = getit(obj, 22, 0.0) #
401
self.target[2] = getit(obj, 32, 0.0) #
403
self.length = obj.get_type(42)[0] #Lens length
404
self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
405
self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
406
self.twist = obj.get_type(50)[0] #view twist angle in degrees
408
self.flags = getit(obj, 70, 0)
409
self.paperspace = self.flags & 1 #
411
self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
414
return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
417
def draw(self, settings):
418
"""for VIEW: generate Blender_camera.
420
obname = 'vw_%s' %self.name # create camera object name
421
#obname = 'ca_%s' %self.name # create camera object name
422
obname = obname[:MAX_NAMELENGTH]
424
if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
425
cam= Camera.New('ortho', obname)
426
ob= SCENE.objects.new(cam)
428
cam.scale = 1.0 # for ortho cameras
430
cam= Camera.New('persp', obname)
431
ob= SCENE.objects.new(cam)
433
cam.angle = 60.0 # for persp cameras
435
#cam.angle = 2 * atan(17.5/self.length) * 180/pi
436
cam.lens = self.length #for persp cameras
437
# hack to update Camera>Lens setting (inaccurate as a focal length)
438
#curLens = cam.lens; cam.lens = curLens
439
# AutoCAD gets clip distance from target:
440
dist = Mathutils.Vector(self.dir).length
441
cam.clipEnd = dist - self.clip_back
442
cam.clipStart = dist - self.clip_front
447
v = Mathutils.Vector(self.dir)
448
# print 'deb:view cam:', cam #------------
449
# print 'deb:view self.target:', self.target #------------
450
# print 'deb:view self.dir:', self.dir #------------
451
# print 'deb:view self.twist:', self.twist #------------
452
# print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
453
transform(v.normalize(), -self.twist, ob)
454
ob.loc = Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
458
class Vport: #-----------------------------------------------------------------
459
"""Class for objects representing dxf VPORTs.
461
def __init__(self, obj, active=None):
462
"""Expects an object of type VPORT as input.
464
if not obj.type == 'vport':
465
raise TypeError, "Wrong type %s for VPORT object!" %obj.type
468
self.name = obj.get_type(2)[0]
469
# self.data = obj.data[:]
470
#print 'deb:vport name, data:', self.name #-------
471
#print 'deb:vport data:', self.data #-------
473
self.height = obj.get_type(40)[0] #vport height (in DCS)
474
self.centerX = getit(obj, 12, 0.0) #vport center pointX (in DCS)
475
self.centerY = getit(obj, 22, 0.0) #vport center pointY (in DCS)
476
self.width = self.height * obj.get_type(41)[0] #vport aspect ratio - width (in DCS)
479
self.dir[0] = getit(obj, 16, 0.0) #vport directionX from target (in WCS)
480
self.dir[1] = getit(obj, 26, 0.0) #
481
self.dir[2] = getit(obj, 36, 0.0) #
483
self.target = [0,0,0]
484
self.target[0] = getit(obj, 17, 0.0) #target pointX(in WCS)
485
self.target[1] = getit(obj, 27, 0.0) #
486
self.target[2] = getit(obj, 37, 0.0) #
488
self.length = obj.get_type(42)[0] #Lens length
489
self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
490
self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
491
self.twist = obj.get_type(51)[0] #view twist angle
493
self.flags = getit(obj, 70, 0)
494
self.paperspace = self.flags & 1 #
496
self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
499
return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
501
def draw(self, settings):
502
"""for VPORT: generate Blender_camera.
504
obname = 'vp_%s' %self.name # create camera object name
505
#obname = 'ca_%s' %self.name # create camera object name
506
obname = obname[:MAX_NAMELENGTH]
508
if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
509
cam= Camera.New('ortho', obname)
510
ob= SCENE.objects.new(cam)
512
cam.scale = 1.0 # for ortho cameras
514
cam= Camera.New('persp', obname)
515
ob= SCENE.objects.new(cam)
517
cam.angle = 60.0 # for persp cameras
519
#cam.angle = 2 * atan(17.5/self.length) * 180/pi
520
cam.lens = self.length #for persp cameras
521
# hack to update Camera>Lens setting (inaccurate as a focal length)
522
#curLens = cam.lens; cam.lens = curLens
523
# AutoCAD gets clip distance from target:
524
dist = Mathutils.Vector(self.dir).length
525
cam.clipEnd = dist - self.clip_back
526
cam.clipStart = dist - self.clip_front
531
v = Mathutils.Vector(self.dir)
532
# print 'deb:view cam:', cam #------------
533
# print 'deb:view self.target:', self.target #------------
534
# print 'deb:view self.dir:', self.dir #------------
535
# print 'deb:view self.twist:', self.twist #------------
536
# print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
537
transform(v.normalize(), -self.twist, ob)
538
ob.loc = Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
543
class Layer: #-----------------------------------------------------------------
544
"""Class for objects representing dxf LAYERs.
546
def __init__(self, obj, name=None, color=None, frozen=None):
547
"""Expects an dxfobject of type layer as input.
548
if no dxfobject - creates surogate layer with default parameters
553
if name: self.name = name
554
else: self.name = LAYER_DEF_NAME
556
if color: self.color = color
557
else: self.color = LAYER_DEF_COLOR
559
if frozen!=None: self.frozen = frozen
560
else: self.frozen = 0
562
if obj.type=='layer':
564
#self.data = obj.data[:]
565
if name: self.name = name
566
#self.bfname = name #--todo---see layernamesmap in f_getLayersmap ---
567
else: self.name = obj.get_type(2)[0] #layer name of object
569
if color: self.color = color
570
else: self.color = obj.get_type(62)[0] #color of object
572
if frozen!=None: self.frozen = frozen
574
self.flags = obj.get_type(70)[0]
575
self.frozen = self.flags & 1
578
return "%s: name - %s, color - %s" %(self.__class__.__name__, self.name, self.color)
582
def getit(obj, typ, default=None): #------------------------------------------
583
"""Universal procedure for geting data from list/objects.
586
if type(obj) == list: #if obj is a list, then searching in a list
588
#print 'deb:getit item, type(item)', item, type(item)
592
break #as soon as the first found
594
# --todo-- I found one case where item was a text instance
595
# that failed with no __getitem__
597
else: #else searching in Object with get_type-Methode
598
item = obj.get_type(typ)
601
#print 'deb:getit:typ, it', typ, it #----------
606
def get_extrusion(data): #-------------------------------------------------
607
"""Find the axis of extrusion.
609
Used to get from object_data the objects Object_Coordinate_System (ocs).
611
#print 'deb:get_extrusion: data: \n', data #---------------
613
vec[0] = getit(data, 210, 0) # 210 = x
614
vec[1] = getit(data, 220, 0) # 220 = y
615
vec[2] = getit(data, 230, 1) # 230 = z
616
#print 'deb:get_extrusion: vec: ', vec #---------------
620
#------------------------------------------
621
def getSceneChild(name):
622
dudu = [i for i in SCENE.objects if i.name==name]
623
# dudu = [i for i in SCENE.getChildren() if i.name==name]
624
#print 'deb:getSceneChild %s -result: %s:' %(name,dudu) #-----------------
625
if dudu!=[]: return dudu[0]
629
class Solid: #-----------------------------------------------------------------
630
"""Class for objects representing dxf SOLID or TRACE.
632
def __init__(self, obj):
633
"""Expects an entity object of type solid or trace as input.
635
if obj.type == 'trace':
637
if not obj.type == 'solid':
638
raise TypeError, "Wrong type \'%s\' for solid/trace object!" %obj.type
641
# self.data = obj.data[:]
643
self.space = getit(obj, 67, 0)
644
self.thic = getit(obj, 39, 0)
645
self.color_index = getit(obj, 62, BYLAYER)
647
self.layer = getit(obj, 8, None)
648
self.extrusion = get_extrusion(obj)
649
self.points = self.get_points(obj)
653
def get_points(self, data):
654
"""Gets start and end points for a solid type object.
656
Solids have 3 or 4 points and fixed codes for each value.
659
# start x, y, z and end x, y, z = 0
664
a[0] = getit(data, 10, None) # 10 = x
665
a[1] = getit(data, 20, None) # 20 = y
666
a[2] = getit(data, 30, 0) # 30 = z
667
b[0] = getit(data, 11, None)
668
b[1] = getit(data, 21, None)
669
b[2] = getit(data, 31, 0)
670
c[0] = getit(data, 12, None)
671
c[1] = getit(data, 22, None)
672
c[2] = getit(data, 32, 0)
675
d[0] = getit(data, 13, None)
677
d[1] = getit(data, 23, None)
678
d[2] = getit(data, 33, 0)
680
#print 'deb:solid.vertices:---------\n', out #-----------------------
685
return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
688
def draw(self, settings):
689
"""for SOLID: generate Blender_geometry.
692
if not points: return
693
edges, faces = [], []
696
obname = 'so_%s' %self.layer # create object name from layer name
697
obname = obname[:MAX_NAMELENGTH]
699
vg_left, vg_right, vg_top, vg_bottom, vg_start, vg_end = [], [], [], [], [], []
700
thic = set_thick(self.thic, settings)
702
thic_points = [[v[0], v[1], v[2] + thic] for v in points[:]]
704
thic_points.extend(points)
707
points.extend(thic_points)
710
faces = [[0,1,3,2], [4,6,7,5], [0,4,5,1],
711
[1,5,7,3], [3,7,6,2], [2,6,4,0]]
715
vg_bottom = [0,1,3,2]
719
faces = [[0,1,2], [3,5,4], [0,3,4,1], [1,4,5,2], [2,5,3,0]]
725
elif l == 2: faces = [[0,1,3,2]]
727
if l == 4: faces = [[0,1,3,2]]
728
elif l == 3: faces = [[0,1,2]]
729
elif l == 2: edges = [[0,1]]
731
if M_OBJ: obname, me, ob = makeNewObject()
733
me = Mesh.New(obname) # create a new mesh
734
ob = SCENE.objects.new(me) # create a new mesh_object
735
me.verts.extend(points) # add vertices to mesh
736
if faces: me.faces.extend(faces) # add faces to the mesh
737
if edges: me.edges.extend(edges) # add faces to the mesh
739
if settings.var['vGroup_on'] and not M_OBJ:
740
# each MeshSide becomes vertexGroup for easier material assignment ---------------------
741
replace = Blender.Mesh.AssignModes.ADD #or .AssignModes.ADD/REPLACE
742
if vg_left: me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
743
if vg_right:me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
744
if vg_top: me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
745
if vg_bottom:me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
746
if vg_start:me.addVertGroup('side.start') ; me.assignVertsToGroup('side.start', vg_start, 1.0, replace)
747
if vg_end: me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', vg_end, 1.0, replace)
749
transform(self.extrusion, 0, ob)
753
class Line: #-----------------------------------------------------------------
754
"""Class for objects representing dxf LINEs.
756
def __init__(self, obj):
757
"""Expects an entity object of type line as input.
759
if not obj.type == 'line':
760
raise TypeError, "Wrong type \'%s\' for line object!" %obj.type
762
# self.data = obj.data[:]
764
self.space = getit(obj, 67, 0)
765
self.thic = getit(obj, 39, 0)
766
#print 'deb:self.thic: ', self.thic #---------------------
767
self.color_index = getit(obj, 62, BYLAYER)
769
self.layer = getit(obj, 8, None)
770
self.extrusion = get_extrusion(obj)
771
self.points = self.get_points(obj)
774
def get_points(self, data):
775
"""Gets start and end points for a line type object.
777
Lines have a fixed number of points (two) and fixed codes for each value.
779
# start x,y,z and end x,y,z = 0
782
a[0] = getit(data, 10, None) # 10 = x
783
a[1] = getit(data, 20, None) # 20 = y
784
a[2] = getit(data, 30, 0) # 30 = z
785
b[0] = getit(data, 11, None)
786
b[1] = getit(data, 21, None)
787
b[2] = getit(data, 31, 0)
793
return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
796
def draw(self, settings):
797
"""for LINE: generate Blender_geometry.
799
# Generate the geometery
800
#settings.var['curves_on']=False
803
thic = set_thick(self.thic, settings)
805
if settings.var['lines_as'] == 4: # as thin_box
806
thic = settings.var['thick_min']
807
width = settings.var['width_min']
808
elif settings.var['lines_as'] == 3: # as thin cylinder
809
cyl_rad = 0.5 * settings.var['width_min']
811
elif settings.var['lines_as'] == 5: # LINE curve representation-------------------------
812
obname = 'li_%s' %self.layer # create object name from layer name
813
obname = obname[:MAX_NAMELENGTH]
815
c = Curve.New(obname) # create new curve data
816
curve = c.appendNurb(BezTriple.New(points[0]))
817
curve.append(BezTriple.New(points[1]))
819
point.handleTypes = [VECT, VECT]
820
curve.flagU = 0 # 0 sets the curve not cyclic=open
821
c.setResolu(settings.var['curve_res'])
822
c.update() #important for handles calculation
824
ob = SCENE.objects.new(c) # create a new curve_object
826
#if False: # --todo-- better support for 210-group
827
if thic != 0.0: #hack: Blender2.45 curve-extrusion
829
if abs(t) > 5.0: t = 5.0 * cmp(t,0) # Blender2.45 accepts only (0.0 - 5.0)
831
c.setExt1(abs(t)) # curve-extrusion
835
#c.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
836
#ob.LocZ = t + self.loc[2]
840
else: # LINE mesh representation ------------------------------
841
global activObjectLayer
842
global activObjectName
843
#print 'deb:draw:line.ob IN activObjectName: ', activObjectName #---------------------
845
if M_OBJ: obname, me, ob = makeNewObject()
847
if activObjectLayer == self.layer and settings.var['one_mesh_on']:
848
obname = activObjectName
849
#print 'deb:line.draw obname from activObjectName: ', obname #---------------------
850
ob = getSceneChild(obname) # open an existing mesh_object
851
#ob = SCENE.getChildren(obname) # open an existing mesh_object
852
#me = Mesh.Get(ob.name) # open objects mesh data
853
me = ob.getData(name_only=False, mesh=True)
855
obname = 'li_%s' %self.layer # create object name from layer name
856
obname = obname[:MAX_NAMELENGTH]
857
me = Mesh.New(obname) # create a new mesh
858
ob = SCENE.objects.new(me) # create a new mesh_object
859
activObjectName = ob.name
860
activObjectLayer = self.layer
861
#print ('deb:line.draw new line.ob+mesh:"%s" created!' %ob.name) #---------------------
863
faces, edges = [], []
866
#if settings.var['width_force']: #--todo-----------
869
t, e = thic, self.extrusion
870
#print 'deb:thic, extr: ', t, e #---------------------
871
points.extend([[v[0]+t*e[0], v[1]+t*e[1], v[2]+t*e[2]] for v in points[:]])
872
faces = [[0+n, 1+n, 3+n, 2+n]]
876
me.verts.extend(points) # adds vertices to global mesh
877
if faces: me.faces.extend(faces) # add faces to the mesh
878
if edges: me.edges.extend(edges) # add faces to the mesh
880
if settings.var['vGroup_on'] and not M_OBJ:
881
# entities with the same color build one vertexGroup for easier material assignment ----
882
ob.link(me) # link mesh to that object
883
vG_name = 'color_%s' %self.color_index
884
if edges: faces = edges
885
replace = Blender.Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD
887
me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
888
#print 'deb: existed vGroup:', vG_name #---------------------
890
me.addVertGroup(vG_name)
891
me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
892
#print 'deb: create new vGroup:', vG_name #---------------------
895
#print 'deb:draw:line.ob OUT activObjectName: ', activObjectName #---------------------
900
class Point: #-----------------------------------------------------------------
901
"""Class for objects representing dxf POINTs.
903
def __init__(self, obj):
904
"""Expects an entity object of type point as input.
906
if not obj.type == 'point':
907
raise TypeError, "Wrong type %s for point object!" %obj.type
909
# self.data = obj.data[:]
911
self.space = getit(obj, 67, 0)
912
self.thic = getit(obj, 39, 0)
913
#print 'deb:self.thic: ', self.thic #---------------------
914
self.color_index = getit(obj, 62, BYLAYER)
916
self.layer = getit(obj, 8, None)
917
self.extrusion = get_extrusion(obj)
918
self.points = self.get_points(obj)
921
def get_points(self, data):
922
"""Gets coordinates for a point type object.
924
Points have fixed codes for each value.
927
a[0] = getit(data, 10, None) # 10 = x
928
a[1] = getit(data, 20, None) # 20 = y
929
a[2] = getit(data, 30, 0) # 30 = z
935
return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
938
def draw(self, settings):
939
"""for POINT: generate Blender_geometry.
942
obname = 'po_%s' %self.layer # create object name from layer name
943
obname = obname[:MAX_NAMELENGTH]
944
points_as = settings.var['points_as']
945
thic = settings.var['thick_min']
946
if thic < settings.var['dist_min']: thic = settings.var['dist_min']
948
if points_as in [1,3,4,5]:
949
if True: # points_as in [1,5]: # as 'empty'
951
elif points_as == 3: # as 'thin sphere'
952
res = settings.var['thin_res']
953
c = Mesh.Primitives.UVsphere(res,res,thic)
954
elif points_as == 4: # as 'thin box'
955
c = Mesh.Primitives.Cube(thic)
956
ob = SCENE.objects.new(c, obname) # create a new object
957
transform(self.extrusion, 0, ob)
958
ob.loc = tuple(points[0])
960
elif points_as == 2: # as 'vertex'
961
global activObjectLayer
962
global activObjectName
963
#print 'deb:draw:point.ob IN activObjectName: ', activObjectName #---------------------
964
if M_OBJ: obname, me, ob = makeNewObject()
966
if activObjectLayer == self.layer and settings.var['one_mesh_on']:
967
obname = activObjectName
968
#print 'deb:draw:point.ob obname from activObjectName: ', obname #---------------------
969
ob = getSceneChild(obname) # open an existing mesh_object
970
#ob = SCENE.getChildren(obname) # open an existing mesh_object
971
me = ob.getData(name_only=False, mesh=True)
972
#me = Mesh.Get(ob.name) # open objects mesh data
974
me = Mesh.New(obname) # create a new mesh
975
ob = SCENE.objects.new(me) # create a new mesh_object
976
activObjectName = ob.name
977
activObjectLayer = self.layer
978
#print ('deb:draw:point new point.ob+mesh:"%s" created!' %ob.name) #---------------------
979
me.verts.extend(points) # add vertices to mesh
985
class Polyline: #-----------------------------------------------------------------
986
"""Class for objects representing dxf POLYLINEs.
988
def __init__(self, obj):
989
"""Expects an entity object of type polyline as input.
991
#print 'deb:polyline.init.START:----------------' #------------------------
992
if not obj.type == 'polyline':
993
raise TypeError, "Wrong type %s for polyline object!" %obj.type
995
# self.data = obj.data[:]
997
self.space = getit(obj, 67, 0)
998
self.elevation = getit(obj, 30, 0)
999
#print 'deb:elevation: ', self.elevation #---------------
1000
self.thic = getit(obj, 39, 0)
1001
self.color_index = getit(obj, 62, BYLAYER)
1003
self.flags = getit(obj, 70, 0)
1004
self.closed = self.flags & 1 # closed in the M direction
1005
self.curved = self.flags & 2 # Bezier-curve-fit vertices have been added
1006
self.spline = self.flags & 4 # NURBS-curve-fit vertices have been added
1007
self.poly3d = self.flags & 8 # 3D-polyline
1008
self.plmesh = self.flags & 16 # 3D-polygon mesh
1009
self.closeN = self.flags & 32 # closed in the N direction
1010
self.plface = self.flags & 64 # 3D-polyface mesh
1011
self.contin = self.flags & 128 # the linetype pattern is generated continuously
1013
self.pltype='poly2d' # default is a 2D-polyline
1014
if self.poly3d: self.pltype='poly3d'
1015
elif self.plface: self.pltype='plface'
1016
elif self.plmesh: self.pltype='plmesh'
1018
self.swidth = getit(obj, 40, 0) # default start width
1019
self.ewidth = getit(obj, 41, 0) # default end width
1020
#self.bulge = getit(obj, 42, None) # bulge of the segment
1021
self.vectorsM = getit(obj, 71, None) # PolyMesh: expansion in M-direction / PolyFace: number of the vertices
1022
self.vectorsN = getit(obj, 72, None) # PolyMesh: expansion in M-direction / PolyFace: number of faces
1023
#self.resolM = getit(obj, 73, None) # resolution of surface in M direction
1024
#self.resolN = getit(obj, 74, None) # resolution of surface in N direction
1025
self.curvNoFitted = False
1026
self.curvQuadrati = False
1027
self.curvCubicBsp = False
1028
self.curvBezier = False
1029
curvetype = getit(obj, 75, 0) # type of curve/surface: 0=None/5=Quadric/6=Cubic/8=Bezier
1030
if curvetype == 0: self.curvNoFitted = True
1031
elif curvetype == 5: self.curvQuadrati = True
1032
elif curvetype == 6: self.curvCubicBsp = True
1033
elif curvetype == 8: self.curvBezier = True
1035
self.layer = getit(obj, 8, None)
1036
self.extrusion = get_extrusion(obj)
1038
self.points = [] #list with vertices coordinats
1039
self.faces = [] #list with vertices assigment to faces
1040
#print 'deb:polyline.init.ENDinit:----------------' #------------
1045
return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
1049
def doubles_out(self, settings, d_points):
1050
"""routine to sort out of double.vertices-----------------------------
1052
minimal_dist = settings.var['dist_min'] * 0.1
1055
for i in xrange(len(d_points)-1):
1057
point2 = d_points[i+1]
1058
#print 'deb:double.vertex p1,p2', point, point2 #------------------------
1059
delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
1060
if delta.length > minimal_dist:
1061
temp_points.append(point)
1064
#print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
1065
temp_points.append(d_points[-1]) #------ incl. last vertex -------------
1066
#if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
1067
d_points = temp_points #-----vertex.list without "double.vertices"
1068
#print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1072
def tribles_out(self, settings, d_points):
1073
"""routine to sort out of three_in_place.vertices-----------------------------
1075
minimal_dist = settings.var['dist_min'] * 0.1
1078
for i in xrange(len(d_points)-2):
1079
point1 = d_points[i]
1080
point2 = d_points[i+1]
1081
point3 = d_points[i+2]
1082
#print 'deb:double.vertex p1,p2', point, point2 #------------------------
1083
delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
1084
delta23 = Mathutils.Vector(point3.loc) - Mathutils.Vector(point2.loc)
1085
if delta12.length < minimal_dist and delta23.length < minimal_dist:
1088
temp_points.append(point1)
1089
#print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
1090
point1 = d_points[-2]
1091
point2 = d_points[-1]
1092
delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
1093
if delta12.length > minimal_dist:
1094
temp_points.append(d_points[-2]) #------ incl. 2last vertex -------------
1095
temp_points.append(d_points[-1]) #------ incl. 1last vertex -------------
1096
#if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
1097
d_points = temp_points #-----vertex.list without "double.vertices"
1098
#print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1102
def draw(self, settings): #-------------%%%% DRAW POLYLINE %%%---------------
1103
"""for POLYLINE: generate Blender_geometry.
1105
#print 'deb:drawPOLYLINE.START:----------------' #------------------------
1106
#print 'deb:POLYLINEdraw self.pltype:', self.pltype #------------------------
1107
#print 'deb:POLYLINEdraw self.points:\n', self.points #------------------------
1109
#---- 3dPolyFace - mesh with free topology
1110
if self.pltype=='plface' and settings.drawTypes['plmesh']:
1111
ob = self.drawPlFace(settings)
1112
#---- 3dPolyMesh - mesh with ortogonal topology
1113
elif self.pltype=='plmesh' and settings.drawTypes['plmesh']:
1114
ob = self.drawPlMesh(settings)
1116
#---- 2dPolyline - plane polyline with arc/wide/thic segments
1117
elif self.pltype=='poly2d' and settings.drawTypes['polyline']:
1118
if settings.var['plines_as'] in [5,6]: # and self.spline:
1119
ob = self.drawPolyCurve(settings)
1121
ob = self.drawPoly2d(settings)
1123
#---- 3dPolyline - non-plane polyline (thin segments = without arc/wide/thic)
1124
elif self.pltype=='poly3d' and settings.drawTypes['pline3']:
1125
if settings.var['plines3_as'] in [5,6]: # and self.spline:
1126
ob = self.drawPolyCurve(settings)
1128
ob = self.drawPoly2d(settings)
1130
#---- Spline - curved polyline (thin segments = without arc/wide/thic)
1131
elif self.pltype=='spline' and settings.drawTypes['spline']:
1132
if settings.var['splines_as'] in [5,6]:
1133
ob = self.drawPolyCurve(settings)
1135
ob = self.drawPoly2d(settings)
1139
def drawPlFace(self, settings): #---- 3dPolyFace - mesh with free topology
1140
"""Generate the geometery of polyface.
1142
#print 'deb:drawPlFace.START:----------------' #------------------------
1145
#print 'deb:len of pointsList ====== ', len(self.points) #------------------------
1146
for point in self.points:
1148
faces.append(point.face)
1150
points.append(point.loc)
1152
if settings.var['plmesh_flip']: # ----------------------
1155
face = [face[-1]] + face[:-1]
1157
#print 'deb:drawPlFace: len of points_list:\n', len(points) #-----------------------
1158
#print 'deb:drawPlFace: len of faces_list:\n', len(faces) #-----------------------
1159
#print 'deb:drawPlFace: points_list:\n', points #-----------------------
1160
#print 'deb:drawPlFace: faces_list:\n', faces #-----------------------
1161
obname = 'pf_%s' %self.layer # create object name from layer name
1162
obname = obname[:MAX_NAMELENGTH]
1163
me = Mesh.New(obname) # create a new mesh
1164
ob = SCENE.objects.new(me) # create a new mesh_object
1165
me.verts.extend(points) # add vertices to mesh
1166
me.faces.extend(faces) # add faces to the mesh
1167
if settings.var['normals_out']: # ----------------------
1171
#print 'deb:drawPlFace: len of me.faces:\n', len(me.faces) #-----------------------
1173
if settings.var['meshSmooth_on']: # ----------------------
1174
for i in xrange(len(me.faces)):
1175
me.faces[i].smooth = True
1176
#me.Mode(AUTOSMOOTH)
1177
transform(self.extrusion, 0, ob)
1178
#print 'deb:drawPlFace.END:----------------' #------------------------
1183
def drawPlMesh(self, settings): #---- 3dPolyMesh - mesh with orthogonal topology
1184
"""Generate the geometery of polymesh.
1186
#print 'deb:polymesh.draw.START:----------------' #------------------------
1188
#print 'deb:len of pointsList ====== ', len(self.points) #------------------------
1192
for j in xrange(m - 1):
1193
for i in xrange(n - 1):
1195
faces.append([nn+i, nn+i+1, nn+n+i+1, nn+n+i])
1197
if self.closed: #mesh closed in N-direction
1199
for i in xrange(n - 1):
1200
faces.append([nn+i, nn+i+1, i+1, i])
1202
if self.closeN: #mesh closed in M-direction
1203
for j in xrange(m-1):
1205
faces.append([nn+n-1, nn, nn+n, nn+n-1+n])
1207
if self.closed and self.closeN: #mesh closed in M/N-direction
1208
faces.append([ (n*m)-1, (m-1)*n, 0, n-1])
1210
#print 'deb:len of points_list:\n', len(points) #-----------------------
1211
#print 'deb:faces_list:\n', faces #-----------------------
1212
obname = 'pm_%s' %self.layer # create object name from layer name
1213
obname = obname[:MAX_NAMELENGTH]
1214
me = Mesh.New(obname) # create a new mesh
1215
ob = SCENE.objects.new(me) # create a new mesh_object
1216
me.verts.extend([point.loc for point in self.points]) # add vertices to mesh
1217
me.faces.extend(faces) # add faces to the mesh
1218
if settings.var['normals_out']: # ----------------------
1222
if settings.var['meshSmooth_on']: # ----------------------
1223
for i in xrange(len(faces)):
1224
me.faces[i].smooth = True
1225
#me.Mode(AUTOSMOOTH)
1227
transform(self.extrusion, 0, ob)
1228
#print 'deb:polymesh.draw.END:----------------' #------------------------
1232
def drawPolyCurve(self, settings): #---- Polyline - draw as Blender-curve
1233
"""Generate the geometery of polyline as Blender-curve.
1235
#print 'deb:polyline2dCurve.draw.START:----------------' #---
1236
if len(self.points) < 2:
1237
#print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
1240
if self.spline: pline_typ = 'ps' # Polyline-NURBSpline
1241
elif self.curved: pline_typ = 'pc' # Polyline-BezierCurve
1242
else: pline_typ = 'pl' # Polyline classic
1243
obname = '%s_%s' %(pline_typ, self.layer) # create object_name from layer name
1244
obname = obname[:MAX_NAMELENGTH]
1247
if settings.var['Z_force_on']:
1248
self.elevation = settings.var['Z_elev']
1249
for point in self.points:
1250
point.loc[2] = self.elevation
1251
d_points.append(point)
1252
else: #for DXFr10-format: update all points[].loc[2] == None -> 0.0
1253
for point in self.points:
1254
if point.loc[2] == None:
1255
point.loc[2] = self.elevation
1256
d_points.append(point)
1258
#d_points = self.tribles_out(settings, d_points)
1259
#d_points = self.doubles_out(settings, d_points)
1260
#print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1262
thic = set_thick(self.thic, settings)
1263
if thic != 0.0: #hack: Blender<2.45 curve-extrusion
1264
LocZ = d_points[0].loc[2]
1266
for point in d_points:
1268
temp_points.append(point)
1269
d_points = temp_points
1271
#print 'deb:polyline2dCurve.draw d_points=', d_points #---------------
1272
pline = Curve.New(obname) # create new curve data
1273
#pline.setResolu(24) #--todo-----
1275
if False: #old self.spline: # NURBSplines-----OK-----
1276
#print 'deb:polyline2dCurve.draw self.spline!' #---------------
1279
if self.curvQuadrati:
1280
# Bezier-curve form simulated in NURBS-curve
1281
# generate middlepoints except start/end-segments ---
1282
#print 'deb:polyline2dCurve.draw extraQBspline!' #---------------
1284
point = d_points[0].loc
1285
point.append(weight1)
1286
temp_points.append(point)
1287
for i in xrange(1,len(d_points)-2):
1288
point1 = d_points[i].loc
1289
point2 = d_points[i+1].loc
1290
mpoint = list((Mathutils.Vector(point1) + Mathutils.Vector(point2)) * 0.5)
1291
mpoint.append(weight2)
1292
point1.append(weight1)
1293
temp_points.append(point1)
1294
temp_points.append(mpoint)
1295
point2.append(weight1)
1296
temp_points.append(point2)
1297
point = d_points[-1].loc
1298
point.append(weight1)
1299
temp_points.append(point)
1300
d_points = temp_points
1306
temp_points.append(d)
1307
d_points = temp_points
1310
# generate extended startpoint and endpoint------
1311
point1 = Mathutils.Vector(d_points[0][:3])
1312
point2 = Mathutils.Vector(d_points[1][:3])
1313
startpoint = list(point1 - point2 + point1)
1314
startpoint.append(weight1)
1315
point1 = Mathutils.Vector(d_points[-1][:3])
1316
point2 = Mathutils.Vector(d_points[-2][:3])
1317
endpoint = list(point1 - point2 + point1)
1318
endpoint.append(weight1)
1320
temp_points.append(startpoint)
1321
temp_points.extend(d_points)
1322
d_points = temp_points
1323
d_points.append(endpoint)
1326
curve = pline.appendNurb(point)
1327
curve.setType(4) #NURBS curve
1328
for point in d_points[1:]:
1331
curve.flagU = 1 # Set curve cyclic=close
1333
curve.flagU = 0 # Set curve not cyclic=open
1335
if self.spline: # NURBSplines-----OK-----
1336
#print 'deb:polyline2dCurve.draw self.spline!' #---------------
1340
pkt.append(d.weight)
1341
nurbs_points.append(pkt)
1342
firstpoint = nurbs_points[0]
1343
curve = pline.appendNurb(firstpoint)
1344
curve.setType(4) # set curvetype NURBS
1345
for point in nurbs_points[1:]:
1348
curve.flagU = 1+0 # Set curve cyclic=close and uni
1350
curve.flagU = 0+2 # Set curve not cyclic=open
1351
try: curve.orderU = 5 # works only with >2.46svn080625
1352
except AttributeError: pass
1353
#print 'deb: dir(curve):', dir(curve) #----------------
1355
elif False: #orig self.curved: #--Bezier-curves---OK-------
1356
#print 'deb:polyline2dCurve.draw self.curved!' #---------------
1357
curve = pline.appendNurb(BezTriple.New(d_points[0]))
1358
for p in d_points[1:]:
1359
curve.append(BezTriple.New(p))
1361
point.handleTypes = [AUTO, AUTO]
1363
curve.flagU = 1 # Set curve cyclic=close
1365
curve.flagU = 0 # Set curve not cyclic=open
1366
curve[0].handleTypes = [FREE, ALIGN] #remi--todo-----
1367
curve[-1].handleTypes = [ALIGN, FREE] #remi--todo-----
1369
elif self.curved: #--SPLINE as Bezier-curves---wip------
1370
#print 'deb:polyline2dCurve.draw self.curved!' #---------------
1371
begtangent, endtangent = None, None
1372
if d_points[0].tangent:
1373
begtangent = d_points[0]
1374
d_points = d_points[1:]
1375
if d_points[-1].tangent:
1376
endtangent = d_points[-1]
1377
d_points = d_points[:-1]
1378
curve = pline.appendNurb(BezTriple.New(d_points[0]))
1379
for p in d_points[1:]:
1380
curve.append(BezTriple.New(p))
1382
point.handleTypes = [AUTO, AUTO]
1383
#curve.setType(1) #Bezier curve
1385
curve.flagU = 5 #1 # Set curve cyclic=close
1387
curve.flagU = 4 #0 # Set curve not cyclic=open
1389
#print 'deb:polyline2dCurve.draw curve[0].vec:', curve[0].vec #-----
1390
#print 'deb:polyline2dCurve.draw begtangent:', begtangent #-----
1391
p0h1,p0,p0h2 = curve[0].vec
1392
p0h1 = [p0h1[i]+begtangent[i] for i in range(3)]
1393
curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
1394
curve[0].handleTypes = [FREE, ALIGN] #remi--todo-----
1396
#print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
1397
#print 'deb:polyline2dCurve.draw endtangent:', endtangent #-----
1398
p0h1,p0,p0h2 = curve[-1].vec
1399
p0h2 = [p0h2[i]+endtangent[i] for i in range(3)]
1400
#print 'deb:drawPlineCurve: p0h2:', p0h2 #----------
1401
curve.__setitem__(-1,BezTriple.New(p0h1+p0+p0h2))
1402
#print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
1403
curve[-1].handleTypes = [ALIGN, FREE] #remi--todo-----
1407
else: #-- only straight line- and arc-segments----OK------
1408
#print 'deb:polyline2dCurve.draw curve:', curve #-----
1410
arc_res = settings.var['curve_arc']
1411
prevHandleType = VECT
1412
#d_points.append(d_points[0]) #------ first vertex added at the end of list --------
1413
#curve.setType(0) #polygon_type of Blender_curve
1414
for i in xrange(len(d_points)):
1415
point1 = d_points[i]
1416
#point2 = d_points[i+1]
1417
if False: #-----outdated!- standard calculation ----------------------------------
1418
if point1.bulge and (i < len(d_points)-2 or self.closed):
1419
verts, center = calcBulge(point1, point2, arc_res, triples=False)
1420
if i == 0: curve = pline.appendNurb(BezTriple.New(verts[0]))
1421
else: curve.append(BezTriple.New(verts[0]))
1422
curve[-1].handleTypes = [VECT, VECT] #--todo--calculation of bezier-tangents
1424
curve.append(BezTriple.New(p))
1425
curve[-1].handleTypes = [AUTO, AUTO]
1427
if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
1428
else: curve.append(BezTriple.New(point1.loc))
1429
curve[-1].handleTypes = [VECT, VECT] #--todo--calculation of bezier-tangents
1431
elif True: #----- optimised Bezier-Handles calculation --------------------------------
1432
#print 'deb:drawPlineCurve: i:', i #---------
1433
if point1.bulge and not (i == len(d_points)-1 and point1.bulge and not self.closed):
1434
if i == len(d_points)-1: point2 = d_points[0]
1435
else: point2 = d_points[i+1]
1438
# calculate additional points for bulge
1439
VectorTriples = calcBulge(point1, point2, arc_res, triples=True)
1441
if prevHandleType == FREE:
1442
#print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
1443
VectorTriples[0][:3] = prevHandleVect
1444
#print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
1446
if i == 0: curve = pline.appendNurb(BezTriple.New(VectorTriples[0]))
1447
else: curve.append(BezTriple.New(VectorTriples[0]))
1448
curve[-1].handleTypes = [prevHandleType, FREE]
1450
for p in VectorTriples[1:-1]:
1451
curve.append(BezTriple.New(p))
1452
curve[-1].handleTypes = [FREE, FREE]
1454
prevHandleVect = VectorTriples[-1][:3]
1455
prevHandleType = FREE
1456
#print 'deb:drawPlineCurve: prevHandleVect:', prevHandleVect #---------
1458
#print 'deb:drawPlineCurve: else' #----------
1459
if prevHandleType == FREE:
1460
VectorTriples = prevHandleVect + list(point1) + list(point1)
1461
#print 'deb:drawPlineCurve: VectorTriples:', VectorTriples #---------
1462
curve.append(BezTriple.New(VectorTriples))
1463
curve[-1].handleTypes = [FREE, VECT]
1464
prevHandleType = VECT
1466
if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
1467
else: curve.append(BezTriple.New(point1.loc))
1468
curve[-1].handleTypes = [VECT, VECT]
1472
#print 'deb:drawPlineCurve: curve[-1].vec[0]', curve[-1].vec[0] #----------
1475
curve.flagU = 1 # Set curve cyclic=close
1476
if prevHandleType == FREE:
1477
#print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
1478
#print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
1479
prevHandleType2 = curve[0].handleTypes[1]
1480
p0h1,p0,p0h2 = curve[0].vec
1481
#print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
1482
p0h1 = prevHandleVect
1484
#print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
1485
#curve[0].vec = [p0h1,p0,p0h2]
1486
curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
1488
curve[0].handleTypes = [FREE,prevHandleType2]
1489
#print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
1490
#print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
1492
curve[0].handleTypes[0] = VECT
1494
curve.flagU = 0 # Set curve not cyclic=open
1496
if settings.var['fill_on']:
1497
pline.setFlag(6) # 2+4 set top and button caps
1499
pline.setFlag(pline.getFlag() & ~6) # dont set top and button caps
1501
pline.setResolu(settings.var['curve_res'])
1503
ob = SCENE.objects.new(pline) # create a new curve_object
1505
if thic != 0.0: #hack: Blender<2.45 curve-extrusion
1507
pline.setExt1(1.0) # curve-extrusion accepts only (0.0 - 2.0)
1508
ob.LocZ = thic + LocZ
1510
transform(self.extrusion, 0, ob)
1512
ob.SizeZ *= abs(thic)
1514
#print 'deb:polyline2dCurve.draw.END:----------------' #-----
1518
def drawPoly2d(self, settings): #---- 2dPolyline - plane lines/arcs with wide/thic
1519
"""Generate the geometery of regular polyline.
1521
#print 'deb:polyline2d.draw.START:----------------' #------------------------
1526
swidth_default = self.swidth #default start width of POLYLINEs segments
1527
ewidth_default = self.ewidth #default end width of POLYLINEs segments
1528
#print 'deb:drawPoly2d self.swidth=', self.swidth #------------------------
1529
thic = set_thick(self.thic, settings)
1530
if self.spline: pline_typ = 'ps'
1531
elif self.curved: pline_typ = 'pc'
1532
else: pline_typ = 'pl'
1533
obname = '%s_%s' %(pline_typ, self.layer) # create object_name from layer name
1534
obname = obname[:MAX_NAMELENGTH]
1536
if len(self.points) < 2:
1537
#print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
1540
if settings.var['Z_force_on']:
1541
self.elevation = settings.var['Z_elev']
1542
for point in self.points:
1543
point.loc[2] = self.elevation
1544
d_points.append(point)
1545
else: #for DXFr10-format: update all non-existing LocZ points[].loc[2] == None -> 0.0 elevation
1546
for point in self.points:
1547
if point.loc[2] == None:
1548
point.loc[2] = self.elevation
1549
d_points.append(point)
1550
#print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1551
#print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
1554
#if closed polyline, add duplic of the first vertex at the end of pointslist
1555
if self.closed: #new_b8
1556
if d_points[-1].loc != d_points[0].loc: # if not equal, then set the first at the end of pointslist
1557
d_points.append(d_points[0])
1559
if d_points[-1].loc == d_points[0].loc: # if equal, then set to closed, and modify the last point
1560
d_points[-1] = d_points[0]
1562
#print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1563
#print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
1565
d_points = self.doubles_out(settings, d_points)
1566
#print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1568
"""# routine to sort out of "double.vertices" ------------------------------------
1569
minimal_dist = settings.var['dist_min'] * 0.1
1571
for i in xrange(len(d_points)-1):
1573
point2 = d_points[i+1]
1574
#print 'deb:double.vertex p1,p2', point, point2 #------------------------
1575
delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
1576
if delta.length > minimal_dist:
1577
temp_points.append(point)
1578
#else: print 'deb:drawPoly2d double.vertex sort out!' #------------------------
1579
temp_points.append(d_points[-1]) #------ incl. last vertex -------------
1580
#if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
1581
d_points = temp_points #-----vertex.list without "double.vertices"
1582
#print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1585
#print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1586
if len(d_points) < 2: #if too few vertex, then return
1587
#print 'deb:drawPoly2d corrupted Vertices' #---------
1590
# analyze of straight- and bulge-segments
1591
# generation of additional points for bulge segments
1592
arc_res = settings.var['arc_res']/sqrt(settings.var['arc_rad'])
1593
wide_segment_exist = False
1594
bulg_points = [] # for each point set None (or center for arc-subPoints)
1595
for i in xrange(len(d_points)-1):
1596
point1 = d_points[i]
1597
point2 = d_points[i+1]
1598
#print 'deb:drawPoly2d_bulg tocalc.point1:', point1 #------------------------
1599
#print 'deb:drawPoly2d_bulg tocalc.point2:', point2 #------------------------
1601
swidth = point1.swidth
1602
ewidth = point1.ewidth
1603
#print 'deb:drawPoly2d point1.swidth=', swidth #------------------------
1604
if swidth == None: swidth = swidth_default
1605
if ewidth == None: ewidth = ewidth_default
1606
if swidth != 0.0 or ewidth != 0.0: wide_segment_exist = True
1607
#print 'deb:drawPoly2d vertex_swidth=', swidth #------------------------
1609
if settings.var['width_force']: # force minimal width for thin segments
1610
width_min = settings.var['width_min']
1611
if swidth < width_min: swidth = width_min
1612
if ewidth < width_min: ewidth = width_min
1613
if not settings.var['width_on']: # then force minimal width for all segments
1617
#if point1.bulge and (i < (len(d_points)-1) or self.closed):
1618
if point1.bulge and i < (len(d_points)-1): #10_b8
1619
verts, center = calcBulge(point1, point2, arc_res) #calculate additional points for bulge
1620
points.extend(verts)
1621
delta_width = (ewidth - swidth) / len(verts)
1622
width_list = [swidth + (delta_width * ii) for ii in xrange(len(verts)+1)]
1623
swidths.extend(width_list[:-1])
1624
ewidths.extend(width_list[1:])
1625
bulg_list = [center for ii in xrange(len(verts))]
1626
#the last point in bulge has index False for better indexing of bulg_end!
1627
bulg_list[-1] = None
1628
bulg_points.extend(bulg_list)
1631
points.append(point1.loc)
1632
swidths.append(swidth)
1633
ewidths.append(ewidth)
1634
bulg_points.append(None)
1635
points.append(d_points[-1].loc)
1638
#--calculate width_vectors: left-side- and right-side-points ----------------
1639
# 1.level:IF width ---------------------------------------
1640
if (settings.var['width_on'] and wide_segment_exist) or settings.var['width_force']:
1641
#new_b8 points.append(d_points[0].loc) #temporarly add first vertex at the end (for better loop)
1642
dist_min05 = 0.5 * settings.var['dist_min'] #minimal width for zero_witdh
1644
pointsLs = [] # list of left-start-points
1645
pointsLe = [] # list of left-end-points
1646
pointsRs = [] # list of right-start-points
1647
pointsRe = [] # list of right-end-points
1648
pointsW = [] # list of all border-points
1649
#rotMatr90 = Mathutils.Matrix(rotate 90 degree around Z-axis) = normalvectorXY
1650
rotMatr90 = Mathutils.Matrix([0, -1, 0], [1, 0, 0], [0, 0, 1])
1652
last_bulg_point = False
1653
for i in xrange(len(points)-1):
1655
point2 = points[i+1]
1656
point1vec = Mathutils.Vector(point1)
1657
point2vec = Mathutils.Vector(point2)
1658
swidth05 = swidths[i] * 0.5
1659
ewidth05 = ewidths[i] * 0.5
1660
if swidth05 == 0: swidth05 = dist_min05
1661
if ewidth05 == 0: ewidth05 = dist_min05
1662
normal_vector = rotMatr90 * (point2vec-point1vec).normalize()
1664
last_bulg_point = False
1666
elif bulg_points[i] != None:
1667
centerVec = Mathutils.Vector(bulg_points[i])
1668
if bulg_points[i+1] == None: last_bulg_point = True
1670
else: bulg_in = False
1673
#makes clean intersections for arc-segments
1674
radius1vec = point1vec - centerVec
1675
radius2vec = point2vec - centerVec
1676
angle = Mathutils.AngleBetweenVecs(normal_vector, radius1vec)
1678
normal_vector1 = radius1vec.normalize()
1679
normal_vector2 = radius2vec.normalize()
1681
normal_vector1 = - radius1vec.normalize()
1682
normal_vector2 = - radius2vec.normalize()
1684
swidth05vec = swidth05 * normal_vector1
1685
ewidth05vec = ewidth05 * normal_vector2
1686
pointsLs.append(point1vec + swidth05vec) #vertex left start
1687
pointsRs.append(point1vec - swidth05vec) #vertex right start
1688
pointsLe.append(point2vec + ewidth05vec) #vertex left end
1689
pointsRe.append(point2vec - ewidth05vec) #vertex right end
1692
swidth05vec = swidth05 * normal_vector
1693
ewidth05vec = ewidth05 * normal_vector
1694
pointsLs.append(point1vec + swidth05vec) #vertex left start
1695
pointsRs.append(point1vec - swidth05vec) #vertex right start
1696
pointsLe.append(point2vec + ewidth05vec) #vertex left end
1697
pointsRe.append(point2vec - ewidth05vec) #vertex right end
1699
# additional last point is also calculated
1700
#pointsLs.append(pointsLs[0])
1701
#pointsRs.append(pointsRs[0])
1702
#pointsLe.append(pointsLe[0])
1703
#pointsRe.append(pointsRe[0])
1705
pointsLc, pointsRc = [], [] # lists Left/Right corners = intersection points
1707
# 2.level:IF width and corner-trim
1708
if settings.var['pl_trim_on']: #optional clean corner-intersections
1710
# set STARTpoints of the first point points[0]
1712
pointsLc.append(pointsLs[0])
1713
pointsRc.append(pointsRs[0])
1715
pointsLs.append(pointsLs[0])
1716
pointsRs.append(pointsRs[0])
1717
pointsLe.append(pointsLe[0])
1718
pointsRe.append(pointsRe[0])
1719
points.append(points[0])
1720
vecL3, vecL4 = pointsLs[0], pointsLe[0]
1721
vecR3, vecR4 = pointsRs[0], pointsRe[0]
1722
lenL = len(pointsLs)-1
1723
#print 'deb:drawPoly2d pointsLs():\n', pointsLs #----------------
1724
#print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs) #----------------
1726
last_bulg_point = False
1728
# LOOP: makes (ENDpoints[i],STARTpoints[i+1])
1729
for i in xrange(lenL):
1730
if bulg_points[i] != None:
1731
if bulg_points[i+1] == None: #makes clean intersections for arc-segments
1732
last_bulg_point = True
1735
#pointsLc.extend((points[i], pointsLs[i]))
1736
#pointsRc.extend((points[i], pointsRs[i]))
1737
vecL1, vecL2 = vecL3, vecL4
1738
vecR1, vecR2 = vecR3, vecR4
1739
vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
1740
vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
1741
#compute left- and right-cornerpoints
1742
#cornerpointL = Geometry.LineIntersect2D(vec1, vec2, vec3, vec4)
1743
cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
1744
cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
1745
#print 'deb:drawPoly2d cornerpointL: ', cornerpointL #-------------
1746
#print 'deb:drawPoly2d cornerpointR: ', cornerpointR #-------------
1748
# IF not cornerpoint THEN check if identic start-endpoints (=collinear segments)
1749
if cornerpointL == None or cornerpointR == None:
1750
if vecL2 == vecL3 and vecR2 == vecR3:
1751
#print 'deb:drawPoly2d pointVec: ####### identic ##########' #----------------
1752
pointsLc.append(pointsLe[i])
1753
pointsRc.append(pointsRe[i])
1755
pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1756
pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1758
cornerpointL = cornerpointL[0] # because Mathutils.LineIntersect() -> (pkt1,pkt2)
1759
cornerpointR = cornerpointR[0]
1760
#print 'deb:drawPoly2d cornerpointL: ', cornerpointL #-------------
1761
#print 'deb:drawPoly2d cornerpointR: ', cornerpointR #-------------
1762
pointVec0 = Mathutils.Vector(points[i])
1763
pointVec = Mathutils.Vector(points[i+1])
1764
pointVec2 = Mathutils.Vector(points[i+2])
1765
#print 'deb:drawPoly2d pointVec0: ', pointVec0 #-------------
1766
#print 'deb:drawPoly2d pointVec: ', pointVec #-------------
1767
#print 'deb:drawPoly2d pointVec2: ', pointVec2 #-------------
1768
# if diststance(cornerL-center-cornerR) < limiter * (seg1_endWidth + seg2_startWidth)
1769
max_cornerDist = (vecL2 - vecR2).length + (vecL3 - vecR3).length
1770
is_cornerDist = (cornerpointL - pointVec).length + (cornerpointR - pointVec).length
1771
#corner_angle = Mathutils.AngleBetweenVecs((pointVec0 - pointVec),(pointVec - pointVec2))
1772
#print 'deb:drawPoly2d corner_angle: ', corner_angle #-------------
1773
#print 'deb:drawPoly2d max_cornerDist, is_cornerDist: ', max_cornerDist, is_cornerDist #-------------
1774
#if abs(corner_angle) < 90.0:
1775
# intersection --------- limited by TRIM_LIMIT (1.0 - 5.0)
1776
if is_cornerDist < max_cornerDist * settings.var['pl_trim_max']:
1777
# clean corner intersection
1778
pointsLc.append(cornerpointL)
1779
pointsRc.append(cornerpointR)
1780
elif False: # the standard no-intersection
1781
# --todo-- not optimal, because produces X-face
1782
pointsLc.extend((pointsLe[i],pointsLs[i+1]))
1783
pointsRc.extend((pointsRe[i],pointsRs[i+1]))
1784
elif False: # --todo-- the optimised non-intersection
1785
if (cornerpointL - vecL1).length < (cornerpointR - vecR1).length:
1789
limit_dist = settings.var['dist_min']
1790
if left_angle: # if left turning angle
1791
#print 'deb:drawPoly2d it is left turning angle' #-------------
1792
# to avoid triangelface/doubleVertex
1793
delta1 = (cornerpointL - vecL1).normalize() * limit_dist
1794
delta4 = (cornerpointL - vecL4).normalize() * limit_dist
1795
pointsLc.extend((cornerpointL - delta1, cornerpointL - delta4))
1796
pointsRc.extend((pointsRe[i],pointsRs[i+1]))
1797
else: # if right turning angle
1798
#print 'deb:drawPoly2d right turning angle' #-------------
1799
delta1 = (cornerpointR - vecR1).normalize() * limit_dist
1800
delta4 = (cornerpointR - vecR4).normalize() * limit_dist
1801
pointsRc.extend((cornerpointR - delta1, cornerpointR - delta4))
1802
pointsLc.extend((pointsLe[i],pointsLs[i+1]))
1804
pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1805
pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1807
pointsLc.append(pointsLe[-1])
1808
pointsRc.append(pointsRe[-1])
1810
# 2.level:IF width but no-trim
1813
# set STARTpoints of the first point points[0]
1815
pointsLc.append(pointsLs[0])
1816
pointsRc.append(pointsRs[0])
1818
pointsLs.append(pointsLs[0])
1819
pointsRs.append(pointsRs[0])
1820
pointsLe.append(pointsLe[0])
1821
pointsRe.append(pointsRe[0])
1822
points.append(points[0])
1823
vecL3, vecL4 = pointsLs[0], pointsLe[0]
1824
vecR3, vecR4 = pointsRs[0], pointsRe[0]
1825
lenL = len(pointsLs)-1
1826
#print 'deb:drawPoly2d pointsLs():\n', pointsLs #----------------
1827
#print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs) #----------------
1829
last_bulg_point = False
1831
# LOOP: makes (ENDpoints[i],STARTpoints[i+1])
1832
for i in xrange(lenL):
1833
vecL1, vecL2 = vecL3, vecL4
1834
vecR1, vecR2 = vecR3, vecR4
1835
vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
1836
vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
1837
if bulg_points[i] != None:
1838
#compute left- and right-cornerpoints
1840
cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
1841
cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
1842
pointsLc.append(cornerpointL[0])
1843
pointsRc.append(cornerpointR[0])
1845
pointVec = Mathutils.Vector(point[i])
1848
pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1849
pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1851
pointsLc.append(pointsLe[-1])
1852
pointsRc.append(pointsRe[-1])
1854
len1 = len(pointsLc)
1855
#print 'deb:drawPoly2d len1:', len1 #-----------------------
1856
#print 'deb:drawPoly2d len1 len(pointsLc),len(pointsRc):', len(pointsLc),len(pointsRc) #-----------------------
1857
pointsW = pointsLc + pointsRc # all_points_List = left_side + right_side
1858
#print 'deb:drawPoly2d pointsW():\n', pointsW #----------------
1860
# 2.level:IF width and thickness ---------------------
1863
thic_pointsW.extend([[point[0], point[1], point[2]+thic] for point in pointsW])
1865
thic_pointsW.extend(pointsW)
1866
pointsW = thic_pointsW
1868
pointsW.extend(thic_pointsW)
1870
f_start, f_end = [], []
1871
f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
1872
f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
1873
f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
1874
f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
1877
f_bottom.append([len1-1, 0, len1, len1+len1-1]) #bottom face
1878
f_top.append( [len1+len1+len1-1, len1+len1+len1+len1-1, len1+len1+len1, len1+len1+0]) #top face
1879
f_left.append( [0, len1-1, len1+len1+len1-1, len1+len1]) #left face
1880
f_right.append( [len1, len1+len1+len1, len1+len1+len1+len1-1, len1+len1-1]) #right face
1882
f_start = [[0, len1, len1+len1+len1, len1+len1]]
1883
f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
1885
faces = f_left + f_right + f_bottom + f_top + f_start + f_end
1886
#faces = f_bottom + f_top
1887
#faces = f_left + f_right + f_start + f_end
1888
#print 'deb:faces_list:\n', faces #-----------------------
1889
if M_OBJ: obname, me, ob = makeNewObject()
1891
me = Mesh.New(obname) # create a new mesh
1892
ob = SCENE.objects.new(me) # create a new mesh_object
1893
me.verts.extend(pointsW) # add vertices to mesh
1894
me.faces.extend(faces) # add faces to the mesh
1896
# each MeshSide becomes vertexGroup for easier material assignment ---------------------
1897
# The mesh must first be linked to an object so the method knows which object to update.
1898
# This is because vertex groups in Blender are stored in the object -- not in the mesh,
1899
# which may be linked to more than one object.
1900
if settings.var['vGroup_on'] and not M_OBJ:
1901
# each MeshSide becomes vertexGroup for easier material assignment ---------------------
1902
replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD
1903
vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
1904
for v in f_left: vg_left.extend(v)
1905
for v in f_right: vg_right.extend(v)
1906
for v in f_top: vg_top.extend(v)
1907
for v in f_bottom: vg_bottom.extend(v)
1908
me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', list(set(vg_left)), 1.0, replace)
1909
me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
1910
me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
1911
me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
1913
me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
1914
me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace)
1916
if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
1917
#if self.spline or self.curved:
1919
smooth_len = len(f_left) + len(f_right)
1920
for i in xrange(smooth_len):
1921
me.faces[i].smooth = True
1922
#me.Modes(AUTOSMOOTH)
1924
# 2.level:IF width, but no-thickness ---------------------
1927
faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
1929
faces.append([len1, 0, len1-1, len1+len1-1])
1930
if M_OBJ: obname, me, ob = makeNewObject()
1932
me = Mesh.New(obname) # create a new mesh
1933
ob = SCENE.objects.new(me) # create a new mesh_object
1934
me.verts.extend(pointsW) # add vertices to mesh
1935
me.faces.extend(faces) # add faces to the mesh
1938
# 1.level:IF no-width, but thickness ---------------------
1942
thic_points.extend([[point[0], point[1], point[2]+thic] for point in points])
1944
thic_points.extend(points)
1945
points = thic_points
1947
points.extend(thic_points)
1949
faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
1951
faces.append([len1-1, 0, len1, 2*len1-1])
1952
if M_OBJ: obname, me, ob = makeNewObject()
1954
me = Mesh.New(obname) # create a new mesh
1955
ob = SCENE.objects.new(me) # create a new mesh_object
1956
me.verts.extend(points) # add vertices to mesh
1957
me.faces.extend(faces) # add faces to the mesh
1959
if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
1960
#if self.spline or self.curved:
1962
for i in xrange(len(faces)):
1963
me.faces[i].smooth = True
1964
#me.Modes(AUTOSMOOTH)
1966
# 1.level:IF no-width and no-thickness ---------------------
1968
edges = [[num, num+1] for num in xrange(len(points)-1)]
1970
edges.append([len(points)-1, 0])
1971
if M_OBJ: obname, me, ob = makeNewObject()
1973
me = Mesh.New(obname) # create a new mesh
1974
ob = SCENE.objects.new(me) # create a new mesh_object
1975
me.verts.extend(points) # add vertices to mesh
1976
me.edges.extend(edges) # add edges to the mesh
1978
transform(self.extrusion, 0, ob)
1979
#print 'deb:polyline.draw.END:----------------' #-----------------------
1985
class Vertex(object): #-----------------------------------------------------------------
1986
"""Generic vertex object used by POLYLINEs, (and maybe others).
1987
also used by class_LWPOLYLINEs but without obj-parameter
1990
def __init__(self, obj=None):
1991
"""Initializes vertex data.
1993
The optional obj arg is an entity object of type vertex.
1995
#print 'deb:Vertex.init.START:----------------' #-----------------------
1998
self.swidth = None #0
1999
self.ewidth = None #0
2001
self.tangent = False
2004
if not obj.type == 'vertex':
2005
raise TypeError, "Wrong type %s for vertex object!" %obj.type
2006
self.type = obj.type
2007
# self.data = obj.data[:]
2011
#print 'deb:Vertex.init.END:----------------' #------------------------
2014
def get_props(self, data):
2015
"""Gets coords for a VERTEX type object.
2017
Each vert can have a number of properties.
2018
Verts should be coded as
2025
self.x = getit(data, 10, None)
2026
self.y = getit(data, 20, None)
2027
self.z = getit(data, 30, None)
2029
self.flags = getit(data, 70, 0) # flags
2030
self.curved = self.flags&1 # Bezier-curve-fit:additional-vertex
2031
self.curved_t = self.flags&2 # Bezier-curve-fit:tangent exists
2032
self.spline = self.flags&8 # NURBSpline-fit:additional-vertex
2033
self.spline_c = self.flags&16 # NURBSpline-fit:control-vertex
2034
self.poly3d = self.flags&32 # polyline3d:control-vertex
2035
self.plmesh = self.flags&64 # polymesh3d:control-vertex
2036
self.plface = self.flags&128 # polyface
2038
# if PolyFace.Vertex with Face_definition
2040
self.curve_tangent = getit(data, 50, None) # curve_tangent
2041
if not self.curve_tangent==None:
2043
#elif self.spline_c: # NURBSpline:control-vertex
2044
# self.weight = getit(data, 41, 1.0) # weight od control point
2046
elif self.plface and not self.plmesh:
2047
v1 = getit(data, 71, 0) # polyface:Face.vertex 1.
2048
v2 = getit(data, 72, 0) # polyface:Face.vertex 2.
2049
v3 = getit(data, 73, 0) # polyface:Face.vertex 3.
2050
v4 = getit(data, 74, None) # polyface:Face.vertex 4.
2051
self.face = [abs(v1)-1,abs(v2)-1,abs(v3)-1]
2053
if abs(v4) != abs(v1):
2054
self.face.append(abs(v4)-1)
2055
else: #--parameter for polyline2d
2056
self.swidth = getit(data, 40, None) # start width
2057
self.ewidth = getit(data, 41, None) # end width
2058
self.bulge = getit(data, 42, 0) # bulge of segment
2065
def __getitem__(self, key):
2066
return self.loc[key]
2069
def __setitem__(self, key, value):
2075
return self.loc.__iter__()
2079
return str(self.loc)
2083
return "Vertex %s, swidth=%s, ewidth=%s, bulge=%s, face=%s" %(self.loc, self.swidth, self.ewidth, self.bulge, self.face)
2088
def setx(self, value):
2090
x = property(getx, setx)
2095
def sety(self, value):
2097
y = property(gety, sety)
2102
def setz(self, value):
2104
z = property(getz, setz)
2108
class Spline(Polyline): #-----------------------------------------------------------------
2109
"""Class for objects representing dxf SPLINEs.
2111
"""Expects an entity object of type spline as input.
2112
100 - Subclass marker (AcDbSpline)
2113
210,220, 230 - Normal vector (omitted if the spline is nonplanar) X,Y,Z values of normal vector
2114
70 - Spline flag (bit coded):
2119
16 = Linear (planar bit is also set)
2120
71 - Degree of the spline curve
2121
72 - Number of knots
2122
73 - Number of control points
2123
74 - Number of fit points (if any)
2124
42 - Knot tolerance (default = 0.0000001)
2125
43 - Control-point tolerance (default = 0.0000001)
2126
44 - Fit tolerance (default = 0.0000000001)
2127
12,22,32 - Start tangent--may be omitted (in WCS). X,Y,Z values of start tangent--may be omitted (in WCS).
2128
13,23, 33 - End tangent--may be omitted (in WCS). X,Y,Z values of end tangent--may be omitted (in WCS)
2129
40 - Knot value (one entry per knot)
2130
41 - Weight (if not 1); with multiple group pairs, are present if all are not 1
2131
10,20, 30 - Control points (in WCS) one entry per control point.
2132
DXF: X value; APP: 3D point, Y and Z values of control points (in WCS) (one entry per control point)
2133
11,21, 31 - Fit points (in WCS) one entry per fit point.
2134
X,Y,Z values of fit points (in WCS) (one entry per fit point)
2136
def __init__(self, obj):
2137
#print 'deb:Spline.START:----------------' #------------------------
2138
if not obj.type == 'spline':
2139
raise TypeError, "Wrong type %s for spline object!" %obj.type
2140
self.type = obj.type
2141
# self.data = obj.data[:]
2144
self.num_points = obj.get_type(73)[0]
2146
# optional data (with defaults)
2147
self.space = getit(obj, 67, 0)
2149
self.color_index = getit(obj, 62, BYLAYER)
2151
#self.elevation = getit(obj, 30, 0)
2152
self.thic = 0 # getit(obj, 39, 0)
2155
self.swidth = width # default start width
2156
self.ewidth = width # default end width
2158
self.flags = getit(obj, 70, 0)
2159
self.closed = self.flags & 1 # closed spline
2160
self.period = self.flags & 2 # Periodic spline
2161
self.ration = self.flags & 4 # Rational spline
2162
self.planar = self.flags & 8 # Planar
2163
self.linear = self.flags & 16 # Linear (and Planar)
2165
self.curvNoFitted = False
2166
self.curvQuadrati = False
2167
self.curvCubicBsp = False
2168
self.curvBezier = False
2169
self.degree = getit(obj, 71, 0) # Degree of the spline curve
2170
if self.degree == 0: self.curvNoFitted = True
2171
elif self.degree == 1: self.curvQuadrati = True
2172
elif self.degree == 2: self.curvCubicBsp = True
2173
#elif self.degree == 3: self.curvBezier = True
2174
#elif self.degree == 3: self.spline = True
2176
self.knotpk_len = getit(obj, 72, 0) # Number of knots
2177
self.ctrlpk_len = getit(obj, 73, 0) # Number of control points
2178
self.fit_pk_len = getit(obj, 74, 0) # Number of fit points (if any)
2180
#print 'deb:Spline self.fit_pk_len=', self.fit_pk_len #------------------------
2181
#self.fit_pk_len = 0 # temp for debug
2182
if self.fit_pk_len and 'spline_as'==5:
2189
self.knotpk_tol = getit(obj, 42, 0.0000001) # Knot tolerance (default = 0.0000001)
2190
self.ctrlpk_tol = getit(obj, 43, 0.0000001) # Control-point tolerance (default = 0.0000001)
2191
self.fit_pk_tol = getit(obj, 44, 0.0000000001) # Fit tolerance (default = 0.0000000001)
2193
self.layer = getit(obj, 8, None)
2194
self.extrusion = get_extrusion(obj)
2196
self.pltype = 'spline' # spline is a 2D- or 3D-polyline
2198
self.points = self.get_points(obj.data)
2199
#self.knots_val = self.get_knots_val(obj.data) # 40 - Knot value (one entry per knot)
2200
#self.knots_wgh = self.get_knots_wgh(obj.data) # 41 - Weight (default 1)
2202
#print 'deb:Spline obj.data:\n', obj.data #------------------------
2203
#print 'deb:Spline self.points:\n', self.points #------------------------
2204
#print 'deb:Spline.ENDinit:----------------' #------------------------
2207
def get_points(self, data):
2208
"""Gets points for a spline type object.
2210
Splines have fixed number of verts, and
2211
each vert can have a number of properties.
2212
Verts should be coded as
2221
if self.spline: # NURBSpline definition
2223
#print 'deb:Spline.get_points spilne_item:', item #------------------------
2224
if item[0] == 10: # control point
2225
if point: points.append(point)
2229
elif item[0] == 20: # 20 = y
2231
elif item[0] == 30: # 30 = z
2233
elif item[0] == 41: # 41 = weight
2234
point.weight = item[1]
2235
#print 'deb:Spline.get_points control point:', point #------------------------
2237
elif self.curved: # Bezier definition
2239
#print 'deb:Spline.get_points curved_item:', item #------------------------
2240
if item[0] == 11: # fit point
2241
if point: points.append(point)
2243
point.tangent = False
2245
elif item[0] == 21: # 20 = y
2247
elif item[0] == 31: # 30 = z
2249
#print 'deb:Spline.get_points fit point:', point #------------------------
2251
elif item[0] == 12: # start tangent
2252
if point: points.append(point)
2254
point.tangent = True
2256
elif item[0] == 22: # = y
2258
elif item[0] == 32: # = z
2260
#print 'deb:Spline.get_points fit begtangent:', point #------------------------
2262
elif item[0] == 13: # end tangent
2263
if point: points.append(point)
2265
pointend.tangent = True
2266
pointend.x = item[1]
2267
elif item[0] == 23: # 20 = y
2268
pointend.y = item[1]
2269
elif item[0] == 33: # 30 = z
2270
pointend.z = item[1]
2271
#print 'deb:Spline.get_points fit endtangent:', pointend #------------------------
2272
points.append(point)
2273
if self.curved and pointend:
2274
points.append(pointend)
2275
#print 'deb:Spline points:\n', points #------------------------
2279
return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
2283
class LWpolyline(Polyline): #-------------------------------------------------------------
2284
"""Class for objects representing dxf LWPOLYLINEs.
2286
def __init__(self, obj):
2287
"""Expects an entity object of type lwpolyline as input.
2289
#print 'deb:LWpolyline.START:----------------' #------------------------
2290
if not obj.type == 'lwpolyline':
2291
raise TypeError, "Wrong type %s for polyline object!" %obj.type
2292
self.type = obj.type
2293
# self.data = obj.data[:]
2296
self.num_points = obj.get_type(90)[0]
2298
# optional data (with defaults)
2299
self.space = getit(obj, 67, 0)
2300
self.elevation = getit(obj, 38, 0)
2301
self.thic = getit(obj, 39, 0)
2302
self.color_index = getit(obj, 62, BYLAYER)
2303
width = getit(obj, 43, 0)
2304
self.swidth = width # default start width
2305
self.ewidth = width # default end width
2306
#print 'deb:LWpolyline width=', width #------------------------
2307
#print 'deb:LWpolyline elevation=', self.elevation #------------------------
2309
self.flags = getit(obj, 70, 0)
2310
self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen
2312
self.layer = getit(obj, 8, None)
2313
self.extrusion = get_extrusion(obj)
2315
self.points = self.get_points(obj.data)
2317
self.pltype = 'poly2d' # LW-polyline is a 2D-polyline
2322
#print 'deb:LWpolyline.obj.data:\n', obj.data #------------------------
2323
#print 'deb:LWpolyline.ENDinit:----------------' #------------------------
2326
def get_points(self, data):
2327
"""Gets points for a polyline type object.
2329
LW-Polylines have no fixed number of verts, and
2330
each vert can have a number of properties.
2331
Verts should be coded as
2339
num = self.num_points
2343
if item[0] == 10: # 10 = x
2345
points.append(point)
2348
point.z = self.elevation
2349
elif item[0] == 20: # 20 = y
2351
elif item[0] == 40: # 40 = start width
2352
point.swidth = item[1]
2353
elif item[0] == 41: # 41 = end width
2354
point.ewidth = item[1]
2355
elif item[0] == 42: # 42 = bulge
2356
point.bulge = item[1]
2357
points.append(point)
2362
return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
2365
class Text: #-----------------------------------------------------------------
2366
"""Class for objects representing dxf TEXT.
2368
def __init__(self, obj):
2369
"""Expects an entity object of type text as input.
2371
if not obj.type == 'text':
2372
raise TypeError, "Wrong type %s for text object!" %obj.type
2373
self.type = obj.type
2374
# self.data = obj.data[:]
2377
self.height = 1.7 * obj.get_type(40)[0] #text.height
2378
self.value = obj.get_type(1)[0] #The text string value
2380
# optional data (with defaults)
2381
self.space = getit(obj, 67, 0)
2382
self.color_index = getit(obj, 62, BYLAYER)
2383
self.thic = getit(obj, 39, 0)
2385
self.rotation = getit(obj, 50, 0) # radians
2386
self.width_factor = getit(obj, 41, 1) # Scaling factor along local x axis
2387
self.oblique = getit(obj, 51, 0) # oblique angle: skew in degrees -90 <= oblique <= 90
2389
#self.style = getit(obj, 7, 'STANDARD') # --todo---- Text style name (optional, default = STANDARD)
2391
#Text generation flags (optional, default = 0):
2392
#2 = backward (mirrored in X),
2393
#4 = upside down (mirrored in Y)
2394
self.flags = getit(obj, 71, 0)
2395
self.mirrorX, self.mirrorY = 1.0, 1.0
2396
if self.flags&2: self.mirrorX = - 1.0
2397
if self.flags&4: self.mirrorY = - 1.0
2399
# vertical.alignment: 0=baseline, 1=bottom, 2=middle, 3=top
2400
self.valignment = getit(obj, 73, 0)
2401
#Horizontal text justification type (optional, default = 0) integer codes (not bit-coded)
2402
#0=left, 1=center, 2=right
2403
#3=aligned, 4=middle, 5=fit
2404
self.halignment = getit(obj, 72, 0)
2406
self.layer = getit(obj, 8, None)
2407
self.loc1, self.loc2 = self.get_loc(obj)
2408
if self.loc2[0] != None and self.halignment != 5:
2409
self.loc = self.loc2
2411
self.loc = self.loc1
2412
self.extrusion = get_extrusion(obj)
2415
def get_loc(self, data):
2416
"""Gets adjusted location for text type objects.
2418
If group 72 and/or 73 values are nonzero then the first alignment point values
2419
are ignored and AutoCAD calculates new values based on the second alignment
2420
point and the length and height of the text string itself (after applying the
2421
text style). If the 72 and 73 values are zero or missing, then the second
2422
alignment point is meaningless.
2423
I don't know how to calc text size...
2425
# bottom left x, y, z and justification x, y, z = 0
2426
#x, y, z, jx, jy, jz = 0, 0, 0, 0, 0, 0
2427
x = getit(data, 10, None) #First alignment point (in OCS).
2428
y = getit(data, 20, None)
2429
z = getit(data, 30, 0.0)
2430
jx = getit(data, 11, None) #Second alignment point (in OCS).
2431
jy = getit(data, 21, None)
2432
jz = getit(data, 31, 0.0)
2433
return [x, y, z],[jx, jy, jz]
2437
return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
2440
def draw(self, settings):
2441
"""for TEXTs: generate Blender_geometry.
2443
obname = 'tx_%s' %self.layer # create object name from layer name
2444
obname = obname[:MAX_NAMELENGTH]
2445
txt = Text3d.New(obname)
2446
ob = SCENE.objects.new(txt) # create a new text_object
2448
txt.setText(self.value)
2449
txt.setSize(1.0) #Blender<2.45 accepts only (0.0 - 5.0)
2450
#txt.setSize(self.height)
2451
#txt.setWidth(self.bold)
2452
#setLineSeparation(sep)
2453
txt.setShear(self.oblique/90)
2455
thic = set_thick(self.thic, settings)
2457
thic = self.thic * 0.5
2459
txt.setExtrudeDepth(1.0) #Blender<2.45 accepts only (0.1 - 10.0)
2460
if self.halignment == 0:
2462
elif self.halignment == 1:
2463
align = Text3d.MIDDLE
2464
elif self.halignment == 2:
2465
align = Text3d.RIGHT
2468
txt.setAlignment(align)
2470
if self.valignment == 1:
2472
elif self.valignment == 2:
2473
txt.setYoffset(- self.height * 0.5)
2474
elif self.valignment == 3:
2475
txt.setYoffset(- self.height)
2477
# move the object center to the text location
2478
ob.loc = tuple(self.loc)
2479
transform(self.extrusion, self.rotation, ob)
2481
# flip it and scale it to the text width
2482
ob.SizeX *= self.height * self.width_factor * self.mirrorX
2483
ob.SizeY *= self.height * self.mirrorY
2484
if thic != 0.0: ob.SizeZ *= abs(thic)
2489
def set_thick(thickness, settings):
2490
"""Set thickness relative to settings variables.
2492
Set thickness relative to settings variables:
2493
'thick_on','thick_force','thick_min'.
2494
Accepted also minus values of thickness
2495
python trick: sign(x)=cmp(x,0)
2497
if settings.var['thick_force']:
2498
if settings.var['thick_on']:
2499
if abs(thickness) < settings.var['thick_min']:
2500
thic = settings.var['thick_min'] * cmp(thickness,0)
2501
else: thic = thickness
2502
else: thic = settings.var['thick_min']
2504
if settings.var['thick_on']: thic = thickness
2511
class Mtext: #-----------------------------------------------------------------
2512
"""Class for objects representing dxf MTEXT.
2515
def __init__(self, obj):
2516
"""Expects an entity object of type mtext as input.
2518
if not obj.type == 'mtext':
2519
raise TypeError, "Wrong type %s for mtext object!" %obj.type
2520
self.type = obj.type
2521
# self.data = obj.data[:]
2524
self.height = obj.get_type(40)[0]
2525
self.width = obj.get_type(41)[0]
2526
self.alignment = obj.get_type(71)[0] # alignment 1=TL, 2=TC, 3=TR, 4=ML, 5=MC, 6=MR, 7=BL, 8=BC, 9=BR
2527
self.value = self.get_text(obj) # The text string value
2529
# optional data (with defaults)
2530
self.space = getit(obj, 67, 0)
2531
self.color_index = getit(obj, 62, BYLAYER)
2532
self.rotation = getit(obj, 50, 0) # radians
2534
self.width_factor = getit(obj, 42, 1) # Scaling factor along local x axis
2535
self.line_space = getit(obj, 44, 1) # percentage of default
2537
self.layer = getit(obj, 8, None)
2538
self.loc = self.get_loc(obj)
2539
self.extrusion = get_extrusion(obj)
2542
def get_text(self, data):
2543
"""Reconstructs mtext data from dxf codes.
2548
if item[0] == 1: # There should be only one primary...
2550
elif item[0] == 3: # There may be any number of extra strings (in order)
2551
secondary.append(item[1])
2553
#raise ValueError, "Empty Mtext Object!"
2554
string = "Empty Mtext Object!"
2556
string = primary.replace(r'\P', '\n')
2558
string = ''.join(secondary)+primary
2559
string = string.replace(r'\P', '\n')
2563
def get_loc(self, data):
2564
"""Gets location for a mtext type objects.
2566
Mtext objects have only one point indicating
2569
loc[0] = getit(data, 10, None)
2570
loc[1] = getit(data, 20, None)
2571
loc[2] = getit(data, 30, 0.0)
2576
return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
2579
def draw(self, settings):
2580
"""for MTEXTs: generate Blender_geometry.
2582
# Now Create an object
2583
obname = 'tm_%s' %self.layer # create object name from layer name
2584
obname = obname[:MAX_NAMELENGTH]
2585
txt = Text3d.New(obname)
2586
ob = SCENE.objects.new(txt) # create a new text_object
2589
# Blender doesn't give access to its text object width currently
2590
# only to the text3d's curve width...
2591
#txt.setWidth(text.width/10)
2592
txt.setLineSeparation(self.line_space)
2593
txt.setExtrudeDepth(0.5)
2594
txt.setText(self.value)
2596
# scale it to the text size
2597
ob.SizeX = self.height * self.width_factor
2598
ob.SizeY = self.height
2599
ob.SizeZ = self.height
2601
# move the object center to the text location
2602
ob.loc = tuple(self.loc)
2603
transform(self.extrusion, self.rotation, ob)
2608
class Circle: #-----------------------------------------------------------------
2609
"""Class for objects representing dxf CIRCLEs.
2612
def __init__(self, obj):
2613
"""Expects an entity object of type circle as input.
2615
if not obj.type == 'circle':
2616
raise TypeError, "Wrong type %s for circle object!" %obj.type
2617
self.type = obj.type
2618
# self.data = obj.data[:]
2621
self.radius = obj.get_type(40)[0]
2623
# optional data (with defaults)
2624
self.space = getit(obj, 67, 0)
2625
self.thic = getit(obj, 39, 0)
2626
self.color_index = getit(obj, 62, BYLAYER)
2628
self.layer = getit(obj, 8, None)
2629
self.loc = self.get_loc(obj)
2630
self.extrusion = get_extrusion(obj)
2634
def get_loc(self, data):
2635
"""Gets the center location for circle type objects.
2637
Circles have a single coord location.
2640
loc[0] = getit(data, 10, None)
2641
loc[1] = getit(data, 20, None)
2642
loc[2] = getit(data, 30, 0.0)
2648
return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
2651
def draw(self, settings):
2652
"""for CIRCLE: generate Blender_geometry.
2654
obname = 'ci_%s' %self.layer # create object name from layer name
2655
obname = obname[:MAX_NAMELENGTH]
2656
radius = self.radius
2658
thic = set_thick(self.thic, settings)
2660
if settings.var['lines_as'] == 4: # as thin_box
2661
thic = settings.var['thick_min']
2662
width = settings.var['width_min']
2663
if settings.var['lines_as'] == 3: # as thin cylinder
2664
cyl_rad = 0.5 * settings.var['width_min']
2666
if settings.var['lines_as'] == 5: # draw CIRCLE as curve -------------
2667
if True: # universal version
2668
arc_res = settings.var['curve_arc']
2670
start, end = 0.0, 360.0
2671
VectorTriples = calcArc(None, radius, start, end, arc_res, True)
2672
c = Curve.New(obname) # create new curve data
2673
curve = c.appendNurb(BezTriple.New(VectorTriples[0]))
2674
for p in VectorTriples[1:-1]:
2675
curve.append(BezTriple.New(p))
2677
point.handleTypes = [FREE, FREE]
2678
else: # standard version
2679
c = Curve.New(obname) # create new curve data
2680
p1 = (0, -radius, 0)
2683
p4 = (-radius, 0, 0)
2685
p1 = BezTriple.New(p1)
2686
p2 = BezTriple.New(p2)
2687
p3 = BezTriple.New(p3)
2688
p4 = BezTriple.New(p4)
2690
curve = c.appendNurb(p1)
2695
point.handleTypes = [AUTO, AUTO]
2697
curve.flagU = 1 # 1 sets the curve cyclic=closed
2698
if settings.var['fill_on']:
2699
c.setFlag(6) # 2+4 set top and button caps
2701
c.setFlag(c.getFlag() & ~6) # dont set top and button caps
2703
c.setResolu(settings.var['curve_res'])
2706
#--todo-----to check---------------------------
2707
ob = SCENE.objects.new(c) # create a new curve_object
2708
ob.loc = tuple(self.loc)
2709
if thic != 0.0: #hack: Blender<2.45 curve-extrusion
2711
c.setExt1(1.0) # curve-extrusion accepts only (0.0 - 2.0)
2712
ob.LocZ = thic + self.loc[2]
2713
transform(self.extrusion, 0, ob)
2715
ob.SizeZ *= abs(thic)
2718
elif False: # create a new mesh_object with buildin_circle_primitive
2719
verts_num = settings.var['arc_res'] * sqrt(radius / settings.var['arc_rad'])
2720
if verts_num > 100: verts_num = 100 # Blender accepts only values [3:500]
2721
if verts_num < 4: verts_num = 4 # Blender accepts only values [3:500]
2723
loc2 = thic * 0.5 #-----blenderAPI draw Cylinder with 2*thickness
2724
self.loc[2] += loc2 #---new location for the basis of cylinder
2725
#print 'deb:circleDraw:self.loc2:', self.loc #-----------------------
2726
c = Mesh.Primitives.Cylinder(int(verts_num), radius*2, abs(thic))
2728
c = Mesh.Primitives.Circle(int(verts_num), radius*2)
2731
ob = SCENE.objects.new(c, obname) # create a new circle_mesh_object
2732
ob.loc = tuple(self.loc)
2733
transform(self.extrusion, 0, ob)
2736
else: # draw CIRCLE as mesh -----------------------------------------------
2737
if M_OBJ: obname, me, ob = makeNewObject()
2739
me = Mesh.New(obname) # create a new mesh
2740
ob = SCENE.objects.new(me) # create a new mesh_object
2741
# set a number of segments in entire circle
2742
arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
2743
start, end = 0.0 , 360.0
2744
verts = calcArc(None, radius, start, end, arc_res, False)
2745
verts = verts[:-1] #list without last point/edge (cause by circle it is equal to the first point)
2746
#print 'deb:circleDraw: verts:', verts #---------------
2751
thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
2753
thic_verts.extend(verts)
2756
verts.extend(thic_verts)
2758
f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
2759
#f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1)]
2760
f_band.append([len1 - 1, 0, len1, len1 + len1 -1])
2762
smooth_len = len(f_band)
2763
if settings.var['fill_on']:
2765
verts.append([0,0,thic]) #center of top side
2766
verts.append([0,0,0]) #center of bottom side
2768
verts.append([0,0,0]) #center of bottom side
2769
verts.append([0,0,thic]) #center of top side
2770
center1 = len(verts)-2
2771
center2 = len(verts)-1
2772
f_bottom = [[num+1, num, center1] for num in xrange(len1 - 1)]
2773
f_bottom.append([0, len1 - 1, center1])
2774
f_top = [[num+len1, num+1+len1, center2] for num in xrange(len1 - 1)]
2775
f_top.append([len1-1+len1, 0+len1, center2])
2776
#print 'deb:circleDraw:verts:', verts #---------------
2777
faces = f_band + f_bottom + f_top
2778
#print 'deb:circleDraw:faces:', faces #---------------
2779
me.verts.extend(verts) # add vertices to mesh
2780
me.faces.extend(faces) # add faces to the mesh
2782
if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
2783
for i in xrange(smooth_len):
2784
me.faces[i].smooth = True
2785
# each MeshSide becomes vertexGroup for easier material assignment ---------------------
2786
if settings.var['vGroup_on'] and not M_OBJ:
2787
# each MeshSide becomes vertexGroup for easier material assignment ---------------------
2788
replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD
2789
vg_band, vg_top, vg_bottom = [], [], []
2790
for v in f_band: vg_band.extend(v)
2791
me.addVertGroup('side.band') ; me.assignVertsToGroup('side.band', list(set(vg_band)), 1.0, replace)
2792
if settings.var['fill_on']:
2793
for v in f_top: vg_top.extend(v)
2794
for v in f_bottom: vg_bottom.extend(v)
2795
me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
2796
me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
2798
else: # if thic == 0
2799
if settings.var['fill_on']:
2801
verts.append([0,0,0]) #center of circle
2804
faces.extend([[num, num+1, center1] for num in xrange(len1)])
2805
faces.append([len1-1, 0, center1])
2806
#print 'deb:circleDraw:verts:', verts #---------------
2807
#print 'deb:circleDraw:faces:', faces #---------------
2808
me.verts.extend(verts) # add vertices to mesh
2809
me.faces.extend(faces) # add faces to the mesh
2811
me.verts.extend(verts) # add vertices to mesh
2812
edges = [[num, num+1] for num in xrange(len(verts))]
2813
edges[-1][1] = 0 # it points the "new" last edge to the first vertex
2814
me.edges.extend(edges) # add edges to the mesh
2816
ob.loc = tuple(self.loc)
2817
transform(self.extrusion, 0, ob)
2821
class Arc: #-----------------------------------------------------------------
2822
"""Class for objects representing dxf ARCs.
2825
def __init__(self, obj):
2826
"""Expects an entity object of type arc as input.
2828
if not obj.type == 'arc':
2829
raise TypeError, "Wrong type %s for arc object!" %obj.type
2830
self.type = obj.type
2831
# self.data = obj.data[:]
2834
self.radius = obj.get_type(40)[0]
2835
self.start_angle = obj.get_type(50)[0]
2836
self.end_angle = obj.get_type(51)[0]
2838
# optional data (with defaults)
2839
self.space = getit(obj, 67, 0)
2840
self.thic = getit(obj, 39, 0)
2841
self.color_index = getit(obj, 62, BYLAYER)
2843
self.layer = getit(obj, 8, None)
2844
self.loc = self.get_loc(obj)
2845
self.extrusion = get_extrusion(obj)
2846
#print 'deb:Arc__init__: center, radius, start, end:\n', self.loc, self.radius, self.start_angle, self.end_angle #---------
2850
def get_loc(self, data):
2851
"""Gets the center location for arc type objects.
2853
Arcs have a single coord location.
2856
loc[0] = getit(data, 10, None)
2857
loc[1] = getit(data, 20, None)
2858
loc[2] = getit(data, 30, 0.0)
2864
return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
2867
def draw(self, settings):
2868
"""for ARC: generate Blender_geometry.
2870
obname = 'ar_%s' %self.layer # create object name from layer name
2871
obname = obname[:MAX_NAMELENGTH]
2874
radius = self.radius
2875
start = self.start_angle
2876
end = self.end_angle
2877
#print 'deb:calcArcPoints:\n center, radius, start, end:\n', center, radius, start, end #---------
2878
thic = set_thick(self.thic, settings)
2880
if settings.var['lines_as'] == 4: # as thin_box
2881
thic = settings.var['thick_min']
2882
width = settings.var['width_min']
2883
if settings.var['lines_as'] == 3: # as thin cylinder
2884
cyl_rad = 0.5 * settings.var['width_min']
2886
if settings.var['lines_as'] == 5: # draw ARC as curve -------------
2887
arc_res = settings.var['curve_arc']
2889
VectorTriples = calcArc(None, radius, start, end, arc_res, triples)
2890
arc = Curve.New(obname) # create new curve data
2891
curve = arc.appendNurb(BezTriple.New(VectorTriples[0]))
2892
for p in VectorTriples[1:]:
2893
curve.append(BezTriple.New(p))
2895
point.handleTypes = [FREE, FREE]
2896
curve.flagU = 0 # 0 sets the curve not cyclic=open
2897
arc.setResolu(settings.var['curve_res'])
2899
arc.update() #important for handles calculation
2901
ob = SCENE.objects.new(arc) # create a new curve_object
2902
ob.loc = tuple(self.loc)
2903
if thic != 0.0: #hack: Blender<2.45 curve-extrusion
2905
arc.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
2906
ob.LocZ = thic + self.loc[2]
2907
transform(self.extrusion, 0, ob)
2909
ob.SizeZ *= abs(thic)
2912
else: # draw ARC as mesh --------------------
2913
if M_OBJ: obname, me, ob = makeNewObject()
2915
me = Mesh.New(obname) # create a new mesh
2916
ob = SCENE.objects.new(me) # create a new mesh_object
2917
# set a number of segments in entire circle
2918
arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
2920
verts = calcArc(None, radius, start, end, arc_res, False)
2921
#verts = [list(point) for point in verts]
2923
#print 'deb:len1:', len1 #-----------------------
2925
radius_out = radius + (0.5 * width)
2926
radius_in = radius - (0.5 * width)
2927
if radius_in <= 0.0:
2928
radius_in = settings.var['dist_min']
2933
pointVec = Mathutils.Vector(point)
2934
pointVec = pointVec.normalize()
2935
verts_in.append(list(radius_in * pointVec)) #vertex inside
2936
verts_out.append(list(radius_out * pointVec)) #vertex outside
2937
verts = verts_in + verts_out
2939
#print 'deb:verts:', verts #---------------------
2942
thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
2944
thic_verts.extend(verts)
2947
verts.extend(thic_verts)
2948
f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
2949
f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
2950
f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
2951
f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
2952
f_start = [[0, len1, len1+len1+len1, len1+len1]]
2953
f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
2954
faces = f_left + f_right + f_bottom + f_top + f_start + f_end
2956
me.verts.extend(verts) # add vertices to mesh
2957
me.faces.extend(faces) # add faces to the mesh
2959
if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
2960
smooth_len = len(f_left) + len(f_right)
2961
for i in xrange(smooth_len):
2962
me.faces[i].smooth = True
2963
# each MeshSide becomes vertexGroup for easier material assignment ---------------------
2964
if settings.var['vGroup_on'] and not M_OBJ:
2965
# each MeshSide becomes vertexGroup for easier material assignment ---------------------
2966
replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD
2967
vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
2968
for v in f_left: vg_left.extend(v)
2969
for v in f_right: vg_right.extend(v)
2970
for v in f_top: vg_top.extend(v)
2971
for v in f_bottom: vg_bottom.extend(v)
2972
me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', list(set(vg_left)), 1.0, replace)
2973
me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
2974
me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
2975
me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
2976
me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
2977
me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace)
2980
else: # if thick=0 - draw only flat ring
2981
faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
2982
me.verts.extend(verts) # add vertices to mesh
2983
me.faces.extend(faces) # add faces to the mesh
2987
thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
2989
thic_verts.extend(verts)
2992
verts.extend(thic_verts)
2994
#print 'deb:len1:', len1 #-----------------------
2995
#print 'deb:verts:', verts #---------------------
2996
faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
2998
me.verts.extend(verts) # add vertices to mesh
2999
me.faces.extend(faces) # add faces to the mesh
3000
if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
3001
for i in xrange(len(faces)):
3002
me.faces[i].smooth = True
3005
edges = [[num, num+1] for num in xrange(len(verts)-1)]
3006
me.verts.extend(verts) # add vertices to mesh
3007
me.edges.extend(edges) # add edges to the mesh
3010
#ob = SCENE.objects.new(me) # create a new arc_object
3012
ob.loc = tuple(center)
3013
#ob.loc = Mathutils.Vector(ob.loc)
3014
transform(self.extrusion, 0, ob)
3019
class BlockRecord: #-----------------------------------------------------------------
3020
"""Class for objects representing dxf block_records.
3023
def __init__(self, obj):
3024
"""Expects an entity object of type block_record as input.
3026
if not obj.type == 'block_record':
3027
raise TypeError, "Wrong type %s for block_record object!" %obj.type
3028
self.type = obj.type
3029
# self.data = obj.data[:]
3032
self.name = getit(obj, 2, None)
3034
# optional data (with defaults)
3035
self.insertion_units = getit(obj, 70, None)
3036
self.insert_units = getit(obj, 1070, None)
3037
"""code 1070 Einfuegeeinheiten:
3038
0 = Keine Einheiten; 1 = Zoll; 2 = Fuss; 3 = Meilen; 4 = Millimeter;
3039
5 = Zentimeter; 6 = Meter; 7 = Kilometer; 8 = Mikrozoll;
3040
9 = Mils; 10 = Yard; 11 = Angstrom; 12 = Nanometer;
3041
13 = Mikrons; 14 = Dezimeter; 15 = Dekameter;
3042
16 = Hektometer; 17 = Gigameter; 18 = Astronomische Einheiten;
3043
19 = Lichtjahre; 20 = Parsecs
3048
return "%s: name - %s, insert units - %s" %(self.__class__.__name__, self.name, self.insertion_units)
3053
class Block: #-----------------------------------------------------------------
3054
"""Class for objects representing dxf BLOCKs.
3057
def __init__(self, obj):
3058
"""Expects an entity object of type block as input.
3060
if not obj.type == 'block':
3061
raise TypeError, "Wrong type %s for block object!" %obj.type
3063
self.type = obj.type
3064
self.name = obj.name
3065
self.data = obj.data[:]
3068
self.flags = getit(obj, 70, 0)
3069
self.anonim = self.flags & 1 #anonymous block generated by hatching, associative dimensioning, other
3070
self.atrib = self.flags & 2 # has attribute definitions
3071
self.xref = self.flags & 4 # is an external reference (xref)
3072
self.xref_lay = self.flags & 8 # is an xref overlay
3073
self.dep_ext = self.flags & 16 # is externally dependent
3074
self.dep_res = self.flags & 32 # resolved external reference
3075
self.xref_ext = self.flags & 64 # is a referenced external reference xref
3076
#--todo--- if self.flag > 4: self.xref = True
3078
# optional data (with defaults)
3079
self.path = getit(obj, 1, '') # Xref path name
3080
self.discription = getit(obj, 4, '')
3082
self.entities = dxfObject('block_contents') #creates empty entities_container for this block
3083
self.entities.data = objectify([ent for ent in obj.data if type(ent) != list])
3085
self.layer = getit(obj, 8, None)
3086
self.loc = self.get_loc(obj)
3088
#print 'deb:Block %s data:\n%s' %(self.name, self.data) #------------
3089
#print 'deb:Block %s self.entities.data:\n%s' %(self.name, self.entities.data) #------------
3093
def get_loc(self, data):
3094
"""Gets the insert point of the block.
3097
loc[0] = getit(data, 10, 0.0) # 10 = x
3098
loc[1] = getit(data, 20, 0.0) # 20 = y
3099
loc[2] = getit(data, 30, 0.0) # 30 = z
3104
return "%s: name - %s, description - %s, xref-path - %s" %(self.__class__.__name__, self.name, self.discription, self.path)
3109
class Insert: #-----------------------------------------------------------------
3110
"""Class for objects representing dxf INSERTs.
3113
def __init__(self, obj):
3114
"""Expects an entity object of type insert as input.
3116
if not obj.type == 'insert':
3117
raise TypeError, "Wrong type %s for insert object!" %obj.type
3118
self.type = obj.type
3119
self.data = obj.data[:]
3120
#print 'deb:Insert_init_ self.data:\n', self.data #-----------
3123
self.name = obj.get_type(2)[0]
3125
# optional data (with defaults)
3126
self.rotation = getit(obj, 50, 0)
3127
self.space = getit(obj, 67, 0)
3128
self.color_index = getit(obj, 62, BYLAYER)
3130
self.layer = getit(obj, 8, None)
3131
self.loc = self.get_loc(obj)
3132
self.scale = self.get_scale(obj)
3133
self.rows, self.columns = self.get_array(obj)
3134
self.extrusion = get_extrusion(obj)
3136
#self.flags = getit(obj.data, 66, 0) #
3137
#self.attrib = self.flags & 1
3140
def get_loc(self, data):
3141
"""Gets the origin location of the insert.
3144
loc[0] = getit(data, 10, 0.0)
3145
loc[1] = getit(data, 20, 0.0)
3146
loc[2] = getit(data, 30, 0.0)
3150
def get_scale(self, data):
3151
"""Gets the x/y/z scale factors of the insert.
3154
scale[0] = getit(data, 41, 1.0)
3155
scale[1] = getit(data, 42, 1.0)
3156
scale[2] = getit(data, 43, 1.0)
3160
def get_array(self, data):
3161
"""Returns the pair (row number, row spacing), (column number, column spacing).
3163
columns = getit(data, 70, 1)
3164
rows = getit(data, 71, 1)
3165
cspace = getit(data, 44, 0.0)
3166
rspace = getit(data, 45, 0.0)
3167
return (rows, rspace), (columns, cspace)
3170
def get_target(self, data):
3171
"""Gets the origin location of the insert.
3174
loc[0] = getit(data, 1011, 0.0)
3175
loc[1] = getit(data, 1021, 0.0)
3176
loc[2] = getit(data, 1031, 0.0)
3180
def get_color(self, data):
3181
"""Gets the origin location of the insert.
3184
loc[0] = getit(data, 1010, 0.0)
3185
loc[1] = getit(data, 1020, 0.0)
3186
loc[2] = getit(data, 1030, 0.0)
3190
def get_ave_render(self, data):
3191
"""Gets the origin location of the insert.
3194
loc[0] = getit(data, 1010, 0.0)
3195
loc[1] = getit(data, 1020, 0.0)
3196
loc[2] = getit(data, 1030, 0.0)
3201
return "%s: layer - %s, name - %s" %(self.__class__.__name__, self.layer, self.name)
3204
def draw(self, settings, deltaloc):
3205
"""for INSERT(block): draw empty-marker for duplicated Blender_Group.
3207
Blocks are made of three objects:
3208
the block_record in the tables section
3209
the block in the blocks section
3210
the insert object (one or more) in the entities section
3211
block_record gives the insert units,
3212
block provides the objects drawn in the block,
3213
insert object gives the location/scale/rotation of the block instances.
3216
name = self.name.lower()
3217
if name == 'ave_render':
3218
if settings.var['lights_on']: #if lights support activated
3219
a_data = get_ave_data(self.data)
3220
# AVE_RENDER objects:
3221
# 7:'Pref', 0:'Full Opt', 0:'Quick Opt', 1:'Scanl Opt', 2:'Raytr Opt', 0:'RFile Opt'
3222
# 0:'Fog Opt', 0:'BG Opt', 0:'SCENE1','','','','','','','','','',
3223
# '','','','','','','','','','','','',
3225
if a_data.key == 'SCENE': # define set of lights as blender group
3227
elif False: # define set of lights as blender group
3230
elif name == 'ave_global':
3231
if settings.var['lights_on']: #if lights support activated
3233
elif name == 'sh_spot':
3234
if settings.var['lights_on']: #if lights support activated
3235
obname = settings.blocknamesmap[self.name]
3236
obname = 'sp_%s' %obname # create object name from block name
3237
#obname = obname[:MAX_NAMELENGTH]
3238
# blender: 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', or 'Photon'
3239
li = Lamp.New('Spot', obname)
3240
ob = SCENE.objects.new(li)
3241
intensity = 2.0 #--todo-- -----------
3242
li.setEnergy(intensity)
3243
target = self.get_target(self.data)
3244
color = self.get_color(self.data)
3249
ob.loc = tuple(self.loc)
3250
transform(self.extrusion, 0, ob)
3253
elif name == 'overhead':
3254
if settings.var['lights_on']: #if lights support activated
3255
obname = settings.blocknamesmap[self.name]
3256
obname = 'la_%s' %obname # create object name from block name
3257
#obname = obname[:MAX_NAMELENGTH]
3258
# blender: 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', or 'Photon'
3259
li = Lamp.New('Lamp', obname)
3260
ob = SCENE.objects.new(li)
3261
intensity = 2.0 #--todo-- -----------
3262
li.setEnergy(intensity)
3263
target = self.get_target(self.data)
3264
color = self.get_color(self.data)
3269
ob.loc = tuple(self.loc)
3270
transform(self.extrusion, 0, ob)
3273
elif name == 'direct':
3274
if settings.var['lights_on']: #if lights support activated
3275
obname = settings.blocknamesmap[self.name]
3276
obname = 'su_%s' %obname # create object name from block name
3277
#obname = obname[:MAX_NAMELENGTH]
3278
# blender: 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', or 'Photon'
3279
li = Lamp.New('Sun', obname)
3280
ob = SCENE.objects.new(li)
3281
intensity = 2.0 #--todo-- -----------
3282
li.setEnergy(intensity)
3283
color = self.get_color(self.data)
3288
ob.loc = tuple(self.loc)
3289
transform(self.extrusion, 0, ob)
3292
elif settings.drawTypes['insert']: #if insert_drawType activated
3293
#print 'deb:draw. settings.blocknamesmap:', settings.blocknamesmap #--------------------
3294
obname = settings.blocknamesmap[self.name]
3295
obname = 'in_%s' %obname # create object name from block name
3296
#obname = obname[:MAX_NAMELENGTH]
3298
# if material BYBLOCK def needed: use as placeholder a mesh-vertex instead of empty
3299
ob = SCENE.objects.new('Empty', obname) # create a new empty_object
3300
empty_size = 1.0 * settings.var['g_scale']
3301
if empty_size < 0.01: empty_size = 0.01 #Blender limits (0.01-10.0)
3302
elif empty_size > 10.0: empty_size = 10.0
3303
ob.drawSize = empty_size
3305
# get our block_def-group
3306
block = settings.blocks(self.name)
3308
ob.enableDupGroup = True
3310
if block.name.startswith('xr_'):
3311
ob.name = 'xb_' + ob.name[3:]
3313
#print 'deb:draw.block.deltaloc:', deltaloc #--------------------
3314
ob.loc = tuple(self.loc)
3316
deltaloc = rotXY_Vec(self.rotation, deltaloc)
3317
#print 'deb:draw.block.loc:', deltaloc #--------------------
3318
ob.loc = [ob.loc[0]+deltaloc[0], ob.loc[1]+deltaloc[1], ob.loc[2]+deltaloc[2]]
3319
transform(self.extrusion, self.rotation, ob)
3320
ob.size = tuple(self.scale)
3326
class Ellipse: #-----------------------------------------------------------------
3327
"""Class for objects representing dxf ELLIPSEs.
3330
def __init__(self, obj):
3331
"""Expects an entity object of type ellipse as input.
3333
if not obj.type == 'ellipse':
3334
raise TypeError, "Wrong type %s for ellipse object!" %obj.type
3335
self.type = obj.type
3336
# self.data = obj.data[:]
3339
self.ratio = obj.get_type(40)[0] # Ratio of minor axis to major axis
3340
self.start_angle = obj.get_type(41)[0] # in radians
3341
self.end_angle = obj.get_type(42)[0]
3343
# optional data (with defaults)
3344
self.space = getit(obj, 67, 0)
3345
self.thic = getit(obj, 39, 0.0)
3346
self.color_index = getit(obj, 62, BYLAYER)
3348
self.layer = getit(obj, 8, None)
3349
self.loc = self.get_loc(obj)
3350
self.major = self.get_major(obj)
3351
self.extrusion = get_extrusion(obj)
3354
def get_loc(self, data):
3355
"""Gets the center location for arc type objects.
3357
Arcs have a single coord location.
3359
loc = [0.0, 0.0, 0.0]
3360
loc[0] = getit(data, 10, 0.0)
3361
loc[1] = getit(data, 20, 0.0)
3362
loc[2] = getit(data, 30, 0.0)
3366
def get_major(self, data):
3367
"""Gets the major axis for ellipse type objects.
3369
The ellipse major axis defines the rotation of the ellipse and its radius.
3371
loc = [0.0, 0.0, 0.0]
3372
loc[0] = getit(data, 11, 0.0)
3373
loc[1] = getit(data, 21, 0.0)
3374
loc[2] = getit(data, 31, 0.0)
3379
return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
3382
def draw(self, settings):
3383
"""for ELLIPSE: generate Blender_geometry.
3385
obname = 'el_%s' %self.layer # create object name from layer name
3386
obname = obname[:MAX_NAMELENGTH]
3390
start = degrees(self.start_angle)
3391
end = degrees(self.end_angle)
3392
if abs(end - 360.0) < 0.00001: end = 360.0
3393
ellipse_closed = False
3394
if end - start == 360.0: ellipse_closed = True
3396
else: # bug in AutoCAD_2002 dxf-exporter into r12 for ELLIPSE->POLYLINE_ARC
3397
#print 'deb:calcEllipse---------:\n start=%s\n end=%s' %(self.start_angle, self.end_angle) #---------
3398
if self.start_angle > pi+pi: self.start_angle %= pi+pi
3399
if self.end_angle > pi+pi: self.end_angle %= pi+pi
3400
if abs(self.end_angle - pi - pi) < 0.00001: self.end_angle = pi + pi
3401
ellipse_closed = False
3402
if abs(self.end_angle - self.start_angle) == pi + pi: ellipse_closed = True
3403
test = self.start_angle % pi
3404
if test < 0.001 or pi - test < 0.001: start = self.start_angle
3406
start = atan(tan(self.start_angle) * self.ratio)
3407
if start < 0.0: start += pi
3408
if self.start_angle > pi: start += pi
3409
test = self.end_angle % pi
3410
if test < 0.001 or pi - test < 0.001: end = self.end_angle
3412
end = atan(tan(self.end_angle) * self.ratio)
3413
if end < 0.0: end += pi
3414
if self.end_angle > pi: end += pi
3415
start = degrees(start)
3418
# rotation = Angle between major and WORLDX
3419
# doesnt work, couse produces always positive value: rotation = Mathutils.AngleBetweenVecs(major, WORLDX)
3420
if self.major[0] == 0:
3422
if self.major[1] < 0: rotation += 180
3424
rotation = degrees(atan(self.major[1] / self.major[0]))
3425
if self.major[0] < 0:
3428
major = Mathutils.Vector(self.major)
3429
#radius = sqrt(self.major[0]**2 + self.major[1]**2 + self.major[2]**2)
3430
radius = major.length
3431
#print 'deb:calcEllipse:\n center, radius, start, end:\n', center, radius, start, end #---------
3433
thic = set_thick(self.thic, settings)
3435
if settings.var['lines_as'] == 4: # as thin_box
3436
thic = settings.var['thick_min']
3437
width = settings.var['width_min']
3438
elif settings.var['lines_as'] == 3: # as thin cylinder
3439
cyl_rad = 0.5 * settings.var['width_min']
3441
elif settings.var['lines_as'] == 5: # draw ELLIPSE as curve -------------
3442
arc_res = settings.var['curve_arc']
3444
VectorTriples = calcArc(None, radius, start, end, arc_res, triples)
3445
arc = Curve.New(obname) # create new curve data
3446
curve = arc.appendNurb(BezTriple.New(VectorTriples[0]))
3448
for p in VectorTriples[1:-1]:
3449
curve.append(BezTriple.New(p))
3451
point.handleTypes = [FREE, FREE]
3452
curve.flagU = 1 # 0 sets the curve not cyclic=open
3453
if settings.var['fill_on']:
3454
arc.setFlag(6) # 2+4 set top and button caps
3456
arc.setFlag(arc.getFlag() & ~6) # dont set top and button caps
3458
for p in VectorTriples[1:]:
3459
curve.append(BezTriple.New(p))
3461
point.handleTypes = [FREE, FREE]
3462
curve.flagU = 0 # 0 sets the curve not cyclic=open
3464
arc.setResolu(settings.var['curve_res'])
3465
arc.update() #important for handles calculation
3467
ob = SCENE.objects.new(arc) # create a new curve_object
3468
ob.loc = tuple(self.loc)
3469
if thic != 0.0: #hack: Blender<2.45 curve-extrusion
3471
arc.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
3472
ob.LocZ = thic + self.loc[2]
3473
transform(self.extrusion, rotation, ob)
3474
ob.SizeY *= self.ratio
3476
ob.SizeZ *= abs(thic)
3480
else: # draw ELLIPSE as mesh --------------------------------------
3481
if M_OBJ: obname, me, ob = makeNewObject()
3483
me = Mesh.New(obname) # create a new mesh
3484
ob = SCENE.objects.new(me) # create a new mesh_object
3485
# set a number of segments in entire circle
3486
arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
3488
verts = calcArc(None, radius, start, end, arc_res, False)
3489
#verts = [list(point) for point in verts]
3490
if False: #--todo--: if ellipse_closed:
3491
verts = verts[:-1] #list without last point/edge (cause closed curve)
3493
#print 'deb:len1:', len1 #-----------------------
3495
radius_out = radius + (0.5 * width)
3496
radius_in = radius - (0.5 * width)
3497
if radius_in <= 0.0:
3498
radius_in = settings.var['dist_min']
3503
pointVec = Mathutils.Vector(point)
3504
pointVec = pointVec.normalize()
3505
verts_in.append(list(radius_in * pointVec)) #vertex inside
3506
verts_out.append(list(radius_out * pointVec)) #vertex outside
3507
verts = verts_in + verts_out
3509
#print 'deb:verts:', verts #---------------------
3512
thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
3514
thic_verts.extend(verts)
3517
verts.extend(thic_verts)
3518
f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
3519
f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
3520
f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
3521
f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
3522
f_start = [[0, len1, len1+len1+len1, len1+len1]]
3523
f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
3524
faces = f_left + f_right + f_bottom + f_top + f_start + f_end
3526
me.verts.extend(verts) # add vertices to mesh
3527
me.faces.extend(faces) # add faces to the mesh
3529
if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
3530
smooth_len = len(f_left) + len(f_right)
3531
for i in xrange(smooth_len):
3532
me.faces[i].smooth = True
3533
if settings.var['vGroup_on'] and not M_OBJ:
3534
# each MeshSide becomes vertexGroup for easier material assignment ---------------------
3535
replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD
3536
vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
3537
for v in f_left: vg_left.extend(v)
3538
for v in f_right: vg_right.extend(v)
3539
for v in f_top: vg_top.extend(v)
3540
for v in f_bottom: vg_bottom.extend(v)
3541
me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', list(set(vg_left)), 1.0, replace)
3542
me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
3543
me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
3544
me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
3545
me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
3546
me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace)
3549
else: # if thick=0 - draw only flat ring
3550
faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
3551
me.verts.extend(verts) # add vertices to mesh
3552
me.faces.extend(faces) # add faces to the mesh
3556
thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
3558
thic_verts.extend(verts)
3561
verts.extend(thic_verts)
3563
#print 'deb:len1:', len1 #-----------------------
3564
#print 'deb:verts:', verts #---------------------
3565
faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
3567
me.verts.extend(verts) # add vertices to mesh
3568
me.faces.extend(faces) # add faces to the mesh
3569
if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
3570
for i in xrange(len(faces)):
3571
me.faces[i].smooth = True
3574
edges = [[num, num+1] for num in xrange(len(verts)-1)]
3575
me.verts.extend(verts) # add vertices to mesh
3576
me.edges.extend(edges) # add edges to the mesh
3578
#print 'deb:calcEllipse transform rotation: ', rotation #---------
3579
ob.loc = tuple(center)
3580
#old ob.SizeY = self.ratio
3581
transform(self.extrusion, rotation, ob)
3582
#old transform(self.extrusion, 0, ob)
3583
ob.SizeY *= self.ratio
3589
class Face: #-----------------------------------------------------------------
3590
"""Class for objects representing dxf 3DFACEs.
3593
def __init__(self, obj):
3594
"""Expects an entity object of type 3dfaceplot as input.
3596
if not obj.type == '3dface':
3597
raise TypeError, "Wrong type %s for 3dface object!" %obj.type
3598
self.type = obj.type
3599
# self.data = obj.data[:]
3601
# optional data (with defaults)
3602
self.space = getit(obj, 67, 0)
3603
self.color_index = getit(obj, 62, BYLAYER)
3605
self.layer = getit(obj, 8, None)
3606
self.points = self.get_points(obj)
3609
def get_points(self, data):
3610
"""Gets 3-4 points for a 3d face type object.
3612
Faces have three or optionally four verts.
3618
a[0] = getit(data, 10, None) # 10 = x
3619
a[1] = getit(data, 20, None) # 20 = y
3620
a[2] = getit(data, 30, 0.0) # 30 = z
3621
b[0] = getit(data, 11, None)
3622
b[1] = getit(data, 21, None)
3623
b[2] = getit(data, 31, 0.0)
3624
c[0] = getit(data, 12, None)
3625
c[1] = getit(data, 22, None)
3626
c[2] = getit(data, 32, 0.0)
3629
d[0] = getit(data, 13, None)
3631
d[1] = getit(data, 23, None)
3632
d[2] = getit(data, 33, 0.0)
3635
#if len(out) < 4: print '3dface with only 3 vertices:\n',a,b,c,d #-----------------
3640
return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
3643
def draw(self, settings):
3644
"""for 3DFACE: generate Blender_geometry.
3646
# Generate the geometery
3647
points = self.points
3649
global activObjectLayer
3650
global activObjectName
3651
#print 'deb:draw:face.ob IN activObjectName: ', activObjectName #---------------------
3653
if M_OBJ: obname, me, ob = makeNewObject()
3655
if activObjectLayer == self.layer and settings.var['one_mesh_on']:
3656
obname = activObjectName
3657
#print 'deb:face.draw obname from activObjectName: ', obname #---------------------
3658
ob = getSceneChild(obname) # open an existing mesh_object
3659
#ob = SCENE.getChildren(obname) # open an existing mesh_object
3660
me = ob.getData(name_only=False, mesh=True)
3662
obname = 'fa_%s' %self.layer # create object name from layer name
3663
obname = obname[:MAX_NAMELENGTH]
3664
me = Mesh.New(obname) # create a new mesh
3665
ob = SCENE.objects.new(me) # create a new mesh_object
3666
activObjectName = ob.name
3667
activObjectLayer = self.layer
3668
#print ('deb:except. new face.ob+mesh:"%s" created!' %ob.name) #---------------------
3670
#me = Mesh.Get(ob.name) # open objects mesh data
3671
faces, edges = [], []
3673
if len(self.points) == 4:
3674
faces = [[0+n,1+n,2+n,3+n]]
3675
elif len(self.points) == 3:
3676
faces = [[0+n,1+n,2+n]]
3677
elif len(self.points) == 2:
3680
me.verts.extend(points) # add vertices to mesh
3681
if faces: me.faces.extend(faces) # add faces to the mesh
3682
if edges: me.edges.extend(edges) # add faces to the mesh
3683
if settings.var['vGroup_on'] and not M_OBJ:
3684
# entities with the same color build one vertexGroup for easier material assignment ---------------------
3685
ob.link(me) # link mesh to that object
3686
vG_name = 'color_%s' %self.color_index
3687
if edges: faces = edges
3688
replace = Blender.Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD
3690
me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
3691
#print 'deb: existed vGroup:', vG_name #---------------------
3693
me.addVertGroup(vG_name)
3694
me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
3695
#print 'deb: create new vGroup:', vG_name #--------------------
3697
#print 'deb:draw:face.ob OUT activObjectName: ', activObjectName #---------------------
3701
#---------------------------------------------------------------------------------------
3702
# type to object maping (sorted-dictionary for f_obiectify ONLY!, format={'key':Class} )
3707
'block_record':BlockRecord,
3714
'polyline':Polyline,
3715
'lwpolyline':LWpolyline,
3729
def objectify(data): #-----------------------------------------------------------------
3730
"""Expects a section type object's data as input.
3732
Maps object data to the correct object type.
3734
#print 'deb:objectify start %%%%%%%%%%%' #---------------
3735
objects = [] # colector for finished objects
3736
known_types = type_map.keys() # so we don't have to call foo.keys() every iteration
3737
curves_on = GUI_A['curves_on'].val
3739
while index < len(data):
3741
#print 'deb:objectify item: \n', item #------------
3742
if type(item) != list and item.type == 'table':
3743
item.data = objectify(item.data) # tables have sub-objects
3744
objects.append(item)
3745
elif type(item) != list and item.type == 'polyline': #remi --todo-----------
3746
#print 'deb:gosub Polyline\n' #-------------
3747
pline = Polyline(item)
3751
if item.type == 'vertex':
3752
#print 'deb:objectify gosub Vertex--------' #-------------
3754
if pline.spline: # if NURBSpline-curve
3755
# then for Blender-mesh filter only additional_vertices
3757
# then for Blender-curve filter only spline_control_vertices
3758
if (v.spline and not curves_on) or (curves_on and v.spline_c): #correct for real NURBS-import
3759
#if (v.spline and not curves_on) or (curves_on and not v.spline_c): #fake for Bezier-emulation of NURBS-import
3760
pline.points.append(v)
3761
elif pline.curved: # if Bezier-curve
3762
# then for Blender-mesh filter only curve_additional_vertices
3764
# then for Blender-curve filter curve_control_vertices
3765
if not curves_on or (curves_on and not v.curved):
3766
pline.points.append(v)
3768
pline.points.append(v)
3769
elif item.type == 'seqend':
3770
#print 'deb:objectify it is seqEND ---------\n' #-------------
3773
print "Error: non-vertex found before seqend!"
3774
index -= 1 #so go back one step
3776
objects.append(pline)
3777
elif type(item) != list and item.type in ['block', 'insert']:
3778
if not settings.var['block_nn'] and item.name.startswith('*X'):
3779
#print 'deb:objectify item.type:"%s", item.name:"%s"' %(item.type, item.name) #------------
3781
elif settings.var['blockFilter_on'] and not settings.accepted_block(item.name):
3785
objects.append(type_map[item.type](item))
3788
elif type(item) != list and item.type in known_types:
3789
# proccess the object and append the resulting object
3791
objects.append(type_map[item.type](item))
3795
#we will just let the data pass un-harrased
3796
#objects.append(item)
3799
#print 'deb:objectify objects:\n', objects #------------
3800
#print 'deb:objectify END %%%%%%%%' #------------
3805
class MatColors: #-----------------------------------------------------------------
3806
"""A smart container for dxf-color based materials.
3808
This class is a wrapper around a dictionary mapping dxf-color indicies to materials.
3809
When called with a color_index
3810
it returns a material corresponding to that index.
3811
Behind the scenes it checks if that index is in its keys, and if not it creates
3812
a new material. It then adds the new index:material pair to its dict and returns
3817
"""Expects a map - a dictionary mapping layer names to layers.
3819
#self.layersmap = layersmap # a dictionary of layername:layerobject
3820
self.colMaterials = {} # a dictionary of color_index:blender_material
3821
#print 'deb:init_MatColors argument.map: ', map #------------------
3824
def __call__(self, color=None):
3825
"""Return the material associated with color.
3827
If a layer name is provided, the color of that layer is used.
3829
if color == None: color = 256 # color 256=BYLAYER
3830
if type(color) == str: # looking for color of LAYER named "color"
3831
#--todo---bug with ARC from ARC-T0.DXF layer="T-3DARC-1"-----
3832
#print 'deb:color is string:--------: ', color
3834
#color = layersmap[color].color
3835
#print 'deb:color=self.map[color].color:', color #------------------
3837
#layer = Layer(name=color, color=256, frozen=False)
3838
#layersmap[color] = layer
3840
if color in layersmap.keys():
3841
color = layersmap[color].color
3842
if color == 256: # color 256 = BYLAYER
3843
#--todo-- should looking for color of LAYER
3844
#if layersmap: color = layersmap[color].color
3846
if color == 0: # color 0 = BYBLOCK
3847
#--todo-- should looking for color of paret-BLOCK
3848
#if layersmap: color = layersmap[color].color
3850
color = abs(color) # cause the value could be nagative = means the layer is turned off
3852
if color not in self.colMaterials.keys():
3854
return self.colMaterials[color]
3857
def add(self, color):
3858
"""Create a new material 'ColorNr-N' using the provided color index-N.
3860
#global color_map #--todo-- has not to be global?
3861
mat = Material.New('ColorNr-%s' %color)
3862
mat.setRGBCol(color_map[color])
3863
#mat.mode |= Material.Modes.SHADELESS #--todo--
3864
#mat.mode |= Material.Modes.WIRE
3865
# try: mat.setMode('Shadeless', 'Wire') #work-around for 2.45rc-bug
3867
self.colMaterials[color] = mat
3871
class MatLayers: #-----------------------------------------------------------------
3872
"""A smart container for dxf-layer based materials.
3874
This class is a wrapper around a dictionary mapping dxf-layer names to materials.
3875
When called with a layer name it returns a material corrisponding to that.
3876
Behind the scenes it checks if that layername is in its keys, and if not it creates
3877
a new material. It then adds the new layername:material pair to its dict and returns
3882
"""Expects a map - a dictionary mapping layer names to layers.
3884
#self.layersmap = layersmap # a dictionary of layername:layer
3885
self.layMaterials = {} # a dictionary of layer_name:blender_material
3886
#print 'deb:init_MatLayers argument.map: ', map #------------------
3889
def __call__(self, layername=None, color=None):
3890
"""Return the material associated with dxf-layer.
3892
If a dxf-layername is not provided, create a new material
3894
#global layernamesmap
3895
layername_short = layername
3896
if layername in layernamesmap.keys():
3897
layername_short = layernamesmap[layername]
3898
colorlayername = layername_short
3899
if color: colorlayername = str(color) + colorlayername
3900
if colorlayername not in self.layMaterials.keys():
3901
self.add(layername, color, colorlayername)
3902
return self.layMaterials[colorlayername]
3905
def add(self, layername, color, colorlayername):
3906
"""Create a new material 'layername'.
3908
try: mat = Material.Get('L-%s' %colorlayername)
3909
except: mat = Material.New('L-%s' %colorlayername)
3910
#print 'deb:MatLayers material: ', mat #----------
3912
#print 'deb:MatLayers material_from: ', settings.var['material_from'] #----------
3913
if settings.var['material_from'] == 3 and color:
3914
if color == 0 or color == 256: mat_color = 3
3915
else: mat_color = color
3916
elif layersmap and layername:
3917
mat_color = layersmap[layername].color
3919
#print 'deb:MatLayers color: ', color #-----------
3920
#print 'deb:MatLayers mat_color: ', mat_color #-----------
3921
mat.setRGBCol(color_map[abs(mat_color)])
3922
#mat.mode |= Material.Modes.SHADELESS
3923
#mat.mode |= Material.Modes.WIRE
3924
# try: mat.setMode('Shadeless', 'Wire') #work-around for 2.45rc-bug
3926
self.layMaterials[colorlayername] = mat
3931
class Blocks: #-----------------------------------------------------------------
3932
"""A smart container for blocks.
3934
This class is a wrapper around a dictionary mapping block names to Blender data blocks.
3935
When called with a name string it returns a block corresponding to that name.
3936
Behind the scenes it checks if that name is in its keys, and if not it creates
3937
a new data block. It then adds the new name:block_data pair to its dict and returns
3941
def __init__(self, blocksmap, settings):
3942
"""Expects a dictionary mapping block_name:block_data.
3944
self.blocksmap = blocksmap #a dictionary mapping block_name:block_data
3945
self.settings = settings
3946
self.blocks = {} #container for blender groups representing blocks
3949
def __call__(self, name=None):
3950
"""Return the data block associated with that block_name.
3952
If that name is not in its keys, it creates a new data block.
3953
If no name is provided return entire self.blocks container.
3957
if name not in self.blocks.keys():
3959
return self.blocks[name]
3962
def addBlock(self, name):
3963
"""Create a new 'block group' for the block name.
3965
block = self.blocksmap[name]
3967
if block.xref: prefix = 'xr'
3968
blender_group = Group.New('%s_%s' %(prefix,name)) # Blender groupObject contains definition of BLOCK
3969
block_def = [blender_group, block.loc]
3970
self.settings.write("\nDrawing block:\'%s\' ..." % name)
3973
obname = 'xr_%s' %name # create object name from xref block name
3974
#obname = obname[:MAX_NAMELENGTH]
3975
# if material BYBLOCK def needed: use as placeholder a mesh-vertex instead of empty
3976
ob = SCENE.objects.new('Empty', obname) # create a new empty_object
3977
empty_size = 1.0 * settings.var['g_scale']
3978
if empty_size < 0.01: empty_size = 0.01 #Blender limits (0.01-10.0)
3979
elif empty_size > 10.0: empty_size = 10.0
3980
ob.drawSize = empty_size
3981
ob.loc = tuple(block.loc)
3982
ob.properties['xref_path'] = block.path
3984
insertFlag=True; blockFlag=True
3986
oblist.append((ob, insertFlag, blockFlag))
3991
drawEntities(block.entities, self.settings, block_def)
3993
self.settings.write("Drawing block:\'%s\' done!" %name)
3994
self.blocks[name] = blender_group
4000
class Settings: #-----------------------------------------------------------------
4001
"""A container for all the import settings and objects used by the draw functions.
4003
This is like a collection of globally accessable persistant properties and functions.
4005
# Optimization constants
4011
def __init__(self, keywords, drawTypes):
4012
"""initialize all the important settings used by the draw functions.
4014
self.obj_number = 1 #global object_number for progress_bar
4016
self.var = dict(keywords) #a dictionary of (key_variable:Value) control parameter
4017
self.drawTypes = dict(drawTypes) #a dictionary of (entity_type:True/False) = import on/off for this entity_type
4019
self.var['colorFilter_on'] = False #deb:remi------------
4020
self.acceptedColors = [0,2,3,4,5,6,7,8,9,
4023
self.var['layerFilter_on'] = False #deb:remi------------
4024
self.acceptedLayers = ['3',
4028
self.var['groupFilter_on'] = False #deb:remi------------
4029
self.acceptedLayers = ['3',
4033
#self.var['blockFilter_on'] = 0 #deb:remi------------
4034
self.acceptedBlocks = ['WALL_1871',
4037
self.unwantedBlocks = ['BOX05',
4042
def update(self, keywords, drawTypes):
4043
"""update all the important settings used by the draw functions.
4044
mostly used after loading parameters from INI-file
4047
for k, v in keywords.iteritems():
4049
#print 'deb:settings_update var %s= %s' %(k, self.var[k]) #--------------
4050
for t, v in drawTypes.iteritems():
4051
self.drawTypes[t] = v
4052
#print 'deb:settings_update drawType %s= %s' %(t, self.drawTypes[t]) #--------------
4054
self.drawTypes['arc'] = self.drawTypes['line']
4055
self.drawTypes['circle'] = self.drawTypes['line']
4056
self.drawTypes['ellipse'] = self.drawTypes['line']
4057
self.drawTypes['trace'] = self.drawTypes['solid']
4058
self.drawTypes['insert'] = self.drawTypes['block']
4059
#self.drawTypes['vport'] = self.drawTypes['view']
4061
#print 'deb:self.drawTypes', self.drawTypes #---------------
4064
def validate(self, drawing):
4065
"""Given the drawing, build dictionaries of Layers, Colors and Blocks.
4069
#adjust the distance parameter to globalScale
4070
if self.var['g_scale'] != 1.0:
4071
self.var['dist_min'] = self.var['dist_min'] / self.var['g_scale']
4072
self.var['thick_min'] = self.var['thick_min'] / self.var['g_scale']
4073
self.var['width_min'] = self.var['width_min'] / self.var['g_scale']
4074
self.var['arc_rad'] = self.var['arc_rad'] / self.var['g_scale']
4076
self.g_origin = Mathutils.Vector(self.var['g_originX'], self.var['g_originY'], self.var['g_originZ'])
4078
# First sort out all the section_items
4079
sections = dict([(item.name, item) for item in drawing.data])
4081
# The section:header may be omited
4082
if 'header' in sections.keys():
4083
self.write("found section:header")
4085
self.write("File contains no section:header!")
4087
if self.var['optimization'] == 0: self.var['one_mesh_on'] = 0
4088
# The section:tables may be partialy or completely missing.
4089
self.layersTable = False
4090
self.colMaterials = MatColors() #A container for dxf-color based materials
4091
self.layMaterials = MatLayers() #A container for dxf-layer based materials
4092
#self.collayMaterials = MatColLayers({}) #A container for dxf-color+layer based materials
4093
global layersmap, layernamesmap
4094
layersmap, layernamesmap = {}, {}
4095
if 'tables' in sections.keys():
4096
self.write("found section:tables")
4097
views, vports, layers = False, False, False
4098
for table in drawing.tables.data:
4099
if table.name == 'layer':
4100
self.write("found table:layers")
4102
elif table.name == 'view':
4103
print "found table:view"
4105
elif table.name == 'vport':
4106
print "found table:vport"
4108
if layers: #----------------------------------
4109
# Read the layers table and get the layer colors
4110
layersmap, layernamesmap = getLayersmap(layers)
4111
#self.colMaterials = MatColors()
4112
#self.layMaterials = MatLayers()
4114
self.write("File contains no table:layers!")
4117
if views: #----------------------------------
4118
if self.var['views_on']:
4119
for item in views.data:
4120
if type(item) != list and item.type == 'view':
4121
#print 'deb:settings_valid views dir(item)=', dir(item) #-------------
4122
#print 'deb:settings_valid views item=', item #-------------
4123
ob = item.draw(self)
4124
#viewsmap[item.name] = [item.length]
4125
#--todo-- add to obj_list for global.Scaling
4126
insertFlag, blockFlag = False, False
4127
oblist.append((ob, insertFlag, blockFlag))
4130
self.write("File contains no table:views!")
4133
if vports: #----------------------------------
4134
if self.var['views_on']:
4135
for item in vports.data:
4136
if type(item) != list and item.type == 'vport':
4137
#print 'deb:settings_valid views dir(item)=', dir(item) #-------------
4138
#print 'deb:settings_valid views item=', item #-------------
4139
ob = item.draw(self)
4140
#viewsmap[item.name] = [item.length]
4141
#--todo-- add to obj_list for global.Scaling
4142
insertFlag, blockFlag = False, False
4143
oblist.append((ob, insertFlag, blockFlag))
4145
self.write("File contains no table:vports!")
4149
self.write("File contains no section:tables!")
4150
self.write("File contains no table:layers!")
4153
# The section:blocks may be omited
4154
if 'blocks' in sections.keys():
4155
self.write("found section:blocks")
4156
# Read the block definitions and build our block object
4157
if self.drawTypes['insert']: #if support for entity type 'Insert' is activated
4158
#Build a dictionary of blockname:block_data pairs
4159
blocksmap, obj_number = getBlocksmap(drawing, layersmap, self.var['layFrozen_on'])
4160
self.obj_number += obj_number
4161
self.blocknamesmap = getBlocknamesmap(blocksmap)
4162
self.blocks = Blocks(blocksmap, self) # initiates container for blocks_data
4163
self.usedBlocks = blocksmap.keys()
4164
#print 'deb:settings_valid self.usedBlocks', self.usedBlocks #----------
4166
self.write("ignored, because support for BLOCKs is turn off!")
4167
#print 'deb:settings_valid self.obj_number', self.obj_number #----------
4169
self.write("File contains no section:blocks!")
4170
self.drawTypes['insert'] = False
4172
# The section:entities
4173
if 'entities' in sections.keys():
4174
self.write("found section:entities")
4175
self.obj_number += len(drawing.entities.data)
4176
self.obj_number = 1.0 / self.obj_number
4179
def accepted_block(self, name):
4180
if name not in self.usedBlocks: return False
4181
if name in self.unwantedBlocks: return False
4182
elif name in self.acceptedBlocks: return True
4183
#elif (name.find('*X')+1): return False
4184
#elif name.startswith('3'): return True
4185
#elif name.endswith('H'): return False
4189
def write(self, text, newline=True):
4190
"""Wraps the built-in print command in a optimization check.
4192
if self.var['optimization'] <= self.MID:
4200
"""Update Blender if optimization level is low enough.
4202
if self.var['optimization'] <= self.MIN:
4206
def progress(self, done, text):
4207
"""Wrapper for Blender.Window.DrawProgressBar.
4209
if self.var['optimization'] <= self.PRO:
4210
progressbar = done * self.obj_number
4211
Window.DrawProgressBar(progressbar, text)
4212
#print 'deb:drawer done, progressbar: ', done, progressbar #-----------------------
4214
def layer_isOff(self, layername): # no more used -------
4215
"""Given a layer name, and return its visible status.
4217
# if layer is off then color_index is negative
4218
if layersmap and layersmap[layername].color < 0: return True
4219
#print 'deb:layer_isOff: layer is ON' #---------------
4223
def layer_isFrozen(self, layername): # no more used -------
4224
"""Given a layer name, and return its frozen status.
4226
if layersmap and layersmap[layername].frozen: return True
4227
#print 'deb:layer_isFrozen: layer is not FROZEN' #---------------
4232
def analyzeDXF(dxfFile): #---------------------------------------
4233
"""list statistics about LAYER and BLOCK dependences into textfile.INF
4236
Window.WaitCursor(True) # Let the user know we are thinking
4237
print 'reading DXF file: %s.' % dxfFile
4238
time1 = Blender.sys.time() #time marker1
4239
drawing = readDXF(dxfFile, objectify)
4240
print 'finish reading in %.4f sec.' % (Blender.sys.time()-time1)
4242
# First sort out all the section_items
4243
sections = dict([(item.name, item) for item in drawing.data])
4245
# The section:header may be omited
4246
if 'header' in sections.keys(): print "found section:header"
4247
else: print "File contains no section:header!"
4249
# The section:tables may be partialy or completely missing.
4255
layersmap_str = '#File contains no table:layers!'
4256
viewsmap_str = '#File contains no table:views!'
4257
vportsmap_str = '#File contains no table:vports!'
4258
if 'tables' in sections.keys():
4259
print "found section:tables"
4260
views, vports, layers = False, False, False
4261
for table in drawing.tables.data:
4262
if table.name == 'layer':
4263
print "found table:layers"
4265
elif table.name == 'view':
4266
print "found table:view"
4268
elif table.name == 'vport':
4269
print "found table:vport"
4271
if layers: #----------------------------------
4272
for item in layers.data:
4273
if type(item) != list and item.type == 'layer':
4275
layersmap[item.name] = [item.color, item.frozen]
4276
#print 'deb:analyzeDXF: layersmap=' , layersmap #-------------
4277
layersmap_str = '#list of LAYERs: name, color, frozen_status ---------------------------\n'
4278
key_list = layersmap.keys()
4280
for key in key_list:
4281
#for layer_name, layer_data in layersmap.iteritems():
4282
layer_name, layer_data = key, layersmap[key]
4283
layer_str = '\'%s\': col=%s' %(layer_name,layer_data[0])#-------------
4284
if layer_data[1]: layer_str += ', frozen'
4285
layersmap_str += layer_str + '\n'
4286
#print 'deb:analyzeDXF: layersmap_str=\n' , layersmap_str #-------------
4288
print "File contains no table:layers!"
4290
if views: #----------------------------------
4291
for item in views.data:
4292
if type(item) != list and item.type == 'view':
4294
viewsmap[item.name] = [item.length]
4295
#print 'deb:analyzeDXF: viewsmap=' , viewsmap #-------------
4296
viewsmap_str = '#list of VIEWs: name, focus_length ------------------------------------\n'
4297
key_list = viewsmap.keys()
4299
for key in key_list:
4300
#for view_name, view_data in viewsmap.iteritems():
4301
view_name, view_data = key, viewsmap[key]
4302
view_str = '\'%s\': length=%s' %(view_name,view_data[0])#-------------
4303
#if view_data[1]: view_str += ', something'
4304
viewsmap_str += view_str + '\n'
4305
#print 'deb:analyzeDXF: layersmap_str=\n' , layersmap_str #-------------
4307
print "File contains no table:views!"
4309
if vports: #----------------------------------
4310
for item in vports.data:
4311
if type(item) != list and item.type == 'vport':
4313
vportsmap[item.name] = [item.length]
4314
#print 'deb:analyzeDXF: vportsmap=' , vportsmap #-------------
4315
vportsmap_str = '#list of VPORTs: name, focus_length -----------------------------------\n'
4316
key_list = vportsmap.keys()
4318
for key in key_list:
4319
#for vport_name, vport_data in vportsmap.iteritems():
4320
vport_name, vport_data = key, vportsmap[key]
4321
vport_str = '\'%s\': length=%s' %(vport_name,vport_data[0])#-------------
4322
#if vport_data[1]: vport_str += ', something'
4323
vportsmap_str += vport_str + '\n'
4324
#print 'deb:analyzeDXF: vportsmap_str=\n' , vportsmap_str #-------------
4326
print "File contains no table:vports!"
4329
print "File contains no section:tables!"
4330
print "File contains no tables:layers,views,vports!"
4332
# The section:blocks may be omited
4333
if 'blocks' in sections.keys():
4334
print "found section:blocks"
4336
for item in drawing.blocks.data:
4337
#print 'deb:getBlocksmap item=' ,item #--------
4338
#print 'deb:getBlocksmap item.entities=' ,item.entities #--------
4339
#print 'deb:getBlocksmap item.entities.data=' ,item.entities.data #--------
4340
if type(item) != list and item.type == 'block':
4342
if item.xref: xref = True
4345
for item2 in item.entities.data:
4346
if type(item2) != list and item2.type == 'insert':
4347
#print 'deb:getBlocksmap dir(item2)=', dir(item2) #----------
4348
item2str = [item2.name, item2.layer, item2.color_index, item2.scale, item2.space]
4349
childList.append(item2str)
4350
try: blocksmap[item.name] = [used, childList, xref]
4351
except KeyError: print 'Cannot map "%s" - "%s" as Block!' %(item.name, item)
4352
#print 'deb:analyzeDXF: blocksmap=' , blocksmap #-------------
4354
for item2 in drawing.entities.data:
4355
if type(item2) != list and item2.type == 'insert':
4356
if not layersmap or (layersmap and not layersmap[item2.layer][1]): #if insert_layer is not frozen
4357
blocksmap[item2.name][0] = True # marked as world used BLOCK
4359
key_list = blocksmap.keys()
4361
for key in key_list:
4362
if blocksmap[key][0]: #if used
4363
for child in blocksmap[key][1]:
4364
if not layersmap or (layersmap and not layersmap[child[1]][1]): #if insert_layer is not frozen
4365
blocksmap[child[0]][0] = True # marked as used BLOCK
4367
blocksmap_str = '#list of BLOCKs: name:(unused)(xref) -[child_name, layer, color, scale, space]-------\n'
4368
key_list = blocksmap.keys()
4370
for key in key_list:
4371
#for block_name, block_data in blocksmap.iteritems():
4372
block_name, block_data = key, blocksmap[key]
4373
block_str = '\'%s\': ' %(block_name) #-------------
4375
if block_data[0]: used = ''
4376
# else: used = '(unused)'
4378
if block_data[2]: xref = '(xref)'
4379
blocksmap_str += block_str + used + xref +'\n'
4381
for block_item in block_data[1]:
4382
block_data_str = ' - %s\n' %block_item
4383
blocksmap_str += block_data_str
4384
#print 'deb:analyzeDXF: blocksmap_str=\n' , blocksmap_str #-------------
4386
blocksmap_str = '#File contains no section:blocks!'
4387
print "File contains no section:blocks!"
4389
Window.WaitCursor(False)
4390
output_str = '%s\n%s\n%s\n%s' %(viewsmap_str, vportsmap_str, layersmap_str, blocksmap_str)
4391
infFile = dxfFile[:-4] + '_DXF.INF' # replace last char:'.dxf' with '_DXF.inf'
4393
f = file(infFile, 'w')
4394
f.write(INFFILE_HEADER + '\n# this is a comment line\n\n')
4397
Draw.PupMenu('DXF importer: report saved in INF-file:%t|' + '\'%s\'' %infFile)
4399
Draw.PupMenu('DXF importer: ERROR by writing report in INF-file:%t|' + '\'%s\'' %infFile)
4406
def main(dxfFile): #---------------#############################-----------
4407
#print 'deb:filename:', filename #--------------
4410
editmode = Window.EditMode() # are we in edit mode? If so ...
4412
Window.EditMode(0) # leave edit mode before
4414
#SCENE = bpy.data.scenes.active
4415
#SCENE.objects.selected = [] # deselect all
4417
global cur_COUNTER #counter for progress_bar
4421
#print "Getting settings..."
4422
global GUI_A, GUI_B, g_scale_as
4423
if not GUI_A['g_scale_on'].val:
4424
GUI_A['g_scale'].val = 1.0
4428
for k, v in GUI_A.iteritems():
4430
for k, v in GUI_B.iteritems():
4431
drawTypes[k] = v.val
4432
#print 'deb:startUInew keywords: ', keywords #--------------
4433
#print 'deb:startUInew drawTypes: ', drawTypes #--------------
4435
# The settings object controls how dxf entities are drawn
4436
settings.update(keywords, drawTypes)
4437
#print 'deb:settings.var:\n', settings.var #-----------------------
4440
#Draw.PupMenu('DXF importer: EXIT!%t')
4441
#print '\nDXF Import: terminated by user!'
4442
print '\nDXF Import: terminated, cause settings failure!'
4443
Window.WaitCursor(False)
4444
if editmode: Window.EditMode(1) # and put things back how we fond them
4447
#no more used dxfFile = dxfFileName.val
4448
#print 'deb: dxfFile file: ', dxfFile #----------------------
4449
if dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile):
4450
Window.WaitCursor(True) # Let the user know we are thinking
4451
print 'reading file: %s.' % dxfFile
4452
time1 = Blender.sys.time() #time marker1
4453
drawing = readDXF(dxfFile, objectify)
4454
print 'reading finished in %.4f sec.' % (Blender.sys.time()-time1)
4455
Window.WaitCursor(False)
4457
if UI_MODE: Draw.PupMenu('DXF importer: Alert!%t| no valid DXF-file selected!')
4458
print "DXF importer: Alert! - no valid DXF-file selected."
4459
Window.WaitCursor(False)
4460
if editmode: Window.EditMode(1) # and put things back how we fond them
4463
# Draw all the know entity types in the current scene
4464
oblist = [] # a list of all created AND linked objects for final f_globalScale
4465
time2 = Blender.sys.time() #time marker2
4467
Window.WaitCursor(True) # Let the user know we are thinking
4468
settings.write("\n\nDrawing entities...")
4470
settings.validate(drawing)
4472
global activObjectLayer, activObjectName
4473
activObjectLayer, activObjectName = None, None
4475
if M_OBJ: car_init()
4477
drawEntities(drawing.entities, settings)
4479
#print 'deb:drawEntities after: oblist:', oblist #-----------------------
4481
if oblist: # and settings.var['g_scale'] != 1:
4482
globalScale(oblist, settings.var['g_scale'])
4484
# Set visibility for all layers on all View3d
4485
#Window.ViewLayers([i+1 for i in range(18)]) # for 2.45
4486
SCENE.setLayers([i+1 for i in range(18)])
4488
SCENE.objects.selected = [i[0] for i in oblist] #select only the imported objects
4489
#SCENE.objects.selected = SCENE.objects #select all objects in current scene
4492
time_text = Blender.sys.time() - time2
4493
Window.WaitCursor(False)
4494
if settings.var['paper_space_on']: space = 'from paper space'
4495
else: space = 'from model space'
4496
ob_len = len(oblist)
4497
message = ' %s objects imported %s in %.4f sec. -----DONE-----' % (ob_len, space, time_text)
4498
settings.progress(1.0/settings.obj_number, 'DXF import done!')
4500
#settings.write(message)
4501
if UI_MODE: Draw.PupMenu('DXF importer: Done!|finished in %.4f sec.' % time_text)
4504
# restore state even if things didn't work
4505
#print 'deb:drawEntities finally!' #-----------------------
4506
Window.WaitCursor(False)
4507
if editmode: Window.EditMode(1) # and put things back how we fond them
4511
def getOCS(az): #-----------------------------------------------------------------
4512
"""An implimentation of the Arbitrary Axis Algorithm.
4514
#decide if we need to transform our coords
4515
#if az[0] == 0 and az[1] == 0:
4516
if abs(az[0]) < 0.00001 and abs(az[1]) < 0.00001:
4520
ax = Mathutils.Vector(-1.0, 0, 0)
4521
ay = Mathutils.Vector(0, 1.0, 0)
4522
az = Mathutils.Vector(0, 0, -1.0)
4525
az = Mathutils.Vector(az)
4527
cap = 0.015625 # square polar cap value (1/64.0)
4528
if abs(az.x) < cap and abs(az.y) < cap:
4529
ax = Mathutils.CrossVecs(WORLDY, az)
4531
ax = Mathutils.CrossVecs(WORLDZ, az)
4533
ay = Mathutils.CrossVecs(az, ax)
4539
def transform(normal, rotation, obj): #--------------------------------------------
4540
"""Use the calculated ocs to determine the objects location/orientation in space.
4542
Quote from dxf docs:
4543
The elevation value stored with an entity and output in DXF files is a sum
4544
of the Z-coordinate difference between the UCS XY plane and the OCS XY
4545
plane, and the elevation value that the user specified at the time the entity
4548
ma = Mathutils.Matrix([1,0,0],[0,1,0],[0,0,1])
4549
o = Mathutils.Vector(obj.loc)
4550
ocs = getOCS(normal)
4552
ma = Mathutils.Matrix(ocs[0], ocs[1], ocs[2])
4554
ma = Mathutils.Matrix(ocs[0], ocs[1], ocs[2])
4557
g = radians(-rotation)
4558
rmat = Mathutils.Matrix([cos(g), -sin(g), 0], [sin(g), cos(g), 0], [0, 0, 1])
4563
#print 'deb:new obj.matrix:\n', obj.getMatrix() #--------------------
4567
def rotXY_Vec(rotation, vec): #----------------------------------------------------
4568
"""Rotate vector vec in XY-plane. vec must be in radians
4571
o = Mathutils.Vector(vec)
4572
g = radians(-rotation)
4573
vec = o * Mathutils.Matrix([cos(g), -sin(g), 0], [sin(g), cos(g), 0], [0, 0, 1])
4578
def getLayersmap(dxflayers): #------------------------------------------------------
4579
"""Build two dictionaries: 1.layername:layer object, and 2.layername:layername_short
4580
gets set of layers from TABLES SECTION LAYERS
4584
for item in dxflayers.data:
4585
if type(item) != list and item.type == 'layer':
4586
layersmap[item.name] = item
4587
layername_short = item.name[:MAX_NAMELENGTH-1]
4588
i = 0 #sufix for layernames cause Blender-objectnames-limits
4589
while layername_short in layernamesmap.keys():
4591
suffix = str(i) #--todo--set zero-leading number format
4592
layername_short = layername_short[:-2] + suffix
4593
layernamesmap[item.name] = layername_short
4595
#print 'deb:getLayersmap layersmap:\n', layersmap #------------
4596
#print 'deb:getLayersmap layernamesmap:\n', layernamesmap #------------
4597
return layersmap, layernamesmap
4601
def getBlocksmap(drawing, layersmap, layFrozen_on=False): #--------------------------------------------------------
4602
"""Build a dictionary of blockname:block_data pairs
4605
for item in drawing.blocks.data:
4606
#print 'deb:getBlocksmap item=%s\n i.entities=%s\n i.data=%s' %(item,item.entities,item.entities.data)
4607
if type(item) != list and item.type == 'block':
4610
for item2 in item.entities.data:
4611
if type(item2) != list and item2.type == 'insert':
4612
#print 'deb:getBlocksmap dir(item2)=', dir(item2) #----------
4613
item2str = [item2.name, item2.layer]
4614
childList.append(item2str)
4615
try: usedblocks[item.name] = [used, childList]
4616
except KeyError: print 'Cannot map "%s" - "%s" as Block!' %(item.name, item)
4617
#print 'deb:getBlocksmap: usedblocks=' , usedblocks #-------------
4618
#print 'deb:getBlocksmap: layersmap=' , layersmap #-------------
4620
for item in drawing.entities.data:
4621
if type(item) != list and item.type == 'insert':
4622
if not layersmap or (not layersmap[item.layer].frozen or layFrozen_on): #if insert_layer is not frozen
4623
try: usedblocks[item.name][0] = True
4626
key_list = usedblocks.keys()
4628
for key in key_list:
4629
if usedblocks[key][0]: #if parent used, then set used also all child blocks
4630
for child in usedblocks[key][1]:
4631
if not layersmap or (layersmap and not layersmap[child[1]].frozen): #if insert_layer is not frozen
4632
usedblocks[child[0]][0] = True # marked as used BLOCK
4634
usedblocks = [i for i in usedblocks.keys() if usedblocks[i][0]]
4635
#print 'deb:getBlocksmap: usedblocks=' , usedblocks #-------------
4638
for item in drawing.blocks.data:
4639
if type(item) != list and item.type == 'block' and item.name in usedblocks:
4640
#if item.name.startswith('*X'): #--todo--
4641
obj_number += len(item.entities.data)
4642
try: blocksmap[item.name] = item
4643
except KeyError: print 'Cannot map "%s" - "%s" as Block!' %(item.name, item)
4646
#print 'deb:getBlocksmap: blocksmap:\n', blocksmap #------------
4647
return blocksmap, obj_number
4650
def getBlocknamesmap(blocksmap): #--------------------------------------------------------
4651
"""Build a dictionary of blockname:blockname_short pairs
4653
#print 'deb:getBlocknamesmap blocksmap:\n', blocksmap #------------
4655
for n in blocksmap.keys():
4656
blockname_short = n[:MAX_NAMELENGTH-1]
4657
i = 0 #sufix for blockname cause Blender-objectnamelength-limit
4658
while blockname_short in blocknamesmap.keys():
4661
blockname_short = blockname_short[:-2] + suffix
4662
blocknamesmap[n] = blockname_short
4663
#print 'deb:getBlocknamesmap blocknamesmap:\n', blocknamesmap #------------
4664
return blocknamesmap
4667
def drawEntities(entities, settings, block_def=None): #----------------------------------------
4668
"""Draw every kind of thing in the entity list.
4670
If provided 'block_def': the entities are to be added to the Blender 'group'.
4672
for _type in type_map.keys():
4673
#print 'deb:drawEntities_type:', _type #------------------
4674
# for each known type get a list of that type and call the associated draw function
4675
entities_type = entities.get_type(_type)
4676
if entities_type: drawer(_type, entities_type, settings, block_def)
4679
def drawer(_type, entities, settings, block_def): #------------------------------------------
4680
"""Call with a list of entities and a settings object to generate Blender geometry.
4682
If 'block_def': the entities are to be added to the Blender 'group'.
4684
global layersmap, layersmapshort
4685
#print 'deb:drawer _type, entities:\n ', _type, entities #-----------------------
4688
# Break out early if settings says we aren't drawing the current dxf-type
4689
global cur_COUNTER #counter for progress_bar
4691
#print 'deb:drawer.check:_type: ', _type #--------------------
4692
if _type == '3dface':_type = 'face' # hack, while python_variable_name can not beginn with a nummber
4693
if not settings.drawTypes[_type] or _type == 'block_record':
4694
message = 'Skipping dxf\'%ss\' entities' %_type
4695
settings.write(message, True)
4696
cur_COUNTER += len(entities)
4697
settings.progress(cur_COUNTER, message)
4699
#print 'deb:drawer.todo:_type:', _type #-----------------------
4700
#print 'deb:drawer entities:\n ', entities #-----------------------
4702
len_temp = len(entities)
4703
# filtering only model-space enitities (no paper-space enitities)
4704
if settings.var['paper_space_on']:
4705
entities = [entity for entity in entities if entity.space != 0]
4707
entities = [entity for entity in entities if entity.space == 0]
4709
# filtering only objects with color from acceptedColorsList
4710
if settings.var['colorFilter_on']:
4711
entities = [entity for entity in entities if entity.color in settings.acceptedColors]
4713
# filtering only objects on layers from acceptedLayersList
4714
if settings.var['layerFilter_on']:
4715
#entities = [entity for entity in entities if entity.layer[0] in ['M','3','0'] and not entity.layer.endswith('H')]
4716
entities = [entity for entity in entities if entity.layer in settings.acceptedLayers]
4718
# patch for incomplete layer table in HL2-DXF-files
4720
for entity in entities:
4721
oblayer = entity.layer
4722
if oblayer not in layersmap.keys():
4723
layer_obj = Layer(None, name=oblayer)
4724
layersmap[oblayer] = layer_obj
4725
layername_short = oblayer[:MAX_NAMELENGTH-1]
4726
i = 0 #sufix for layernames cause Blender-objectnames-limits
4727
while layername_short in layernamesmap.keys():
4729
suffix = str(i) #--todo--set zero-leading number format
4730
layername_short = layername_short[:-2] + suffix
4731
layernamesmap[oblayer] = layername_short
4733
# filtering only objects on not-frozen layers
4734
if layersmap and not settings.var['layFrozen_on']:
4735
entities = [entity for entity in entities if not layersmap[entity.layer].frozen]
4737
global activObjectLayer, activObjectName
4738
activObjectLayer = ''
4739
activObjectName = ''
4741
message = "Drawing dxf\'%ss\'..." %_type
4742
cur_COUNTER += len_temp - len(entities)
4743
settings.write(message, False)
4744
settings.progress(cur_COUNTER, message)
4745
if len(entities) > 0.1 / settings.obj_number:
4746
show_progress = int(0.03 / settings.obj_number)
4747
else: show_progress = 0
4750
#print 'deb:drawer cur_COUNTER: ', cur_COUNTER #-----------------------
4752
for entity in entities: #----loop-------------------------------------
4753
settings.write('\b.', False)
4757
if cur_temp == show_progress:
4758
settings.progress(cur_COUNTER, message)
4760
#print 'deb:drawer show_progress=',show_progress #----------------
4762
# get the layer group (just to make things a little cleaner)
4763
if settings.var['group_bylayer_on'] and not block_def:
4764
group = getGroup('l:%s' % layernamesmap[entity.layer])
4766
if _type == 'insert': #---- INSERT and MINSERT=array --------------------
4767
if not settings.var['block_nn'] and entity.name.startswith('*X'): #---- support for noname BLOCKs
4768
#print 'deb:drawer entity.name:', entity.name #------------
4770
elif settings.var['blockFilter_on'] and not settings.accepted_block(entity.name):
4773
#print 'deb:insert entity.loc:', entity.loc #----------------
4775
columns = entity.columns[0]
4776
coldist = entity.columns[1]
4777
rows = entity.rows[0]
4778
rowdist = entity.rows[1]
4780
#print 'deb:insert columns, rows:', columns, rows #-----------
4781
for col in xrange(columns):
4782
deltaloc[0] = col * coldist
4783
for row in xrange(rows):
4784
deltaloc[1] = row * rowdist
4785
#print 'deb:insert col=%s, row=%s,deltaloc=%s' %(col, row, deltaloc) #------
4786
ob = entity.draw(settings, deltaloc) #-----draw BLOCK----------
4789
bl_loc = block_def[1]
4790
ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]]
4791
else: blockFlag = False
4792
setObjectProperties(ob, group, entity, settings, block_def)
4794
if settings.var['optimization'] <= settings.MIN:
4795
#if settings.var['g_origin_on'] and not block_def: ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin
4796
if settings.var['g_scale_on']: globalScaleOne(ob, insertFlag, blockFlag, settings.var['g_scale'])
4798
else: oblist.append((ob, insertFlag, blockFlag))
4800
else: #---draw entities except BLOCKs/INSERTs---------------------
4802
alt_obname = activObjectName
4803
ob = entity.draw(settings)
4805
if M_OBJ and ob.type=='Mesh': #'Curve', 'Text'
4808
bl_loc = block_def[1]
4809
ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]]
4812
elif ob.name != alt_obname:
4815
bl_loc = block_def[1]
4816
ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]]
4817
else: blockFlag = False
4818
setObjectProperties(ob, group, entity, settings, block_def)
4819
if settings.var['optimization'] <= settings.MIN:
4820
#if settings.var['g_origin_on'] and not block_def: ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin
4821
if settings.var['g_scale_on']: globalScaleOne(ob, insertFlag, blockFlag, settings.var['g_scale'])
4823
else: oblist.append((ob, insertFlag, blockFlag))
4825
#print 'deb:Finished drawing:', entities[0].type #------------------------
4826
message = "\nDrawing dxf\'%ss\' done!" % _type
4827
settings.write(message, True)
4831
def globalScale(oblist, SCALE): #---------------------------------------------------------
4832
"""Global_scale for list of all imported objects.
4834
oblist is a list of pairs (ob, insertFlag), where insertFlag=True/False
4836
#print 'deb:globalScale.oblist: ---------%\n', oblist #---------------------
4838
ob, insertFlag, blockFlag = l[0], l[1], l[2]
4839
globalScaleOne(ob, insertFlag, blockFlag, SCALE)
4842
def globalScaleOne(ob, insertFlag, blockFlag, SCALE): #---------------------------------------------------------
4843
"""Global_scale imported object.
4845
#print 'deb:globalScaleOne ob: ', ob #---------------------
4846
if settings.var['g_origin_on'] and not blockFlag:
4847
ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin
4849
SCALE_MAT= Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1])
4850
if insertFlag: # by BLOCKs/INSERTs only insert-point coords must be scaled------------
4851
ob.loc = Mathutils.Vector(ob.loc) * SCALE_MAT
4852
else: # entire scaling for all other imported objects ------------
4853
if ob.type == 'Mesh':
4854
me = ob.getData(name_only=False, mesh=True)
4855
#me = Mesh.Get(ob.name)
4856
# set centers of all objects in (0,0,0)
4857
#me.transform(ob.matrixWorld*SCALE_MAT)
4858
#ob.loc = Mathutils.Vector([0,0,0])
4859
# preseve centers of all objects
4860
me.transform(SCALE_MAT)
4861
ob.loc = Mathutils.Vector(ob.loc) * SCALE_MAT
4862
else: #--todo-- also for curves: neutral scale factor after import
4863
ob.setMatrix(ob.matrixWorld*SCALE_MAT)
4866
def setObjectProperties(ob, group, entity, settings, block_def): #-----------------------
4867
"""Link object to scene.
4870
if not ob: #remi--todo-----------------------
4871
message = "\nObject \'%s\' not found!" %entity
4872
settings.write(message)
4876
setGroup(group, ob) # if object belongs to group
4878
if block_def: # if object belongs to BLOCK_def - Move it to layer nr19
4879
setGroup(block_def[0], ob)
4880
#print 'deb:setObjectProperties \'%s\' set to block_def_group!' %ob.name #---------
4883
#ob.layers = [i+1 for i in xrange(20)] #remi--todo------------
4884
ob.layers = [settings.var['target_layer']]
4886
# Set material for any objects except empties
4887
if ob.type != 'Empty' and settings.var['material_on']:
4888
setMaterial_from(entity, ob, settings, block_def)
4890
# Set the visibility
4891
#if settings.layer_isOff(entity.layer):
4892
if layersmap and layersmap[entity.layer].color < 0: # color is negative if layer is off
4893
#ob.layers = [20] #remi--todo-------------
4894
ob.restrictDisplay = True
4895
ob.restrictRender = True
4897
#print 'deb:\n---------linking Object %s!' %ob.name #----------
4901
def getGroup(name): #-----------------------------------------------------------------
4902
"""Returns a Blender group-object.
4905
group = Group.Get(name)
4906
except: # What is the exception?
4907
group = Group.New(name)
4911
def setGroup(group, ob): #------------------------------------------------------------
4912
"""Assigns object to Blender group.
4915
group.objects.link(ob)
4917
group.objects.append(ob) #remi?---------------
4921
def setMaterial_from(entity, ob, settings, block_def): #------------------------------------------------
4922
""" Set Blender-material for the object controled by item.
4924
Set Blender-material for the object
4925
- controlled by settings.var['material_from']
4927
if settings.var['material_from'] == 1: # 1= material from color
4928
if entity.color_index == BYLAYER or entity.color_index == 256:
4929
mat = settings.colMaterials(entity.layer)
4930
elif entity.color_index == BYBLOCK or entity.color_index == 0:
4931
#--todo-- looking for block.color_index
4932
#mat = settings.colMaterials(block.color_index)
4933
#if block_def: mat = settings.colMaterials(block_def[2])
4934
mat = settings.colMaterials(3)
4936
mat = settings.colMaterials(entity.color_index)
4938
elif settings.var['material_from'] == 2: # 2= material from layer_name
4939
mat = settings.layMaterials(layername=entity.layer)
4941
elif settings.var['material_from'] == 3: # 3= material from layer+color
4942
mat = settings.layMaterials(layername=entity.layer, color=entity.color_index)
4944
# elif settings.var['material_from'] == 4: # 4= material from block_name
4946
# elif settings.var['material_from'] == 5: # 5= material from XDATA
4948
# elif settings.var['material_from'] == 6: # 6= material from INI-file
4950
else: # set neutral material
4952
mat = Material.Get('dxf-neutral')
4954
mat = Material.New('dxf-neutral')
4955
mat.setRGBCol(color_map[3])
4956
try:mat.setMode('Shadeless', 'Wire') #work-around for 2.45rc1-bug
4958
mat.mode |= Material.Modes.SHADELESS #
4959
mat.mode |= Material.Modes.WIRE
4961
#print 'deb:material mat:', mat #-----------
4962
ob.setMaterials([mat]) #assigns Blender-material to object
4964
settings.write("material error - \'%s\'!" %mat)
4965
ob.colbits = 0x01 # Set OB materials.
4969
def calcBulge(p1, p2, arc_res, triples=False): #-------------------------------------------------
4970
"""given startpoint, endpoint and bulge of arc, returns points/segments of its representation.
4972
Needs to take into account bulge sign.
4973
negative = clockwise
4974
positive = counter-clockwise
4976
to find center given two points, and arc angle
4978
Cord = sqrt(start^2 + end^2)
4980
radius = ((Cord/2)^2+S^2)/2*S
4981
angle of arc = 4*atan( bulge )
4982
angle from p1 to center is (180-angle)/2
4983
get vector pointing from p1 to p2 (p2 - p1)
4984
normalize it and multiply by radius
4985
rotate around p1 by angle to center, point to center.
4986
start angle = angle between (center - p1) and worldX
4987
end angle = angle between (center - p2) and worldX
4989
calculate the center, radius, start angle, and end angle
4990
returns points/segments of its mesh representation
4991
incl.startpoint, without endpoint
4995
p1 = Mathutils.Vector(p1.loc)
4996
p2 = Mathutils.Vector(p2.loc)
4997
cord = p2 - p1 # vector from p1 to p2
4998
clength = cord.length
4999
s = (bulge * clength)/2.0 # sagitta (height)
5000
radius = abs(((clength/2.0)**2.0 + s**2.0)/(2.0*s)) # magic formula
5001
angle = (degrees(4.0*atan(bulge))) # theta (included angle)
5002
radial = cord.normalize() * radius # a radius length vector aligned with cord
5003
delta = (180.0 - abs(angle))/2.0 # the angle from cord to center
5004
if bulge < 0: delta = -delta
5005
rmat = Mathutils.RotationMatrix(-delta, 3, 'Z')
5006
center = p1 + (rmat * radial) # rotate radial by delta degrees, then add to p1 to find center
5007
#length = radians(abs(angle)) * radius
5008
#print 'deb:calcBulge:\n angle, delta: ', angle, delta #----------------
5009
#print 'deb:center, radius: ', center, radius #----------------------
5010
startpoint = p1 - center
5011
endpoint = p2 - center
5012
#print 'deb:calcBulg: startpoint:', startpoint #---------
5013
#print 'deb:calcBulg: endpoint:', endpoint #---------
5015
if not triples: #IF mesh-representation -----------
5016
if arc_res > 1024: arc_res = 1024
5017
elif arc_res < 4: arc_res = 4
5018
pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION
5019
if pieces < 3: pieces = 3
5020
else: #IF curve-representation -------------------------------
5021
if arc_res > 32: arc_res = 32
5022
elif arc_res < 3: arc_res = 3
5023
pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION
5024
if pieces < 2: pieces = 2
5026
step = angle/pieces # set step so pieces * step = degrees in arc
5027
stepmatrix = Mathutils.RotationMatrix(-step, 3, "Z")
5029
if not triples: #IF mesh-representation -----------
5030
points = [startpoint]
5032
for i in xrange(int(pieces)-1): #fast (but not so acurate as: vector * RotMatrix(-step*i,3,"Z")
5033
point = stepmatrix * point
5034
points.append(point)
5035
points = [ point+center for point in points]
5036
# vector to point convertion:
5037
points = [list(point) for point in points]
5038
return points, list(center)
5040
else: #IF curve-representation -------------------------------
5041
# correct Bezier curves representation for free segmented circles/arcs
5042
step2 = radians(step * 0.5)
5043
bulg = radius * (1 - cos(step2))
5044
deltaY = 4.0 * bulg / (3.0 * sin(step2) )
5045
#print 'deb:calcArcCurve: bulg, deltaY:\n', bulg, deltaY #---------
5046
#print 'deb:calcArcCurve: step:\n', step #---------
5048
#org handler0 = Mathutils.Vector(0.0, -deltaY, 0.0)
5049
#handler = startmatrix * handler0
5050
#endhandler = endmatrix * handler0
5051
rotMatr90 = Mathutils.Matrix([0, -1, 0], [1, 0, 0], [0, 0, 1])
5052
handler = rotMatr90 * startpoint
5053
handler = - deltaY * handler.normalize()
5054
endhandler = rotMatr90 * endpoint
5055
endhandler = - deltaY * endhandler.normalize()
5057
points = [startpoint]
5058
handlers1 = [startpoint + handler]
5059
handlers2 = [startpoint - handler]
5060
point = Mathutils.Vector(startpoint)
5061
for i in xrange(int(pieces)-1):
5062
point = stepmatrix * point
5063
handler = stepmatrix * handler
5064
handler1 = point + handler
5065
handler2 = point - handler
5066
points.append(point)
5067
handlers1.append(handler1)
5068
handlers2.append(handler2)
5069
points.append(endpoint)
5070
handlers1.append(endpoint + endhandler)
5071
handlers2.append(endpoint - endhandler)
5073
points = [point + center for point in points]
5074
handlers1 = [point + center for point in handlers1]
5075
handlers2 = [point + center for point in handlers2]
5077
VectorTriples = [list(h1)+list(p)+list(h2) for h1,p,h2 in zip(handlers1, points, handlers2)]
5078
#print 'deb:calcBulgCurve: handlers1:\n', handlers1 #---------
5079
#print 'deb:calcBulgCurve: points:\n', points #---------
5080
#print 'deb:calcBulgCurve: handlers2:\n', handlers2 #---------
5081
#print 'deb:calcBulgCurve: VectorTriples:\n', VectorTriples #---------
5082
return VectorTriples
5087
def calcArc(center, radius, start, end, arc_res, triples): #-----------------------------------------
5088
"""calculate Points (or BezierTriples) for ARC/CIRCLEs representation.
5090
Given parameters of the ARC/CIRCLE,
5091
returns points/segments (or BezierTriples) and centerPoint
5093
# center is currently set by object
5094
# if start > end: start = start - 360
5095
if end > 360: end = end % 360.0
5097
startmatrix = Mathutils.RotationMatrix(-start, 3, "Z")
5098
startpoint = startmatrix * Mathutils.Vector(radius, 0, 0)
5099
endmatrix = Mathutils.RotationMatrix(-end, 3, "Z")
5100
endpoint = endmatrix * Mathutils.Vector(radius, 0, 0)
5102
if end < start: end +=360.0
5104
#length = radians(angle) * radius
5106
if not triples: #IF mesh-representation -----------
5107
if arc_res > 1024: arc_res = 1024
5108
elif arc_res < 4: arc_res = 4
5109
pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION
5110
if pieces < 3: pieces = 3
5111
step = angle/pieces # set step so pieces * step = degrees in arc
5112
stepmatrix = Mathutils.RotationMatrix(-step, 3, "Z")
5114
points = [startpoint]
5116
for i in xrange(int(pieces)-1):
5117
point = stepmatrix * point
5118
points.append(point)
5119
points.append(endpoint)
5122
centerVec = Mathutils.Vector(center)
5123
#points = [point + centerVec for point in points()]
5124
points = [point + centerVec for point in points]
5125
# vector to point convertion:
5126
points = [list(point) for point in points]
5129
else: #IF curve-representation ---------------
5130
if arc_res > 32: arc_res = 32
5131
elif arc_res < 3: arc_res = 3
5132
pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION
5133
if pieces < 2: pieces = 2
5134
step = angle/pieces # set step so pieces * step = degrees in arc
5135
stepmatrix = Mathutils.RotationMatrix(-step, 3, "Z")
5137
# correct Bezier curves representation for free segmented circles/arcs
5138
step2 = radians(step * 0.5)
5139
bulg = radius * (1 - cos(step2))
5140
deltaY = 4.0 * bulg / (3.0 * sin(step2) )
5141
#print 'deb:calcArcCurve: bulg, deltaY:\n', bulg, deltaY #---------
5142
#print 'deb:calcArcCurve: step:\n', step #---------
5143
handler0 = Mathutils.Vector(0.0, -deltaY, 0.0)
5145
points = [startpoint]
5146
handler = startmatrix * handler0
5147
endhandler = endmatrix * handler0
5148
handlers1 = [startpoint + handler]
5149
handlers2 = [startpoint - handler]
5150
point = Mathutils.Vector(startpoint)
5151
for i in xrange(int(pieces)-1):
5152
point = stepmatrix * point
5153
handler = stepmatrix * handler
5154
handler1 = point + handler
5155
handler2 = point - handler
5156
points.append(point)
5157
handlers1.append(handler1)
5158
handlers2.append(handler2)
5159
points.append(endpoint)
5160
handlers1.append(endpoint + endhandler)
5161
handlers2.append(endpoint - endhandler)
5162
VectorTriples = [list(h1)+list(p)+list(h2) for h1,p,h2 in zip(handlers1, points, handlers2)]
5163
#print 'deb:calcArcCurve: handlers1:\n', handlers1 #---------
5164
#print 'deb:calcArcCurve: points:\n', points #---------
5165
#print 'deb:calcArcCurve: handlers2:\n', handlers2 #---------
5166
#print 'deb:calcArcCurve: VectorTriples:\n', VectorTriples #---------
5167
return VectorTriples
5170
def drawCurveCircle(circle): #--- no more used --------------------------------------------
5171
"""Given a dxf circle object return a blender circle object using curves.
5173
c = Curve.New('circle') # create new curve data
5175
radius = circle.radius
5177
p1 = (0, -radius, 0)
5180
p4 = (-radius, 0, 0)
5182
p1 = BezTriple.New(p1)
5183
p2 = BezTriple.New(p2)
5184
p3 = BezTriple.New(p3)
5185
p4 = BezTriple.New(p4)
5187
curve = c.appendNurb(p1)
5192
point.handleTypes = [AUTO, AUTO]
5193
curve.flagU = 1 # Set curve cyclic
5196
ob = Object.New('Curve', 'circle') # make curve object
5200
def drawCurveArc(self): #---- only for ELLIPSE -------------------------------------------------------------
5201
"""Given a dxf ELLIPSE object return a blender_curve.
5204
radius = self.radius
5205
start = self.start_angle
5206
end = self.end_angle
5209
start = start - 360.0
5210
startmatrix = Mathutils.RotationMatrix(start, 3, "Z")
5211
startpoint = startmatrix * Mathutils.Vector((radius, 0, 0))
5212
endmatrix = Mathutils.RotationMatrix(end, 3, "Z")
5213
endpoint = endmatrix * Mathutils.Vector((radius, 0, 0))
5214
# Note: handles must be tangent to arc and of correct length...
5216
a = Curve.New('arc') # create new curve data
5218
p1 = (0, -radius, 0)
5221
p4 = (-radius, 0, 0)
5223
p1 = BezTriple.New(p1)
5224
p2 = BezTriple.New(p2)
5225
p3 = BezTriple.New(p3)
5226
p4 = BezTriple.New(p4)
5228
curve = a.appendNurb(p1)
5233
point.handleTypes = [AUTO, AUTO]
5234
curve.flagU = 1 # Set curve cyclic
5237
ob = Object.New('Curve', 'arc') # make curve object
5243
# GUI STUFF -----#################################################-----------------
5244
from Blender.BGL import *
5252
EVENT_CHOOSE_INI = 7
5253
EVENT_CHOOSE_DXF = 8
5255
EVENT_PRESETCURV = 10
5265
GUI_EVENT = EVENT_NONE
5267
GUI_A = {} # GUI-buttons dictionary for parameter
5268
GUI_B = {} # GUI-buttons dictionary for drawingTypes
5270
# settings default, initialize ------------------------
5272
points_as_menu = "convert to: %t|empty %x1|mesh.vertex %x2|thin sphere %x3|thin box %x4|*curve.vertex %x5"
5273
lines_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|thin box %x4|Bezier-curve %x5|NURBS-curve %x6"
5274
mlines_as_menu = "convert to: %t|*edge %x1|*mesh %x2|*thin cylinder %x3|*thin box %x|*curve %x5"
5275
plines_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|*thin box %x4|Bezier-curve %x5|NURBS-curve %x6"
5276
splines_as_menu = "convert to: %t|mesh %x2|*thin cylinder %x3|*thin box %x4|Bezier-curve %x5|NURBS-curve %x6"
5277
plines3_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|*thin box %x4|Bezier-curve %x5|NURBS-curve %x6"
5278
plmesh_as_menu = "convert to: %t|*edge %x1|mesh %x2|NURBS-surface %x6"
5279
solids_as_menu = "convert to: %t|*edge %x1|mesh %x2"
5280
blocks_as_menu = "convert to: %t|dupliGroup %x1|*real.Group %x2|*exploded %x3"
5281
texts_as_menu = "convert to: %t|text %x1|*mesh %x2|*curve %x5"
5282
material_from_menu= "material from: %t|*LINESTYLE %x7|COLOR %x1|LAYER %x2|*LAYER+COLOR %x3|*BLOCK %x4|*XDATA %x5|*INI-File %x6"
5283
g_scale_list = ''.join((
5297
'| x 0.00001 %x-5'))
5299
#print 'deb: g_scale_list', g_scale_list #-----------
5301
dxfFileName = Draw.Create("")
5302
iniFileName = Draw.Create(INIFILE_DEFAULT_NAME + INIFILE_EXTENSION)
5304
config_UI = Draw.Create(0) #switch_on/off extended config_UI
5305
g_scale_as = Draw.Create(int(log10(G_SCALE)))
5319
'blockFilter_on': 0,
5320
'layerFilter_on': 0,
5321
'colorFilter_on': 0,
5322
'groupFilter_on': 0,
5324
'target_layer' : TARGET_LAYER,
5325
'group_bylayer_on' : GROUP_BYLAYER,
5326
'g_originX' : G_ORIGIN_X,
5327
'g_originY' : G_ORIGIN_Y,
5328
'g_originZ' : G_ORIGIN_Z,
5330
'g_scale' : float(G_SCALE),
5331
# 'g_scale_as': int(log10(G_SCALE)), # 0,
5334
'thick_min' : float(MIN_THICK),
5337
'width_min' : float(MIN_WIDTH),
5340
'dist_min' : float(MIN_DIST),
5346
'curve_res' : CURV_RESOLUTION,
5347
'curve_arc' : CURVARC_RESOLUTION,
5348
'arc_res' : ARC_RESOLUTION,
5349
'arc_rad' : ARC_RADIUS,
5350
'thin_res' : THIN_RESOLUTION,
5351
'pl_trim_max' : TRIM_LIMIT,
5355
'paper_space_on': 0,
5358
'Z_elev': float(ELEVATION),
5393
# creating of GUI-buttons
5394
# GUI_A - GUI-buttons dictionary for parameter
5395
# GUI_B - GUI-buttons dictionary for drawingTypes
5396
for k, v in keywords_org.iteritems():
5397
GUI_A[k] = Draw.Create(v)
5398
for k, v in drawTypes_org.iteritems():
5399
GUI_B[k] = Draw.Create(v)
5400
#print 'deb:init GUI_A: ', GUI_A #---------------
5401
#print 'deb:init GUI_B: ', GUI_B #---------------
5403
model_space_on = Draw.Create(1)
5405
# initialize settings-object controls how dxf entities are drawn
5406
settings = Settings(keywords_org, drawTypes_org)
5409
def update_RegistryKey(key, item): #
5410
"""updates key in Blender.Registry
5412
cache = True # data is also saved to a file
5413
rdict = Registry.GetKey('DXF_Importer', cache)
5414
if not rdict: rdict = {}
5417
Registry.SetKey('DXF_Importer', rdict, cache)
5418
#print 'deb:update_RegistryKey rdict', rdict #---------------
5421
def check_RegistryKey(key):
5422
""" check if the key is already there (saved on a previous execution of this script)
5424
cache = True # data is also saved to a file
5425
rdict = Registry.GetKey('DXF_Importer', cache)
5426
#print 'deb:check_RegistryKey rdict:', rdict #----------------
5427
if rdict: # if found, get the values saved there
5432
#update_RegistryKey() # if data isn't valid rewrite it
5435
def saveConfig(): #--todo-----------------------------------------------
5436
"""Save settings/config/materials from GUI to INI-file.
5438
Write all config data to INI-file.
5442
iniFile = iniFileName.val
5443
#print 'deb:saveConfig inifFile: ', inifFile #----------------------
5444
if iniFile.lower().endswith(INIFILE_EXTENSION):
5446
#--todo-- sort key.list for output
5447
#key_list = GUI_A.keys().val
5449
#for key in key_list:
5450
# l_name, l_data = key, GUI_A[key].val
5453
output_str = '[%s,%s]' %(GUI_A, GUI_B)
5454
if output_str =='None':
5455
Draw.PupMenu('DXF importer: INI-file: Alert!%t|no config-data present to save!')
5457
#if BPyMessages.Warning_SaveOver(iniFile): #<- remi find it too abstarct
5458
if sys.exists(iniFile):
5460
f = file(iniFile, 'r')
5461
try: header_str = f.readline()
5464
if header_str.startswith(INIFILE_HEADER[0:13]):
5465
if Draw.PupMenu(' OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile) == 1:
5467
else: save_ok = False
5468
elif Draw.PupMenu(' OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile +
5469
'|Alert: this file has no valid ImportDXF-header| ! it may belong to another aplication !') == 1:
5471
else: save_ok = False
5472
else: save_ok = True
5475
# replace: ',' -> ',\n'
5476
# replace: '{' -> '\n{\n'
5477
# replace: '}' -> '\n}\n'
5478
output_str = ',\n'.join(output_str.split(','))
5479
output_str = '\n}'.join(output_str.split('}'))
5480
output_str = '{\n'.join(output_str.split('{'))
5482
f = file(iniFile, 'w')
5484
f.write(INIFILE_HEADER + '\n# this is a comment line\n')
5487
#Draw.PupMenu('DXF importer: INI-file: Done!%t|config-data saved in ' + '\'%s\'' %iniFile)
5489
Draw.PupMenu('DXF importer: INI-file: Error!%t|failure by writing to ' + '\'%s\'|no config-data saved!' %iniFile)
5492
Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid name/extension for INI-file selected!')
5493
print "DXF importer: Alert!: no valid INI-file selected."
5495
if dxfFileName.val.lower().endswith('.dxf'):
5496
iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
5499
def loadConfig(): #remi--todo-----------------------------------------------
5500
"""Load settings/config/materials from INI-file.
5502
Read material-assignements from config-file.
5504
#070724 buggy Window.FileSelector(loadConfigFile, 'Load config data from INI-file', inifilename)
5505
global iniFileName, GUI_A, GUI_B
5507
iniFile = iniFileName.val
5508
update_RegistryKey('iniFileName', iniFile)
5509
#print 'deb:loadConfig iniFile: ', iniFile #----------------------
5510
if iniFile.lower().endswith(INIFILE_EXTENSION) and sys.exists(iniFile):
5512
f = file(iniFile, 'r')
5514
header_str = f.readline()
5515
if header_str.startswith(INIFILE_HEADER):
5518
#print 'deb:loadConfig data_str from %s: \n' %iniFile , data_str #-----------------
5519
data = eval(data_str)
5520
for k, v in data[0].iteritems():
5521
try: GUI_A[k].val = v
5522
except: GUI_A[k] = Draw.Create(v)
5523
for k, v in data[1].iteritems():
5524
try: GUI_B[k].val = v
5525
except: GUI_B[k] = Draw.Create(v)
5527
Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid header in INI-file: ' + '\'%s\'' %iniFile)
5531
Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid INI-file selected!')
5532
print "DXF importer: Alert!: no valid INI-file selected."
5534
if dxfFileName.val.lower().endswith('.dxf'):
5535
iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION
5539
def updateConfig(keywords, drawTypes): #-----------------------------------------------
5540
"""updates GUI_settings with given dictionaries
5544
#print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
5545
for k, v in keywords.iteritems():
5547
for k, v in drawTypes.iteritems():
5550
def resetDefaultConfig(): #-----------------------------------------------
5551
"""Resets settings/config/materials to defaults.
5554
#print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #---------
5555
updateConfig(keywords_org, drawTypes_org)
5558
def presetConfig_curv(activate): #-----------------------------------------------
5559
"""Sets settings/config/materials for curve representation.
5564
GUI_A['curves_on'].val = 1
5565
GUI_A['points_as'].val = 5
5566
GUI_A['lines_as'].val = 5
5567
GUI_A['mlines_as'].val = 5
5568
GUI_A['plines_as'].val = 5
5569
GUI_A['splines_as'].val = 5
5570
GUI_A['plines3_as'].val = 5
5572
GUI_A['curves_on'].val = 0
5573
GUI_A['points_as'].val = 2
5574
GUI_A['lines_as'].val = 2
5575
GUI_A['mlines_as'].val = 2
5576
GUI_A['plines_as'].val = 2
5577
GUI_A['splines_as'].val = 6
5578
GUI_A['plines3_as'].val = 2
5581
def resetDefaultConfig_2D(): #-----------------------------------------------
5582
"""Sets settings/config/materials to defaults 2D.
5585
presetConfig_curv(1)
5628
updateConfig(keywords2d, drawTypes2d)
5630
def resetDefaultConfig_3D(): #-----------------------------------------------
5631
"""Sets settings/config/materials to defaults 3D.
5634
presetConfig_curv(0)
5677
updateConfig(keywords3d, drawTypes3d)
5680
def inputGlobalScale():
5681
"""Pop-up UI-Block for global scale factor
5684
#print 'deb:inputGlobalScale ##########' #------------
5685
x_scale = Draw.Create(GUI_A['g_scale'].val)
5687
#block.append("global translation vector:")
5688
block.append(("", x_scale, 0.0, 10000000.0))
5690
retval = Draw.PupBlock("set global scale factor:", block)
5692
GUI_A['g_scale'].val = float(x_scale.val)
5695
def inputOriginVector():
5696
"""Pop-up UI-Block for global translation vector
5699
#print 'deb:inputOriginVector ##########' #------------
5700
x_origin = Draw.Create(GUI_A['g_originX'].val)
5701
y_origin = Draw.Create(GUI_A['g_originY'].val)
5702
z_origin = Draw.Create(GUI_A['g_originZ'].val)
5704
#block.append("global translation vector:")
5705
block.append(("X: ", x_origin, -100000000.0, 100000000.0))
5706
block.append(("Y: ", y_origin, -100000000.0, 100000000.0))
5707
block.append(("Z: ", z_origin, -100000000.0, 100000000.0))
5709
retval = Draw.PupBlock("set global translation vector:", block)
5711
GUI_A['g_originX'].val = x_origin.val
5712
GUI_A['g_originY'].val = y_origin.val
5713
GUI_A['g_originZ'].val = z_origin.val
5716
def draw_UI(): #-----------------------------------------------------------------
5717
""" Draw startUI and setup Settings.
5719
global GUI_A, GUI_B #__version__
5720
global user_preset, iniFileName, dxfFileName, config_UI, g_scale_as
5721
global model_space_on
5723
# This is for easy layout changes
5724
but_0c = 70 #button 1.column width
5725
but_1c = 70 #button 1.column width
5726
but_2c = 70 #button 2.column
5727
but_3c = 70 #button 3.column
5730
menu_w = (3 * butt_margin) + but_0c + but_1c + but_2c + but_3c #menu width
5734
y = simple_menu_h # y is menu upper.y
5735
if config_UI.val: y += extend_menu_h
5737
but0c = x + menu_margin #buttons 0.column position.x
5738
but1c = but0c + but_0c + butt_margin
5739
but2c = but1c + but_1c + butt_margin
5740
but3c = but2c + but_2c + butt_margin
5741
but4c = but3c + but_3c
5743
# Here starts menu -----------------------------------------------------
5744
#glClear(GL_COLOR_BUFFER_BIT)
5745
#glRasterPos2d(8, 125)
5748
colorbox(x, y+20, x+menu_w+menu_margin*2, menu_margin)
5749
Draw.Label("DXF-Importer v" + __version__, but0c, y, menu_w, 20)
5752
b0, b0_ = but0c, but_0c + butt_margin
5753
b1, b1_ = but1c, but_1c
5759
GUI_B['point'] = Draw.Toggle('POINT', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['point'].val, "support dxf-POINT on/off")
5760
if GUI_B['point'].val:
5761
GUI_A['points_as'] = Draw.Menu(points_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['points_as'].val, "select target Blender-object")
5762
# Draw.Label('-->', but2c, y, but_2c, 20)
5767
GUI_B['line'] = Draw.Toggle('LINE...etc', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['line'].val, "support dxf-LINE,ARC,CIRCLE,ELLIPSE on/off")
5768
if GUI_B['line'].val:
5769
GUI_A['lines_as'] = Draw.Menu(lines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['lines_as'].val, "select target Blender-object")
5774
GUI_B['mline'] = Draw.Toggle('*MLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['mline'].val, "(*wip)support dxf-MLINE on/off")
5775
if GUI_B['mline'].val:
5776
GUI_A['mlines_as'] = Draw.Menu(mlines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['mlines_as'].val, "select target Blender-object")
5781
GUI_B['spline'] = Draw.Toggle('SPLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['spline'].val, "support dxf-SPLINE on/off")
5782
if GUI_B['spline'].val:
5783
GUI_A['splines_as'] = Draw.Menu(splines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['splines_as'].val, "select target Blender-object")
5788
GUI_B['polyline'] = Draw.Toggle('2D/LWPLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['polyline'].val, "support dxf-2D-POLYLINE on/off")
5789
if GUI_B['polyline'].val:
5790
GUI_A['plines_as'] = Draw.Menu(plines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plines_as'].val, "select target Blender-object")
5795
GUI_B['pline3'] = Draw.Toggle('3D-PLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['pline3'].val, "support dxf-3D-POLYLINE on/off")
5796
if GUI_B['pline3'].val:
5797
GUI_A['plines3_as'] = Draw.Menu(plines3_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plines3_as'].val, "select target Blender-object")
5801
# -----------------------------------------------
5804
b0, b0_ = but2c, but_2c + butt_margin
5805
b1, b1_ = but3c, but_3c
5810
GUI_B['plmesh'] = Draw.Toggle('PL-MESH/FACE', EVENT_NONE, b0, y, b0_+b1_-40, 20, GUI_B['plmesh'].val, "support dxf-POLYMESH/POLYFACE on/off")
5811
# GUI_A['plmesh_as'] = Draw.Menu(plmesh_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plmesh_as'].val, "select target Blender-object")
5812
GUI_A['plmesh_flip'] = Draw.Toggle('N', EVENT_NONE, b1+b1_-40, y, 20, 20, GUI_A['plmesh_flip'].val, "flip DXF normals on/off")
5813
GUI_A['normals_out'] = Draw.Toggle('N', EVENT_NONE, b1+b1_-20, y, 20, 20, GUI_A['normals_out'].val, "force Blender normals to outside on/off")
5817
GUI_B['solid'] = Draw.Toggle('SOLID', EVENT_NONE, b0, y, b0_, 20, GUI_B['solid'].val, "support dxf-SOLID and TRACE on/off")
5818
GUI_B['face'] = Draw.Toggle('3DFACE', EVENT_NONE, b1, y, b1_, 20, GUI_B['face'].val, "support dxf-3DFACE on/off")
5819
# GUI_A['solids_as'] = Draw.Menu(solids_as_menu, EVENT_NONE, but3c, y, but_3c, 20, GUI_A['solids_as'].val, "select target Blender-object")
5820
#print 'deb:support solid, trace', GUI_B['trace'].val, GUI_B['solid'].val # ------------
5824
GUI_B['text'] = Draw.Toggle('TEXT', EVENT_NONE, b0, y, b0_, 20, GUI_B['text'].val, "support dxf-TEXT on/off")
5825
GUI_B['mtext'] = Draw.Toggle('*MTEXT', EVENT_NONE, b1, y, b1_, 20, GUI_B['mtext'].val, "(*wip)support dxf-MTEXT on/off")
5826
# GUI_A['texts_as'] = Draw.Menu(texts_as_menu, EVENT_NONE, but3c, y, but_3c, 20, GUI_A['texts_as'].val, "select target Blender-object")
5830
GUI_B['block'] = Draw.Toggle('BLOCK', EVENT_REDRAW, b0, y, b0_-30, 20, GUI_B['block'].val, "support dxf-BLOCK and ARRAY on/off")
5831
GUI_B['insert'].val = GUI_B['block'].val
5832
if GUI_B['block'].val:
5833
GUI_A['block_nn'] = Draw.Toggle('n', EVENT_NONE, b1-30, y, 15, 20, GUI_A['block_nn'].val, "support hatch/noname BLOCKs *X... on/off")
5834
GUI_A['xref_on'] = Draw.Toggle('Xref', EVENT_NONE, b1-15, y, 35, 20, GUI_A['xref_on'].val, "support for XREF-BLOCKs (place holders) on/off")
5835
GUI_A['blocks_as'] = Draw.Menu(blocks_as_menu, EVENT_NONE, b1+20, y, b1_-20, 20, GUI_A['blocks_as'].val, "select target representation for imported BLOCKs")
5843
GUI_A['views_on'] = Draw.Toggle('views', EVENT_NONE, b0, y, b0_-25, 20, GUI_A['views_on'].val, "imports VIEWs and VIEWPORTs as cameras on/off")
5844
GUI_A['cams_on'] = Draw.Toggle('*cams', EVENT_NONE, b1-25, y, b1_-25, 20, GUI_A['cams_on'].val, "(*wip) support ASHADE cameras on/off")
5845
GUI_A['lights_on'] = Draw.Toggle('*lights', EVENT_NONE, b1+25, y, b1_-25, 20, GUI_A['lights_on'].val, "(*wip) support AVE_RENDER lights on/off")
5849
if y < y_down: y_down = y
5850
# -----end supported objects--------------------------------------
5857
b0 = but0c + (menu_w - but_*6)/2
5859
GUI_A['paper_space_on'] = Draw.Toggle('paper', EVENT_NONE, b0+but_*0, y, but_, 20, GUI_A['paper_space_on'].val, "import only from Paper-Space on/off")
5860
GUI_A['layFrozen_on'] = Draw.Toggle ('frozen', EVENT_NONE, b0+but_*1, y, but_, 20, GUI_A['layFrozen_on'].val, "import also from frozen LAYERs on/off")
5861
GUI_A['layerFilter_on'] = Draw.Toggle('layer', EVENT_NONE, b0+but_*2, y, but_, 20, GUI_A['layerFilter_on'].val, "(*wip) LAYER filtering on/off")
5862
GUI_A['colorFilter_on'] = Draw.Toggle('color', EVENT_NONE, b0+but_*3, y, but_, 20, GUI_A['colorFilter_on'].val, "(*wip) COLOR filtering on/off")
5863
GUI_A['groupFilter_on'] = Draw.Toggle('group', EVENT_NONE, b0+but_*4, y, but_, 20, GUI_A['groupFilter_on'].val, "(*wip) GROUP filtering on/off")
5864
GUI_A['blockFilter_on'] = Draw.Toggle('block', EVENT_NONE, b0+but_*5, y, but_, 20, GUI_A['blockFilter_on'].val, "(*wip) BLOCK filtering on/off")
5865
#GUI_A['dummy_on'] = Draw.Toggle('-', EVENT_NONE, but3c, y, but_3c, 20, GUI_A['dummy_on'].val, "dummy on/off")
5868
# -----end filters--------------------------------------
5870
b0, b0_ = but0c, but_0c + butt_margin
5871
b1, b1_ = but1c, but_1c
5876
GUI_A['g_origin_on'] = Draw.Toggle('glob.reLoc', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_origin_on'].val, "global relocate all DXF objects on/off")
5877
if GUI_A['g_origin_on'].val:
5878
tmp = Draw.PushButton('=', EVENT_ORIGIN, b1, y, 20, 20, "edit relocation-vector (x,y,z in DXF units)")
5879
origin_str = '(%.4f, %.4f, %.4f)' % (
5880
GUI_A['g_originX'].val,
5881
GUI_A['g_originY'].val,
5882
GUI_A['g_originZ'].val
5884
tmp = Draw.Label(origin_str, b1+20, y, 300, 20)
5885
#GUI_A['g_origin'] = Draw.String('', EVENT_ORIGIN, b1, y, b1_, 20, GUI_A['g_origin'].val, "global translation-vector (x,y,z) in DXF units")
5890
GUI_A['g_scale_on'] = Draw.Toggle('glob.Scale', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_scale_on'].val, "global scale all DXF objects on/off")
5891
if GUI_A['g_scale_on'].val:
5892
g_scale_as = Draw.Menu(g_scale_list, EVENT_SCALE, b1, y, 45, 20, g_scale_as.val, "factor for scaling the DXFdata")
5893
if g_scale_as.val == 12:
5896
if g_scale_as.val == 6: #scale inches to meters
5897
GUI_A['g_scale'].val = 0.0254000
5898
elif g_scale_as.val == 7: #scale feets to meters
5899
GUI_A['g_scale'].val = 0.3048000
5900
elif g_scale_as.val == 8: #scale yards to meters
5901
GUI_A['g_scale'].val = 0.9144000
5903
GUI_A['g_scale'].val = 10.0 ** int(g_scale_as.val)
5904
scale_float = GUI_A['g_scale'].val
5905
if scale_float < 0.000001 or scale_float > 1000000:
5906
scale_str = ' = %s' % GUI_A['g_scale'].val
5908
scale_str = ' = %.6f' % GUI_A['g_scale'].val
5909
Draw.Label(scale_str, b1+45, y, 200, 20)
5913
# -----end material,translate,scale------------------------------------------
5915
b0, b0_ = but0c, but_0c + butt_margin
5916
b1, b1_ = but1c, but_1c
5923
GUI_A['meshSmooth_on'] = Draw.Toggle('smooth', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['meshSmooth_on'].val, "mesh smooth for circles/arc-segments on/off")
5924
GUI_A['pl_trim_on'] = Draw.Toggle('trim', EVENT_NONE, b1-20, y, 32, 20, GUI_A['pl_trim_on'].val, "clean intersection of POLYLINE-wide-segments on/off")
5925
GUI_A['pl_trim_max'] = Draw.Number('', EVENT_NONE, b1+12, y, b1_-12, 20, GUI_A['pl_trim_max'].val, 0, 5, "threshold intersection of POLYLINE-wide-segments: 0.0-5.0")
5930
# GUI_A['thin_res'] = Draw.Number('thin:', EVENT_NONE, but0c, y, but_0c, 20, GUI_A['thin_res'].val, 4, 64, "thin cylinder resolution - number of segments (4-64)")
5931
GUI_A['arc_rad'] = Draw.Number('bR:', EVENT_NONE, b0, y, b0_, 20, GUI_A['arc_rad'].val, 0.01, 100, "basis radius for arc/circle resolution (0.01-100)")
5932
GUI_A['arc_res'] = Draw.Number('', EVENT_NONE, b1, y, b1_/2, 20, GUI_A['arc_res'].val, 3, 500, "arc/circle resolution - number of segments (3-500)")
5933
GUI_A['fill_on'] = Draw.Toggle('caps', EVENT_NONE, b1+b1_/2, y, b1_/2, 20, GUI_A['fill_on'].val, "draws top and bottom caps of CYLINDERs/closed curves on/off")
5938
GUI_A['curve_arc'] = Draw.Number('', EVENT_NONE, b0, y, b0_/2, 20, GUI_A['curve_arc'].val, 3, 32, "Bezier circle: amount of segments: 3-32")
5939
GUI_A['curve_res'] = Draw.Number('', EVENT_NONE, b0+b0_/2, y, b0_/2, 20, GUI_A['curve_res'].val, 1, 128, "Set the Curve's U-resolution value: 1-128")
5940
GUI_A['curves_on'] = Draw.Toggle('to Curves', EVENT_PRESETCURV, b1, y, b1_, 20, GUI_A['curves_on'].val, "set Curve as target object type on/off")
5944
GUI_A['group_bylayer_on'] = Draw.Toggle('Layer', EVENT_NONE, b0, y, 30, 20, GUI_A['group_bylayer_on'].val, "DXF-entities group by layer on/off")
5945
GUI_A['vGroup_on'] = Draw.Toggle('vGroups', EVENT_NONE, b0+30, y, b1_-10, 20, GUI_A['vGroup_on'].val, "sort faces into VertexGroups on/off")
5946
GUI_A['one_mesh_on'] = Draw.Toggle('oneMesh', EVENT_NONE, b1+10, y, b1_-10, 20, GUI_A['one_mesh_on'].val, "draw DXF-entities into one mesh-object. Recommended for big DXF-files. on/off")
5950
GUI_A['material_on'] = Draw.Toggle('material', EVENT_REDRAW, b0, y, b0_-20, 20, GUI_A['material_on'].val, "support for material assignment on/off")
5951
if GUI_A['material_on'].val:
5952
GUI_A['material_from'] = Draw.Menu(material_from_menu, EVENT_NONE, b1-20, y, b1_+20, 20, GUI_A['material_from'].val, "material assignment from?")
5956
# -----------------------------------------------
5958
b0, b0_ = but2c, but_2c + butt_margin
5959
b1, b1_ = but3c, but_3c
5965
GUI_A['Z_force_on'] = Draw.Toggle('*elevation', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['Z_force_on'].val, "*set objects Z-coordinates to elevation on/off")
5966
if GUI_A['Z_force_on'].val:
5967
GUI_A['Z_elev'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['Z_elev'].val, -1000, 1000, "set default elevation(Z-coordinate)")
5972
GUI_A['dist_on'] = Draw.Toggle('dist.:', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['dist_on'].val, "support distance on/off")
5973
GUI_A['dist_force'] = Draw.Toggle('F', EVENT_NONE, b0+b0_-20, y, 20, 20, GUI_A['dist_force'].val, "force minimal distance on/off")
5974
GUI_A['dist_min'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['dist_min'].val, 0, 10, "minimal length/distance (double.vertex removing)")
5979
GUI_A['thick_on'] = Draw.Toggle('thick:', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['thick_on'].val, "support thickness on/off")
5980
GUI_A['thick_force'] = Draw.Toggle('F', EVENT_REDRAW, b0+b0_-20, y, 20, 20, GUI_A['thick_force'].val, "force for thickness at least limiter value on/off")
5981
if GUI_A['thick_force'].val:
5982
GUI_A['thick_min'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['thick_min'].val, 0, 10, "minimal value for thickness")
5987
GUI_A['width_on'] = Draw.Toggle('width:', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['width_on'].val, "support width on/off")
5988
GUI_A['width_force'] = Draw.Toggle('F', EVENT_REDRAW, b0+b0_-20, y, 20, 20, GUI_A['width_force'].val, "force for width at least limiter value on/off")
5989
if GUI_A['width_force'].val:
5990
GUI_A['width_min'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['width_min'].val, 0, 10, "minimal value for width")
5994
but, but_ = but2c, 25
5998
if y < y_down: y_down = y
5999
# -----end options --------------------------------------
6002
#--------------------------------------
6005
#GUI_A['dummy_on'] = Draw.Toggle(' - ', EVENT_NONE, but0c, y, but_0c, 20, GUI_A['dummy_on'].val, "reserved")
6008
Draw.PushButton('INI file >', EVENT_CHOOSE_INI, but0c, y, but_0c, 20, 'Select INI-file from project directory')
6009
iniFileName = Draw.String(' :', EVENT_NONE, but1c, y, menu_w-but_1c-60, 20, iniFileName.val, FILENAME_MAX, "write here the name of the INI-file")
6011
Draw.PushButton('#', EVENT_PRESETS, but, y, 20, 20, "toggle Preset-INI-files")
6012
Draw.PushButton('L', EVENT_LOAD_INI, but+20, y, 20, 20, 'Loads configuration from ini-file: %s' % iniFileName.val)
6013
Draw.PushButton('S', EVENT_SAVE_INI, but+40, y, 20, 20, 'Saves configuration to ini-file: %s' % iniFileName.val)
6017
b0, b0_ = but2c, but_2c + butt_margin
6018
b1, b1_ = but3c, but_3c
6025
Draw.PushButton('DXFfile >', EVENT_CHOOSE_DXF, but0c, y, but_0c, 20, 'Select DXF-file from project directory')
6026
dxfFileName = Draw.String(' :', EVENT_NONE, but1c, y, but_1c+but_2c+but_3c-20, 20, dxfFileName.val, FILENAME_MAX, "type the name of DXF-file or type *.dxf for multi-import")
6027
Draw.PushButton('*.*', EVENT_DXF_DIR, but3c+but_3c-20, y, 20, 20, 'import all dxf files from this directory')
6031
config_UI = Draw.Toggle('CONFIG', EVENT_REDRAW, but0c, y, but_0c+bm, 20, config_UI.val, 'Advanced configuration on/off' )
6033
but, but_ = but1c, but_1c+bm
6035
Draw.PushButton('X', EVENT_RESET, but, y, 15, 20, "reset configuration to defaults")
6036
Draw.PushButton('2D', EVENT_PRESET2D, but+but_, y, but_, 20, 'set configuration for 2D import')
6037
Draw.PushButton('3D', EVENT_PRESET3D, but+(but_*2), y, but_, 20, 'set configuration for 3D import')
6041
GUI_A['newScene_on'] = Draw.Toggle('newScene', EVENT_NONE, but2c, y, but_2c, 20, GUI_A['newScene_on'].val, "create new Scene for each imported dxf file on/off")
6042
GUI_A['target_layer'] = Draw.Number('layer', EVENT_NONE, but3c, y, but_3c, 20, GUI_A['target_layer'].val, 1, 18, "target Blender-layer (<19> reserved for block_definitions)")
6046
Draw.PushButton('EXIT', EVENT_EXIT, but0c, y, but_0c+bm, 20, '' )
6047
Draw.PushButton('HELP', EVENT_HELP, but1c, y, but_1c+bm, 20, 'calls DXF-Importer Manual Page on Wiki.Blender.org')
6049
GUI_A['optimization'] = Draw.Number('', EVENT_NONE, but2c, y+20, 40, 20, GUI_A['optimization'].val, 0, 3, "Optimization Level: 0=Debug/directDrawing, 1=Verbose, 2=ProgressBar, 3=SilentMode")
6052
Draw.PushButton('TEST', EVENT_LIST, but2c, y, 40, 20, 'DXF-Analyze-Tool: reads data from selected dxf file and writes report in project_directory/dxf_blendname.INF')
6053
Draw.PushButton('START IMPORT', EVENT_START, but2c+40, y, but_2c-40+but_3c+butt_margin, 40, 'Start the import process. For Cancel go to console and hit Ctrl-C')
6061
Draw.Label(' ', but0c-menu_margin, y, menu_margin, 20)
6062
Draw.Label(LAB, but0c, y, menu_w, 20)
6063
Draw.Label(' ', but0c+menu_w, y, menu_margin, 20)
6066
#-- END GUI Stuf-----------------------------------------------------
6068
def colorbox(x,y,xright,bottom):
6069
glColor3f(0.75, 0.75, 0.75)
6070
glRecti(x + 1, y + 1, xright - 1, bottom - 1)
6072
def dxf_callback(input_filename):
6074
dxfFileName.val=input_filename
6075
# dirname == Blender.sys.dirname(Blender.Get('filename'))
6076
# update_RegistryKey('DirName', dirname)
6077
# update_RegistryKey('dxfFileName', input_filename)
6079
def ini_callback(input_filename):
6081
iniFileName.val=input_filename
6083
def event(evt, val):
6084
if evt in (Draw.QKEY, Draw.ESCKEY) and not val:
6088
# global EVENT_NONE,EVENT_LOAD_DXF,EVENT_LOAD_INI,EVENT_SAVE_INI,EVENT_EXIT
6089
global config_UI, user_preset
6092
######### Manages GUI events
6093
if (evt==EVENT_EXIT):
6095
print 'DXF-Importer *** exit ***' #---------------------
6096
elif (evt==EVENT_CHOOSE_INI):
6097
Window.FileSelector(ini_callback, "INI-file Selection", '*.ini')
6098
elif (evt==EVENT_REDRAW):
6100
elif (evt==EVENT_RESET):
6101
resetDefaultConfig()
6103
elif (evt==EVENT_PRESET2D):
6104
resetDefaultConfig_2D()
6106
elif (evt==EVENT_SCALE):
6107
if g_scale_as.val == 12:
6109
if GUI_A['g_scale'].val < 0.00000001:
6110
GUI_A['g_scale'].val = 0.00000001
6112
elif (evt==EVENT_ORIGIN):
6115
elif (evt==EVENT_PRESET3D):
6116
resetDefaultConfig_3D()
6118
elif (evt==EVENT_PRESETCURV):
6119
presetConfig_curv(GUI_A['curves_on'].val)
6121
elif (evt==EVENT_PRESETS):
6123
index = str(user_preset)
6124
if user_preset > 5: user_preset = 0; index = ''
6125
iniFileName.val = INIFILE_DEFAULT_NAME + index + INIFILE_EXTENSION
6127
elif (evt==EVENT_LIST):
6128
dxfFile = dxfFileName.val
6129
update_RegistryKey('dxfFileName', dxfFileName.val)
6130
if dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile):
6133
Draw.PupMenu('DXF importer: Alert!%t|no valid DXF-file selected!')
6134
print "DXF importer: error, no valid DXF-file selected! try again"
6136
elif (evt==EVENT_HELP):
6139
webbrowser.open('http://wiki.blender.org/index.php?title=Scripts/Manual/Import/DXF-3D')
6141
Draw.PupMenu('DXF importer: HELP Alert!%t|no connection to manual-page on Blender-Wiki! try:|\
6142
http://wiki.blender.org/index.php?title=Scripts/Manual/Import/DXF-3D')
6144
elif (evt==EVENT_LOAD_INI):
6147
elif (evt==EVENT_SAVE_INI):
6150
elif (evt==EVENT_DXF_DIR):
6151
dxfFile = dxfFileName.val
6154
dxfPathName = '/'.join(dxfFile.split('/')[:-1]) + '/'
6155
elif '\\' in dxfFile:
6156
dxfPathName = '\\'.join(dxfFile.split('\\')[:-1]) + '\\'
6157
dxfFileName.val = dxfPathName + '*.dxf'
6158
# dirname == Blender.sys.dirname(Blender.Get('filename'))
6159
# update_RegistryKey('DirName', dirname)
6160
# update_RegistryKey('dxfFileName', dxfFileName.val)
6161
GUI_A['newScene_on'].val = 1
6163
elif (evt==EVENT_CHOOSE_DXF):
6164
filename = '' # '*.dxf'
6165
if dxfFileName.val: filename = dxfFileName.val
6166
Window.FileSelector(dxf_callback, "DXF-file Selection", filename)
6167
elif (evt==EVENT_START):
6168
dxfFile = dxfFileName.val
6169
#print 'deb: dxfFile file: ', dxfFile #----------------------
6170
if E_M: dxfFileName.val, dxfFile = e_mode(dxfFile) #evaluation mode
6171
update_RegistryKey('dxfFileName', dxfFileName.val)
6172
if dxfFile.lower().endswith('*.dxf'):
6173
if Draw.PupMenu('DXF importer: OK?|will import all DXF-files from:|%s' % dxfFile) == 1:
6176
multi_import(dxfFile[:-5]) # cut last 5 characters '*.dxf'
6181
elif dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile):
6182
print '\nStandard Mode: active'
6183
if GUI_A['newScene_on'].val:
6184
_dxf_file = dxfFile.split('/')[-1].split('\\')[-1]
6185
_dxf_file = _dxf_file[:-4] # cut last char:'.dxf'
6186
_dxf_file = _dxf_file[:MAX_NAMELENGTH] #? [-MAX_NAMELENGTH:])
6188
SCENE = Blender.Scene.New(_dxf_file)
6191
#or so? Blender.Scene.makeCurrent(_dxf_file)
6192
#sce = bpy.data.scenes.new(_dxf_file)
6193
#bpy.data.scenes.active = sce
6195
SCENE = Blender.Scene.GetCurrent()
6196
SCENE.objects.selected = [] # deselect all
6198
#SCENE.objects.selected = SCENE.objects
6203
Draw.PupMenu('DXF importer: Alert!%t|no valid DXF-file selected!')
6204
print "DXF importer: error, no valid DXF-file selected! try again"
6210
def multi_import(DIR):
6211
"""Imports all DXF-files from directory DIR.
6215
batchTIME = Blender.sys.time()
6216
#if #DIR == "": DIR = os.path.curdir
6217
if DIR == "": DIR = Blender.sys.dirname(Blender.Get('filename'))
6218
print 'Multifiles Import from %s' %DIR
6220
[sys.join(DIR, f) for f in os.listdir(DIR) if f.lower().endswith('.dxf')]
6222
print '...None DXF-files found. Abort!'
6226
for dxfFile in files:
6228
print '\nDXF-file', i, 'of', len(files) #,'\nImporting', dxfFile
6229
if GUI_A['newScene_on'].val:
6230
_dxf_file = dxfFile.split('/')[-1].split('\\')[-1]
6231
_dxf_file = _dxf_file[:-4] # cut last char:'.dxf'
6232
_dxf_file = _dxf_file[:MAX_NAMELENGTH] #? [-MAX_NAMELENGTH:])
6233
SCENE = Blender.Scene.New(_dxf_file)
6235
#or so? Blender.Scene.makeCurrent(_dxf_file)
6236
#sce = bpy.data.scenes.new(_dxf_file)
6237
#bpy.data.scenes.active = sce
6239
SCENE = Blender.Scene.GetCurrent()
6240
SCENE.objects.selected = [] # deselect all
6244
print 'TOTAL TIME: %.6f' % (Blender.sys.time() - batchTIME)
6245
print '\a\r', # beep when done
6251
if __name__ == "__main__":
6253
# recall last used DXF-file and INI-file names
6254
dxffilename = check_RegistryKey('dxfFileName')
6255
#print 'deb:start dxffilename:', dxffilename #----------------
6256
if dxffilename: dxfFileName.val = dxffilename
6258
dirname = Blender.sys.dirname(Blender.Get('filename'))
6259
#print 'deb:start dirname:', dirname #----------------
6260
dxfFileName.val = sys.join(dirname, '')
6261
inifilename = check_RegistryKey('iniFileName')
6262
if inifilename: iniFileName.val = inifilename
6264
Draw.Register(draw_UI, event, bevent)
6271
TIME= Blender.sys.time()
6272
#DIR = '/dxf_r12_testfiles/'
6275
print 'Searching for files'
6276
os.system('find %s -iname "*.dxf" > /tmp/tempdxf_list' % DIR)
6277
# os.system('find /storage/ -iname "*.dxf" > /tmp/tempdxf_list')
6279
file= open('/tmp/tempdxf_list', 'r')
6280
lines= file.readlines()
6282
# sort by filesize for faster testing
6283
lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines]
6285
lines = [f[1] for f in lines_size]
6287
for i, _dxf in enumerate(lines):
6290
print 'Importing', _dxf, '\nNUMBER', i, 'of', len(lines)
6292
_dxf_file= _dxf.split('/')[-1].split('\\')[-1]
6293
_dxf_file = _dxf_file[:-4] # cut last char:'.dxf'
6294
_dxf_file = _dxf_file[:MAX_NAMELENGTH] #? [-MAX_NAMELENGTH:])
6295
sce = bpy.data.scenes.new(_dxf_file)
6296
bpy.data.scenes.active = sce
6297
dxfFileName.val = _dxf
6300
print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
b'\\ No newline at end of file'