4 Name: 'Autodesk DXF (.dxf)'
7 Tooltip: 'Import for DXF geometry data (Drawing eXchange Format).'
9 __author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)'
10 __version__ = '1.12 - 2008.08.03 by migius'
11 __url__ = ["http://blenderartists.org/forum/showthread.php?t=84319",
12 "http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"]
13 __email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"]
15 This script imports objects from DXF (2d/3d) into Blender.
17 This script imports 2d and 3d geometery from DXF files.
18 Supported DXF format versions: from (r2.5) r12 up to 2008.
19 Enhanced features are:
20 - configurable object filtering and geometry manipulation,
21 - configurable material pre-processing,
22 - DXF-code analyze and reporting.
24 Supported DXF r12 objects:
31 MINSERT (=array of blocks),
35 2d-POLYLINE (=plane, incl. arc, variable-width, curve, spline),
36 3d-POLYLINE (=non-plane),
40 XREF (External Reference).
42 Supported DXF>r12 objects:
44 LWPOLYLINE (LightWeight Polyline),
51 DXF>r12: GROUP, RAY/XLINE, LEADER, 3DSOLID, BODY, REGION, dynamic BLOCK
53 Supported geometry: 2d and 3d DXF-objects.
54 Curves imported as Blender curves or meshes optionally.
56 Supported layout modes:
57 "model space" is default,
58 "paper space" as option (= "layout views")
60 Supported scene definition objescts produced with AVE_RENDER:
61 scene: selection of lights assigned to the camera,
62 lights: DIRECT, OVERHEAD, SH_SPOT,
63 (wip v1.13 import of AVE_RENDER material definitions)
66 Entire DXF BLOCK hierarchy is preserved after import into Blender
67 (BLOCKs as groups on layer19, INSERTs as dupliGroups on target layer).
76 (wip v1.13: XDATA, grouped status)
77 It is recommended to use DXF-object properties for assign Blender materials.
80 - Recommend that you run 'RemoveDoubles' on each imported mesh after using this script
81 - Blocks are created on layer 19 then referenced at each insert point.
82 - support for DXF-files up to 160MB on systems with 1GB RAM
83 - DXF-files with over 1500 objects decrease import performance.
84 The problem is not the inefficiency of python-scripting but Blenders performance
85 in creating new objects in scene database - probably a database management problem.
91 v1.0 - 2007/2008 by migius
93 -- (to see more, search for "--todo--" in script code)
94 -- command-line-mode/batch-mode
95 -- in-place-editing for dupliGroups
96 -- support for MLINE (is exported to r12 as BLOCK*Unnamed with LINEs)
97 -- support for MTEXT (is exported to r12 as TEXT???)
98 -- blender_object.properties['dxf_layer_name']
99 -- better support for long dxf-layer-names
100 -- add configuration file.ini handles multiple material setups
101 -- added f_layerFilter
102 -- to-check: obj/mat/group/_mapping-idea from ideasman42:
103 -- curves: added "fill/non-fill" option for closed curves: CIRCLEs,ELLIPSEs,POLYLINEs
104 -- "normalize Z" option to correct non-planar figures
105 -- LINEs need "width" in 3d-space incl vGroups
106 -- support width_force for LINEs/ELLIPSEs = "solidify"
107 -- add better support for color_index BYLAYER=256, BYBLOCK=0
108 -- bug: "oneMesh" produces irregularly errors
109 -- bug: Registry recall from hd_cache ?? only win32 bug??
110 -- support DXF-definitions of scene, lights and cameras
111 -- support ortho mode for VIEWs and VPORTs as cameras
114 v1.12 - 2008.08.03 by migius
115 c2 warningfix: relocating of globals: layersmap, oblist
116 c2 modif UI: buttons newScene+targetLayer moved to start panel
117 v1.12 - 2008.07.04 by migius
118 c1 added control Curve's OrderU parameter
119 c1 modif UI: preset buttons X-2D-3D moved to start panel
120 b6 added handling exception of not registered LAYERs (Hammer-HL-editor DXF output)
121 b5 rebuild UI: global preset 2D for Curve-Import
122 b5 added UI-options: PL-MESH N+N plmesh_flip and normals_out
123 b5 added support for SPLINEs, added control OrderU parameter
124 b5 rewrote draw module for NURBS_curve and Bezier_curve
125 v1.12 - 2008.06.22 by migius
126 b4 change versioning system 1.0.12 -> 1.12
127 b4 print at start version-info to console
128 b3 bugfix: ob.name conflict with existing meshes (different ob.name/mesh.name)
129 v1.0.12: 2008.05.24 by migius
130 b2 added support for LWPOLYLINEs
131 b2 added support for ProE in readerDXF.py
132 v1.0.12: 2008.02.08 by migius
133 b1 update: object = Object.Get(obname) -> f_getSceChild().getChildren()
134 a9 bugfix by non-existing tables views, vports, layers (Kai reported)
135 v1.0.12: 2008.01.17 by migius
136 a8 lately used INI-dir/filename persistently stored in Registry
137 a8 lately used DXF-dir/filename persistently stored in Registry
138 a7 fix missing layersmap{} for dxf-files without "section:layer"
139 a6 added support for XREF external referenced BLOCKs
140 a6 check for bug in AutoCAD2002:DXFr12export: ELLIPSE->POLYLINE_ARC fault angles
141 a6 support VIEWs and VPORTs as cameras: ortho and perspective mode
142 a6 save resources through ignoring unused BLOCKs (not-inserted or on frozen/blocked layers)
143 a6 added try_finally: f.close() for all IO-files
144 a6 added handling for TypeError raise
145 a5 bugfix f_getOCS for (0,0,z!=1.0) (ellipse in Kai's dxf)
146 a4 added to analyzeTool: report about VIEWs, VPORTs, unused/xref BLOCKs
147 a4 bugfix: individual support for 2D/3DPOLYLINE/POLYMESH
148 a4 added to UI: (*wip)BLOCK-(F): name filtering for BLOCKs
149 a4 added to UI: BLOCK-(n): filter anoname/hatch BLOCKs *X...
150 a2 g_scale_as is no more GUI_A-variable
151 a2 bugfix "material": negative sign color_index
152 a2 added support for BLOCKs defined with origin !=(0,0,0)
153 a1 added 'global.reLocation-vector' option
155 v1.0.11: 2007.11.24 by migius
156 c8 added 'curve_resolution_U' option
157 c8 added context_sensitivity for some UI-buttons
158 c8 bugfix ELLIPSE rotation, added closed_variant and caps
159 c7 rebuild UI: new layout, grouping and meta-buttons
160 c6 rewritten support for ELLIPSE mesh & curve representation
161 c6 restore selector-buttons for DXF-drawTypes: LINE & Co
162 c6 change header of INI/INF-files: # at begin
163 c6 apply scale(1,1,1) after glob.Scale for all mesh objects, not for curve objects.
164 c5 fixing 'material_on' option
165 c4 added "analyze DXF-file" UI-option: print LAYER/BLOCK-dependences into a textfile
166 c3 human-formating of data in INI-Files
167 c2 added "caps" for closed Bezier-curves
168 c2 added "set elevation" UI-option
169 c1 rewrite POLYLINE2d-arc-segments Bezier-interpreter
171 b9 rewrite POLYLINE2d-arc-segments trimming (clean-trim)
172 b8 added "import from frozen layers" UI-option
173 b8 added "import from paper space" UI-option
174 b8 support Bezier curves for LINEs incl.thickness(0.0-10.0)
175 b8 added meshSmooth_on for circle/arc/polyline
176 b8 added vertexGroups for circle/arc
177 b7 added width_force for ARCs/CIRCLEs = "thin_box" option
178 b3 cleanup code, rename f_drawArc/Bulg->f_calcArc/Bulg
179 b2 fixing material assignment by LAYER+COLOR
180 b1 fixing Bezier curves representation of POLYLINEs-arc-segments
181 b0 added global_scale_presets: "yard/feet/inch to meter"
183 v1.0.10: 2007.10.18 by migius
184 a6 bugfix CircleDrawCaps for OSX
185 a5 added two "curve_res" UI-buttons for Bezier curves representation
186 a5 improved Bezier curves representation of circles/arcs: correct handlers
187 a4 try to fix malformed endpoints of Blender curves of ARC/POLYLINE-arc segments.
188 a3 bugfix: open-POLYLINEs with end_point.loc==start_point.loc
189 a2 bugfix: f_transform for OCS=(0,0,-1) oriented objects
190 a1 added "fill_on=caps" option to draw top and bottom sides of CIRCLEs and ELLIPSEs
191 a1 rewrite f_CIRCLE.Draw: from Mesh.Primitive to Mesh
192 a1 bugfix "newScene"-mode: all Cylinders/Arcs were drawn at <0,0,0>location
194 v1.0.beta09: 2007.09.02 by migius
195 g5 redesign UI: grouping of buttons
196 g3 update multi-import-mode: <*.*> button
197 g- added multi-import-mode: (path/*) for importing many dxf-files at once
198 g- added import into newScene
199 g- redesign UI: user presets, into newScene-import
201 f- bugfix: thickness for Bezier/Bsplines into Blender-curves
202 f- BlenderWiki documentation, on-line Manual
203 f- added import POLYLINE-Bsplines into Blender-NURBSCurves
204 f- added import POLYLINE-arc-segments into Blender-BezierCurves
205 f- added import POLYLINE-Bezier-curves into Blender-Curves
206 d5 rewrite: Optimization Levels, added 'directDrawing'
207 d4 added: f_set_thick(controlled by ini-parameters)
208 d4 bugfix: face-normals in objects with minus thickness
209 d4 added: placeholder'Empty'-size in f_Insert.draw
210 d3 rewrite f_Text.Draw: added support for all Text's parameters
211 d2 redesign: progressbar
212 e- tuning by ideasman42: better use of the Py API.
213 c- tuning by ideasman42
214 b- rewrite f_Text.Draw rotation/transform
215 b- bugfix: POLYLINE-segment-intersection more reliable now
216 b- bugfix: circle:_thic, 'Empties':no material_assignment
217 b- added material assignment (from layer and/or color)
218 a- added empty, cylinder and UVsphere for POINTs
219 a- added support for 2d-POLYLINE: splines, fitted curves, fitted surfaces
220 a- redesign f_Drawer for block_definitions
221 a- rewrite import into Blender-Curve-Object
223 v1.0.beta08 - 2007.07.27 by migius: "full 3d"-release
224 l- bugfix: solid_vgroups, clean:scene.objects.new()
225 l- redesign UI to standard Draw.Register+FileSelector, advanced_config_option
226 k- bugfix UI:fileSelect() for MacOSX os.listdir()
227 k- added reset/save/load for config-data
228 k- redesign keywords/drawTypes/Draw.Create_Buttons
229 j- new UI using UIBlock() with own FileSelector, cause problem Window.FileSelector()
230 i- rewritten Class:Settings for better config-parameter management
231 h- bugfix: face-normals in objects with minus thickness
232 h- added Vertex-Groups in POLYLINE and SOLID meshes, for easy material assignment
233 h- beautify code, whitespace->tabs
234 h- added settings.thic_force switch for forcing thickness
235 h- added "one Mesh" option for all entities from the same Layer, sorted in<br>
236 Vertex-Groups(color_name) (fewer objects = better import performance)
237 g- rewrote: insert-point-handle-object is a small tetrahedron
238 e- bugfix: closed-polymesh3d
239 - rewrote: UI, type_map.keys, f_drawer, all class_f_draw(added "settings" as attribut)
240 - added 2d/3d-support for Polyline_Width incl. angle intersection
241 beta07: 2007.06.19 by migius
242 - added 3d-support for LWPolylines
243 - added 2d/3d-support for Points
244 beta06: 2007.06.15 by migius
246 - added 2d/3d-support for MINSERT=BlockArray in f_drawer, added f_rotXY_Vec
247 beta05: 2007.06.14 by migius
248 - added 2d/3d-support for 3d-PolyLine, PolyMesh and PolyFace
249 - added Global-Scale for size control of imported scenes
250 beta04: 2007.06.12 by migius
251 - rewrote the f_drawBulge for correct import the arc-segments of Polylines
252 beta03: 2007.06.10 by migius
254 beta02: 2007.06.09 by migius
255 - added 3d-support for Arcs and Circles
256 - added support for Object_Thickness(=height)
257 beta01: 2007.06.08 by migius
258 - added 3d-support for Blocks/Inserts within nested-structures
259 - rewrote f_transform for correct 3d-location/3d-rotation
260 - added 3d-support Lines, 3dFaces
261 - added 2d+3d-support for Solids and Traces
263 v0.9 - 2007.01 by kitsu: (for 2.43)
264 - first draft of true POLYLINE import
267 v0.8 - 2006.12 by kitsu:
268 - first draft of object space coordinates OCS import
271 v0.5b - 2006.10 by kitsu: (for 2.42a)
277 # --------------------------------------------------------------------------
278 # DXF Import v1.0 by Ed Blake (AKA kitsu) and Remigiusz Fiedler (AKA migius)
279 # --------------------------------------------------------------------------
280 # ***** BEGIN GPL LICENSE BLOCK *****
282 # This program is free software; you can redistribute it and/or
283 # modify it under the terms of the GNU General Public License
284 # as published by the Free Software Foundation; either version 2
285 # of the License, or (at your option) any later version.
287 # This program is distributed in the hope that it will be useful,
288 # but WITHOUT ANY WARRANTY; without even the implied warranty of
289 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
290 # GNU General Public License for more details.
292 # You should have received a copy of the GNU General Public License
293 # along with this program; if not, write to the Free Software Foundation,
294 # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
296 # ***** END GPL LICENCE BLOCK *****
297 # --------------------------------------------------------------------------
300 from Blender import *
301 #from Blender.Mathutils import Vector, Matrix
305 from dxfReader import readDXF
306 #from dxfReader import get_name, get_layer
307 from dxfReader import Object as dxfObject
308 from dxfColorMap import color_map
314 if os.name:# != 'mac':
316 psyco.log(Blender.Get('tempdir')+"/blender.log-psyco")
318 psyco.full(memory=100)
319 psyco.profile(0.05, memory=100)
321 #print 'psyco imported'
323 #print 'psyco not imported'
329 print 'DXF-Importer v%s *** start ***' %(__version__) #---------------------
332 WORLDX = Mathutils.Vector((1,0,0))
333 WORLDY = Mathutils.Vector((1,1,0))
334 WORLDZ = Mathutils.Vector((0,0,1))
336 G_SCALE = 1.0 #(0.0001-1000) global scaling factor for all dxf data
337 G_ORIGIN_X = 0.0 #global translation-vector (x,y,z) in DXF units
340 MIN_DIST = 0.001 #cut-off value for sort out short-distance polyline-"duoble_vertex"
341 ARC_RESOLUTION = 64 #(4-500) arc/circle resolution - number of segments
342 ARC_RADIUS = 1.0 #(0.01-100) arc/circle radius for number of segments algorithm
343 CURV_RESOLUTION = 12 #(1-128) Bezier curves U-resolution
344 CURVARC_RESOLUTION = 4 #(3-32) resolution of circle represented as Bezier curve
345 THIN_RESOLUTION = 8 #(4-64) thin_cylinder arc_resolution - number of segments
346 MIN_THICK = MIN_DIST * 10.0 #minimal thickness by forced thickness
347 MIN_WIDTH = MIN_DIST * 10.0 #minimal width by forced width
348 TRIM_LIMIT = 3.0 #limit for triming of polylines-wide-segments (values:0.0 - 5.0)
349 ELEVATION = 0.0 #standard elevation = coordinate Z
353 TARGET_LAYER = 3 #target blender_layer
354 GROUP_BYLAYER = 0 #(0/1) all entities from same layer import into one blender-group
355 LAYER_DEF_NAME = 'AAAA' #default layer name
356 LAYER_DEF_COLOR = 4 #default layer color
358 LAB = "*) parts under construction"
361 FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE)
362 MAX_NAMELENGTH = 17 #max_effective_obnamelength in blender =21=17+(.001)
363 INIFILE_DEFAULT_NAME = 'importDXF'
364 INIFILE_EXTENSION = '.ini'
365 INIFILE_HEADER = '#ImportDXF.py ver.1.0 config data'
366 INFFILE_HEADER = '#ImportDXF.py ver.1.0 analyze of DXF-data'
368 AUTO = BezTriple.HandleTypes.AUTO
369 FREE = BezTriple.HandleTypes.FREE
370 VECT = BezTriple.HandleTypes.VECT
371 ALIGN = BezTriple.HandleTypes.ALIGN
374 class View: #-----------------------------------------------------------------
375 """Class for objects representing dxf VIEWs.
377 def __init__(self, obj, active=None):
378 """Expects an object of type VIEW as input.
380 if not obj.type == 'view':
381 raise TypeError, "Wrong type %s for VIEW object!" %obj.type
384 self.name = obj.get_type(2)[0]
385 # self.data = obj.data[:]
388 self.centerX = getit(obj, 10, 0.0) #view center pointX (in DCS)
389 self.centerY = getit(obj, 20, 0.0) #view center pointY (in DCS)
390 self.height = obj.get_type(40)[0] #view height (in DCS)
391 self.width = obj.get_type(41)[0] #view width (in DCS)
394 self.dir[0] = getit(obj, 11, 0.0) #view directionX from target (in WCS)
395 self.dir[1] = getit(obj, 21, 0.0) #
396 self.dir[2] = getit(obj, 31, 0.0) #
398 self.target = [0,0,0]
399 self.target[0] = getit(obj, 12, 0.0) #target pointX(in WCS)
400 self.target[1] = getit(obj, 22, 0.0) #
401 self.target[2] = getit(obj, 32, 0.0) #
403 self.length = obj.get_type(42)[0] #Lens length
404 self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
405 self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
406 self.twist = obj.get_type(50)[0] #view twist angle in degrees
408 self.flags = getit(obj, 70, 0)
409 self.paperspace = self.flags & 1 #
411 self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
414 return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
417 def draw(self, settings):
418 """for VIEW: generate Blender_camera.
420 obname = 'vw_%s' %self.name # create camera object name
421 #obname = 'ca_%s' %self.name # create camera object name
422 obname = obname[:MAX_NAMELENGTH]
424 if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
425 cam= Camera.New('ortho', obname)
426 ob= SCENE.objects.new(cam)
428 cam.scale = 1.0 # for ortho cameras
430 cam= Camera.New('persp', obname)
431 ob= SCENE.objects.new(cam)
433 cam.angle = 60.0 # for persp cameras
435 #cam.angle = 2 * atan(17.5/self.length) * 180/pi
436 cam.lens = self.length #for persp cameras
437 # hack to update Camera>Lens setting (inaccurate as a focal length)
438 #curLens = cam.lens; cam.lens = curLens
439 # AutoCAD gets clip distance from target:
440 dist = Mathutils.Vector(self.dir).length
441 cam.clipEnd = dist - self.clip_back
442 cam.clipStart = dist - self.clip_front
447 v = Mathutils.Vector(self.dir)
448 # print 'deb:view cam:', cam #------------
449 # print 'deb:view self.target:', self.target #------------
450 # print 'deb:view self.dir:', self.dir #------------
451 # print 'deb:view self.twist:', self.twist #------------
452 # print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
453 transform(v.normalize(), -self.twist, ob)
454 ob.loc = Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
458 class Vport: #-----------------------------------------------------------------
459 """Class for objects representing dxf VPORTs.
461 def __init__(self, obj, active=None):
462 """Expects an object of type VPORT as input.
464 if not obj.type == 'vport':
465 raise TypeError, "Wrong type %s for VPORT object!" %obj.type
468 self.name = obj.get_type(2)[0]
469 # self.data = obj.data[:]
470 #print 'deb:vport name, data:', self.name #-------
471 #print 'deb:vport data:', self.data #-------
473 self.height = obj.get_type(40)[0] #vport height (in DCS)
474 self.centerX = getit(obj, 12, 0.0) #vport center pointX (in DCS)
475 self.centerY = getit(obj, 22, 0.0) #vport center pointY (in DCS)
476 self.width = self.height * obj.get_type(41)[0] #vport aspect ratio - width (in DCS)
479 self.dir[0] = getit(obj, 16, 0.0) #vport directionX from target (in WCS)
480 self.dir[1] = getit(obj, 26, 0.0) #
481 self.dir[2] = getit(obj, 36, 0.0) #
483 self.target = [0,0,0]
484 self.target[0] = getit(obj, 17, 0.0) #target pointX(in WCS)
485 self.target[1] = getit(obj, 27, 0.0) #
486 self.target[2] = getit(obj, 37, 0.0) #
488 self.length = obj.get_type(42)[0] #Lens length
489 self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
490 self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
491 self.twist = obj.get_type(51)[0] #view twist angle
493 self.flags = getit(obj, 70, 0)
494 self.paperspace = self.flags & 1 #
496 self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
499 return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
501 def draw(self, settings):
502 """for VPORT: generate Blender_camera.
504 obname = 'vp_%s' %self.name # create camera object name
505 #obname = 'ca_%s' %self.name # create camera object name
506 obname = obname[:MAX_NAMELENGTH]
508 if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
509 cam= Camera.New('ortho', obname)
510 ob= SCENE.objects.new(cam)
512 cam.scale = 1.0 # for ortho cameras
514 cam= Camera.New('persp', obname)
515 ob= SCENE.objects.new(cam)
517 cam.angle = 60.0 # for persp cameras
519 #cam.angle = 2 * atan(17.5/self.length) * 180/pi
520 cam.lens = self.length #for persp cameras
521 # hack to update Camera>Lens setting (inaccurate as a focal length)
522 #curLens = cam.lens; cam.lens = curLens
523 # AutoCAD gets clip distance from target:
524 dist = Mathutils.Vector(self.dir).length
525 cam.clipEnd = dist - self.clip_back
526 cam.clipStart = dist - self.clip_front
531 v = Mathutils.Vector(self.dir)
532 # print 'deb:view cam:', cam #------------
533 # print 'deb:view self.target:', self.target #------------
534 # print 'deb:view self.dir:', self.dir #------------
535 # print 'deb:view self.twist:', self.twist #------------
536 # print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
537 transform(v.normalize(), -self.twist, ob)
538 ob.loc = Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
543 class Layer: #-----------------------------------------------------------------
544 """Class for objects representing dxf LAYERs.
546 def __init__(self, obj, name=None, color=None, frozen=None):
547 """Expects an dxfobject of type layer as input.
548 if no dxfobject - creates surogate layer with default parameters
553 if name: self.name = name
554 else: self.name = LAYER_DEF_NAME
556 if color: self.color = color
557 else: self.color = LAYER_DEF_COLOR
559 if frozen!=None: self.frozen = frozen
560 else: self.frozen = 0
562 if obj.type=='layer':
564 #self.data = obj.data[:]
565 if name: self.name = name
566 #self.bfname = name #--todo---see layernamesmap in f_getLayersmap ---
567 else: self.name = obj.get_type(2)[0] #layer name of object
569 if color: self.color = color
570 else: self.color = obj.get_type(62)[0] #color of object
572 if frozen!=None: self.frozen = frozen
574 self.flags = obj.get_type(70)[0]
575 self.frozen = self.flags & 1
578 return "%s: name - %s, color - %s" %(self.__class__.__name__, self.name, self.color)
582 def getit(obj, typ, default=None): #------------------------------------------
583 """Universal procedure for geting data from list/objects.
586 if type(obj) == list: #if obj is a list, then searching in a list
588 #print 'deb:getit item, type(item)', item, type(item)
592 break #as soon as the first found
594 # --todo-- I found one case where item was a text instance
595 # that failed with no __getitem__
597 else: #else searching in Object with get_type-Methode
598 item = obj.get_type(typ)
601 #print 'deb:getit:typ, it', typ, it #----------
606 def get_extrusion(data): #-------------------------------------------------
607 """Find the axis of extrusion.
609 Used to get from object_data the objects Object_Coordinate_System (ocs).
611 #print 'deb:get_extrusion: data: \n', data #---------------
613 vec[0] = getit(data, 210, 0) # 210 = x
614 vec[1] = getit(data, 220, 0) # 220 = y
615 vec[2] = getit(data, 230, 1) # 230 = z
616 #print 'deb:get_extrusion: vec: ', vec #---------------
620 #------------------------------------------
621 def getSceneChild(name):
622 dudu = [i for i in SCENE.objects if i.name==name]
623 # dudu = [i for i in SCENE.getChildren() if i.name==name]
624 #print 'deb:getSceneChild %s -result: %s:' %(name,dudu) #-----------------
625 if dudu!=[]: return dudu[0]
629 class Solid: #-----------------------------------------------------------------
630 """Class for objects representing dxf SOLID or TRACE.
632 def __init__(self, obj):
633 """Expects an entity object of type solid or trace as input.
635 if obj.type == 'trace':
637 if not obj.type == 'solid':
638 raise TypeError, "Wrong type \'%s\' for solid/trace object!" %obj.type
641 # self.data = obj.data[:]
643 self.space = getit(obj, 67, 0)
644 self.thic = getit(obj, 39, 0)
645 self.color_index = getit(obj, 62, BYLAYER)
647 self.layer = getit(obj, 8, None)
648 self.extrusion = get_extrusion(obj)
649 self.points = self.get_points(obj)
653 def get_points(self, data):
654 """Gets start and end points for a solid type object.
656 Solids have 3 or 4 points and fixed codes for each value.
659 # start x, y, z and end x, y, z = 0
664 a[0] = getit(data, 10, None) # 10 = x
665 a[1] = getit(data, 20, None) # 20 = y
666 a[2] = getit(data, 30, 0) # 30 = z
667 b[0] = getit(data, 11, None)
668 b[1] = getit(data, 21, None)
669 b[2] = getit(data, 31, 0)
670 c[0] = getit(data, 12, None)
671 c[1] = getit(data, 22, None)
672 c[2] = getit(data, 32, 0)
675 d[0] = getit(data, 13, None)
677 d[1] = getit(data, 23, None)
678 d[2] = getit(data, 33, 0)
680 #print 'deb:solid.vertices:---------\n', out #-----------------------
685 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
688 def draw(self, settings):
689 """for SOLID: generate Blender_geometry.
692 if not points: return
693 edges, faces = [], []
696 obname = 'so_%s' %self.layer # create object name from layer name
697 obname = obname[:MAX_NAMELENGTH]
699 vg_left, vg_right, vg_top, vg_bottom, vg_start, vg_end = [], [], [], [], [], []
700 thic = set_thick(self.thic, settings)
702 thic_points = [[v[0], v[1], v[2] + thic] for v in points[:]]
704 thic_points.extend(points)
707 points.extend(thic_points)
710 faces = [[0,1,3,2], [4,6,7,5], [0,4,5,1],
711 [1,5,7,3], [3,7,6,2], [2,6,4,0]]
715 vg_bottom = [0,1,3,2]
719 faces = [[0,1,2], [3,5,4], [0,3,4,1], [1,4,5,2], [2,5,3,0]]
725 elif l == 2: faces = [[0,1,3,2]]
727 if l == 4: faces = [[0,1,3,2]]
728 elif l == 3: faces = [[0,1,2]]
729 elif l == 2: edges = [[0,1]]
731 if M_OBJ: obname, me, ob = makeNewObject()
733 me = Mesh.New(obname) # create a new mesh
734 ob = SCENE.objects.new(me) # create a new mesh_object
735 me.verts.extend(points) # add vertices to mesh
736 if faces: me.faces.extend(faces) # add faces to the mesh
737 if edges: me.edges.extend(edges) # add faces to the mesh
739 if settings.var['vGroup_on'] and not M_OBJ:
740 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
741 replace = Blender.Mesh.AssignModes.ADD #or .AssignModes.ADD/REPLACE
742 if vg_left: me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
743 if vg_right:me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
744 if vg_top: me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
745 if vg_bottom:me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
746 if vg_start:me.addVertGroup('side.start') ; me.assignVertsToGroup('side.start', vg_start, 1.0, replace)
747 if vg_end: me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', vg_end, 1.0, replace)
749 transform(self.extrusion, 0, ob)
753 class Line: #-----------------------------------------------------------------
754 """Class for objects representing dxf LINEs.
756 def __init__(self, obj):
757 """Expects an entity object of type line as input.
759 if not obj.type == 'line':
760 raise TypeError, "Wrong type \'%s\' for line object!" %obj.type
762 # self.data = obj.data[:]
764 self.space = getit(obj, 67, 0)
765 self.thic = getit(obj, 39, 0)
766 #print 'deb:self.thic: ', self.thic #---------------------
767 self.color_index = getit(obj, 62, BYLAYER)
769 self.layer = getit(obj, 8, None)
770 self.extrusion = get_extrusion(obj)
771 self.points = self.get_points(obj)
774 def get_points(self, data):
775 """Gets start and end points for a line type object.
777 Lines have a fixed number of points (two) and fixed codes for each value.
779 # start x,y,z and end x,y,z = 0
782 a[0] = getit(data, 10, None) # 10 = x
783 a[1] = getit(data, 20, None) # 20 = y
784 a[2] = getit(data, 30, 0) # 30 = z
785 b[0] = getit(data, 11, None)
786 b[1] = getit(data, 21, None)
787 b[2] = getit(data, 31, 0)
793 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
796 def draw(self, settings):
797 """for LINE: generate Blender_geometry.
799 # Generate the geometery
800 #settings.var['curves_on']=False
803 thic = set_thick(self.thic, settings)
805 if settings.var['lines_as'] == 4: # as thin_box
806 thic = settings.var['thick_min']
807 width = settings.var['width_min']
808 elif settings.var['lines_as'] == 3: # as thin cylinder
809 cyl_rad = 0.5 * settings.var['width_min']
811 elif settings.var['lines_as'] == 5: # LINE curve representation-------------------------
812 obname = 'li_%s' %self.layer # create object name from layer name
813 obname = obname[:MAX_NAMELENGTH]
815 c = Curve.New(obname) # create new curve data
816 curve = c.appendNurb(BezTriple.New(points[0]))
817 curve.append(BezTriple.New(points[1]))
819 point.handleTypes = [VECT, VECT]
820 curve.flagU = 0 # 0 sets the curve not cyclic=open
821 c.setResolu(settings.var['curve_res'])
822 c.update() #important for handles calculation
824 ob = SCENE.objects.new(c) # create a new curve_object
826 #if False: # --todo-- better support for 210-group
827 if thic != 0.0: #hack: Blender2.45 curve-extrusion
829 if abs(t) > 5.0: t = 5.0 * cmp(t,0) # Blender2.45 accepts only (0.0 - 5.0)
831 c.setExt1(abs(t)) # curve-extrusion
835 #c.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
836 #ob.LocZ = t + self.loc[2]
840 else: # LINE mesh representation ------------------------------
841 global activObjectLayer
842 global activObjectName
843 #print 'deb:draw:line.ob IN activObjectName: ', activObjectName #---------------------
845 if M_OBJ: obname, me, ob = makeNewObject()
847 if activObjectLayer == self.layer and settings.var['one_mesh_on']:
848 obname = activObjectName
849 #print 'deb:line.draw obname from activObjectName: ', obname #---------------------
850 ob = getSceneChild(obname) # open an existing mesh_object
851 #ob = SCENE.getChildren(obname) # open an existing mesh_object
852 #me = Mesh.Get(ob.name) # open objects mesh data
853 me = ob.getData(name_only=False, mesh=True)
855 obname = 'li_%s' %self.layer # create object name from layer name
856 obname = obname[:MAX_NAMELENGTH]
857 me = Mesh.New(obname) # create a new mesh
858 ob = SCENE.objects.new(me) # create a new mesh_object
859 activObjectName = ob.name
860 activObjectLayer = self.layer
861 #print ('deb:line.draw new line.ob+mesh:"%s" created!' %ob.name) #---------------------
863 faces, edges = [], []
866 #if settings.var['width_force']: #--todo-----------
869 t, e = thic, self.extrusion
870 #print 'deb:thic, extr: ', t, e #---------------------
871 points.extend([[v[0]+t*e[0], v[1]+t*e[1], v[2]+t*e[2]] for v in points[:]])
872 faces = [[0+n, 1+n, 3+n, 2+n]]
876 me.verts.extend(points) # adds vertices to global mesh
877 if faces: me.faces.extend(faces) # add faces to the mesh
878 if edges: me.edges.extend(edges) # add faces to the mesh
880 if settings.var['vGroup_on'] and not M_OBJ:
881 # entities with the same color build one vertexGroup for easier material assignment ----
882 ob.link(me) # link mesh to that object
883 vG_name = 'color_%s' %self.color_index
884 if edges: faces = edges
885 replace = Blender.Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD
887 me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
888 #print 'deb: existed vGroup:', vG_name #---------------------
890 me.addVertGroup(vG_name)
891 me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
892 #print 'deb: create new vGroup:', vG_name #---------------------
895 #print 'deb:draw:line.ob OUT activObjectName: ', activObjectName #---------------------
900 class Point: #-----------------------------------------------------------------
901 """Class for objects representing dxf POINTs.
903 def __init__(self, obj):
904 """Expects an entity object of type point as input.
906 if not obj.type == 'point':
907 raise TypeError, "Wrong type %s for point object!" %obj.type
909 # self.data = obj.data[:]
911 self.space = getit(obj, 67, 0)
912 self.thic = getit(obj, 39, 0)
913 #print 'deb:self.thic: ', self.thic #---------------------
914 self.color_index = getit(obj, 62, BYLAYER)
916 self.layer = getit(obj, 8, None)
917 self.extrusion = get_extrusion(obj)
918 self.points = self.get_points(obj)
921 def get_points(self, data):
922 """Gets coordinates for a point type object.
924 Points have fixed codes for each value.
927 a[0] = getit(data, 10, None) # 10 = x
928 a[1] = getit(data, 20, None) # 20 = y
929 a[2] = getit(data, 30, 0) # 30 = z
935 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
938 def draw(self, settings):
939 """for POINT: generate Blender_geometry.
942 obname = 'po_%s' %self.layer # create object name from layer name
943 obname = obname[:MAX_NAMELENGTH]
944 points_as = settings.var['points_as']
945 thic = settings.var['thick_min']
946 if thic < settings.var['dist_min']: thic = settings.var['dist_min']
948 if points_as in [1,3,4,5]:
949 if True: # points_as in [1,5]: # as 'empty'
951 elif points_as == 3: # as 'thin sphere'
952 res = settings.var['thin_res']
953 c = Mesh.Primitives.UVsphere(res,res,thic)
954 elif points_as == 4: # as 'thin box'
955 c = Mesh.Primitives.Cube(thic)
956 ob = SCENE.objects.new(c, obname) # create a new object
957 transform(self.extrusion, 0, ob)
958 ob.loc = tuple(points[0])
960 elif points_as == 2: # as 'vertex'
961 global activObjectLayer
962 global activObjectName
963 #print 'deb:draw:point.ob IN activObjectName: ', activObjectName #---------------------
964 if M_OBJ: obname, me, ob = makeNewObject()
966 if activObjectLayer == self.layer and settings.var['one_mesh_on']:
967 obname = activObjectName
968 #print 'deb:draw:point.ob obname from activObjectName: ', obname #---------------------
969 ob = getSceneChild(obname) # open an existing mesh_object
970 #ob = SCENE.getChildren(obname) # open an existing mesh_object
971 me = ob.getData(name_only=False, mesh=True)
972 #me = Mesh.Get(ob.name) # open objects mesh data
974 me = Mesh.New(obname) # create a new mesh
975 ob = SCENE.objects.new(me) # create a new mesh_object
976 activObjectName = ob.name
977 activObjectLayer = self.layer
978 #print ('deb:draw:point new point.ob+mesh:"%s" created!' %ob.name) #---------------------
979 me.verts.extend(points) # add vertices to mesh
985 class Polyline: #-----------------------------------------------------------------
986 """Class for objects representing dxf POLYLINEs.
988 def __init__(self, obj):
989 """Expects an entity object of type polyline as input.
991 #print 'deb:polyline.init.START:----------------' #------------------------
992 if not obj.type == 'polyline':
993 raise TypeError, "Wrong type %s for polyline object!" %obj.type
995 # self.data = obj.data[:]
997 self.space = getit(obj, 67, 0)
998 self.elevation = getit(obj, 30, 0)
999 #print 'deb:elevation: ', self.elevation #---------------
1000 self.thic = getit(obj, 39, 0)
1001 self.color_index = getit(obj, 62, BYLAYER)
1003 self.flags = getit(obj, 70, 0)
1004 self.closed = self.flags & 1 # closed in the M direction
1005 self.curved = self.flags & 2 # Bezier-curve-fit vertices have been added
1006 self.spline = self.flags & 4 # NURBS-curve-fit vertices have been added
1007 self.poly3d = self.flags & 8 # 3D-polyline
1008 self.plmesh = self.flags & 16 # 3D-polygon mesh
1009 self.closeN = self.flags & 32 # closed in the N direction
1010 self.plface = self.flags & 64 # 3D-polyface mesh
1011 self.contin = self.flags & 128 # the linetype pattern is generated continuously
1013 self.pltype='poly2d' # default is a 2D-polyline
1014 if self.poly3d: self.pltype='poly3d'
1015 elif self.plface: self.pltype='plface'
1016 elif self.plmesh: self.pltype='plmesh'
1018 self.swidth = getit(obj, 40, 0) # default start width
1019 self.ewidth = getit(obj, 41, 0) # default end width
1020 #self.bulge = getit(obj, 42, None) # bulge of the segment
1021 self.vectorsM = getit(obj, 71, None) # PolyMesh: expansion in M-direction / PolyFace: number of the vertices
1022 self.vectorsN = getit(obj, 72, None) # PolyMesh: expansion in M-direction / PolyFace: number of faces
1023 #self.resolM = getit(obj, 73, None) # resolution of surface in M direction
1024 #self.resolN = getit(obj, 74, None) # resolution of surface in N direction
1025 self.curvNoFitted = False
1026 self.curvQuadrati = False
1027 self.curvCubicBsp = False
1028 self.curvBezier = False
1029 curvetype = getit(obj, 75, 0) # type of curve/surface: 0=None/5=Quadric/6=Cubic/8=Bezier
1030 if curvetype == 0: self.curvNoFitted = True
1031 elif curvetype == 5: self.curvQuadrati = True
1032 elif curvetype == 6: self.curvCubicBsp = True
1033 elif curvetype == 8: self.curvBezier = True
1035 self.layer = getit(obj, 8, None)
1036 self.extrusion = get_extrusion(obj)
1038 self.points = [] #list with vertices coordinats
1039 self.faces = [] #list with vertices assigment to faces
1040 #print 'deb:polyline.init.ENDinit:----------------' #------------
1045 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
1049 def doubles_out(self, settings, d_points):
1050 """routine to sort out of double.vertices-----------------------------
1052 minimal_dist = settings.var['dist_min'] * 0.1
1055 for i in xrange(len(d_points)-1):
1057 point2 = d_points[i+1]
1058 #print 'deb:double.vertex p1,p2', point, point2 #------------------------
1059 delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
1060 if delta.length > minimal_dist:
1061 temp_points.append(point)
1064 #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
1065 temp_points.append(d_points[-1]) #------ incl. last vertex -------------
1066 #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
1067 d_points = temp_points #-----vertex.list without "double.vertices"
1068 #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1072 def tribles_out(self, settings, d_points):
1073 """routine to sort out of three_in_place.vertices-----------------------------
1075 minimal_dist = settings.var['dist_min'] * 0.1
1078 for i in xrange(len(d_points)-2):
1079 point1 = d_points[i]
1080 point2 = d_points[i+1]
1081 point3 = d_points[i+2]
1082 #print 'deb:double.vertex p1,p2', point, point2 #------------------------
1083 delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
1084 delta23 = Mathutils.Vector(point3.loc) - Mathutils.Vector(point2.loc)
1085 if delta12.length < minimal_dist and delta23.length < minimal_dist:
1088 temp_points.append(point1)
1089 #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
1090 point1 = d_points[-2]
1091 point2 = d_points[-1]
1092 delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
1093 if delta12.length > minimal_dist:
1094 temp_points.append(d_points[-2]) #------ incl. 2last vertex -------------
1095 temp_points.append(d_points[-1]) #------ incl. 1last vertex -------------
1096 #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
1097 d_points = temp_points #-----vertex.list without "double.vertices"
1098 #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1102 def draw(self, settings): #-------------%%%% DRAW POLYLINE %%%---------------
1103 """for POLYLINE: generate Blender_geometry.
1105 #print 'deb:drawPOLYLINE.START:----------------' #------------------------
1106 #print 'deb:POLYLINEdraw self.pltype:', self.pltype #------------------------
1107 #print 'deb:POLYLINEdraw self.points:\n', self.points #------------------------
1109 #---- 3dPolyFace - mesh with free topology
1110 if self.pltype=='plface' and settings.drawTypes['plmesh']:
1111 ob = self.drawPlFace(settings)
1112 #---- 3dPolyMesh - mesh with ortogonal topology
1113 elif self.pltype=='plmesh' and settings.drawTypes['plmesh']:
1114 ob = self.drawPlMesh(settings)
1116 #---- 2dPolyline - plane polyline with arc/wide/thic segments
1117 elif self.pltype=='poly2d' and settings.drawTypes['polyline']:
1118 if settings.var['plines_as'] in [5,6]: # and self.spline:
1119 ob = self.drawPolyCurve(settings)
1121 ob = self.drawPoly2d(settings)
1123 #---- 3dPolyline - non-plane polyline (thin segments = without arc/wide/thic)
1124 elif self.pltype=='poly3d' and settings.drawTypes['pline3']:
1125 if settings.var['plines3_as'] in [5,6]: # and self.spline:
1126 ob = self.drawPolyCurve(settings)
1128 ob = self.drawPoly2d(settings)
1130 #---- Spline - curved polyline (thin segments = without arc/wide/thic)
1131 elif self.pltype=='spline' and settings.drawTypes['spline']:
1132 if settings.var['splines_as'] in [5,6]:
1133 ob = self.drawPolyCurve(settings)
1135 ob = self.drawPoly2d(settings)
1139 def drawPlFace(self, settings): #---- 3dPolyFace - mesh with free topology
1140 """Generate the geometery of polyface.
1142 #print 'deb:drawPlFace.START:----------------' #------------------------
1145 #print 'deb:len of pointsList ====== ', len(self.points) #------------------------
1146 for point in self.points:
1148 faces.append(point.face)
1150 points.append(point.loc)
1152 if settings.var['plmesh_flip']: # ----------------------
1155 face = [face[-1]] + face[:-1]
1157 #print 'deb:drawPlFace: len of points_list:\n', len(points) #-----------------------
1158 #print 'deb:drawPlFace: len of faces_list:\n', len(faces) #-----------------------
1159 #print 'deb:drawPlFace: points_list:\n', points #-----------------------
1160 #print 'deb:drawPlFace: faces_list:\n', faces #-----------------------
1161 obname = 'pf_%s' %self.layer # create object name from layer name
1162 obname = obname[:MAX_NAMELENGTH]
1163 me = Mesh.New(obname) # create a new mesh
1164 ob = SCENE.objects.new(me) # create a new mesh_object
1165 me.verts.extend(points) # add vertices to mesh
1166 me.faces.extend(faces) # add faces to the mesh
1167 if settings.var['normals_out']: # ----------------------
1171 #print 'deb:drawPlFace: len of me.faces:\n', len(me.faces) #-----------------------
1173 if settings.var['meshSmooth_on']: # ----------------------
1174 for i in xrange(len(me.faces)):
1175 me.faces[i].smooth = True
1176 #me.Mode(AUTOSMOOTH)
1177 transform(self.extrusion, 0, ob)
1178 #print 'deb:drawPlFace.END:----------------' #------------------------
1183 def drawPlMesh(self, settings): #---- 3dPolyMesh - mesh with orthogonal topology
1184 """Generate the geometery of polymesh.
1186 #print 'deb:polymesh.draw.START:----------------' #------------------------
1188 #print 'deb:len of pointsList ====== ', len(self.points) #------------------------
1192 for j in xrange(m - 1):
1193 for i in xrange(n - 1):
1195 faces.append([nn+i, nn+i+1, nn+n+i+1, nn+n+i])
1197 if self.closed: #mesh closed in N-direction
1199 for i in xrange(n - 1):
1200 faces.append([nn+i, nn+i+1, i+1, i])
1202 if self.closeN: #mesh closed in M-direction
1203 for j in xrange(m-1):
1205 faces.append([nn+n-1, nn, nn+n, nn+n-1+n])
1207 if self.closed and self.closeN: #mesh closed in M/N-direction
1208 faces.append([ (n*m)-1, (m-1)*n, 0, n-1])
1210 #print 'deb:len of points_list:\n', len(points) #-----------------------
1211 #print 'deb:faces_list:\n', faces #-----------------------
1212 obname = 'pm_%s' %self.layer # create object name from layer name
1213 obname = obname[:MAX_NAMELENGTH]
1214 me = Mesh.New(obname) # create a new mesh
1215 ob = SCENE.objects.new(me) # create a new mesh_object
1216 me.verts.extend([point.loc for point in self.points]) # add vertices to mesh
1217 me.faces.extend(faces) # add faces to the mesh
1218 if settings.var['normals_out']: # ----------------------
1222 if settings.var['meshSmooth_on']: # ----------------------
1223 for i in xrange(len(faces)):
1224 me.faces[i].smooth = True
1225 #me.Mode(AUTOSMOOTH)
1227 transform(self.extrusion, 0, ob)
1228 #print 'deb:polymesh.draw.END:----------------' #------------------------
1232 def drawPolyCurve(self, settings): #---- Polyline - draw as Blender-curve
1233 """Generate the geometery of polyline as Blender-curve.
1235 #print 'deb:polyline2dCurve.draw.START:----------------' #---
1236 if len(self.points) < 2:
1237 #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
1240 if self.spline: pline_typ = 'ps' # Polyline-NURBSpline
1241 elif self.curved: pline_typ = 'pc' # Polyline-BezierCurve
1242 else: pline_typ = 'pl' # Polyline classic
1243 obname = '%s_%s' %(pline_typ, self.layer) # create object_name from layer name
1244 obname = obname[:MAX_NAMELENGTH]
1247 if settings.var['Z_force_on']:
1248 self.elevation = settings.var['Z_elev']
1249 for point in self.points:
1250 point.loc[2] = self.elevation
1251 d_points.append(point)
1252 else: #for DXFr10-format: update all points[].loc[2] == None -> 0.0
1253 for point in self.points:
1254 if point.loc[2] == None:
1255 point.loc[2] = self.elevation
1256 d_points.append(point)
1258 #d_points = self.tribles_out(settings, d_points)
1259 #d_points = self.doubles_out(settings, d_points)
1260 #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1262 thic = set_thick(self.thic, settings)
1263 if thic != 0.0: #hack: Blender<2.45 curve-extrusion
1264 LocZ = d_points[0].loc[2]
1266 for point in d_points:
1268 temp_points.append(point)
1269 d_points = temp_points
1271 #print 'deb:polyline2dCurve.draw d_points=', d_points #---------------
1272 pline = Curve.New(obname) # create new curve data
1273 #pline.setResolu(24) #--todo-----
1275 if False: #old self.spline: # NURBSplines-----OK-----
1276 #print 'deb:polyline2dCurve.draw self.spline!' #---------------
1279 if self.curvQuadrati:
1280 # Bezier-curve form simulated in NURBS-curve
1281 # generate middlepoints except start/end-segments ---
1282 #print 'deb:polyline2dCurve.draw extraQBspline!' #---------------
1284 point = d_points[0].loc
1285 point.append(weight1)
1286 temp_points.append(point)
1287 for i in xrange(1,len(d_points)-2):
1288 point1 = d_points[i].loc
1289 point2 = d_points[i+1].loc
1290 mpoint = list((Mathutils.Vector(point1) + Mathutils.Vector(point2)) * 0.5)
1291 mpoint.append(weight2)
1292 point1.append(weight1)
1293 temp_points.append(point1)
1294 temp_points.append(mpoint)
1295 point2.append(weight1)
1296 temp_points.append(point2)
1297 point = d_points[-1].loc
1298 point.append(weight1)
1299 temp_points.append(point)
1300 d_points = temp_points
1306 temp_points.append(d)
1307 d_points = temp_points
1310 # generate extended startpoint and endpoint------
1311 point1 = Mathutils.Vector(d_points[0][:3])
1312 point2 = Mathutils.Vector(d_points[1][:3])
1313 startpoint = list(point1 - point2 + point1)
1314 startpoint.append(weight1)
1315 point1 = Mathutils.Vector(d_points[-1][:3])
1316 point2 = Mathutils.Vector(d_points[-2][:3])
1317 endpoint = list(point1 - point2 + point1)
1318 endpoint.append(weight1)
1320 temp_points.append(startpoint)
1321 temp_points.extend(d_points)
1322 d_points = temp_points
1323 d_points.append(endpoint)
1326 curve = pline.appendNurb(point)
1327 curve.setType(4) #NURBS curve
1328 for point in d_points[1:]:
1331 curve.flagU = 1 # Set curve cyclic=close
1333 curve.flagU = 0 # Set curve not cyclic=open
1335 if self.spline: # NURBSplines-----OK-----
1336 #print 'deb:polyline2dCurve.draw self.spline!' #---------------
1340 pkt.append(d.weight)
1341 nurbs_points.append(pkt)
1342 firstpoint = nurbs_points[0]
1343 curve = pline.appendNurb(firstpoint)
1344 curve.setType(4) # set curvetype NURBS
1345 for point in nurbs_points[1:]:
1348 curve.flagU = 1+0 # Set curve cyclic=close and uni
1350 curve.flagU = 0+2 # Set curve not cyclic=open
1351 try: curve.orderU = 5 # works only with >2.46svn080625
1352 except AttributeError: pass
1353 #print 'deb: dir(curve):', dir(curve) #----------------
1355 elif False: #orig self.curved: #--Bezier-curves---OK-------
1356 #print 'deb:polyline2dCurve.draw self.curved!' #---------------
1357 curve = pline.appendNurb(BezTriple.New(d_points[0]))
1358 for p in d_points[1:]:
1359 curve.append(BezTriple.New(p))
1361 point.handleTypes = [AUTO, AUTO]
1363 curve.flagU = 1 # Set curve cyclic=close
1365 curve.flagU = 0 # Set curve not cyclic=open
1366 curve[0].handleTypes = [FREE, ALIGN] #remi--todo-----
1367 curve[-1].handleTypes = [ALIGN, FREE] #remi--todo-----
1369 elif self.curved: #--SPLINE as Bezier-curves---wip------
1370 #print 'deb:polyline2dCurve.draw self.curved!' #---------------
1371 begtangent, endtangent = None, None
1372 if d_points[0].tangent:
1373 begtangent = d_points[0]
1374 d_points = d_points[1:]
1375 if d_points[-1].tangent:
1376 endtangent = d_points[-1]
1377 d_points = d_points[:-1]
1378 curve = pline.appendNurb(BezTriple.New(d_points[0]))
1379 for p in d_points[1:]:
1380 curve.append(BezTriple.New(p))
1382 point.handleTypes = [AUTO, AUTO]
1383 #curve.setType(1) #Bezier curve
1385 curve.flagU = 5 #1 # Set curve cyclic=close
1387 curve.flagU = 4 #0 # Set curve not cyclic=open
1389 #print 'deb:polyline2dCurve.draw curve[0].vec:', curve[0].vec #-----
1390 #print 'deb:polyline2dCurve.draw begtangent:', begtangent #-----
1391 p0h1,p0,p0h2 = curve[0].vec
1392 p0h1 = [p0h1[i]+begtangent[i] for i in range(3)]
1393 curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
1394 curve[0].handleTypes = [FREE, ALIGN] #remi--todo-----
1396 #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
1397 #print 'deb:polyline2dCurve.draw endtangent:', endtangent #-----
1398 p0h1,p0,p0h2 = curve[-1].vec
1399 p0h2 = [p0h2[i]+endtangent[i] for i in range(3)]
1400 #print 'deb:drawPlineCurve: p0h2:', p0h2 #----------
1401 curve.__setitem__(-1,BezTriple.New(p0h1+p0+p0h2))
1402 #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
1403 curve[-1].handleTypes = [ALIGN, FREE] #remi--todo-----
1407 else: #-- only straight line- and arc-segments----OK------
1408 #print 'deb:polyline2dCurve.draw curve:', curve #-----
1410 arc_res = settings.var['curve_arc']
1411 prevHandleType = VECT
1412 #d_points.append(d_points[0]) #------ first vertex added at the end of list --------
1413 #curve.setType(0) #polygon_type of Blender_curve
1414 for i in xrange(len(d_points)):
1415 point1 = d_points[i]
1416 #point2 = d_points[i+1]
1417 if False: #-----outdated!- standard calculation ----------------------------------
1418 if point1.bulge and (i < len(d_points)-2 or self.closed):
1419 verts, center = calcBulge(point1, point2, arc_res, triples=False)
1420 if i == 0: curve = pline.appendNurb(BezTriple.New(verts[0]))
1421 else: curve.append(BezTriple.New(verts[0]))
1422 curve[-1].handleTypes = [VECT, VECT] #--todo--calculation of bezier-tangents
1424 curve.append(BezTriple.New(p))
1425 curve[-1].handleTypes = [AUTO, AUTO]
1427 if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
1428 else: curve.append(BezTriple.New(point1.loc))
1429 curve[-1].handleTypes = [VECT, VECT] #--todo--calculation of bezier-tangents
1431 elif True: #----- optimised Bezier-Handles calculation --------------------------------
1432 #print 'deb:drawPlineCurve: i:', i #---------
1433 if point1.bulge and not (i == len(d_points)-1 and point1.bulge and not self.closed):
1434 if i == len(d_points)-1: point2 = d_points[0]
1435 else: point2 = d_points[i+1]
1438 # calculate additional points for bulge
1439 VectorTriples = calcBulge(point1, point2, arc_res, triples=True)
1441 if prevHandleType == FREE:
1442 #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
1443 VectorTriples[0][:3] = prevHandleVect
1444 #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
1446 if i == 0: curve = pline.appendNurb(BezTriple.New(VectorTriples[0]))
1447 else: curve.append(BezTriple.New(VectorTriples[0]))
1448 curve[-1].handleTypes = [prevHandleType, FREE]
1450 for p in VectorTriples[1:-1]:
1451 curve.append(BezTriple.New(p))
1452 curve[-1].handleTypes = [FREE, FREE]
1454 prevHandleVect = VectorTriples[-1][:3]
1455 prevHandleType = FREE
1456 #print 'deb:drawPlineCurve: prevHandleVect:', prevHandleVect #---------
1458 #print 'deb:drawPlineCurve: else' #----------
1459 if prevHandleType == FREE:
1460 VectorTriples = prevHandleVect + list(point1) + list(point1)
1461 #print 'deb:drawPlineCurve: VectorTriples:', VectorTriples #---------
1462 curve.append(BezTriple.New(VectorTriples))
1463 curve[-1].handleTypes = [FREE, VECT]
1464 prevHandleType = VECT
1466 if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
1467 else: curve.append(BezTriple.New(point1.loc))
1468 curve[-1].handleTypes = [VECT, VECT]
1472 #print 'deb:drawPlineCurve: curve[-1].vec[0]', curve[-1].vec[0] #----------
1475 curve.flagU = 1 # Set curve cyclic=close
1476 if prevHandleType == FREE:
1477 #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
1478 #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
1479 prevHandleType2 = curve[0].handleTypes[1]
1480 p0h1,p0,p0h2 = curve[0].vec
1481 #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
1482 p0h1 = prevHandleVect
1484 #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
1485 #curve[0].vec = [p0h1,p0,p0h2]
1486 curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
1488 curve[0].handleTypes = [FREE,prevHandleType2]
1489 #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
1490 #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
1492 curve[0].handleTypes[0] = VECT
1494 curve.flagU = 0 # Set curve not cyclic=open
1496 if settings.var['fill_on']:
1497 pline.setFlag(6) # 2+4 set top and button caps
1499 pline.setFlag(pline.getFlag() & ~6) # dont set top and button caps
1501 pline.setResolu(settings.var['curve_res'])
1503 ob = SCENE.objects.new(pline) # create a new curve_object
1505 if thic != 0.0: #hack: Blender<2.45 curve-extrusion
1507 pline.setExt1(1.0) # curve-extrusion accepts only (0.0 - 2.0)
1508 ob.LocZ = thic + LocZ
1510 transform(self.extrusion, 0, ob)
1512 ob.SizeZ *= abs(thic)
1514 #print 'deb:polyline2dCurve.draw.END:----------------' #-----
1518 def drawPoly2d(self, settings): #---- 2dPolyline - plane lines/arcs with wide/thic
1519 """Generate the geometery of regular polyline.
1521 #print 'deb:polyline2d.draw.START:----------------' #------------------------
1526 swidth_default = self.swidth #default start width of POLYLINEs segments
1527 ewidth_default = self.ewidth #default end width of POLYLINEs segments
1528 #print 'deb:drawPoly2d self.swidth=', self.swidth #------------------------
1529 thic = set_thick(self.thic, settings)
1530 if self.spline: pline_typ = 'ps'
1531 elif self.curved: pline_typ = 'pc'
1532 else: pline_typ = 'pl'
1533 obname = '%s_%s' %(pline_typ, self.layer) # create object_name from layer name
1534 obname = obname[:MAX_NAMELENGTH]
1536 if len(self.points) < 2:
1537 #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
1540 if settings.var['Z_force_on']:
1541 self.elevation = settings.var['Z_elev']
1542 for point in self.points:
1543 point.loc[2] = self.elevation
1544 d_points.append(point)
1545 else: #for DXFr10-format: update all non-existing LocZ points[].loc[2] == None -> 0.0 elevation
1546 for point in self.points:
1547 if point.loc[2] == None:
1548 point.loc[2] = self.elevation
1549 d_points.append(point)
1550 #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1551 #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
1554 #if closed polyline, add duplic of the first vertex at the end of pointslist
1555 if self.closed: #new_b8
1556 if d_points[-1].loc != d_points[0].loc: # if not equal, then set the first at the end of pointslist
1557 d_points.append(d_points[0])
1559 if d_points[-1].loc == d_points[0].loc: # if equal, then set to closed, and modify the last point
1560 d_points[-1] = d_points[0]
1562 #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1563 #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
1565 d_points = self.doubles_out(settings, d_points)
1566 #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1568 """# routine to sort out of "double.vertices" ------------------------------------
1569 minimal_dist = settings.var['dist_min'] * 0.1
1571 for i in xrange(len(d_points)-1):
1573 point2 = d_points[i+1]
1574 #print 'deb:double.vertex p1,p2', point, point2 #------------------------
1575 delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
1576 if delta.length > minimal_dist:
1577 temp_points.append(point)
1578 #else: print 'deb:drawPoly2d double.vertex sort out!' #------------------------
1579 temp_points.append(d_points[-1]) #------ incl. last vertex -------------
1580 #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
1581 d_points = temp_points #-----vertex.list without "double.vertices"
1582 #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1585 #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1586 if len(d_points) < 2: #if too few vertex, then return
1587 #print 'deb:drawPoly2d corrupted Vertices' #---------
1590 # analyze of straight- and bulge-segments
1591 # generation of additional points for bulge segments
1592 arc_res = settings.var['arc_res']/sqrt(settings.var['arc_rad'])
1593 wide_segment_exist = False
1594 bulg_points = [] # for each point set None (or center for arc-subPoints)
1595 for i in xrange(len(d_points)-1):
1596 point1 = d_points[i]
1597 point2 = d_points[i+1]
1598 #print 'deb:drawPoly2d_bulg tocalc.point1:', point1 #------------------------
1599 #print 'deb:drawPoly2d_bulg tocalc.point2:', point2 #------------------------
1601 swidth = point1.swidth
1602 ewidth = point1.ewidth
1603 #print 'deb:drawPoly2d point1.swidth=', swidth #------------------------
1604 if swidth == None: swidth = swidth_default
1605 if ewidth == None: ewidth = ewidth_default
1606 if swidth != 0.0 or ewidth != 0.0: wide_segment_exist = True
1607 #print 'deb:drawPoly2d vertex_swidth=', swidth #------------------------
1609 if settings.var['width_force']: # force minimal width for thin segments
1610 width_min = settings.var['width_min']
1611 if swidth < width_min: swidth = width_min
1612 if ewidth < width_min: ewidth = width_min
1613 if not settings.var['width_on']: # then force minimal width for all segments
1617 #if point1.bulge and (i < (len(d_points)-1) or self.closed):
1618 if point1.bulge and i < (len(d_points)-1): #10_b8
1619 verts, center = calcBulge(point1, point2, arc_res) #calculate additional points for bulge
1620 points.extend(verts)
1621 delta_width = (ewidth - swidth) / len(verts)
1622 width_list = [swidth + (delta_width * ii) for ii in xrange(len(verts)+1)]
1623 swidths.extend(width_list[:-1])
1624 ewidths.extend(width_list[1:])
1625 bulg_list = [center for ii in xrange(len(verts))]
1626 #the last point in bulge has index False for better indexing of bulg_end!
1627 bulg_list[-1] = None
1628 bulg_points.extend(bulg_list)
1631 points.append(point1.loc)
1632 swidths.append(swidth)
1633 ewidths.append(ewidth)
1634 bulg_points.append(None)
1635 points.append(d_points[-1].loc)
1638 #--calculate width_vectors: left-side- and right-side-points ----------------
1639 # 1.level:IF width ---------------------------------------
1640 if (settings.var['width_on'] and wide_segment_exist) or settings.var['width_force']:
1641 #new_b8 points.append(d_points[0].loc) #temporarly add first vertex at the end (for better loop)
1642 dist_min05 = 0.5 * settings.var['dist_min'] #minimal width for zero_witdh
1644 pointsLs = [] # list of left-start-points
1645 pointsLe = [] # list of left-end-points
1646 pointsRs = [] # list of right-start-points
1647 pointsRe = [] # list of right-end-points
1648 pointsW = [] # list of all border-points
1649 #rotMatr90 = Mathutils.Matrix(rotate 90 degree around Z-axis) = normalvectorXY
1650 rotMatr90 = Mathutils.Matrix([0, -1, 0], [1, 0, 0], [0, 0, 1])
1652 last_bulg_point = False
1653 for i in xrange(len(points)-1):
1655 point2 = points[i+1]
1656 point1vec = Mathutils.Vector(point1)
1657 point2vec = Mathutils.Vector(point2)
1658 swidth05 = swidths[i] * 0.5
1659 ewidth05 = ewidths[i] * 0.5
1660 if swidth05 == 0: swidth05 = dist_min05
1661 if ewidth05 == 0: ewidth05 = dist_min05
1662 normal_vector = rotMatr90 * (point2vec-point1vec).normalize()
1664 last_bulg_point = False
1666 elif bulg_points[i] != None:
1667 centerVec = Mathutils.Vector(bulg_points[i])
1668 if bulg_points[i+1] == None: last_bulg_point = True
1670 else: bulg_in = False
1673 #makes clean intersections for arc-segments
1674 radius1vec = point1vec - centerVec
1675 radius2vec = point2vec - centerVec
1676 angle = Mathutils.AngleBetweenVecs(normal_vector, radius1vec)
1678 normal_vector1 = radius1vec.normalize()
1679 normal_vector2 = radius2vec.normalize()
1681 normal_vector1 = - radius1vec.normalize()
1682 normal_vector2 = - radius2vec.normalize()
1684 swidth05vec = swidth05 * normal_vector1
1685 ewidth05vec = ewidth05 * normal_vector2
1686 pointsLs.append(point1vec + swidth05vec) #vertex left start
1687 pointsRs.append(point1vec - swidth05vec) #vertex right start
1688 pointsLe.append(point2vec + ewidth05vec) #vertex left end
1689 pointsRe.append(point2vec - ewidth05vec) #vertex right end
1692 swidth05vec = swidth05 * normal_vector
1693 ewidth05vec = ewidth05 * normal_vector
1694 pointsLs.append(point1vec + swidth05vec) #vertex left start
1695 pointsRs.append(point1vec - swidth05vec) #vertex right start
1696 pointsLe.append(point2vec + ewidth05vec) #vertex left end
1697 pointsRe.append(point2vec - ewidth05vec) #vertex right end
1699 # additional last point is also calculated
1700 #pointsLs.append(pointsLs[0])
1701 #pointsRs.append(pointsRs[0])
1702 #pointsLe.append(pointsLe[0])
1703 #pointsRe.append(pointsRe[0])
1705 pointsLc, pointsRc = [], [] # lists Left/Right corners = intersection points
1707 # 2.level:IF width and corner-trim
1708 if settings.var['pl_trim_on']: #optional clean corner-intersections
1710 # set STARTpoints of the first point points[0]
1712 pointsLc.append(pointsLs[0])
1713 pointsRc.append(pointsRs[0])
1715 pointsLs.append(pointsLs[0])
1716 pointsRs.append(pointsRs[0])
1717 pointsLe.append(pointsLe[0])
1718 pointsRe.append(pointsRe[0])
1719 points.append(points[0])
1720 vecL3, vecL4 = pointsLs[0], pointsLe[0]
1721 vecR3, vecR4 = pointsRs[0], pointsRe[0]
1722 lenL = len(pointsLs)-1
1723 #print 'deb:drawPoly2d pointsLs():\n', pointsLs #----------------
1724 #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs) #----------------
1726 last_bulg_point = False
1728 # LOOP: makes (ENDpoints[i],STARTpoints[i+1])
1729 for i in xrange(lenL):
1730 if bulg_points[i] != None:
1731 if bulg_points[i+1] == None: #makes clean intersections for arc-segments
1732 last_bulg_point = True
1735 #pointsLc.extend((points[i], pointsLs[i]))
1736 #pointsRc.extend((points[i], pointsRs[i]))
1737 vecL1, vecL2 = vecL3, vecL4
1738 vecR1, vecR2 = vecR3, vecR4
1739 vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
1740 vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
1741 #compute left- and right-cornerpoints
1742 #cornerpointL = Geometry.LineIntersect2D(vec1, vec2, vec3, vec4)
1743 cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
1744 cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
1745 #print 'deb:drawPoly2d cornerpointL: ', cornerpointL #-------------
1746 #print 'deb:drawPoly2d cornerpointR: ', cornerpointR #-------------
1748 # IF not cornerpoint THEN check if identic start-endpoints (=collinear segments)
1749 if cornerpointL == None or cornerpointR == None:
1750 if vecL2 == vecL3 and vecR2 == vecR3:
1751 #print 'deb:drawPoly2d pointVec: ####### identic ##########' #----------------
1752 pointsLc.append(pointsLe[i])
1753 pointsRc.append(pointsRe[i])
1755 pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1756 pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1758 cornerpointL = cornerpointL[0] # because Mathutils.LineIntersect() -> (pkt1,pkt2)
1759 cornerpointR = cornerpointR[0]
1760 #print 'deb:drawPoly2d cornerpointL: ', cornerpointL #-------------
1761 #print 'deb:drawPoly2d cornerpointR: ', cornerpointR #-------------
1762 pointVec0 = Mathutils.Vector(points[i])
1763 pointVec = Mathutils.Vector(points[i+1])
1764 pointVec2 = Mathutils.Vector(points[i+2])
1765 #print 'deb:drawPoly2d pointVec0: ', pointVec0 #-------------
1766 #print 'deb:drawPoly2d pointVec: ', pointVec #-------------
1767 #print 'deb:drawPoly2d pointVec2: ', pointVec2 #-------------
1768 # if diststance(cornerL-center-cornerR) < limiter * (seg1_endWidth + seg2_startWidth)
1769 max_cornerDist = (vecL2 - vecR2).length + (vecL3 - vecR3).length
1770 is_cornerDist = (cornerpointL - pointVec).length + (cornerpointR - pointVec).length
1771 #corner_angle = Mathutils.AngleBetweenVecs((pointVec0 - pointVec),(pointVec - pointVec2))
1772 #print 'deb:drawPoly2d corner_angle: ', corner_angle #-------------
1773 #print 'deb:drawPoly2d max_cornerDist, is_cornerDist: ', max_cornerDist, is_cornerDist #-------------
1774 #if abs(corner_angle) < 90.0:
1775 # intersection --------- limited by TRIM_LIMIT (1.0 - 5.0)
1776 if is_cornerDist < max_cornerDist * settings.var['pl_trim_max']:
1777 # clean corner intersection
1778 pointsLc.append(cornerpointL)
1779 pointsRc.append(cornerpointR)
1780 elif False: # the standard no-intersection
1781 # --todo-- not optimal, because produces X-face
1782 pointsLc.extend((pointsLe[i],pointsLs[i+1]))
1783 pointsRc.extend((pointsRe[i],pointsRs[i+1]))
1784 elif False: # --todo-- the optimised non-intersection
1785 if (cornerpointL - vecL1).length < (cornerpointR - vecR1).length:
1789 limit_dist = settings.var['dist_min']
1790 if left_angle: # if left turning angle
1791 #print 'deb:drawPoly2d it is left turning angle' #-------------
1792 # to avoid triangelface/doubleVertex
1793 delta1 = (cornerpointL - vecL1).normalize() * limit_dist
1794 delta4 = (cornerpointL - vecL4).normalize() * limit_dist
1795 pointsLc.extend((cornerpointL - delta1, cornerpointL - delta4))
1796 pointsRc.extend((pointsRe[i],pointsRs[i+1]))
1797 else: # if right turning angle
1798 #print 'deb:drawPoly2d right turning angle' #-------------
1799 delta1 = (cornerpointR - vecR1).normalize() * limit_dist
1800 delta4 = (cornerpointR - vecR4).normalize() * limit_dist
1801 pointsRc.extend((cornerpointR - delta1, cornerpointR - delta4))
1802 pointsLc.extend((pointsLe[i],pointsLs[i+1]))
1804 pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1805 pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1807 pointsLc.append(pointsLe[-1])
1808 pointsRc.append(pointsRe[-1])
1810 # 2.level:IF width but no-trim
1813 # set STARTpoints of the first point points[0]
1815 pointsLc.append(pointsLs[0])
1816 pointsRc.append(pointsRs[0])
1818 pointsLs.append(pointsLs[0])
1819 pointsRs.append(pointsRs[0])
1820 pointsLe.append(pointsLe[0])
1821 pointsRe.append(pointsRe[0])
1822 points.append(points[0])
1823 vecL3, vecL4 = pointsLs[0], pointsLe[0]
1824 vecR3, vecR4 = pointsRs[0], pointsRe[0]
1825 lenL = len(pointsLs)-1
1826 #print 'deb:drawPoly2d pointsLs():\n', pointsLs #----------------
1827 #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs) #----------------
1829 last_bulg_point = False
1831 # LOOP: makes (ENDpoints[i],STARTpoints[i+1])
1832 for i in xrange(lenL):
1833 vecL1, vecL2 = vecL3, vecL4
1834 vecR1, vecR2 = vecR3, vecR4
1835 vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
1836 vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
1837 if bulg_points[i] != None:
1838 #compute left- and right-cornerpoints
1840 cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
1841 cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
1842 pointsLc.append(cornerpointL[0])
1843 pointsRc.append(cornerpointR[0])
1845 pointVec = Mathutils.Vector(point[i])
1848 pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1849 pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1851 pointsLc.append(pointsLe[-1])
1852 pointsRc.append(pointsRe[-1])
1854 len1 = len(pointsLc)
1855 #print 'deb:drawPoly2d len1:', len1 #-----------------------
1856 #print 'deb:drawPoly2d len1 len(pointsLc),len(pointsRc):', len(pointsLc),len(pointsRc) #-----------------------
1857 pointsW = pointsLc + pointsRc # all_points_List = left_side + right_side
1858 #print 'deb:drawPoly2d pointsW():\n', pointsW #----------------
1860 # 2.level:IF width and thickness ---------------------
1863 thic_pointsW.extend([[point[0], point[1], point[2]+thic] for point in pointsW])
1865 thic_pointsW.extend(pointsW)
1866 pointsW = thic_pointsW
1868 pointsW.extend(thic_pointsW)
1870 f_start, f_end = [], []
1871 f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
1872 f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
1873 f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
1874 f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
1877 f_bottom.append([len1-1, 0, len1, len1+len1-1]) #bottom face
1878 f_top.append( [len1+len1+len1-1, len1+len1+len1+len1-1, len1+len1+len1, len1+len1+0]) #top face
1879 f_left.append( [0, len1-1, len1+len1+len1-1, len1+len1]) #left face
1880 f_right.append( [len1, len1+len1+len1, len1+len1+len1+len1-1, len1+len1-1]) #right face
1882 f_start = [[0, len1, len1+len1+len1, len1+len1]]
1883 f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
1885 faces = f_left + f_right + f_bottom + f_top + f_start + f_end
1886 #faces = f_bottom + f_top
1887 #faces = f_left + f_right + f_start + f_end
1888 #print 'deb:faces_list:\n', faces #-----------------------
1889 if M_OBJ: obname, me, ob = makeNewObject()
1891 me = Mesh.New(obname) # create a new mesh
1892 ob = SCENE.objects.new(me) # create a new mesh_object
1893 me.verts.extend(pointsW) # add vertices to mesh
1894 me.faces.extend(faces) # add faces to the mesh
1896 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
1897 # The mesh must first be linked to an object so the method knows which object to update.
1898 # This is because vertex groups in Blender are stored in the object -- not in the mesh,
1899 # which may be linked to more than one object.
1900 if settings.var['vGroup_on'] and not M_OBJ:
1901 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
1902 replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD
1903 vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
1904 for v in f_left: vg_left.extend(v)
1905 for v in f_right: vg_right.extend(v)
1906 for v in f_top: vg_top.extend(v)
1907 for v in f_bottom: vg_bottom.extend(v)
1908 me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', list(set(vg_left)), 1.0, replace)
1909 me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
1910 me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
1911 me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
1913 me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
1914 me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace)
1916 if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
1917 #if self.spline or self.curved:
1919 smooth_len = len(f_left) + len(f_right)
1920 for i in xrange(smooth_len):
1921 me.faces[i].smooth = True
1922 #me.Modes(AUTOSMOOTH)
1924 # 2.level:IF width, but no-thickness ---------------------
1927 faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
1929 faces.append([len1, 0, len1-1, len1+len1-1])
1930 if M_OBJ: obname, me, ob = makeNewObject()
1932 me = Mesh.New(obname) # create a new mesh
1933 ob = SCENE.objects.new(me) # create a new mesh_object
1934 me.verts.extend(pointsW) # add vertices to mesh
1935 me.faces.extend(faces) # add faces to the mesh
1938 # 1.level:IF no-width, but thickness ---------------------
1942 thic_points.extend([[point[0], point[1], point[2]+thic] for point in points])
1944 thic_points.extend(points)
1945 points = thic_points
1947 points.extend(thic_points)
1949 faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
1951 faces.append([len1-1, 0, len1, 2*len1-1])
1952 if M_OBJ: obname, me, ob = makeNewObject()
1954 me = Mesh.New(obname) # create a new mesh
1955 ob = SCENE.objects.new(me) # create a new mesh_object
1956 me.verts.extend(points) # add vertices to mesh
1957 me.faces.extend(faces) # add faces to the mesh
1959 if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
1960 #if self.spline or self.curved:
1962 for i in xrange(len(faces)):
1963 me.faces[i].smooth = True
1964 #me.Modes(AUTOSMOOTH)
1966 # 1.level:IF no-width and no-thickness ---------------------
1968 edges = [[num, num+1] for num in xrange(len(points)-1)]
1970 edges.append([len(points)-1, 0])
1971 if M_OBJ: obname, me, ob = makeNewObject()
1973 me = Mesh.New(obname) # create a new mesh
1974 ob = SCENE.objects.new(me) # create a new mesh_object
1975 me.verts.extend(points) # add vertices to mesh
1976 me.edges.extend(edges) # add edges to the mesh
1978 transform(self.extrusion, 0, ob)
1979 #print 'deb:polyline.draw.END:----------------' #-----------------------
1985 class Vertex(object): #-----------------------------------------------------------------
1986 """Generic vertex object used by POLYLINEs, (and maybe others).
1987 also used by class_LWPOLYLINEs but without obj-parameter
1990 def __init__(self, obj=None):
1991 """Initializes vertex data.
1993 The optional obj arg is an entity object of type vertex.
1995 #print 'deb:Vertex.init.START:----------------' #-----------------------
1998 self.swidth = None #0
1999 self.ewidth = None #0
2001 self.tangent = False
2004 if not obj.type == 'vertex':
2005 raise TypeError, "Wrong type %s for vertex object!" %obj.type
2006 self.type = obj.type
2007 # self.data = obj.data[:]
2011 #print 'deb:Vertex.init.END:----------------' #------------------------
2014 def get_props(self, data):
2015 """Gets coords for a VERTEX type object.
2017 Each vert can have a number of properties.
2018 Verts should be coded as
2025 self.x = getit(data, 10, None)
2026 self.y = getit(data, 20, None)
2027 self.z = getit(data, 30, None)
2029 self.flags = getit(data, 70, 0) # flags
2030 self.curved = self.flags&1 # Bezier-curve-fit:additional-vertex
2031 self.curved_t = self.flags&2 # Bezier-curve-fit:tangent exists
2032 self.spline = self.flags&8 # NURBSpline-fit:additional-vertex
2033 self.spline_c = self.flags&16 # NURBSpline-fit:control-vertex
2034 self.poly3d = self.flags&32 # polyline3d:control-vertex
2035 self.plmesh = self.flags&64 # polymesh3d:control-vertex
2036 self.plface = self.flags&128 # polyface
2038 # if PolyFace.Vertex with Face_definition
2040 self.curve_tangent = getit(data, 50, None) # curve_tangent
2041 if not self.curve_tangent==None:
2043 #elif self.spline_c: # NURBSpline:control-vertex
2044 # self.weight = getit(data, 41, 1.0) # weight od control point
2046 elif self.plface and not self.plmesh:
2047 v1 = getit(data, 71, 0) # polyface:Face.vertex 1.
2048 v2 = getit(data, 72, 0) # polyface:Face.vertex 2.
2049 v3 = getit(data, 73, 0) # polyface:Face.vertex 3.
2050 v4 = getit(data, 74, None) # polyface:Face.vertex 4.
2051 self.face = [abs(v1)-1,abs(v2)-1,abs(v3)-1]
2053 if abs(v4) != abs(v1):
2054 self.face.append(abs(v4)-1)
2055 else: #--parameter for polyline2d
2056 self.swidth = getit(data, 40, None) # start width
2057 self.ewidth = getit(data, 41, None) # end width
2058 self.bulge = getit(data, 42, 0) # bulge of segment
2065 def __getitem__(self, key):
2066 return self.loc[key]
2069 def __setitem__(self, key, value):
2075 return self.loc.__iter__()
2079 return str(self.loc)
2083 return "Vertex %s, swidth=%s, ewidth=%s, bulge=%s, face=%s" %(self.loc, self.swidth, self.ewidth, self.bulge, self.face)
2088 def setx(self, value):
2090 x = property(getx, setx)
2095 def sety(self, value):
2097 y = property(gety, sety)
2102 def setz(self, value):
2104 z = property(getz, setz)
2108 class Spline(Polyline): #-----------------------------------------------------------------
2109 """Class for objects representing dxf SPLINEs.
2111 """Expects an entity object of type spline as input.
2112 100 - Subclass marker (AcDbSpline)
2113 210,220, 230 - Normal vector (omitted if the spline is nonplanar) X,Y,Z values of normal vector
2114 70 - Spline flag (bit coded):
2119 16 = Linear (planar bit is also set)
2120 71 - Degree of the spline curve
2121 72 - Number of knots
2122 73 - Number of control points
2123 74 - Number of fit points (if any)
2124 42 - Knot tolerance (default = 0.0000001)
2125 43 - Control-point tolerance (default = 0.0000001)
2126 44 - Fit tolerance (default = 0.0000000001)
2127 12,22,32 - Start tangent--may be omitted (in WCS). X,Y,Z values of start tangent--may be omitted (in WCS).
2128 13,23, 33 - End tangent--may be omitted (in WCS). X,Y,Z values of end tangent--may be omitted (in WCS)
2129 40 - Knot value (one entry per knot)
2130 41 - Weight (if not 1); with multiple group pairs, are present if all are not 1
2131 10,20, 30 - Control points (in WCS) one entry per control point.
2132 DXF: X value; APP: 3D point, Y and Z values of control points (in WCS) (one entry per control point)
2133 11,21, 31 - Fit points (in WCS) one entry per fit point.
2134 X,Y,Z values of fit points (in WCS) (one entry per fit point)
2136 def __init__(self, obj):
2137 #print 'deb:Spline.START:----------------' #------------------------
2138 if not obj.type == 'spline':
2139 raise TypeError, "Wrong type %s for spline object!" %obj.type
2140 self.type = obj.type
2141 # self.data = obj.data[:]
2144 self.num_points = obj.get_type(73)[0]
2146 # optional data (with defaults)
2147 self.space = getit(obj, 67, 0)
2149 self.color_index = getit(obj, 62, BYLAYER)
2151 #self.elevation = getit(obj, 30, 0)
2152 self.thic = 0 # getit(obj, 39, 0)
2155 self.swidth = width # default start width
2156 self.ewidth = width # default end width
2158 self.flags = getit(obj, 70, 0)
2159 self.closed = self.flags & 1 # closed spline
2160 self.period = self.flags & 2 # Periodic spline
2161 self.ration = self.flags & 4 # Rational spline
2162 self.planar = self.flags & 8 # Planar
2163 self.linear = self.flags & 16 # Linear (and Planar)
2165 self.curvNoFitted = False
2166 self.curvQuadrati = False
2167 self.curvCubicBsp = False
2168 self.curvBezier = False
2169 self.degree = getit(obj, 71, 0) # Degree of the spline curve
2170 if self.degree == 0: self.curvNoFitted = True
2171 elif self.degree == 1: self.curvQuadrati = True
2172 elif self.degree == 2: self.curvCubicBsp = True
2173 #elif self.degree == 3: self.curvBezier = True
2174 #elif self.degree == 3: self.spline = True
2176 self.knotpk_len = getit(obj, 72, 0) # Number of knots
2177 self.ctrlpk_len = getit(obj, 73, 0) # Number of control points
2178 self.fit_pk_len = getit(obj, 74, 0) # Number of fit points (if any)
2180 #print 'deb:Spline self.fit_pk_len=', self.fit_pk_len #------------------------
2181 #self.fit_pk_len = 0 # temp for debug
2182 if self.fit_pk_len and 'spline_as'==5:
2189 self.knotpk_tol = getit(obj, 42, 0.0000001) # Knot tolerance (default = 0.0000001)
2190 self.ctrlpk_tol = getit(obj, 43, 0.0000001) # Control-point tolerance (default = 0.0000001)
2191 self.fit_pk_tol = getit(obj, 44, 0.0000000001) # Fit tolerance (default = 0.0000000001)
2193 self.layer = getit(obj, 8, None)
2194 self.extrusion = get_extrusion(obj)
2196 self.pltype = 'spline' # spline is a 2D- or 3D-polyline
2198 self.points = self.get_points(obj.data)
2199 #self.knots_val = self.get_knots_val(obj.data) # 40 - Knot value (one entry per knot)
2200 #self.knots_wgh = self.get_knots_wgh(obj.data) # 41 - Weight (default 1)
2202 #print 'deb:Spline obj.data:\n', obj.data #------------------------
2203 #print 'deb:Spline self.points:\n', self.points #------------------------
2204 #print 'deb:Spline.ENDinit:----------------' #------------------------
2207 def get_points(self, data):
2208 """Gets points for a spline type object.
2210 Splines have fixed number of verts, and
2211 each vert can have a number of properties.
2212 Verts should be coded as
2221 if self.spline: # NURBSpline definition
2223 #print 'deb:Spline.get_points spilne_item:', item #------------------------
2224 if item[0] == 10: # control point
2225 if point: points.append(point)
2229 elif item[0] == 20: # 20 = y
2231 elif item[0] == 30: # 30 = z
2233 elif item[0] == 41: # 41 = weight
2234 point.weight = item[1]
2235 #print 'deb:Spline.get_points control point:', point #------------------------
2237 elif self.curved: # Bezier definition
2239 #print 'deb:Spline.get_points curved_item:', item #------------------------
2240 if item[0] == 11: # fit point
2241 if point: points.append(point)
2243 point.tangent = False
2245 elif item[0] == 21: # 20 = y
2247 elif item[0] == 31: # 30 = z
2249 #print 'deb:Spline.get_points fit point:', point #------------------------
2251 elif item[0] == 12: # start tangent
2252 if point: points.append(point)
2254 point.tangent = True
2256 elif item[0] == 22: # = y
2258 elif item[0] == 32: # = z
2260 #print 'deb:Spline.get_points fit begtangent:', point #------------------------
2262 elif item[0] == 13: # end tangent
2263 if point: points.append(point)
2265 pointend.tangent = True
2266 pointend.x = item[1]
2267 elif item[0] == 23: # 20 = y
2268 pointend.y = item[1]
2269 elif item[0] == 33: # 30 = z
2270 pointend.z = item[1]
2271 #print 'deb:Spline.get_points fit endtangent:', pointend #------------------------
2272 points.append(point)
2273 if self.curved and pointend:
2274 points.append(pointend)
2275 #print 'deb:Spline points:\n', points #------------------------
2279 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
2283 class LWpolyline(Polyline): #-------------------------------------------------------------
2284 """Class for objects representing dxf LWPOLYLINEs.
2286 def __init__(self, obj):
2287 """Expects an entity object of type lwpolyline as input.
2289 #print 'deb:LWpolyline.START:----------------' #------------------------
2290 if not obj.type == 'lwpolyline':
2291 raise TypeError, "Wrong type %s for polyline object!" %obj.type
2292 self.type = obj.type
2293 # self.data = obj.data[:]
2296 self.num_points = obj.get_type(90)[0]
2298 # optional data (with defaults)
2299 self.space = getit(obj, 67, 0)
2300 self.elevation = getit(obj, 38, 0)
2301 self.thic = getit(obj, 39, 0)
2302 self.color_index = getit(obj, 62, BYLAYER)
2303 width = getit(obj, 43, 0)
2304 self.swidth = width # default start width
2305 self.ewidth = width # default end width
2306 #print 'deb:LWpolyline width=', width #------------------------
2307 #print 'deb:LWpolyline elevation=', self.elevation #------------------------
2309 self.flags = getit(obj, 70, 0)
2310 self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen
2312 self.layer = getit(obj, 8, None)
2313 self.extrusion = get_extrusion(obj)
2315 self.points = self.get_points(obj.data)
2317 self.pltype = 'poly2d' # LW-polyline is a 2D-polyline
2322 #print 'deb:LWpolyline.obj.data:\n', obj.data #------------------------
2323 #print 'deb:LWpolyline.ENDinit:----------------' #------------------------
2326 def get_points(self, data):
2327 """Gets points for a polyline type object.
2329 LW-Polylines have no fixed number of verts, and
2330 each vert can have a number of properties.
2331 Verts should be coded as
2339 num = self.num_points
2343 if item[0] == 10: # 10 = x
2345 points.append(point)
2348 point.z = self.elevation
2349 elif item[0] == 20: # 20 = y
2351 elif item[0] == 40: # 40 = start width
2352 point.swidth = item[1]
2353 elif item[0] == 41: # 41 = end width
2354 point.ewidth = item[1]
2355 elif item[0] == 42: # 42 = bulge
2356 point.bulge = item[1]
2357 points.append(point)
2362 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
2365 class Text: #-----------------------------------------------------------------
2366 """Class for objects representing dxf TEXT.
2368 def __init__(self, obj):
2369 """Expects an entity object of type text as input.
2371 if not obj.type == 'text':
2372 raise TypeError, "Wrong type %s for text object!" %obj.type
2373 self.type = obj.type
2374 # self.data = obj.data[:]
2377 self.height = 1.7 * obj.get_type(40)[0] #text.height
2378 self.value = obj.get_type(1)[0] #The text string value
2380 # optional data (with defaults)
2381 self.space = getit(obj, 67, 0)
2382 self.color_index = getit(obj, 62, BYLAYER)
2383 self.thic = getit(obj, 39, 0)
2385 self.rotation = getit(obj, 50, 0) # radians
2386 self.width_factor = getit(obj, 41, 1) # Scaling factor along local x axis
2387 self.oblique = getit(obj, 51, 0) # oblique angle: skew in degrees -90 <= oblique <= 90
2389 #self.style = getit(obj, 7, 'STANDARD') # --todo---- Text style name (optional, default = STANDARD)
2391 #Text generation flags (optional, default = 0):
2392 #2 = backward (mirrored in X),
2393 #4 = upside down (mirrored in Y)
2394 self.flags = getit(obj, 71, 0)
2395 self.mirrorX, self.mirrorY = 1.0, 1.0
2396 if self.flags&2: self.mirrorX = - 1.0
2397 if self.flags&4: self.mirrorY = - 1.0
2399 # vertical.alignment: 0=baseline, 1=bottom, 2=middle, 3=top
2400 self.valignment = getit(obj, 73, 0)
2401 #Horizontal text justification type (optional, default = 0) integer codes (not bit-coded)
2402 #0=left, 1=center, 2=right
2403 #3=aligned, 4=middle, 5=fit
2404 self.halignment = getit(obj, 72, 0)
2406 self.layer = getit(obj, 8, None)
2407 self.loc1, self.loc2 = self.get_loc(obj)
2408 if self.loc2[0] != None and self.halignment != 5:
2409 self.loc = self.loc2
2411 self.loc = self.loc1
2412 self.extrusion = get_extrusion(obj)
2415 def get_loc(self, data):
2416 """Gets adjusted location for text type objects.
2418 If group 72 and/or 73 values are nonzero then the first alignment point values
2419 are ignored and AutoCAD calculates new values based on the second alignment
2420 point and the length and height of the text string itself (after applying the
2421 text style). If the 72 and 73 values are zero or missing, then the second
2422 alignment point is meaningless.
2423 I don't know how to calc text size...
2425 # bottom left x, y, z and justification x, y, z = 0
2426 #x, y, z, jx, jy, jz = 0, 0, 0, 0, 0, 0
2427 x = getit(data, 10, None) #First alignment point (in OCS).
2428 y = getit(data, 20, None)
2429 z = getit(data, 30, 0.0)
2430 jx = getit(data, 11, None) #Second alignment point (in OCS).
2431 jy = getit(data, 21, None)
2432 jz = getit(data, 31, 0.0)
2433 return [x, y, z],[jx, jy, jz]
2437 return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
2440 def draw(self, settings):
2441 """for TEXTs: generate Blender_geometry.
2443 obname = 'tx_%s' %self.layer # create object name from layer name
2444 obname = obname[:MAX_NAMELENGTH]
2445 txt = Text3d.New(obname)
2446 ob = SCENE.objects.new(txt) # create a new text_object
2448 txt.setText(self.value)
2449 txt.setSize(1.0) #Blender<2.45 accepts only (0.0 - 5.0)
2450 #txt.setSize(self.height)
2451 #txt.setWidth(self.bold)
2452 #setLineSeparation(sep)
2453 txt.setShear(self.oblique/90)
2455 thic = set_thick(self.thic, settings)
2457 thic = self.thic * 0.5
2459 txt.setExtrudeDepth(1.0) #Blender<2.45 accepts only (0.1 - 10.0)
2460 if self.halignment == 0:
2462 elif self.halignment == 1:
2463 align = Text3d.MIDDLE
2464 elif self.halignment == 2:
2465 align = Text3d.RIGHT
2468 txt.setAlignment(align)
2470 if self.valignment == 1:
2472 elif self.valignment == 2:
2473 txt.setYoffset(- self.height * 0.5)
2474 elif self.valignment == 3:
2475 txt.setYoffset(- self.height)
2477 # move the object center to the text location
2478 ob.loc = tuple(self.loc)
2479 transform(self.extrusion, self.rotation, ob)
2481 # flip it and scale it to the text width
2482 ob.SizeX *= self.height * self.width_factor * self.mirrorX
2483 ob.SizeY *= self.height * self.mirrorY
2484 if thic != 0.0: ob.SizeZ *= abs(thic)
2489 def set_thick(thickness, settings):
2490 """Set thickness relative to settings variables.
2492 Set thickness relative to settings variables:
2493 'thick_on','thick_force','thick_min'.
2494 Accepted also minus values of thickness
2495 python trick: sign(x)=cmp(x,0)
2497 if settings.var['thick_force']:
2498 if settings.var['thick_on']:
2499 if abs(thickness) < settings.var['thick_min']:
2500 thic = settings.var['thick_min'] * cmp(thickness,0)
2501 else: thic = thickness
2502 else: thic = settings.var['thick_min']
2504 if settings.var['thick_on']: thic = thickness
2511 class Mtext: #-----------------------------------------------------------------
2512 """Class for objects representing dxf MTEXT.
2515 def __init__(self, obj):
2516 """Expects an entity object of type mtext as input.
2518 if not obj.type == 'mtext':
2519 raise TypeError, "Wrong type %s for mtext object!" %obj.type
2520 self.type = obj.type
2521 # self.data = obj.data[:]
2524 self.height = obj.get_type(40)[0]
2525 self.width = obj.get_type(41)[0]
2526 self.alignment = obj.get_type(71)[0] # alignment 1=TL, 2=TC, 3=TR, 4=ML, 5=MC, 6=MR, 7=BL, 8=BC, 9=BR
2527 self.value = self.get_text(obj) # The text string value
2529 # optional data (with defaults)
2530 self.space = getit(obj, 67, 0)
2531 self.color_index = getit(obj, 62, BYLAYER)
2532 self.rotation = getit(obj, 50, 0) # radians
2534 self.width_factor = getit(obj, 42, 1) # Scaling factor along local x axis
2535 self.line_space = getit(obj, 44, 1) # percentage of default
2537 self.layer = getit(obj, 8, None)
2538 self.loc = self.get_loc(obj)
2539 self.extrusion = get_extrusion(obj)
2542 def get_text(self, data):
2543 """Reconstructs mtext data from dxf codes.
2548 if item[0] == 1: # There should be only one primary...
2550 elif item[0] == 3: # There may be any number of extra strings (in order)
2551 secondary.append(item[1])
2553 #raise ValueError, "Empty Mtext Object!"
2554 string = "Empty Mtext Object!"
2556 string = primary.replace(r'\P', '\n')
2558 string = ''.join(secondary)+primary
2559 string = string.replace(r'\P', '\n')
2563 def get_loc(self, data):
2564 """Gets location for a mtext type objects.
2566 Mtext objects have only one point indicating
2569 loc[0] = getit(data, 10, None)
2570 loc[1] = getit(data, 20, None)
2571 loc[2] = getit(data, 30, 0.0)
2576 return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
2579 def draw(self, settings):
2580 """for MTEXTs: generate Blender_geometry.
2582 # Now Create an object
2583 obname = 'tm_%s' %self.layer # create object name from layer name
2584 obname = obname[:MAX_NAMELENGTH]
2585 txt = Text3d.New(obname)
2586 ob = SCENE.objects.new(txt) # create a new text_object
2589 # Blender doesn't give access to its text object width currently
2590 # only to the text3d's curve width...
2591 #txt.setWidth(text.width/10)
2592 txt.setLineSeparation(self.line_space)
2593 txt.setExtrudeDepth(0.5)
2594 txt.setText(self.value)
2596 # scale it to the text size
2597 ob.SizeX = self.height * self.width_factor
2598 ob.SizeY = self.height
2599 ob.SizeZ = self.height
2601 # move the object center to the text location
2602 ob.loc = tuple(self.loc)
2603 transform(self.extrusion, self.rotation, ob)
2608 class Circle: #-----------------------------------------------------------------
2609 """Class for objects representing dxf CIRCLEs.
2612 def __init__(self, obj):
2613 """Expects an entity object of type circle as input.
2615 if not obj.type == 'circle':
2616 raise TypeError, "Wrong type %s for circle object!" %obj.type
2617 self.type = obj.type
2618 # self.data = obj.data[:]
2621 self.radius = obj.get_type(40)[0]
2623 # optional data (with defaults)
2624 self.space = getit(obj, 67, 0)
2625 self.thic = getit(obj, 39, 0)
2626 self.color_index = getit(obj, 62, BYLAYER)
2628 self.layer = getit(obj, 8, None)
2629 self.loc = self.get_loc(obj)
2630 self.extrusion = get_extrusion(obj)
2634 def get_loc(self, data):
2635 """Gets the center location for circle type objects.
2637 Circles have a single coord location.
2640 loc[0] = getit(data, 10, None)
2641 loc[1] = getit(data, 20, None)
2642 loc[2] = getit(data, 30, 0.0)
2648 return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
2651 def draw(self, settings):
2652 """for CIRCLE: generate Blender_geometry.
2654 obname = 'ci_%s' %self.layer # create object name from layer name
2655 obname = obname[:MAX_NAMELENGTH]
2656 radius = self.radius
2658 thic = set_thick(self.thic, settings)
2660 if settings.var['lines_as'] == 4: # as thin_box
2661 thic = settings.var['thick_min']
2662 width = settings.var['width_min']
2663 if settings.var['lines_as'] == 3: # as thin cylinder
2664 cyl_rad = 0.5 * settings.var['width_min']
2666 if settings.var['lines_as'] == 5: # draw CIRCLE as curve -------------
2667 if True: # universal version
2668 arc_res = settings.var['curve_arc']
2670 start, end = 0.0, 360.0
2671 VectorTriples = calcArc(None, radius, start, end, arc_res, True)
2672 c = Curve.New(obname) # create new curve data
2673 curve = c.appendNurb(BezTriple.New(VectorTriples[0]))
2674 for p in VectorTriples[1:-1]:
2675 curve.append(BezTriple.New(p))
2677 point.handleTypes = [FREE, FREE]
2678 else: # standard version
2679 c = Curve.New(obname) # create new curve data
2680 p1 = (0, -radius, 0)
2683 p4 = (-radius, 0, 0)
2685 p1 = BezTriple.New(p1)
2686 p2 = BezTriple.New(p2)
2687 p3 = BezTriple.New(p3)
2688 p4 = BezTriple.New(p4)
2690 curve = c.appendNurb(p1)
2695 point.handleTypes = [AUTO, AUTO]
2697 curve.flagU = 1 # 1 sets the curve cyclic=closed
2698 if settings.var['fill_on']:
2699 c.setFlag(6) # 2+4 set top and button caps
2701 c.setFlag(c.getFlag() & ~6) # dont set top and button caps
2703 c.setResolu(settings.var['curve_res'])
2706 #--todo-----to check---------------------------
2707 ob = SCENE.objects.new(c) # create a new curve_object
2708 ob.loc = tuple(self.loc)
2709 if thic != 0.0: #hack: Blender<2.45 curve-extrusion
2711 c.setExt1(1.0) # curve-extrusion accepts only (0.0 - 2.0)
2712 ob.LocZ = thic + self.loc[2]
2713 transform(self.extrusion, 0, ob)
2715 ob.SizeZ *= abs(thic)
2718 elif False: # create a new mesh_object with buildin_circle_primitive
2719 verts_num = settings.var['arc_res'] * sqrt(radius / settings.var['arc_rad'])
2720 if verts_num > 100: verts_num = 100 # Blender accepts only values [3:500]
2721 if verts_num < 4: verts_num = 4 # Blender accepts only values [3:500]
2723 loc2 = thic * 0.5 #-----blenderAPI draw Cylinder with 2*thickness
2724 self.loc[2] += loc2 #---new location for the basis of cylinder
2725 #print 'deb:circleDraw:self.loc2:', self.loc #-----------------------
2726 c = Mesh.Primitives.Cylinder(int(verts_num), radius*2, abs(thic))
2728 c = Mesh.Primitives.Circle(int(verts_num), radius*2)
2731 ob = SCENE.objects.new(c, obname) # create a new circle_mesh_object
2732 ob.loc = tuple(self.loc)
2733 transform(self.extrusion, 0, ob)
2736 else: # draw CIRCLE as mesh -----------------------------------------------
2737 if M_OBJ: obname, me, ob = makeNewObject()
2739 me = Mesh.New(obname) # create a new mesh
2740 ob = SCENE.objects.new(me) # create a new mesh_object
2741 # set a number of segments in entire circle
2742 arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
2743 start, end = 0.0 , 360.0
2744 verts = calcArc(None, radius, start, end, arc_res, False)
2745 verts = verts[:-1] #list without last point/edge (cause by circle it is equal to the first point)
2746 #print 'deb:circleDraw: verts:', verts #---------------
2751 thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
2753 thic_verts.extend(verts)
2756 verts.extend(thic_verts)
2758 f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
2759 #f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1)]
2760 f_band.append([len1 - 1, 0, len1, len1 + len1 -1])
2762 smooth_len = len(f_band)
2763 if settings.var['fill_on']:
2765 verts.append([0,0,thic]) #center of top side
2766 verts.append([0,0,0]) #center of bottom side
2768 verts.append([0,0,0]) #center of bottom side
2769 verts.append([0,0,thic]) #center of top side
2770 center1 = len(verts)-2
2771 center2 = len(verts)-1
2772 f_bottom = [[num+1, num, center1] for num in xrange(len1 - 1)]
2773 f_bottom.append([0, len1 - 1, center1])
2774 f_top = [[num+len1, num+1+len1, center2] for num in xrange(len1 - 1)]
2775 f_top.append([len1-1+len1, 0+len1, center2])
2776 #print 'deb:circleDraw:verts:', verts #---------------
2777 faces = f_band + f_bottom + f_top
2778 #print 'deb:circleDraw:faces:', faces #---------------
2779 me.verts.extend(verts) # add vertices to mesh