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.11.16 by migius'
11 __url__ = ["http://blenderartists.org/forum/showthread.php?t=84319",
12 "http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"]
13 __email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"]
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.11.16 by migius
115 d1 remove try_finally: cause not supported in python <2.5
116 d1 add Bezier curves bevel radius support (default 1.0)
117 v1.12 - 2008.08.03 by migius
118 c2 warningfix: relocating of globals: layersmap, oblist
119 c2 modif UI: buttons newScene+targetLayer moved to start panel
120 v1.12 - 2008.07.04 by migius
121 c1 added control Curve's OrderU parameter
122 c1 modif UI: preset buttons X-2D-3D moved to start panel
123 b6 added handling exception of not registered LAYERs (Hammer-HL-editor DXF output)
124 b5 rebuild UI: global preset 2D for Curve-Import
125 b5 added UI-options: PL-MESH N+N plmesh_flip and normals_out
126 b5 added support for SPLINEs, added control OrderU parameter
127 b5 rewrote draw module for NURBS_curve and Bezier_curve
128 v1.12 - 2008.06.22 by migius
129 b4 change versioning system 1.0.12 -> 1.12
130 b4 print at start version-info to console
131 b3 bugfix: ob.name conflict with existing meshes (different ob.name/mesh.name)
132 v1.0.12: 2008.05.24 by migius
133 b2 added support for LWPOLYLINEs
134 b2 added support for ProE in readerDXF.py
135 v1.0.12: 2008.02.08 by migius
136 b1 update: object = Object.Get(obname) -> f_getSceChild().getChildren()
137 a9 bugfix by non-existing tables views, vports, layers (Kai reported)
138 v1.0.12: 2008.01.17 by migius
139 a8 lately used INI-dir/filename persistently stored in Registry
140 a8 lately used DXF-dir/filename persistently stored in Registry
141 a7 fix missing layersmap{} for dxf-files without "section:layer"
142 a6 added support for XREF external referenced BLOCKs
143 a6 check for bug in AutoCAD2002:DXFr12export: ELLIPSE->POLYLINE_ARC fault angles
144 a6 support VIEWs and VPORTs as cameras: ortho and perspective mode
145 a6 save resources through ignoring unused BLOCKs (not-inserted or on frozen/blocked layers)
146 a6 added try_finally: f.close() for all IO-files
147 a6 added handling for TypeError raise
148 a5 bugfix f_getOCS for (0,0,z!=1.0) (ellipse in Kai's dxf)
149 a4 added to analyzeTool: report about VIEWs, VPORTs, unused/xref BLOCKs
150 a4 bugfix: individual support for 2D/3DPOLYLINE/POLYMESH
151 a4 added to UI: (*wip)BLOCK-(F): name filtering for BLOCKs
152 a4 added to UI: BLOCK-(n): filter anoname/hatch BLOCKs *X...
153 a2 g_scale_as is no more GUI_A-variable
154 a2 bugfix "material": negative sign color_index
155 a2 added support for BLOCKs defined with origin !=(0,0,0)
156 a1 added 'global.reLocation-vector' option
158 v1.0.11: 2007.11.24 by migius
159 c8 added 'curve_resolution_U' option
160 c8 added context_sensitivity for some UI-buttons
161 c8 bugfix ELLIPSE rotation, added closed_variant and caps
162 c7 rebuild UI: new layout, grouping and meta-buttons
163 c6 rewritten support for ELLIPSE mesh & curve representation
164 c6 restore selector-buttons for DXF-drawTypes: LINE & Co
165 c6 change header of INI/INF-files: # at begin
166 c6 apply scale(1,1,1) after glob.Scale for all mesh objects, not for curve objects.
167 c5 fixing 'material_on' option
168 c4 added "analyze DXF-file" UI-option: print LAYER/BLOCK-dependences into a textfile
169 c3 human-formating of data in INI-Files
170 c2 added "caps" for closed Bezier-curves
171 c2 added "set elevation" UI-option
172 c1 rewrite POLYLINE2d-arc-segments Bezier-interpreter
174 b9 rewrite POLYLINE2d-arc-segments trimming (clean-trim)
175 b8 added "import from frozen layers" UI-option
176 b8 added "import from paper space" UI-option
177 b8 support Bezier curves for LINEs incl.thickness(0.0-10.0)
178 b8 added meshSmooth_on for circle/arc/polyline
179 b8 added vertexGroups for circle/arc
180 b7 added width_force for ARCs/CIRCLEs = "thin_box" option
181 b3 cleanup code, rename f_drawArc/Bulg->f_calcArc/Bulg
182 b2 fixing material assignment by LAYER+COLOR
183 b1 fixing Bezier curves representation of POLYLINEs-arc-segments
184 b0 added global_scale_presets: "yard/feet/inch to meter"
186 v1.0.10: 2007.10.18 by migius
187 a6 bugfix CircleDrawCaps for OSX
188 a5 added two "curve_res" UI-buttons for Bezier curves representation
189 a5 improved Bezier curves representation of circles/arcs: correct handlers
190 a4 try to fix malformed endpoints of Blender curves of ARC/POLYLINE-arc segments.
191 a3 bugfix: open-POLYLINEs with end_point.loc==start_point.loc
192 a2 bugfix: f_transform for OCS=(0,0,-1) oriented objects
193 a1 added "fill_on=caps" option to draw top and bottom sides of CIRCLEs and ELLIPSEs
194 a1 rewrite f_CIRCLE.Draw: from Mesh.Primitive to Mesh
195 a1 bugfix "newScene"-mode: all Cylinders/Arcs were drawn at <0,0,0>location
197 v1.0.beta09: 2007.09.02 by migius
198 g5 redesign UI: grouping of buttons
199 g3 update multi-import-mode: <*.*> button
200 g- added multi-import-mode: (path/*) for importing many dxf-files at once
201 g- added import into newScene
202 g- redesign UI: user presets, into newScene-import
204 f- bugfix: thickness for Bezier/Bsplines into Blender-curves
205 f- BlenderWiki documentation, on-line Manual
206 f- added import POLYLINE-Bsplines into Blender-NURBSCurves
207 f- added import POLYLINE-arc-segments into Blender-BezierCurves
208 f- added import POLYLINE-Bezier-curves into Blender-Curves
209 d5 rewrite: Optimization Levels, added 'directDrawing'
210 d4 added: f_set_thick(controlled by ini-parameters)
211 d4 bugfix: face-normals in objects with minus thickness
212 d4 added: placeholder'Empty'-size in f_Insert.draw
213 d3 rewrite f_Text.Draw: added support for all Text's parameters
214 d2 redesign: progressbar
215 e- tuning by ideasman42: better use of the Py API.
216 c- tuning by ideasman42
217 b- rewrite f_Text.Draw rotation/transform
218 b- bugfix: POLYLINE-segment-intersection more reliable now
219 b- bugfix: circle:_thic, 'Empties':no material_assignment
220 b- added material assignment (from layer and/or color)
221 a- added empty, cylinder and UVsphere for POINTs
222 a- added support for 2d-POLYLINE: splines, fitted curves, fitted surfaces
223 a- redesign f_Drawer for block_definitions
224 a- rewrite import into Blender-Curve-Object
226 v1.0.beta08 - 2007.07.27 by migius: "full 3d"-release
227 l- bugfix: solid_vgroups, clean:scene.objects.new()
228 l- redesign UI to standard Draw.Register+FileSelector, advanced_config_option
229 k- bugfix UI:fileSelect() for MacOSX os.listdir()
230 k- added reset/save/load for config-data
231 k- redesign keywords/drawTypes/Draw.Create_Buttons
232 j- new UI using UIBlock() with own FileSelector, cause problem Window.FileSelector()
233 i- rewritten Class:Settings for better config-parameter management
234 h- bugfix: face-normals in objects with minus thickness
235 h- added Vertex-Groups in POLYLINE and SOLID meshes, for easy material assignment
236 h- beautify code, whitespace->tabs
237 h- added settings.thic_force switch for forcing thickness
238 h- added "one Mesh" option for all entities from the same Layer, sorted in<br>
239 Vertex-Groups(color_name) (fewer objects = better import performance)
240 g- rewrote: insert-point-handle-object is a small tetrahedron
241 e- bugfix: closed-polymesh3d
242 - rewrote: UI, type_map.keys, f_drawer, all class_f_draw(added "settings" as attribut)
243 - added 2d/3d-support for Polyline_Width incl. angle intersection
244 beta07: 2007.06.19 by migius
245 - added 3d-support for LWPolylines
246 - added 2d/3d-support for Points
247 beta06: 2007.06.15 by migius
249 - added 2d/3d-support for MINSERT=BlockArray in f_drawer, added f_rotXY_Vec
250 beta05: 2007.06.14 by migius
251 - added 2d/3d-support for 3d-PolyLine, PolyMesh and PolyFace
252 - added Global-Scale for size control of imported scenes
253 beta04: 2007.06.12 by migius
254 - rewrote the f_drawBulge for correct import the arc-segments of Polylines
255 beta03: 2007.06.10 by migius
257 beta02: 2007.06.09 by migius
258 - added 3d-support for Arcs and Circles
259 - added support for Object_Thickness(=height)
260 beta01: 2007.06.08 by migius
261 - added 3d-support for Blocks/Inserts within nested-structures
262 - rewrote f_transform for correct 3d-location/3d-rotation
263 - added 3d-support Lines, 3dFaces
264 - added 2d+3d-support for Solids and Traces
266 v0.9 - 2007.01 by kitsu: (for 2.43)
267 - first draft of true POLYLINE import
270 v0.8 - 2006.12 by kitsu:
271 - first draft of object space coordinates OCS import
274 v0.5b - 2006.10 by kitsu: (for 2.42a)
280 # --------------------------------------------------------------------------
281 # DXF Import v1.0 by Ed Blake (AKA kitsu) and Remigiusz Fiedler (AKA migius)
282 # --------------------------------------------------------------------------
283 # ***** BEGIN GPL LICENSE BLOCK *****
285 # This program is free software; you can redistribute it and/or
286 # modify it under the terms of the GNU General Public License
287 # as published by the Free Software Foundation; either version 2
288 # of the License, or (at your option) any later version.
290 # This program is distributed in the hope that it will be useful,
291 # but WITHOUT ANY WARRANTY; without even the implied warranty of
292 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
293 # GNU General Public License for more details.
295 # You should have received a copy of the GNU General Public License
296 # along with this program; if not, write to the Free Software Foundation,
297 # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
299 # ***** END GPL LICENCE BLOCK *****
300 # --------------------------------------------------------------------------
303 from Blender import *
304 #from Blender.Mathutils import Vector, Matrix
305 #import bpy #not used yet
308 from dxfReader import readDXF
309 #from dxfReader import get_name, get_layer
310 from dxfReader import Object as dxfObject
311 from dxfColorMap import color_map
319 psyco.log(Blender.Get('tempdir')+"/blender.log-psyco")
321 psyco.full(memory=100)
322 psyco.profile(0.05, memory=100)
324 #print 'psyco imported'
326 print 'psyco not imported'
332 print 'DXF-Importer v%s *** start ***' %(__version__) #---------------------
335 WORLDX = Mathutils.Vector((1,0,0))
336 WORLDY = Mathutils.Vector((1,1,0))
337 WORLDZ = Mathutils.Vector((0,0,1))
339 G_SCALE = 1.0 #(0.0001-1000) global scaling factor for all dxf data
340 G_ORIGIN_X = 0.0 #global translation-vector (x,y,z) in DXF units
343 MIN_DIST = 0.001 #cut-off value for sort out short-distance polyline-"duoble_vertex"
344 ARC_RESOLUTION = 64 #(4-500) arc/circle resolution - number of segments
345 ARC_RADIUS = 1.0 #(0.01-100) arc/circle radius for number of segments algorithm
346 CURV_RESOLUTION = 12 #(1-128) Bezier curves U-resolution
347 CURVARC_RESOLUTION = 4 #(3-32) resolution of circle represented as Bezier curve
348 THIN_RESOLUTION = 8 #(4-64) thin_cylinder arc_resolution - number of segments
349 MIN_THICK = MIN_DIST * 10.0 #minimal thickness by forced thickness
350 MIN_WIDTH = MIN_DIST * 10.0 #minimal width by forced width
351 TRIM_LIMIT = 3.0 #limit for triming of polylines-wide-segments (values:0.0 - 5.0)
352 ELEVATION = 0.0 #standard elevation = coordinate Z value
356 TARGET_LAYER = 3 #target blender_layer
357 GROUP_BYLAYER = 0 #(0/1) all entities from same layer import into one blender-group
358 LAYER_DEF_NAME = 'AAAA' #default layer name
359 LAYER_DEF_COLOR = 4 #default layer color
361 LAB = "*) parts under construction"
364 FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE)
365 MAX_NAMELENGTH = 17 #max_effective_obnamelength in blender =21=17+(.001)
366 INIFILE_DEFAULT_NAME = 'importDXF'
367 INIFILE_EXTENSION = '.ini'
368 INIFILE_HEADER = '#ImportDXF.py ver.1.0 config data'
369 INFFILE_HEADER = '#ImportDXF.py ver.1.0 analyze of DXF-data'
371 AUTO = BezTriple.HandleTypes.AUTO
372 FREE = BezTriple.HandleTypes.FREE
373 VECT = BezTriple.HandleTypes.VECT
374 ALIGN = BezTriple.HandleTypes.ALIGN
377 class View: #-----------------------------------------------------------------
378 """Class for objects representing dxf VIEWs.
380 def __init__(self, obj, active=None):
381 """Expects an object of type VIEW as input.
383 if not obj.type == 'view':
384 raise TypeError, "Wrong type %s for VIEW object!" %obj.type
387 self.name = obj.get_type(2)[0]
388 # self.data = obj.data[:]
391 self.centerX = getit(obj, 10, 0.0) #view center pointX (in DCS)
392 self.centerY = getit(obj, 20, 0.0) #view center pointY (in DCS)
393 self.height = obj.get_type(40)[0] #view height (in DCS)
394 self.width = obj.get_type(41)[0] #view width (in DCS)
397 self.dir[0] = getit(obj, 11, 0.0) #view directionX from target (in WCS)
398 self.dir[1] = getit(obj, 21, 0.0) #
399 self.dir[2] = getit(obj, 31, 0.0) #
401 self.target = [0,0,0]
402 self.target[0] = getit(obj, 12, 0.0) #target pointX(in WCS)
403 self.target[1] = getit(obj, 22, 0.0) #
404 self.target[2] = getit(obj, 32, 0.0) #
406 self.length = obj.get_type(42)[0] #Lens length
407 self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
408 self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
409 self.twist = obj.get_type(50)[0] #view twist angle in degrees
411 self.flags = getit(obj, 70, 0)
412 self.paperspace = self.flags & 1 #
414 self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
417 return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
420 def draw(self, settings):
421 """for VIEW: generate Blender_camera.
423 obname = 'vw_%s' %self.name # create camera object name
424 #obname = 'ca_%s' %self.name # create camera object name
425 obname = obname[:MAX_NAMELENGTH]
427 if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
428 cam= Camera.New('ortho', obname)
429 ob= SCENE.objects.new(cam)
431 cam.scale = 1.0 # for ortho cameras
433 cam= Camera.New('persp', obname)
434 ob= SCENE.objects.new(cam)
436 cam.angle = 60.0 # for persp cameras
438 #cam.angle = 2 * atan(17.5/self.length) * 180/pi
439 cam.lens = self.length #for persp cameras
440 # hack to update Camera>Lens setting (inaccurate as a focal length)
441 #curLens = cam.lens; cam.lens = curLens
442 # AutoCAD gets clip distance from target:
443 dist = Mathutils.Vector(self.dir).length
444 cam.clipEnd = dist - self.clip_back
445 cam.clipStart = dist - self.clip_front
450 v = Mathutils.Vector(self.dir)
451 # print 'deb:view cam:', cam #------------
452 # print 'deb:view self.target:', self.target #------------
453 # print 'deb:view self.dir:', self.dir #------------
454 # print 'deb:view self.twist:', self.twist #------------
455 # print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
456 transform(v.normalize(), -self.twist, ob)
457 ob.loc = Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
461 class Vport: #-----------------------------------------------------------------
462 """Class for objects representing dxf VPORTs.
464 def __init__(self, obj, active=None):
465 """Expects an object of type VPORT as input.
467 if not obj.type == 'vport':
468 raise TypeError, "Wrong type %s for VPORT object!" %obj.type
471 self.name = obj.get_type(2)[0]
472 # self.data = obj.data[:]
473 #print 'deb:vport name, data:', self.name #-------
474 #print 'deb:vport data:', self.data #-------
476 self.height = obj.get_type(40)[0] #vport height (in DCS)
477 self.centerX = getit(obj, 12, 0.0) #vport center pointX (in DCS)
478 self.centerY = getit(obj, 22, 0.0) #vport center pointY (in DCS)
479 self.width = self.height * obj.get_type(41)[0] #vport aspect ratio - width (in DCS)
482 self.dir[0] = getit(obj, 16, 0.0) #vport directionX from target (in WCS)
483 self.dir[1] = getit(obj, 26, 0.0) #
484 self.dir[2] = getit(obj, 36, 0.0) #
486 self.target = [0,0,0]
487 self.target[0] = getit(obj, 17, 0.0) #target pointX(in WCS)
488 self.target[1] = getit(obj, 27, 0.0) #
489 self.target[2] = getit(obj, 37, 0.0) #
491 self.length = obj.get_type(42)[0] #Lens length
492 self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
493 self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
494 self.twist = obj.get_type(51)[0] #view twist angle
496 self.flags = getit(obj, 70, 0)
497 self.paperspace = self.flags & 1 #
499 self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
502 return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
504 def draw(self, settings):
505 """for VPORT: generate Blender_camera.
507 obname = 'vp_%s' %self.name # create camera object name
508 #obname = 'ca_%s' %self.name # create camera object name
509 obname = obname[:MAX_NAMELENGTH]
511 if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
512 cam= Camera.New('ortho', obname)
513 ob= SCENE.objects.new(cam)
515 cam.scale = 1.0 # for ortho cameras
517 cam= Camera.New('persp', obname)
518 ob= SCENE.objects.new(cam)
520 cam.angle = 60.0 # for persp cameras
522 #cam.angle = 2 * atan(17.5/self.length) * 180/pi
523 cam.lens = self.length #for persp cameras
524 # hack to update Camera>Lens setting (inaccurate as a focal length)
525 #curLens = cam.lens; cam.lens = curLens
526 # AutoCAD gets clip distance from target:
527 dist = Mathutils.Vector(self.dir).length
528 cam.clipEnd = dist - self.clip_back
529 cam.clipStart = dist - self.clip_front
534 v = Mathutils.Vector(self.dir)
535 # print 'deb:view cam:', cam #------------
536 # print 'deb:view self.target:', self.target #------------
537 # print 'deb:view self.dir:', self.dir #------------
538 # print 'deb:view self.twist:', self.twist #------------
539 # print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
540 transform(v.normalize(), -self.twist, ob)
541 ob.loc = Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
546 class Layer: #-----------------------------------------------------------------
547 """Class for objects representing dxf LAYERs.
549 def __init__(self, obj, name=None, color=None, frozen=None):
550 """Expects an dxfobject of type layer as input.
551 if no dxfobject - creates surogate layer with default parameters
556 if name: self.name = name
557 else: self.name = LAYER_DEF_NAME
559 if color: self.color = color
560 else: self.color = LAYER_DEF_COLOR
562 if frozen!=None: self.frozen = frozen
563 else: self.frozen = 0
565 if obj.type=='layer':
567 #self.data = obj.data[:]
568 if name: self.name = name
569 #self.bfname = name #--todo---see layernamesmap in f_getLayersmap ---
570 else: self.name = obj.get_type(2)[0] #layer name of object
572 if color: self.color = color
573 else: self.color = obj.get_type(62)[0] #color of object
575 if frozen!=None: self.frozen = frozen
577 self.flags = obj.get_type(70)[0]
578 self.frozen = self.flags & 1
581 return "%s: name - %s, color - %s" %(self.__class__.__name__, self.name, self.color)
585 def getit(obj, typ, default=None): #------------------------------------------
586 """Universal procedure for geting data from list/objects.
589 if type(obj) == list: #if obj is a list, then searching in a list
591 #print 'deb:getit item, type(item)', item, type(item)
595 break #as soon as the first found
597 # --todo-- I found one case where item was a text instance
598 # that failed with no __getitem__
600 else: #else searching in Object with get_type-Methode
601 item = obj.get_type(typ)
604 #print 'deb:getit:typ, it', typ, it #----------
609 def get_extrusion(data): #-------------------------------------------------
610 """Find the axis of extrusion.
612 Used to get from object_data the objects Object_Coordinate_System (ocs).
614 #print 'deb:get_extrusion: data: \n', data #---------------
616 vec[0] = getit(data, 210, 0) # 210 = x
617 vec[1] = getit(data, 220, 0) # 220 = y
618 vec[2] = getit(data, 230, 1) # 230 = z
619 #print 'deb:get_extrusion: vec: ', vec #---------------
623 #------------------------------------------
624 def getSceneChild(name):
625 dudu = [i for i in SCENE.objects if i.name==name]
626 # dudu = [i for i in SCENE.getChildren() if i.name==name]
627 #print 'deb:getSceneChild %s -result: %s:' %(name,dudu) #-----------------
628 if dudu!=[]: return dudu[0]
632 class Solid: #-----------------------------------------------------------------
633 """Class for objects representing dxf SOLID or TRACE.
635 def __init__(self, obj):
636 """Expects an entity object of type solid or trace as input.
638 if obj.type == 'trace':
640 if not obj.type == 'solid':
641 raise TypeError, "Wrong type \'%s\' for solid/trace object!" %obj.type
644 # self.data = obj.data[:]
646 self.space = getit(obj, 67, 0)
647 self.thic = getit(obj, 39, 0)
648 self.color_index = getit(obj, 62, BYLAYER)
650 self.layer = getit(obj, 8, None)
651 self.extrusion = get_extrusion(obj)
652 self.points = self.get_points(obj)
656 def get_points(self, data):
657 """Gets start and end points for a solid type object.
659 Solids have 3 or 4 points and fixed codes for each value.
662 # start x, y, z and end x, y, z = 0
667 a[0] = getit(data, 10, None) # 10 = x
668 a[1] = getit(data, 20, None) # 20 = y
669 a[2] = getit(data, 30, 0) # 30 = z
670 b[0] = getit(data, 11, None)
671 b[1] = getit(data, 21, None)
672 b[2] = getit(data, 31, 0)
673 c[0] = getit(data, 12, None)
674 c[1] = getit(data, 22, None)
675 c[2] = getit(data, 32, 0)
678 d[0] = getit(data, 13, None)
680 d[1] = getit(data, 23, None)
681 d[2] = getit(data, 33, 0)
683 #print 'deb:solid.vertices:---------\n', out #-----------------------
688 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
691 def draw(self, settings):
692 """for SOLID: generate Blender_geometry.
695 if not points: return
696 edges, faces = [], []
699 obname = 'so_%s' %self.layer # create object name from layer name
700 obname = obname[:MAX_NAMELENGTH]
702 vg_left, vg_right, vg_top, vg_bottom, vg_start, vg_end = [], [], [], [], [], []
703 thic = set_thick(self.thic, settings)
705 thic_points = [[v[0], v[1], v[2] + thic] for v in points[:]]
707 thic_points.extend(points)
710 points.extend(thic_points)
713 faces = [[0,1,3,2], [4,6,7,5], [0,4,5,1],
714 [1,5,7,3], [3,7,6,2], [2,6,4,0]]
718 vg_bottom = [0,1,3,2]
722 faces = [[0,1,2], [3,5,4], [0,3,4,1], [1,4,5,2], [2,5,3,0]]
728 elif l == 2: faces = [[0,1,3,2]]
730 if l == 4: faces = [[0,1,3,2]]
731 elif l == 3: faces = [[0,1,2]]
732 elif l == 2: edges = [[0,1]]
734 if M_OBJ: obname, me, ob = makeNewObject()
736 me = Mesh.New(obname) # create a new mesh
737 ob = SCENE.objects.new(me) # create a new mesh_object
738 me.verts.extend(points) # add vertices to mesh
739 if faces: me.faces.extend(faces) # add faces to the mesh
740 if edges: me.edges.extend(edges) # add faces to the mesh
742 if settings.var['vGroup_on'] and not M_OBJ:
743 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
744 replace = Blender.Mesh.AssignModes.ADD #or .AssignModes.ADD/REPLACE
745 if vg_left: me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
746 if vg_right:me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
747 if vg_top: me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
748 if vg_bottom:me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
749 if vg_start:me.addVertGroup('side.start') ; me.assignVertsToGroup('side.start', vg_start, 1.0, replace)
750 if vg_end: me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', vg_end, 1.0, replace)
752 transform(self.extrusion, 0, ob)
756 class Line: #-----------------------------------------------------------------
757 """Class for objects representing dxf LINEs.
759 def __init__(self, obj):
760 """Expects an entity object of type line as input.
762 if not obj.type == 'line':
763 raise TypeError, "Wrong type \'%s\' for line object!" %obj.type
765 # self.data = obj.data[:]
767 self.space = getit(obj, 67, 0)
768 self.thic = getit(obj, 39, 0)
769 #print 'deb:self.thic: ', self.thic #---------------------
770 self.color_index = getit(obj, 62, BYLAYER)
772 self.layer = getit(obj, 8, None)
773 self.extrusion = get_extrusion(obj)
774 self.points = self.get_points(obj)
777 def get_points(self, data):
778 """Gets start and end points for a line type object.
780 Lines have a fixed number of points (two) and fixed codes for each value.
782 # start x,y,z and end x,y,z = 0
785 a[0] = getit(data, 10, None) # 10 = x
786 a[1] = getit(data, 20, None) # 20 = y
787 a[2] = getit(data, 30, 0) # 30 = z
788 b[0] = getit(data, 11, None)
789 b[1] = getit(data, 21, None)
790 b[2] = getit(data, 31, 0)
796 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
799 def draw(self, settings):
800 """for LINE: generate Blender_geometry.
802 # Generate the geometery
803 #settings.var['curves_on']=False
806 thic = set_thick(self.thic, settings)
808 if settings.var['lines_as'] == 4: # as thin_box
809 thic = settings.var['thick_min']
810 width = settings.var['width_min']
811 elif settings.var['lines_as'] == 3: # as thin cylinder
812 cyl_rad = 0.5 * settings.var['width_min']
814 elif settings.var['lines_as'] == 5: # LINE curve representation-------------------------
815 obname = 'li_%s' %self.layer # create object name from layer name
816 obname = obname[:MAX_NAMELENGTH]
818 c = Curve.New(obname) # create new curve data
819 curve = c.appendNurb(BezTriple.New(points[0]))
820 curve.append(BezTriple.New(points[1]))
822 point.handleTypes = [VECT, VECT]
824 curve.flagU = 0 # 0 sets the curve not cyclic=open
825 c.setResolu(settings.var['curve_res'])
826 c.update() #important for handles calculation
828 ob = SCENE.objects.new(c) # create a new curve_object
830 #if False: # --todo-- better support for 210-group
831 if thic != 0.0: #hack: Blender2.45 curve-extrusion
833 if abs(t) > 5.0: t = 5.0 * cmp(t,0) # Blender2.45 accepts only (0.0 - 5.0)
835 c.setExt1(abs(t)) # curve-extrusion
839 #c.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
840 #ob.LocZ = t + self.loc[2]
844 else: # LINE mesh representation ------------------------------
845 global activObjectLayer
846 global activObjectName
847 #print 'deb:draw:line.ob IN activObjectName: ', activObjectName #---------------------
849 if M_OBJ: obname, me, ob = makeNewObject()
851 if activObjectLayer == self.layer and settings.var['one_mesh_on']:
852 obname = activObjectName
853 #print 'deb:line.draw obname from activObjectName: ', obname #---------------------
854 ob = getSceneChild(obname) # open an existing mesh_object
855 #ob = SCENE.getChildren(obname) # open an existing mesh_object
856 #me = Mesh.Get(ob.name) # open objects mesh data
857 me = ob.getData(name_only=False, mesh=True)
859 obname = 'li_%s' %self.layer # create object name from layer name
860 obname = obname[:MAX_NAMELENGTH]
861 me = Mesh.New(obname) # create a new mesh
862 ob = SCENE.objects.new(me) # create a new mesh_object
863 activObjectName = ob.name
864 activObjectLayer = self.layer
865 #print ('deb:line.draw new line.ob+mesh:"%s" created!' %ob.name) #---------------------
867 faces, edges = [], []
870 #if settings.var['width_force']: #--todo-----------
873 t, e = thic, self.extrusion
874 #print 'deb:thic, extr: ', t, e #---------------------
875 points.extend([[v[0]+t*e[0], v[1]+t*e[1], v[2]+t*e[2]] for v in points[:]])
876 faces = [[0+n, 1+n, 3+n, 2+n]]
880 me.verts.extend(points) # adds vertices to global mesh
881 if faces: me.faces.extend(faces) # add faces to the mesh
882 if edges: me.edges.extend(edges) # add faces to the mesh
884 if settings.var['vGroup_on'] and not M_OBJ:
885 # entities with the same color build one vertexGroup for easier material assignment ----
886 ob.link(me) # link mesh to that object
887 vG_name = 'color_%s' %self.color_index
888 if edges: faces = edges
889 replace = Blender.Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD
891 me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
892 #print 'deb: existed vGroup:', vG_name #---------------------
894 me.addVertGroup(vG_name)
895 me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
896 #print 'deb: create new vGroup:', vG_name #---------------------
899 #print 'deb:draw:line.ob OUT activObjectName: ', activObjectName #---------------------
904 class Point: #-----------------------------------------------------------------
905 """Class for objects representing dxf POINTs.
907 def __init__(self, obj):
908 """Expects an entity object of type point as input.
910 if not obj.type == 'point':
911 raise TypeError, "Wrong type %s for point object!" %obj.type
913 # self.data = obj.data[:]
915 self.space = getit(obj, 67, 0)
916 self.thic = getit(obj, 39, 0)
917 #print 'deb:self.thic: ', self.thic #---------------------
918 self.color_index = getit(obj, 62, BYLAYER)
920 self.layer = getit(obj, 8, None)
921 self.extrusion = get_extrusion(obj)
922 self.points = self.get_points(obj)
925 def get_points(self, data):
926 """Gets coordinates for a point type object.
928 Points have fixed codes for each value.
931 a[0] = getit(data, 10, None) # 10 = x
932 a[1] = getit(data, 20, None) # 20 = y
933 a[2] = getit(data, 30, 0) # 30 = z
939 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
942 def draw(self, settings):
943 """for POINT: generate Blender_geometry.
946 obname = 'po_%s' %self.layer # create object name from layer name
947 obname = obname[:MAX_NAMELENGTH]
948 points_as = settings.var['points_as']
949 thic = settings.var['thick_min']
950 if thic < settings.var['dist_min']: thic = settings.var['dist_min']
952 if points_as in [1,3,4,5]:
953 if True: # points_as in [1,5]: # as 'empty'
955 elif points_as == 3: # as 'thin sphere'
956 res = settings.var['thin_res']
957 c = Mesh.Primitives.UVsphere(res,res,thic)
958 elif points_as == 4: # as 'thin box'
959 c = Mesh.Primitives.Cube(thic)
960 ob = SCENE.objects.new(c, obname) # create a new object
961 transform(self.extrusion, 0, ob)
962 ob.loc = tuple(points[0])
964 elif points_as == 2: # as 'vertex'
965 global activObjectLayer
966 global activObjectName
967 #print 'deb:draw:point.ob IN activObjectName: ', activObjectName #---------------------
968 if M_OBJ: obname, me, ob = makeNewObject()
970 if activObjectLayer == self.layer and settings.var['one_mesh_on']:
971 obname = activObjectName
972 #print 'deb:draw:point.ob obname from activObjectName: ', obname #---------------------
973 ob = getSceneChild(obname) # open an existing mesh_object
974 #ob = SCENE.getChildren(obname) # open an existing mesh_object
975 me = ob.getData(name_only=False, mesh=True)
976 #me = Mesh.Get(ob.name) # open objects mesh data
978 me = Mesh.New(obname) # create a new mesh
979 ob = SCENE.objects.new(me) # create a new mesh_object
980 activObjectName = ob.name
981 activObjectLayer = self.layer
982 #print ('deb:draw:point new point.ob+mesh:"%s" created!' %ob.name) #---------------------
983 me.verts.extend(points) # add vertices to mesh
989 class Polyline: #-----------------------------------------------------------------
990 """Class for objects representing dxf POLYLINEs.
992 def __init__(self, obj):
993 """Expects an entity object of type polyline as input.
995 #print 'deb:polyline.init.START:----------------' #------------------------
996 if not obj.type == 'polyline':
997 raise TypeError, "Wrong type %s for polyline object!" %obj.type
999 # self.data = obj.data[:]
1001 self.space = getit(obj, 67, 0)
1002 self.elevation = getit(obj, 30, 0)
1003 #print 'deb:elevation: ', self.elevation #---------------
1004 self.thic = getit(obj, 39, 0)
1005 self.color_index = getit(obj, 62, BYLAYER)
1007 self.flags = getit(obj, 70, 0)
1008 self.closed = self.flags & 1 # closed in the M direction
1009 self.curved = self.flags & 2 # Bezier-curve-fit vertices have been added
1010 self.spline = self.flags & 4 # NURBS-curve-fit vertices have been added
1011 self.poly3d = self.flags & 8 # 3D-polyline
1012 self.plmesh = self.flags & 16 # 3D-polygon mesh
1013 self.closeN = self.flags & 32 # closed in the N direction
1014 self.plface = self.flags & 64 # 3D-polyface mesh
1015 self.contin = self.flags & 128 # the linetype pattern is generated continuously
1017 self.pltype='poly2d' # default is a 2D-polyline
1018 if self.poly3d: self.pltype='poly3d'
1019 elif self.plface: self.pltype='plface'
1020 elif self.plmesh: self.pltype='plmesh'
1022 self.swidth = getit(obj, 40, 0) # default start width
1023 self.ewidth = getit(obj, 41, 0) # default end width
1024 #self.bulge = getit(obj, 42, None) # bulge of the segment
1025 self.vectorsM = getit(obj, 71, None) # PolyMesh: expansion in M-direction / PolyFace: number of the vertices
1026 self.vectorsN = getit(obj, 72, None) # PolyMesh: expansion in M-direction / PolyFace: number of faces
1027 #self.resolM = getit(obj, 73, None) # resolution of surface in M direction
1028 #self.resolN = getit(obj, 74, None) # resolution of surface in N direction
1029 self.curvNoFitted = False
1030 self.curvQuadrati = False
1031 self.curvCubicBsp = False
1032 self.curvBezier = False
1033 curvetype = getit(obj, 75, 0) # type of curve/surface: 0=None/5=Quadric/6=Cubic/8=Bezier
1034 if curvetype == 0: self.curvNoFitted = True
1035 elif curvetype == 5: self.curvQuadrati = True
1036 elif curvetype == 6: self.curvCubicBsp = True
1037 elif curvetype == 8: self.curvBezier = True
1039 self.layer = getit(obj, 8, None)
1040 self.extrusion = get_extrusion(obj)
1042 self.points = [] #list with vertices coordinats
1043 self.faces = [] #list with vertices assigment to faces
1044 #print 'deb:polyline.init.ENDinit:----------------' #------------
1049 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
1053 def doubles_out(self, settings, d_points):
1054 """routine to sort out of double.vertices-----------------------------
1056 minimal_dist = settings.var['dist_min'] * 0.1
1059 for i in xrange(len(d_points)-1):
1061 point2 = d_points[i+1]
1062 #print 'deb:double.vertex p1,p2', point, point2 #------------------------
1063 delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
1064 if delta.length > minimal_dist:
1065 temp_points.append(point)
1068 #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
1069 temp_points.append(d_points[-1]) #------ incl. last vertex -------------
1070 #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
1071 d_points = temp_points #-----vertex.list without "double.vertices"
1072 #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1076 def tribles_out(self, settings, d_points):
1077 """routine to sort out of three_in_place.vertices-----------------------------
1079 minimal_dist = settings.var['dist_min'] * 0.1
1082 for i in xrange(len(d_points)-2):
1083 point1 = d_points[i]
1084 point2 = d_points[i+1]
1085 point3 = d_points[i+2]
1086 #print 'deb:double.vertex p1,p2', point, point2 #------------------------
1087 delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
1088 delta23 = Mathutils.Vector(point3.loc) - Mathutils.Vector(point2.loc)
1089 if delta12.length < minimal_dist and delta23.length < minimal_dist:
1092 temp_points.append(point1)
1093 #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
1094 point1 = d_points[-2]
1095 point2 = d_points[-1]
1096 delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
1097 if delta12.length > minimal_dist:
1098 temp_points.append(d_points[-2]) #------ incl. 2last vertex -------------
1099 temp_points.append(d_points[-1]) #------ incl. 1last vertex -------------
1100 #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
1101 d_points = temp_points #-----vertex.list without "double.vertices"
1102 #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1106 def draw(self, settings): #-------------%%%% DRAW POLYLINE %%%---------------
1107 """for POLYLINE: generate Blender_geometry.
1109 #print 'deb:drawPOLYLINE.START:----------------' #------------------------
1110 #print 'deb:POLYLINEdraw self.pltype:', self.pltype #------------------------
1111 #print 'deb:POLYLINEdraw self.points:\n', self.points #------------------------
1113 #---- 3dPolyFace - mesh with free topology
1114 if self.pltype=='plface' and settings.drawTypes['plmesh']:
1115 ob = self.drawPlFace(settings)
1116 #---- 3dPolyMesh - mesh with ortogonal topology
1117 elif self.pltype=='plmesh' and settings.drawTypes['plmesh']:
1118 ob = self.drawPlMesh(settings)
1120 #---- 2dPolyline - plane polyline with arc/wide/thic segments
1121 elif self.pltype=='poly2d' and settings.drawTypes['polyline']:
1122 if settings.var['plines_as'] in [5,6]: # and self.spline:
1123 ob = self.drawPolyCurve(settings)
1125 ob = self.drawPoly2d(settings)
1127 #---- 3dPolyline - non-plane polyline (thin segments = without arc/wide/thic)
1128 elif self.pltype=='poly3d' and settings.drawTypes['pline3']:
1129 if settings.var['plines3_as'] in [5,6]: # and self.spline:
1130 ob = self.drawPolyCurve(settings)
1132 ob = self.drawPoly2d(settings)
1134 #---- Spline - curved polyline (thin segments = without arc/wide/thic)
1135 elif self.pltype=='spline' and settings.drawTypes['spline']:
1136 if settings.var['splines_as'] in [5,6]:
1137 ob = self.drawPolyCurve(settings)
1139 ob = self.drawPoly2d(settings)
1143 def drawPlFace(self, settings): #---- 3dPolyFace - mesh with free topology
1144 """Generate the geometery of polyface.
1146 #print 'deb:drawPlFace.START:----------------' #------------------------
1149 #print 'deb:len of pointsList ====== ', len(self.points) #------------------------
1150 for point in self.points:
1152 faces.append(point.face)
1154 points.append(point.loc)
1156 if settings.var['plmesh_flip']: # ----------------------
1159 face = [face[-1]] + face[:-1]
1161 #print 'deb:drawPlFace: len of points_list:\n', len(points) #-----------------------
1162 #print 'deb:drawPlFace: len of faces_list:\n', len(faces) #-----------------------
1163 #print 'deb:drawPlFace: points_list:\n', points #-----------------------
1164 #print 'deb:drawPlFace: faces_list:\n', faces #-----------------------
1165 obname = 'pf_%s' %self.layer # create object name from layer name
1166 obname = obname[:MAX_NAMELENGTH]
1167 me = Mesh.New(obname) # create a new mesh
1168 ob = SCENE.objects.new(me) # create a new mesh_object
1169 me.verts.extend(points) # add vertices to mesh
1170 me.faces.extend(faces) # add faces to the mesh
1171 if settings.var['normals_out']: # ----------------------
1175 #print 'deb:drawPlFace: len of me.faces:\n', len(me.faces) #-----------------------
1177 if settings.var['meshSmooth_on']: # ----------------------
1178 for i in xrange(len(me.faces)):
1179 me.faces[i].smooth = True
1180 #me.Mode(AUTOSMOOTH)
1181 transform(self.extrusion, 0, ob)
1182 #print 'deb:drawPlFace.END:----------------' #------------------------
1187 def drawPlMesh(self, settings): #---- 3dPolyMesh - mesh with orthogonal topology
1188 """Generate the geometery of polymesh.
1190 #print 'deb:polymesh.draw.START:----------------' #------------------------
1192 #print 'deb:len of pointsList ====== ', len(self.points) #------------------------
1196 for j in xrange(m - 1):
1197 for i in xrange(n - 1):
1199 faces.append([nn+i, nn+i+1, nn+n+i+1, nn+n+i])
1201 if self.closed: #mesh closed in N-direction
1203 for i in xrange(n - 1):
1204 faces.append([nn+i, nn+i+1, i+1, i])
1206 if self.closeN: #mesh closed in M-direction
1207 for j in xrange(m-1):
1209 faces.append([nn+n-1, nn, nn+n, nn+n-1+n])
1211 if self.closed and self.closeN: #mesh closed in M/N-direction
1212 faces.append([ (n*m)-1, (m-1)*n, 0, n-1])
1214 #print 'deb:len of points_list:\n', len(points) #-----------------------
1215 #print 'deb:faces_list:\n', faces #-----------------------
1216 obname = 'pm_%s' %self.layer # create object name from layer name
1217 obname = obname[:MAX_NAMELENGTH]
1218 me = Mesh.New(obname) # create a new mesh
1219 ob = SCENE.objects.new(me) # create a new mesh_object
1220 me.verts.extend([point.loc for point in self.points]) # add vertices to mesh
1221 me.faces.extend(faces) # add faces to the mesh
1222 if settings.var['normals_out']: # ----------------------
1226 if settings.var['meshSmooth_on']: # ----------------------
1227 for i in xrange(len(faces)):
1228 me.faces[i].smooth = True
1229 #me.Mode(AUTOSMOOTH)
1231 transform(self.extrusion, 0, ob)
1232 #print 'deb:polymesh.draw.END:----------------' #------------------------
1236 def drawPolyCurve(self, settings): #---- Polyline - draw as Blender-curve
1237 """Generate the geometery of polyline as Blender-curve.
1239 #print 'deb:polyline2dCurve.draw.START:----------------' #---
1240 if len(self.points) < 2:
1241 #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
1244 if self.spline: pline_typ = 'ps' # Polyline-NURBSpline
1245 elif self.curved: pline_typ = 'pc' # Polyline-BezierCurve
1246 else: pline_typ = 'pl' # Polyline classic
1247 obname = '%s_%s' %(pline_typ, self.layer) # create object_name from layer name
1248 obname = obname[:MAX_NAMELENGTH]
1251 if settings.var['Z_force_on']:
1252 self.elevation = settings.var['Z_elev']
1253 for point in self.points:
1254 point.loc[2] = self.elevation
1255 d_points.append(point)
1256 else: #for DXFr10-format: update all points[].loc[2] == None -> 0.0
1257 for point in self.points:
1258 if point.loc[2] == None:
1259 point.loc[2] = self.elevation
1260 d_points.append(point)
1262 #d_points = self.tribles_out(settings, d_points)
1263 #d_points = self.doubles_out(settings, d_points)
1264 #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1266 thic = set_thick(self.thic, settings)
1267 if thic != 0.0: #hack: Blender<2.45 curve-extrusion
1268 LocZ = d_points[0].loc[2]
1270 for point in d_points:
1272 temp_points.append(point)
1273 d_points = temp_points
1275 #print 'deb:polyline2dCurve.draw d_points=', d_points #---------------
1276 pline = Curve.New(obname) # create new curve data
1277 #pline.setResolu(24) #--todo-----
1279 if False: #old self.spline: # NURBSplines-----OK-----
1280 #print 'deb:polyline2dCurve.draw self.spline!' #---------------
1283 if self.curvQuadrati:
1284 # Bezier-curve form simulated in NURBS-curve
1285 # generate middlepoints except start/end-segments ---
1286 #print 'deb:polyline2dCurve.draw extraQBspline!' #---------------
1288 point = d_points[0].loc
1289 point.append(weight1)
1290 temp_points.append(point)
1291 for i in xrange(1,len(d_points)-2):
1292 point1 = d_points[i].loc
1293 point2 = d_points[i+1].loc
1294 mpoint = list((Mathutils.Vector(point1) + Mathutils.Vector(point2)) * 0.5)
1295 mpoint.append(weight2)
1296 point1.append(weight1)
1297 temp_points.append(point1)
1298 temp_points.append(mpoint)
1299 point2.append(weight1)
1300 temp_points.append(point2)
1301 point = d_points[-1].loc
1302 point.append(weight1)
1303 temp_points.append(point)
1304 d_points = temp_points
1310 temp_points.append(d)
1311 d_points = temp_points
1314 # generate extended startpoint and endpoint------
1315 point1 = Mathutils.Vector(d_points[0][:3])
1316 point2 = Mathutils.Vector(d_points[1][:3])
1317 startpoint = list(point1 - point2 + point1)
1318 startpoint.append(weight1)
1319 point1 = Mathutils.Vector(d_points[-1][:3])
1320 point2 = Mathutils.Vector(d_points[-2][:3])
1321 endpoint = list(point1 - point2 + point1)
1322 endpoint.append(weight1)
1324 temp_points.append(startpoint)
1325 temp_points.extend(d_points)
1326 d_points = temp_points
1327 d_points.append(endpoint)
1330 curve = pline.appendNurb(point)
1331 curve.setType(4) #NURBS curve
1332 for point in d_points[1:]:
1335 curve.flagU = 1 # Set curve cyclic=close
1337 curve.flagU = 0 # Set curve not cyclic=open
1339 if self.spline: # NURBSplines-----OK-----
1340 #print 'deb:polyline2dCurve.draw self.spline!' #---------------
1344 pkt.append(d.weight)
1345 nurbs_points.append(pkt)
1346 firstpoint = nurbs_points[0]
1347 curve = pline.appendNurb(firstpoint)
1348 curve.setType(4) # set curve_type NURBS
1349 print 'deb: dir(curve):', dir(curve[-1]) #----------------
1350 for point in nurbs_points[1:]:
1352 #TODO: what is the trick for bevel radius? curve[-1].radius = 1.0
1354 curve.flagU = 1+0 # Set curve cyclic=close and uni
1356 curve.flagU = 0+2 # Set curve not cyclic=open
1357 try: curve.orderU = 5 # works only with >2.46svn080625
1358 except AttributeError: pass
1359 #print 'deb: dir(curve):', dir(curve) #----------------
1361 elif False: #orig self.curved: #--Bezier-curves---OK-------
1362 #print 'deb:polyline2dCurve.draw self.curved!' #---------------
1363 curve = pline.appendNurb(BezTriple.New(d_points[0]))
1364 for p in d_points[1:]:
1365 curve.append(BezTriple.New(p))
1367 point.handleTypes = [AUTO, AUTO]
1370 curve.flagU = 1 # Set curve cyclic=close
1372 curve.flagU = 0 # Set curve not cyclic=open
1373 curve[0].handleTypes = [FREE, ALIGN] #remi--todo-----
1374 curve[-1].handleTypes = [ALIGN, FREE] #remi--todo-----
1376 elif self.curved: #--SPLINE as Bezier-curves---wip------
1377 #print 'deb:polyline2dCurve.draw self.curved!' #---------------
1378 begtangent, endtangent = None, None
1379 if d_points[0].tangent:
1380 begtangent = d_points[0]
1381 d_points = d_points[1:]
1382 if d_points[-1].tangent:
1383 endtangent = d_points[-1]
1384 d_points = d_points[:-1]
1385 curve = pline.appendNurb(BezTriple.New(d_points[0]))
1386 for p in d_points[1:]:
1387 curve.append(BezTriple.New(p))
1389 point.handleTypes = [AUTO, AUTO]
1391 #curve.setType(1) #Bezier curve
1393 curve.flagU = 5 #1 # Set curve cyclic=close
1395 curve.flagU = 4 #0 # Set curve not cyclic=open
1397 #print 'deb:polyline2dCurve.draw curve[0].vec:', curve[0].vec #-----
1398 #print 'deb:polyline2dCurve.draw begtangent:', begtangent #-----
1399 p0h1,p0,p0h2 = curve[0].vec
1400 p0h1 = [p0h1[i]+begtangent[i] for i in range(3)]
1401 curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
1402 curve[0].handleTypes = [FREE, ALIGN] #remi--todo-----
1403 curve[0].radius = 1.0
1405 #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
1406 #print 'deb:polyline2dCurve.draw endtangent:', endtangent #-----
1407 p0h1,p0,p0h2 = curve[-1].vec
1408 p0h2 = [p0h2[i]+endtangent[i] for i in range(3)]
1409 #print 'deb:drawPlineCurve: p0h2:', p0h2 #----------
1410 curve.__setitem__(-1,BezTriple.New(p0h1+p0+p0h2))
1411 #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
1412 curve[-1].handleTypes = [ALIGN, FREE] #remi--todo-----
1413 curve[-1].radius = 1.0
1417 else: #-- only straight line- and arc-segments----OK------
1418 #print 'deb:polyline2dCurve.draw curve:', curve #-----
1420 arc_res = settings.var['curve_arc']
1421 prevHandleType = VECT
1422 #d_points.append(d_points[0]) #------ first vertex added at the end of list --------
1423 #curve.setType(0) #polygon_type of Blender_curve
1424 for i in xrange(len(d_points)):
1425 point1 = d_points[i]
1426 #point2 = d_points[i+1]
1427 if False: #-----outdated!- standard calculation ----------------------------------
1428 if point1.bulge and (i < len(d_points)-2 or self.closed):
1429 verts, center = calcBulge(point1, point2, arc_res, triples=False)
1430 if i == 0: curve = pline.appendNurb(BezTriple.New(verts[0]))
1431 else: curve.append(BezTriple.New(verts[0]))
1432 curve[-1].handleTypes = [VECT, VECT] #--todo--calculation of bezier-tangents
1433 curve[-1].radius = 1.0
1435 curve.append(BezTriple.New(p))
1436 curve[-1].handleTypes = [AUTO, AUTO]
1437 curve[-1].radius = 1.0
1439 if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
1440 else: curve.append(BezTriple.New(point1.loc))
1441 curve[-1].handleTypes = [VECT, VECT] #--todo--calculation of bezier-tangents
1442 curve[-1].radius = 1.0
1444 elif True: #----- optimised Bezier-Handles calculation --------------------------------
1445 #print 'deb:drawPlineCurve: i:', i #---------
1446 if point1.bulge and not (i == len(d_points)-1 and point1.bulge and not self.closed):
1447 if i == len(d_points)-1: point2 = d_points[0]
1448 else: point2 = d_points[i+1]
1451 # calculate additional points for bulge
1452 VectorTriples = calcBulge(point1, point2, arc_res, triples=True)
1454 if prevHandleType == FREE:
1455 #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
1456 VectorTriples[0][:3] = prevHandleVect
1457 #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
1459 if i == 0: curve = pline.appendNurb(BezTriple.New(VectorTriples[0]))
1460 else: curve.append(BezTriple.New(VectorTriples[0]))
1461 curve[-1].handleTypes = [prevHandleType, FREE]
1462 curve[-1].radius = 1.0
1464 for p in VectorTriples[1:-1]:
1465 curve.append(BezTriple.New(p))
1466 curve[-1].handleTypes = [FREE, FREE]
1467 curve[-1].radius = 1.0
1469 prevHandleVect = VectorTriples[-1][:3]
1470 prevHandleType = FREE
1471 #print 'deb:drawPlineCurve: prevHandleVect:', prevHandleVect #---------
1473 #print 'deb:drawPlineCurve: else' #----------
1474 if prevHandleType == FREE:
1475 VectorTriples = prevHandleVect + list(point1) + list(point1)
1476 #print 'deb:drawPlineCurve: VectorTriples:', VectorTriples #---------
1477 curve.append(BezTriple.New(VectorTriples))
1478 curve[-1].handleTypes = [FREE, VECT]
1479 prevHandleType = VECT
1480 curve[-1].radius = 1.0
1482 if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
1483 else: curve.append(BezTriple.New(point1.loc))
1484 curve[-1].handleTypes = [VECT, VECT]
1485 curve[-1].radius = 1.0
1489 #print 'deb:drawPlineCurve: curve[-1].vec[0]', curve[-1].vec[0] #----------
1492 curve.flagU = 1 # Set curve cyclic=close
1493 if prevHandleType == FREE:
1494 #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
1495 #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
1496 prevHandleType2 = curve[0].handleTypes[1]
1497 p0h1,p0,p0h2 = curve[0].vec
1498 #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
1499 p0h1 = prevHandleVect
1501 #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
1502 #curve[0].vec = [p0h1,p0,p0h2]
1503 curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
1505 curve[0].handleTypes = [FREE,prevHandleType2]
1506 curve[0].radius = 1.0
1507 #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
1508 #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
1510 curve[0].handleTypes[0] = VECT
1511 curve[0].radius = 1.0
1513 curve.flagU = 0 # Set curve not cyclic=open
1515 if settings.var['fill_on']:
1516 pline.setFlag(6) # 2+4 set top and button caps
1518 pline.setFlag(pline.getFlag() & ~6) # dont set top and button caps
1520 pline.setResolu(settings.var['curve_res'])
1522 ob = SCENE.objects.new(pline) # create a new curve_object
1524 if thic != 0.0: #hack: Blender<2.45 curve-extrusion
1526 pline.setExt1(1.0) # curve-extrusion accepts only (0.0 - 2.0)
1527 ob.LocZ = thic + LocZ
1529 transform(self.extrusion, 0, ob)
1531 ob.SizeZ *= abs(thic)
1533 #print 'deb:polyline2dCurve.draw.END:----------------' #-----
1537 def drawPoly2d(self, settings): #---- 2dPolyline - plane lines/arcs with wide/thic
1538 """Generate the geometery of regular polyline.
1540 #print 'deb:polyline2d.draw.START:----------------' #------------------------
1545 swidth_default = self.swidth #default start width of POLYLINEs segments
1546 ewidth_default = self.ewidth #default end width of POLYLINEs segments
1547 #print 'deb:drawPoly2d self.swidth=', self.swidth #------------------------
1548 thic = set_thick(self.thic, settings)
1549 if self.spline: pline_typ = 'ps'
1550 elif self.curved: pline_typ = 'pc'
1551 else: pline_typ = 'pl'
1552 obname = '%s_%s' %(pline_typ, self.layer) # create object_name from layer name
1553 obname = obname[:MAX_NAMELENGTH]
1555 if len(self.points) < 2:
1556 #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
1559 if settings.var['Z_force_on']:
1560 self.elevation = settings.var['Z_elev']
1561 for point in self.points:
1562 point.loc[2] = self.elevation
1563 d_points.append(point)
1564 else: #for DXFr10-format: update all non-existing LocZ points[].loc[2] == None -> 0.0 elevation
1565 for point in self.points:
1566 if point.loc[2] == None:
1567 point.loc[2] = self.elevation
1568 d_points.append(point)
1569 #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1570 #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
1573 #if closed polyline, add duplic of the first vertex at the end of pointslist
1574 if self.closed: #new_b8
1575 if d_points[-1].loc != d_points[0].loc: # if not equal, then set the first at the end of pointslist
1576 d_points.append(d_points[0])
1578 if d_points[-1].loc == d_points[0].loc: # if equal, then set to closed, and modify the last point
1579 d_points[-1] = d_points[0]
1581 #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1582 #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
1584 d_points = self.doubles_out(settings, d_points)
1585 #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1587 """# routine to sort out of "double.vertices" ------------------------------------
1588 minimal_dist = settings.var['dist_min'] * 0.1
1590 for i in xrange(len(d_points)-1):
1592 point2 = d_points[i+1]
1593 #print 'deb:double.vertex p1,p2', point, point2 #------------------------
1594 delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
1595 if delta.length > minimal_dist:
1596 temp_points.append(point)
1597 #else: print 'deb:drawPoly2d double.vertex sort out!' #------------------------
1598 temp_points.append(d_points[-1]) #------ incl. last vertex -------------
1599 #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
1600 d_points = temp_points #-----vertex.list without "double.vertices"
1601 #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1604 #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1605 if len(d_points) < 2: #if too few vertex, then return
1606 #print 'deb:drawPoly2d corrupted Vertices' #---------
1609 # analyze of straight- and bulge-segments
1610 # generation of additional points for bulge segments
1611 arc_res = settings.var['arc_res']/sqrt(settings.var['arc_rad'])
1612 wide_segment_exist = False
1613 bulg_points = [] # for each point set None (or center for arc-subPoints)
1614 for i in xrange(len(d_points)-1):
1615 point1 = d_points[i]
1616 point2 = d_points[i+1]
1617 #print 'deb:drawPoly2d_bulg tocalc.point1:', point1 #------------------------
1618 #print 'deb:drawPoly2d_bulg tocalc.point2:', point2 #------------------------
1620 swidth = point1.swidth
1621 ewidth = point1.ewidth
1622 #print 'deb:drawPoly2d point1.swidth=', swidth #------------------------
1623 if swidth == None: swidth = swidth_default
1624 if ewidth == None: ewidth = ewidth_default
1625 if swidth != 0.0 or ewidth != 0.0: wide_segment_exist = True
1626 #print 'deb:drawPoly2d vertex_swidth=', swidth #------------------------
1628 if settings.var['width_force']: # force minimal width for thin segments
1629 width_min = settings.var['width_min']
1630 if swidth < width_min: swidth = width_min
1631 if ewidth < width_min: ewidth = width_min
1632 if not settings.var['width_on']: # then force minimal width for all segments
1636 #if point1.bulge and (i < (len(d_points)-1) or self.closed):
1637 if point1.bulge and i < (len(d_points)-1): #10_b8
1638 verts, center = calcBulge(point1, point2, arc_res) #calculate additional points for bulge
1639 points.extend(verts)
1640 delta_width = (ewidth - swidth) / len(verts)
1641 width_list = [swidth + (delta_width * ii) for ii in xrange(len(verts)+1)]
1642 swidths.extend(width_list[:-1])
1643 ewidths.extend(width_list[1:])
1644 bulg_list = [center for ii in xrange(len(verts))]
1645 #the last point in bulge has index False for better indexing of bulg_end!
1646 bulg_list[-1] = None
1647 bulg_points.extend(bulg_list)
1650 points.append(point1.loc)
1651 swidths.append(swidth)
1652 ewidths.append(ewidth)
1653 bulg_points.append(None)
1654 points.append(d_points[-1].loc)
1657 #--calculate width_vectors: left-side- and right-side-points ----------------
1658 # 1.level:IF width ---------------------------------------
1659 if (settings.var['width_on'] and wide_segment_exist) or settings.var['width_force']:
1660 #new_b8 points.append(d_points[0].loc) #temporarly add first vertex at the end (for better loop)
1661 dist_min05 = 0.5 * settings.var['dist_min'] #minimal width for zero_witdh
1663 pointsLs = [] # list of left-start-points
1664 pointsLe = [] # list of left-end-points
1665 pointsRs = [] # list of right-start-points
1666 pointsRe = [] # list of right-end-points
1667 pointsW = [] # list of all border-points
1668 #rotMatr90 = Mathutils.Matrix(rotate 90 degree around Z-axis) = normalvectorXY
1669 rotMatr90 = Mathutils.Matrix([0, -1, 0], [1, 0, 0], [0, 0, 1])
1671 last_bulg_point = False
1672 for i in xrange(len(points)-1):
1674 point2 = points[i+1]
1675 point1vec = Mathutils.Vector(point1)
1676 point2vec = Mathutils.Vector(point2)
1677 swidth05 = swidths[i] * 0.5
1678 ewidth05 = ewidths[i] * 0.5
1679 if swidth05 == 0: swidth05 = dist_min05
1680 if ewidth05 == 0: ewidth05 = dist_min05
1681 normal_vector = rotMatr90 * (point2vec-point1vec).normalize()
1683 last_bulg_point = False
1685 elif bulg_points[i] != None:
1686 centerVec = Mathutils.Vector(bulg_points[i])
1687 if bulg_points[i+1] == None: last_bulg_point = True
1689 else: bulg_in = False
1692 #makes clean intersections for arc-segments
1693 radius1vec = point1vec - centerVec
1694 radius2vec = point2vec - centerVec
1695 angle = Mathutils.AngleBetweenVecs(normal_vector, radius1vec)
1697 normal_vector1 = radius1vec.normalize()
1698 normal_vector2 = radius2vec.normalize()
1700 normal_vector1 = - radius1vec.normalize()
1701 normal_vector2 = - radius2vec.normalize()
1703 swidth05vec = swidth05 * normal_vector1
1704 ewidth05vec = ewidth05 * normal_vector2
1705 pointsLs.append(point1vec + swidth05vec) #vertex left start
1706 pointsRs.append(point1vec - swidth05vec) #vertex right start
1707 pointsLe.append(point2vec + ewidth05vec) #vertex left end
1708 pointsRe.append(point2vec - ewidth05vec) #vertex right end
1711 swidth05vec = swidth05 * normal_vector
1712 ewidth05vec = ewidth05 * normal_vector
1713 pointsLs.append(point1vec + swidth05vec) #vertex left start
1714 pointsRs.append(point1vec - swidth05vec) #vertex right start
1715 pointsLe.append(point2vec + ewidth05vec) #vertex left end
1716 pointsRe.append(point2vec - ewidth05vec) #vertex right end
1718 # additional last point is also calculated
1719 #pointsLs.append(pointsLs[0])
1720 #pointsRs.append(pointsRs[0])
1721 #pointsLe.append(pointsLe[0])
1722 #pointsRe.append(pointsRe[0])
1724 pointsLc, pointsRc = [], [] # lists Left/Right corners = intersection points
1726 # 2.level:IF width and corner-trim
1727 if settings.var['pl_trim_on']: #optional clean corner-intersections
1729 # set STARTpoints of the first point points[0]
1731 pointsLc.append(pointsLs[0])
1732 pointsRc.append(pointsRs[0])
1734 pointsLs.append(pointsLs[0])
1735 pointsRs.append(pointsRs[0])
1736 pointsLe.append(pointsLe[0])
1737 pointsRe.append(pointsRe[0])
1738 points.append(points[0])
1739 vecL3, vecL4 = pointsLs[0], pointsLe[0]
1740 vecR3, vecR4 = pointsRs[0], pointsRe[0]
1741 lenL = len(pointsLs)-1
1742 #print 'deb:drawPoly2d pointsLs():\n', pointsLs #----------------
1743 #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs) #----------------
1745 last_bulg_point = False
1747 # LOOP: makes (ENDpoints[i],STARTpoints[i+1])
1748 for i in xrange(lenL):
1749 if bulg_points[i] != None:
1750 if bulg_points[i+1] == None: #makes clean intersections for arc-segments
1751 last_bulg_point = True
1754 #pointsLc.extend((points[i], pointsLs[i]))
1755 #pointsRc.extend((points[i], pointsRs[i]))
1756 vecL1, vecL2 = vecL3, vecL4
1757 vecR1, vecR2 = vecR3, vecR4
1758 vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
1759 vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
1760 #compute left- and right-cornerpoints
1761 #cornerpointL = Geometry.LineIntersect2D(vec1, vec2, vec3, vec4)
1762 cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
1763 cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
1764 #print 'deb:drawPoly2d cornerpointL: ', cornerpointL #-------------
1765 #print 'deb:drawPoly2d cornerpointR: ', cornerpointR #-------------
1767 # IF not cornerpoint THEN check if identic start-endpoints (=collinear segments)
1768 if cornerpointL == None or cornerpointR == None:
1769 if vecL2 == vecL3 and vecR2 == vecR3:
1770 #print 'deb:drawPoly2d pointVec: ####### identic ##########' #----------------
1771 pointsLc.append(pointsLe[i])
1772 pointsRc.append(pointsRe[i])
1774 pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1775 pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1777 cornerpointL = cornerpointL[0] # because Mathutils.LineIntersect() -> (pkt1,pkt2)
1778 cornerpointR = cornerpointR[0]
1779 #print 'deb:drawPoly2d cornerpointL: ', cornerpointL #-------------
1780 #print 'deb:drawPoly2d cornerpointR: ', cornerpointR #-------------
1781 pointVec0 = Mathutils.Vector(points[i])
1782 pointVec = Mathutils.Vector(points[i+1])
1783 pointVec2 = Mathutils.Vector(points[i+2])
1784 #print 'deb:drawPoly2d pointVec0: ', pointVec0 #-------------
1785 #print 'deb:drawPoly2d pointVec: ', pointVec #-------------
1786 #print 'deb:drawPoly2d pointVec2: ', pointVec2 #-------------
1787 # if diststance(cornerL-center-cornerR) < limiter * (seg1_endWidth + seg2_startWidth)
1788 max_cornerDist = (vecL2 - vecR2).length + (vecL3 - vecR3).length
1789 is_cornerDist = (cornerpointL - pointVec).length + (cornerpointR - pointVec).length
1790 #corner_angle = Mathutils.AngleBetweenVecs((pointVec0 - pointVec),(pointVec - pointVec2))
1791 #print 'deb:drawPoly2d corner_angle: ', corner_angle #-------------
1792 #print 'deb:drawPoly2d max_cornerDist, is_cornerDist: ', max_cornerDist, is_cornerDist #-------------
1793 #if abs(corner_angle) < 90.0:
1794 # intersection --------- limited by TRIM_LIMIT (1.0 - 5.0)
1795 if is_cornerDist < max_cornerDist * settings.var['pl_trim_max']:
1796 # clean corner intersection
1797 pointsLc.append(cornerpointL)
1798 pointsRc.append(cornerpointR)
1799 elif False: # the standard no-intersection
1800 # --todo-- not optimal, because produces X-face
1801 pointsLc.extend((pointsLe[i],pointsLs[i+1]))
1802 pointsRc.extend((pointsRe[i],pointsRs[i+1]))
1803 elif False: # --todo-- the optimised non-intersection
1804 if (cornerpointL - vecL1).length < (cornerpointR - vecR1).length:
1808 limit_dist = settings.var['dist_min']
1809 if left_angle: # if left turning angle
1810 #print 'deb:drawPoly2d it is left turning angle' #-------------
1811 # to avoid triangelface/doubleVertex
1812 delta1 = (cornerpointL - vecL1).normalize() * limit_dist
1813 delta4 = (cornerpointL - vecL4).normalize() * limit_dist
1814 pointsLc.extend((cornerpointL - delta1, cornerpointL - delta4))
1815 pointsRc.extend((pointsRe[i],pointsRs[i+1]))
1816 else: # if right turning angle
1817 #print 'deb:drawPoly2d right turning angle' #-------------
1818 delta1 = (cornerpointR - vecR1).normalize() * limit_dist
1819 delta4 = (cornerpointR - vecR4).normalize() * limit_dist
1820 pointsRc.extend((cornerpointR - delta1, cornerpointR - delta4))
1821 pointsLc.extend((pointsLe[i],pointsLs[i+1]))
1823 pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1824 pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1826 pointsLc.append(pointsLe[-1])
1827 pointsRc.append(pointsRe[-1])
1829 # 2.level:IF width but no-trim
1832 # set STARTpoints of the first point points[0]
1834 pointsLc.append(pointsLs[0])
1835 pointsRc.append(pointsRs[0])
1837 pointsLs.append(pointsLs[0])
1838 pointsRs.append(pointsRs[0])
1839 pointsLe.append(pointsLe[0])
1840 pointsRe.append(pointsRe[0])
1841 points.append(points[0])
1842 vecL3, vecL4 = pointsLs[0], pointsLe[0]
1843 vecR3, vecR4 = pointsRs[0], pointsRe[0]
1844 lenL = len(pointsLs)-1
1845 #print 'deb:drawPoly2d pointsLs():\n', pointsLs #----------------
1846 #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs) #----------------
1848 last_bulg_point = False
1850 # LOOP: makes (ENDpoints[i],STARTpoints[i+1])
1851 for i in xrange(lenL):
1852 vecL1, vecL2 = vecL3, vecL4
1853 vecR1, vecR2 = vecR3, vecR4
1854 vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
1855 vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
1856 if bulg_points[i] != None:
1857 #compute left- and right-cornerpoints
1859 cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
1860 cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
1861 pointsLc.append(cornerpointL[0])
1862 pointsRc.append(cornerpointR[0])
1864 pointVec = Mathutils.Vector(point[i])
1867 pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1868 pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1870 pointsLc.append(pointsLe[-1])
1871 pointsRc.append(pointsRe[-1])
1873 len1 = len(pointsLc)
1874 #print 'deb:drawPoly2d len1:', len1 #-----------------------
1875 #print 'deb:drawPoly2d len1 len(pointsLc),len(pointsRc):', len(pointsLc),len(pointsRc) #-----------------------
1876 pointsW = pointsLc + pointsRc # all_points_List = left_side + right_side
1877 #print 'deb:drawPoly2d pointsW():\n', pointsW #----------------
1879 # 2.level:IF width and thickness ---------------------
1882 thic_pointsW.extend([[point[0], point[1], point[2]+thic] for point in pointsW])
1884 thic_pointsW.extend(pointsW)
1885 pointsW = thic_pointsW
1887 pointsW.extend(thic_pointsW)
1889 f_start, f_end = [], []
1890 f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
1891 f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
1892 f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
1893 f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
1896 f_bottom.append([len1-1, 0, len1, len1+len1-1]) #bottom face
1897 f_top.append( [len1+len1+len1-1, len1+len1+len1+len1-1, len1+len1+len1, len1+len1+0]) #top face
1898 f_left.append( [0, len1-1, len1+len1+len1-1, len1+len1]) #left face
1899 f_right.append( [len1, len1+len1+len1, len1+len1+len1+len1-1, len1+len1-1]) #right face
1901 f_start = [[0, len1, len1+len1+len1, len1+len1]]
1902 f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
1904 faces = f_left + f_right + f_bottom + f_top + f_start + f_end
1905 #faces = f_bottom + f_top
1906 #faces = f_left + f_right + f_start + f_end
1907 #print 'deb:faces_list:\n', faces #-----------------------
1908 if M_OBJ: obname, me, ob = makeNewObject()
1910 me = Mesh.New(obname) # create a new mesh
1911 ob = SCENE.objects.new(me) # create a new mesh_object
1912 me.verts.extend(pointsW) # add vertices to mesh
1913 me.faces.extend(faces) # add faces to the mesh
1915 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
1916 # The mesh must first be linked to an object so the method knows which object to update.
1917 # This is because vertex groups in Blender are stored in the object -- not in the mesh,
1918 # which may be linked to more than one object.
1919 if settings.var['vGroup_on'] and not M_OBJ:
1920 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
1921 replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD
1922 vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
1923 for v in f_left: vg_left.extend(v)
1924 for v in f_right: vg_right.extend(v)
1925 for v in f_top: vg_top.extend(v)
1926 for v in f_bottom: vg_bottom.extend(v)
1927 me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', list(set(vg_left)), 1.0, replace)
1928 me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
1929 me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
1930 me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
1932 me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
1933 me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace)
1935 if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
1936 #if self.spline or self.curved:
1938 smooth_len = len(f_left) + len(f_right)
1939 for i in xrange(smooth_len):
1940 me.faces[i].smooth = True
1941 #me.Modes(AUTOSMOOTH)
1943 # 2.level:IF width, but no-thickness ---------------------
1946 faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
1948 faces.append([len1, 0, len1-1, len1+len1-1])
1949 if M_OBJ: obname, me, ob = makeNewObject()
1951 me = Mesh.New(obname) # create a new mesh
1952 ob = SCENE.objects.new(me) # create a new mesh_object
1953 me.verts.extend(pointsW) # add vertices to mesh
1954 me.faces.extend(faces) # add faces to the mesh
1957 # 1.level:IF no-width, but thickness ---------------------
1961 thic_points.extend([[point[0], point[1], point[2]+thic] for point in points])
1963 thic_points.extend(points)
1964 points = thic_points
1966 points.extend(thic_points)
1968 faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
1970 faces.append([len1-1, 0, len1, 2*len1-1])
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.faces.extend(faces) # add faces to the mesh
1978 if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
1979 #if self.spline or self.curved:
1981 for i in xrange(len(faces)):
1982 me.faces[i].smooth = True
1983 #me.Modes(AUTOSMOOTH)
1985 # 1.level:IF no-width and no-thickness ---------------------
1987 edges = [[num, num+1] for num in xrange(len(points)-1)]
1989 edges.append([len(points)-1, 0])
1990 if M_OBJ: obname, me, ob = makeNewObject()
1992 me = Mesh.New(obname) # create a new mesh
1993 ob = SCENE.objects.new(me) # create a new mesh_object
1994 me.verts.extend(points) # add vertices to mesh
1995 me.edges.extend(edges) # add edges to the mesh
1997 transform(self.extrusion, 0, ob)
1998 #print 'deb:polyline.draw.END:----------------' #-----------------------
2004 class Vertex(object): #-----------------------------------------------------------------
2005 """Generic vertex object used by POLYLINEs, (and maybe others).
2006 also used by class_LWPOLYLINEs but without obj-parameter
2009 def __init__(self, obj=None):
2010 """Initializes vertex data.
2012 The optional obj arg is an entity object of type vertex.
2014 #print 'deb:Vertex.init.START:----------------' #-----------------------
2017 self.swidth = None #0
2018 self.ewidth = None #0
2020 self.tangent = False
2023 if not obj.type == 'vertex':
2024 raise TypeError, "Wrong type %s for vertex object!" %obj.type
2025 self.type = obj.type
2026 # self.data = obj.data[:]
2030 #print 'deb:Vertex.init.END:----------------' #------------------------
2033 def get_props(self, data):
2034 """Gets coords for a VERTEX type object.
2036 Each vert can have a number of properties.
2037 Verts should be coded as
2044 self.x = getit(data, 10, None)
2045 self.y = getit(data, 20, None)
2046 self.z = getit(data, 30, None)
2048 self.flags = getit(data, 70, 0) # flags
2049 self.curved = self.flags&1 # Bezier-curve-fit:additional-vertex
2050 self.curved_t = self.flags&2 # Bezier-curve-fit:tangent exists
2051 self.spline = self.flags&8 # NURBSpline-fit:additional-vertex
2052 self.spline_c = self.flags&16 # NURBSpline-fit:control-vertex
2053 self.poly3d = self.flags&32 # polyline3d:control-vertex
2054 self.plmesh = self.flags&64 # polymesh3d:control-vertex
2055 self.plface = self.flags&128 # polyface
2057 # if PolyFace.Vertex with Face_definition
2059 self.curve_tangent = getit(data, 50, None) # curve_tangent
2060 if not self.curve_tangent==None:
2062 #elif self.spline_c: # NURBSpline:control-vertex
2063 # self.weight = getit(data, 41, 1.0) # weight od control point
2065 elif self.plface and not self.plmesh:
2066 v1 = getit(data, 71, 0) # polyface:Face.vertex 1.
2067 v2 = getit(data, 72, 0) # polyface:Face.vertex 2.
2068 v3 = getit(data, 73, 0) # polyface:Face.vertex 3.
2069 v4 = getit(data, 74, None) # polyface:Face.vertex 4.
2070 self.face = [abs(v1)-1,abs(v2)-1,abs(v3)-1]
2072 if abs(v4) != abs(v1):
2073 self.face.append(abs(v4)-1)
2074 else: #--parameter for polyline2d
2075 self.swidth = getit(data, 40, None) # start width
2076 self.ewidth = getit(data, 41, None) # end width
2077 self.bulge = getit(data, 42, 0) # bulge of segment
2084 def __getitem__(self, key):
2085 return self.loc[key]
2088 def __setitem__(self, key, value):
2094 return self.loc.__iter__()
2098 return str(self.loc)
2102 return "Vertex %s, swidth=%s, ewidth=%s, bulge=%s, face=%s" %(self.loc, self.swidth, self.ewidth, self.bulge, self.face)
2107 def setx(self, value):
2109 x = property(getx, setx)
2114 def sety(self, value):
2116 y = property(gety, sety)
2121 def setz(self, value):
2123 z = property(getz, setz)
2127 class Spline(Polyline): #-----------------------------------------------------------------
2128 """Class for objects representing dxf SPLINEs.
2130 """Expects an entity object of type spline as input.
2131 100 - Subclass marker (AcDbSpline)
2132 210,220, 230 - Normal vector (omitted if the spline is nonplanar) X,Y,Z values of normal vector
2133 70 - Spline flag (bit coded):
2138 16 = Linear (planar bit is also set)
2139 71 - Degree of the spline curve
2140 72 - Number of knots
2141 73 - Number of control points
2142 74 - Number of fit points (if any)
2143 42 - Knot tolerance (default = 0.0000001)
2144 43 - Control-point tolerance (default = 0.0000001)
2145 44 - Fit tolerance (default = 0.0000000001)
2146 12,22,32 - Start tangent--may be omitted (in WCS). X,Y,Z values of start tangent--may be omitted (in WCS).
2147 13,23, 33 - End tangent--may be omitted (in WCS). X,Y,Z values of end tangent--may be omitted (in WCS)
2148 40 - Knot value (one entry per knot)
2149 41 - Weight (if not 1); with multiple group pairs, are present if all are not 1
2150 10,20, 30 - Control points (in WCS) one entry per control point.
2151 DXF: X value; APP: 3D point, Y and Z values of control points (in WCS) (one entry per control point)
2152 11,21, 31 - Fit points (in WCS) one entry per fit point.
2153 X,Y,Z values of fit points (in WCS) (one entry per fit point)
2155 def __init__(self, obj):
2156 #print 'deb:Spline.START:----------------' #------------------------
2157 if not obj.type == 'spline':
2158 raise TypeError, "Wrong type %s for spline object!" %obj.type
2159 self.type = obj.type
2160 # self.data = obj.data[:]
2163 self.num_points = obj.get_type(73)[0]
2165 # optional data (with defaults)
2166 self.space = getit(obj, 67, 0)
2168 self.color_index = getit(obj, 62, BYLAYER)
2170 #self.elevation = getit(obj, 30, 0)
2171 self.thic = 0 # getit(obj, 39, 0)
2174 self.swidth = width # default start width
2175 self.ewidth = width # default end width
2177 self.flags = getit(obj, 70, 0)
2178 self.closed = self.flags & 1 # closed spline
2179 self.period = self.flags & 2 # Periodic spline
2180 self.ration = self.flags & 4 # Rational spline
2181 self.planar = self.flags & 8 # Planar
2182 self.linear = self.flags & 16 # Linear (and Planar)
2184 self.curvNoFitted = False
2185 self.curvQuadrati = False
2186 self.curvCubicBsp = False
2187 self.curvBezier = False
2188 self.degree = getit(obj, 71, 0) # Degree of the spline curve
2189 if self.degree == 0: self.curvNoFitted = True
2190 elif self.degree == 1: self.curvQuadrati = True
2191 elif self.degree == 2: self.curvCubicBsp = True
2192 #elif self.degree == 3: self.curvBezier = True
2193 #elif self.degree == 3: self.spline = True
2195 self.knotpk_len = getit(obj, 72, 0) # Number of knots
2196 self.ctrlpk_len = getit(obj, 73, 0) # Number of control points
2197 self.fit_pk_len = getit(obj, 74, 0) # Number of fit points (if any)
2199 #TODO: import SPLINE as Bezier curve directly, possible?
2200 #print 'deb:Spline self.fit_pk_len=', self.fit_pk_len #------------------------
2201 #self.fit_pk_len = 0 # temp for debug
2202 if self.fit_pk_len and settings.var['splines_as']==5:
2209 self.knotpk_tol = getit(obj, 42, 0.0000001) # Knot tolerance (default = 0.0000001)
2210 self.ctrlpk_tol = getit(obj, 43, 0.0000001) # Control-point tolerance (default = 0.0000001)
2211 self.fit_pk_tol = getit(obj, 44, 0.0000000001) # Fit tolerance (default = 0.0000000001)
2213 self.layer = getit(obj, 8, None)
2214 self.extrusion = get_extrusion(obj)
2216 self.pltype = 'spline' # spline is a 2D- or 3D-polyline
2218 self.points = self.get_points(obj.data)
2219 #self.knots_val = self.get_knots_val(obj.data) # 40 - Knot value (one entry per knot)
2220 #self.knots_wgh = self.get_knots_wgh(obj.data) # 41 - Weight (default 1)
2222 #print 'deb:Spline obj.data:\n', obj.data #------------------------
2223 #print 'deb:Spline self.points:\n', self.points #------------------------
2224 #print 'deb:Spline.ENDinit:----------------' #------------------------
2227 def get_points(self, data):
2228 """Gets points for a spline type object.
2230 Splines have fixed number of verts, and
2231 each vert can have a number of properties.
2232 Verts should be coded as
2241 if self.spline: # NURBSpline definition
2243 #print 'deb:Spline.get_points spilne_item:', item #------------------------
2244 if item[0] == 10: # control point
2245 if point: points.append(point)
2249 elif item[0] == 20: # 20 = y
2251 elif item[0] == 30: # 30 = z
2253 elif item[0] == 41: # 41 = weight
2254 point.weight = item[1]
2255 #print 'deb:Spline.get_points control point:', point #------------------------
2257 elif self.curved: # Bezier definition
2259 #print 'deb:Spline.get_points curved_item:', item #------------------------
2260 if item[0] == 11: # fit point
2261 if point: points.append(point)
2263 point.tangent = False
2265 elif item[0] == 21: # 20 = y
2267 elif item[0] == 31: # 30 = z
2269 #print 'deb:Spline.get_points fit point:', point #------------------------
2271 elif item[0] == 12: # start tangent
2272 if point: points.append(point)
2274 point.tangent = True
2276 elif item[0] == 22: # = y
2278 elif item[0] == 32: # = z
2280 #print 'deb:Spline.get_points fit begtangent:', point #------------------------
2282 elif item[0] == 13: # end tangent
2283 if point: points.append(point)
2285 pointend.tangent = True
2286 pointend.x = item[1]
2287 elif item[0] == 23: # 20 = y
2288 pointend.y = item[1]
2289 elif item[0] == 33: # 30 = z
2290 pointend.z = item[1]
2291 #print 'deb:Spline.get_points fit endtangent:', pointend #------------------------
2292 points.append(point)
2293 if self.curved and pointend:
2294 points.append(pointend)
2295 #print 'deb:Spline points:\n', points #------------------------
2299 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
2303 class LWpolyline(Polyline): #-------------------------------------------------------------
2304 """Class for objects representing dxf LWPOLYLINEs.
2306 def __init__(self, obj):
2307 """Expects an entity object of type lwpolyline as input.
2309 #print 'deb:LWpolyline.START:----------------' #------------------------
2310 if not obj.type == 'lwpolyline':
2311 raise TypeError, "Wrong type %s for polyline object!" %obj.type
2312 self.type = obj.type
2313 # self.data = obj.data[:]
2316 self.num_points = obj.get_type(90)[0]
2318 # optional data (with defaults)
2319 self.space = getit(obj, 67, 0)
2320 self.elevation = getit(obj, 38, 0)
2321 self.thic = getit(obj, 39, 0)
2322 self.color_index = getit(obj, 62, BYLAYER)
2323 width = getit(obj, 43, 0)
2324 self.swidth = width # default start width
2325 self.ewidth = width # default end width
2326 #print 'deb:LWpolyline width=', width #------------------------
2327 #print 'deb:LWpolyline elevation=', self.elevation #------------------------
2329 self.flags = getit(obj, 70, 0)
2330 self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen
2332 self.layer = getit(obj, 8, None)
2333 self.extrusion = get_extrusion(obj)
2335 self.points = self.get_points(obj.data)
2337 self.pltype = 'poly2d' # LW-polyline is a 2D-polyline
2342 #print 'deb:LWpolyline.obj.data:\n', obj.data #------------------------
2343 #print 'deb:LWpolyline.ENDinit:----------------' #------------------------
2346 def get_points(self, data):
2347 """Gets points for a polyline type object.
2349 LW-Polylines have no fixed number of verts, and
2350 each vert can have a number of properties.
2351 Verts should be coded as
2359 num = self.num_points
2363 if item[0] == 10: # 10 = x
2365 points.append(point)
2368 point.z = self.elevation
2369 elif item[0] == 20: # 20 = y
2371 elif item[0] == 40: # 40 = start width
2372 point.swidth = item[1]
2373 elif item[0] == 41: # 41 = end width
2374 point.ewidth = item[1]
2375 elif item[0] == 42: # 42 = bulge
2376 point.bulge = item[1]
2377 points.append(point)
2382 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
2385 class Text: #-----------------------------------------------------------------
2386 """Class for objects representing dxf TEXT.
2388 def __init__(self, obj):
2389 """Expects an entity object of type text as input.
2391 if not obj.type == 'text':
2392 raise TypeError, "Wrong type %s for text object!" %obj.type
2393 self.type = obj.type
2394 # self.data = obj.data[:]
2397 self.height = 1.7 * obj.get_type(40)[0] #text.height
2398 self.value = obj.get_type(1)[0] #The text string value
2400 # optional data (with defaults)
2401 self.space = getit(obj, 67, 0)
2402 self.color_index = getit(obj, 62, BYLAYER)
2403 self.thic = getit(obj, 39, 0)
2405 self.rotation = getit(obj, 50, 0) # radians
2406 self.width_factor = getit(obj, 41, 1) # Scaling factor along local x axis
2407 self.oblique = getit(obj, 51, 0) # oblique angle: skew in degrees -90 <= oblique <= 90
2409 #self.style = getit(obj, 7, 'STANDARD') # --todo---- Text style name (optional, default = STANDARD)
2411 #Text generation flags (optional, default = 0):
2412 #2 = backward (mirrored in X),
2413 #4 = upside down (mirrored in Y)
2414 self.flags = getit(obj, 71, 0)
2415 self.mirrorX, self.mirrorY = 1.0, 1.0
2416 if self.flags&2: self.mirrorX = - 1.0
2417 if self.flags&4: self.mirrorY = - 1.0
2419 # vertical.alignment: 0=baseline, 1=bottom, 2=middle, 3=top
2420 self.valignment = getit(obj, 73, 0)
2421 #Horizontal text justification type (optional, default = 0) integer codes (not bit-coded)
2422 #0=left, 1=center, 2=right
2423 #3=aligned, 4=middle, 5=fit
2424 self.halignment = getit(obj, 72, 0)
2426 self.layer = getit(obj, 8, None)
2427 self.loc1, self.loc2 = self.get_loc(obj)
2428 if self.loc2[0] != None and self.halignment != 5:
2429 self.loc = self.loc2
2431 self.loc = self.loc1
2432 self.extrusion = get_extrusion(obj)
2435 def get_loc(self, data):
2436 """Gets adjusted location for text type objects.
2438 If group 72 and/or 73 values are nonzero then the first alignment point values
2439 are ignored and AutoCAD calculates new values based on the second alignment
2440 point and the length and height of the text string itself (after applying the
2441 text style). If the 72 and 73 values are zero or missing, then the second
2442 alignment point is meaningless.
2443 I don't know how to calc text size...
2445 # bottom left x, y, z and justification x, y, z = 0
2446 #x, y, z, jx, jy, jz = 0, 0, 0, 0, 0, 0
2447 x = getit(data, 10, None) #First alignment point (in OCS).
2448 y = getit(data, 20, None)
2449 z = getit(data, 30, 0.0)
2450 jx = getit(data, 11, None) #Second alignment point (in OCS).
2451 jy = getit(data, 21, None)
2452 jz = getit(data, 31, 0.0)
2453 return [x, y, z],[jx, jy, jz]
2457 return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
2460 def draw(self, settings):
2461 """for TEXTs: generate Blender_geometry.
2463 obname = 'tx_%s' %self.layer # create object name from layer name
2464 obname = obname[:MAX_NAMELENGTH]
2465 txt = Text3d.New(obname)
2466 ob = SCENE.objects.new(txt) # create a new text_object
2468 txt.setText(self.value)
2469 txt.setSize(1.0) #Blender<2.45 accepts only (0.0 - 5.0)
2470 #txt.setSize(self.height)
2471 #txt.setWidth(self.bold)
2472 #setLineSeparation(sep)
2473 txt.setShear(self.oblique/90)
2475 thic = set_thick(self.thic, settings)
2477 thic = self.thic * 0.5
2479 txt.setExtrudeDepth(1.0) #Blender<2.45 accepts only (0.1 - 10.0)
2480 if self.halignment == 0:
2482 elif self.halignment == 1:
2483 align = Text3d.MIDDLE
2484 elif self.halignment == 2:
2485 align = Text3d.RIGHT
2488 txt.setAlignment(align)
2490 if self.valignment == 1:
2492 elif self.valignment == 2:
2493 txt.setYoffset(- self.height * 0.5)
2494 elif self.valignment == 3:
2495 txt.setYoffset(- self.height)
2497 # move the object center to the text location
2498 ob.loc = tuple(self.loc)
2499 transform(self.extrusion, self.rotation, ob)
2501 # flip it and scale it to the text width
2502 ob.SizeX *= self.height * self.width_factor * self.mirrorX
2503 ob.SizeY *= self.height * self.mirrorY
2504 if thic != 0.0: ob.SizeZ *= abs(thic)
2509 def set_thick(thickness, settings):
2510 """Set thickness relative to settings variables.
2512 Set thickness relative to settings variables:
2513 'thick_on','thick_force','thick_min'.
2514 Accepted also minus values of thickness
2515 python trick: sign(x)=cmp(x,0)
2517 if settings.var['thick_force']:
2518 if settings.var['thick_on']:
2519 if abs(thickness) < settings.var['thick_min']:
2520 thic = settings.var['thick_min'] * cmp(thickness,0)
2521 else: thic = thickness
2522 else: thic = settings.var['thick_min']
2524 if settings.var['thick_on']: thic = thickness
2531 class Mtext: #-----------------------------------------------------------------
2532 """Class for objects representing dxf MTEXT.
2535 def __init__(self, obj):
2536 """Expects an entity object of type mtext as input.
2538 if not obj.type == 'mtext':
2539 raise TypeError, "Wrong type %s for mtext object!" %obj.type
2540 self.type = obj.type
2541 # self.data = obj.data[:]
2544 self.height = obj.get_type(40)[0]
2545 self.width = obj.get_type(41)[0]
2546 self.alignment = obj.get_type(71)[0] # alignment 1=TL, 2=TC, 3=TR, 4=ML, 5=MC, 6=MR, 7=BL, 8=BC, 9=BR
2547 self.value = self.get_text(obj) # The text string value
2549 # optional data (with defaults)
2550 self.space = getit(obj, 67, 0)
2551 self.color_index = getit(obj, 62, BYLAYER)
2552 self.rotation = getit(obj, 50, 0) # radians
2554 self.width_factor = getit(obj, 42, 1) # Scaling factor along local x axis
2555 self.line_space = getit(obj, 44, 1) # percentage of default
2557 self.layer = getit(obj, 8, None)
2558 self.loc = self.get_loc(obj)
2559 self.extrusion = get_extrusion(obj)
2562 def get_text(self, data):
2563 """Reconstructs mtext data from dxf codes.
2568 if item[0] == 1: # There should be only one primary...
2570 elif item[0] == 3: # There may be any number of extra strings (in order)
2571 secondary.append(item[1])
2573 #raise ValueError, "Empty Mtext Object!"
2574 string = "Empty Mtext Object!"
2576 string = primary.replace(r'\P', '\n')
2578 string = ''.join(secondary)+primary
2579 string = string.replace(r'\P', '\n')
2583 def get_loc(self, data):
2584 """Gets location for a mtext type objects.
2586 Mtext objects have only one point indicating
2589 loc[0] = getit(data, 10, None)
2590 loc[1] = getit(data, 20, None)
2591 loc[2] = getit(data, 30, 0.0)
2596 return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
2599 def draw(self, settings):
2600 """for MTEXTs: generate Blender_geometry.
2602 # Now Create an object
2603 obname = 'tm_%s' %self.layer # create object name from layer name
2604 obname = obname[:MAX_NAMELENGTH]
2605 txt = Text3d.New(obname)
2606 ob = SCENE.objects.new(txt) # create a new text_object
2609 # Blender doesn't give access to its text object width currently
2610 # only to the text3d's curve width...
2611 #txt.setWidth(text.width/10)
2612 txt.setLineSeparation(self.line_space)
2613 txt.setExtrudeDepth(0.5)
2614 txt.setText(self.value)
2616 # scale it to the text size
2617 ob.SizeX = self.height * self.width_factor
2618 ob.SizeY = self.height
2619 ob.SizeZ = self.height
2621 # move the object center to the text location
2622 ob.loc = tuple(self.loc)
2623 transform(self.extrusion, self.rotation, ob)
2628 class Circle: #-----------------------------------------------------------------
2629 """Class for objects representing dxf CIRCLEs.
2632 def __init__(self, obj):
2633 """Expects an entity object of type circle as input.
2635 if not obj.type == 'circle':
2636 raise TypeError, "Wrong type %s for circle object!" %obj.type
2637 self.type = obj.type
2638 # self.data = obj.data[:]
2641 self.radius = obj.get_type(40)[0]
2643 # optional data (with defaults)
2644 self.space = getit(obj, 67, 0)
2645 self.thic = getit(obj, 39, 0)
2646 self.color_index = getit(obj, 62, BYLAYER)
2648 self.layer = getit(obj, 8, None)
2649 self.loc = self.get_loc(obj)
2650 self.extrusion = get_extrusion(obj)
2654 def get_loc(self, data):
2655 """Gets the center location for circle type objects.
2657 Circles have a single coord location.
2660 loc[0] = getit(data, 10, None)
2661 loc[1] = getit(data, 20, None)
2662 loc[2] = getit(data, 30, 0.0)
2668 return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
2671 def draw(self, settings):
2672 """for CIRCLE: generate Blender_geometry.
2674 obname = 'ci_%s' %self.layer # create object name from layer name
2675 obname = obname[:MAX_NAMELENGTH]
2676 radius = self.radius
2678 thic = set_thick(self.thic, settings)
2680 if settings.var['lines_as'] == 4: # as thin_box
2681 thic = settings.var['thick_min']
2682 width = settings.var['width_min']
2683 if settings.var['lines_as'] == 3: # as thin cylinder
2684 cyl_rad = 0.5 * settings.var['width_min']
2686 if settings.var['lines_as'] == 5: # draw CIRCLE as curve -------------
2687 if True: # universal version
2688 arc_res = settings.var['curve_arc']
2690 start, end = 0.0, 360.0
2691 VectorTriples = calcArc(None, radius, start, end, arc_res, True)
2692 c = Curve.New(obname) # create new curve data
2693 curve = c.appendNurb(BezTriple.New(VectorTriples[0]))
2694 for p in VectorTriples[1:-1]:
2695 curve.append(BezTriple.New(p))
2697 point.handleTypes = [FREE, FREE]
2699 else: # standard version
2700 c = Curve.New(obname) # create new curve data
2701 p1 = (0, -radius, 0)
2704 p4 = (-radius, 0, 0)
2706 p1 = BezTriple.New(p1)
2707 p2 = BezTriple.New(p2)
2708 p3 = BezTriple.New(p3)
2709 p4 = BezTriple.New(p4)
2711 curve = c.appendNurb(p1)
2716 point.handleTypes = [AUTO, AUTO]
2719 curve.flagU = 1 # 1 sets the curve cyclic=closed
2720 if settings.var['fill_on']:
2721 c.setFlag(6) # 2+4 set top and button caps
2723 c.setFlag(c.getFlag() & ~6) # dont set top and button caps
2725 c.setResolu(settings.var['curve_res'])
2728 #--todo-----to check---------------------------
2729 ob = SCENE.objects.new(c) # create a new curve_object
2730 ob.loc = tuple(self.loc)
2731 if thic != 0.0: #hack: Blender<2.45 curve-extrusion
2733 c.setExt1(1.0) # curve-extrusion accepts only (0.0 - 2.0)
2734 ob.LocZ = thic + self.loc[2]
2735 transform(self.extrusion, 0, ob)
2737 ob.SizeZ *= abs(thic)
2740 elif False: # create a new mesh_object with buildin_circle_primitive
2741 verts_num = settings.var['arc_res'] * sqrt(radius / settings.var['arc_rad'])
2742 if verts_num > 100: verts_num = 100 # Blender accepts only values [3:500]
2743 if verts_num < 4: verts_num = 4 # Blender accepts only values [3:500]
2745 loc2 = thic * 0.5 #-----blenderAPI draw Cylinder with 2*thickness
2746 self.loc[2] += loc2 #---new location for the basis of cylinder
2747 #print 'deb:circleDraw:self.loc2:', self.loc #-----------------------
2748 c = Mesh.Primitives.Cylinder(int(verts_num), radius*2, abs(thic))
2750 c = Mesh.Primitives.Circle(int(verts_num), radius*2)
2753 ob = SCENE.objects.new(c, obname) # create a new circle_mesh_object
2754 ob.loc = tuple(self.loc)
2755 transform(self.extrusion, 0, ob)
2758 else: # draw CIRCLE as mesh -----------------------------------------------
2759 if M_OBJ: obname, me, ob = makeNewObject()
2761 me = Mesh.New(obname) # create a new mesh
2762 ob = SCENE.objects.new(me) # create a new mesh_object
2763 # set a number of segments in entire circle
2764 arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
2765 start, end = 0.0 , 360.0
2766 verts = calcArc(None, radius, start, end, arc_res, False)
2767 verts = verts[:-1] #list without last point/edge (cause by circle it is equal to the first point)
2768 #print 'deb:circleDraw: verts:', verts #---------------
2773 thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
2775 thic_verts.extend(verts)
2778 verts.extend(thic_verts)
2780 f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
2781 #f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1)]