4 Name: 'Autodesk DXF (.dxf .dwg)'
7 Tooltip: 'Import for DWG/DXF geometry data.'
9 __author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)'
10 __version__ = '1.12 - 2009.05.26 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 DWG/DXF (2d/3d) into Blender.
17 This script imports 2d and 3d geometery from DXF files.
18 It supports DWG format too, with help of an external converter.
19 Supported DXF format versions: from (r2.5) r12 up to r2008.
20 Enhanced features are:
21 - configurable object filtering and geometry manipulation,
22 - configurable material pre-processing,
23 - DXF-code analyze and reporting.
25 Supported DXF r12 objects:
32 MINSERT (=array of blocks),
36 2d-POLYLINE (=in plane, incl. arc, variable-width, curve, spline),
37 3d-POLYLINE (=non-plane),
41 XREF (External Reference).
43 Supported DXF>r12 objects:
45 LWPOLYLINE (LightWeight Polyline),
52 DXF>r12: GROUP, RAY/XLINE, LEADER, 3DSOLID, BODY, REGION, dynamic BLOCK
54 Supported geometry: 2d and 3d DXF-objects.
55 Curves imported as Blender curves or meshes optionally.
57 Supported layout modes:
58 "model space" is default,
59 "paper space" as option (= "layout views")
61 Supported scene definition objects produced with AVE_RENDER:
62 scene: selection of lights assigned to the camera,
63 lights: DIRECT, OVERHEAD, SH_SPOT,
64 (wip v1.13 import of AVE_RENDER material definitions)
67 Entire DXF BLOCK hierarchy is preserved after import into Blender
68 (BLOCKs as groups on layer19, INSERTs as dupliGroups on target layer).
77 (wip v1.13: XDATA, grouped status)
78 It is recommended to use DXF-object properties for assign Blender materials.
81 - Recommend that you run 'RemoveDoubles' on each imported mesh after using this script
82 - Blocks are created on layer 19 then referenced at each insert point.
83 - support for DXF-files up to 160MB on systems with 1GB RAM
84 - DXF-files with over 1500 objects decrease import performance.
85 The problem is not the inefficiency of python-scripting but Blenders performance
86 in creating new objects in scene database - probably a database management problem.
92 v1.0 - 2007/2008/2009 by migius
94 -- (to see more, search for "--todo--" in script code)
95 -- command-line-mode/batch-mode
96 -- in-place-editing for dupliGroups
97 -- support for MLINE (is exported to r12 as BLOCK*Unnamed with LINEs)
98 -- support for MTEXT (is exported to r12 as TEXT???)
99 -- blender_object.properties['dxf_layer_name']
100 -- better support for long dxf-layer-names
101 -- add configuration file.ini handles multiple material setups
102 -- added f_layerFilter
103 -- to-check: obj/mat/group/_mapping-idea from ideasman42:
104 -- curves: added "fill/non-fill" option for closed curves: CIRCLEs,ELLIPSEs,POLYLINEs
105 -- "normalize Z" option to correct non-planar figures
106 -- LINEs need "width" in 3d-space incl vGroups
107 -- support width_force for LINEs/ELLIPSEs = "solidify"
108 -- add better support for color_index BYLAYER=256, BYBLOCK=0
109 -- bug: "oneMesh" produces irregularly errors
110 -- bug: Registry recall from hd_cache ?? only win32 bug??
111 -- support DXF-definitions of scene, lights and cameras
112 -- support ortho mode for VIEWs and VPORTs as cameras
114 v1.12 - 2009.05.26 by migius
115 d5 bugfix WORLDY(1,1,0) to (0,1,0)
116 v1.12 - 2009.04.11 by migius
117 d4 added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter
118 v1.12 - 2009.03.14 by migius
119 d3 removed all set()functions (problem with osx/python<2.4 reported by Blinkozo)
121 v1.12 - 2009.01.14 by migius
122 d2 temp patch for noname BLOCKS (*X,*U,*D)
123 v1.12 - 2008.11.16 by migius
124 d1 remove try_finally: cause not supported in python <2.5
125 d1 add Bezier curves bevel radius support (default 1.0)
126 v1.12 - 2008.08.03 by migius
127 c2 warningfix: relocating of globals: layersmap, oblist
128 c2 modif UI: buttons newScene+targetLayer moved to start panel
129 v1.12 - 2008.07.04 by migius
130 c1 added control Curve's OrderU parameter
131 c1 modif UI: preset buttons X-2D-3D moved to start panel
132 b6 added handling exception of not registered LAYERs (Hammer-HL-editor DXF output)
133 b5 rebuild UI: global preset 2D for Curve-Import
134 b5 added UI-options: PL-MESH N+N plmesh_flip and normals_out
135 b5 added support for SPLINEs, added control OrderU parameter
136 b5 rewrote draw module for NURBS_curve and Bezier_curve
137 v1.12 - 2008.06.22 by migius
138 b4 change versioning system 1.0.12 -> 1.12
139 b4 print at start version-info to console
140 b3 bugfix: ob.name conflict with existing meshes (different ob.name/mesh.name)
141 v1.0.12: 2008.05.24 by migius
142 b2 added support for LWPOLYLINEs
143 b2 added support for ProE in readerDXF.py
144 v1.0.12: 2008.02.08 by migius
145 b1 update: object = Object.Get(obname) -> f_getSceChild().getChildren()
146 a9 bugfix by non-existing tables views, vports, layers (Kai reported)
147 v1.0.12: 2008.01.17 by migius
148 a8 lately used INI-dir/filename persistently stored in Registry
149 a8 lately used DXF-dir/filename persistently stored in Registry
150 a7 fix missing layersmap{} for dxf-files without "section:layer"
151 a6 added support for XREF external referenced BLOCKs
152 a6 check for bug in AutoCAD2002:DXFr12export: ELLIPSE->POLYLINE_ARC fault angles
153 a6 support VIEWs and VPORTs as cameras: ortho and perspective mode
154 a6 save resources through ignoring unused BLOCKs (not-inserted or on frozen/blocked layers)
155 a6 added try_finally: f.close() for all IO-files
156 a6 added handling for TypeError raise
157 a5 bugfix f_getOCS for (0,0,z!=1.0) (ellipse in Kai's dxf)
158 a4 added to analyzeTool: report about VIEWs, VPORTs, unused/xref BLOCKs
159 a4 bugfix: individual support for 2D/3DPOLYLINE/POLYMESH
160 a4 added to UI: (*wip)BLOCK-(F): name filtering for BLOCKs
161 a4 added to UI: BLOCK-(n): filter anoname/hatch BLOCKs *X...
162 a2 g_scale_as is no more GUI_A-variable
163 a2 bugfix "material": negative sign color_index
164 a2 added support for BLOCKs defined with origin !=(0,0,0)
165 a1 added 'global.reLocation-vector' option
167 v1.0.11: 2007.11.24 by migius
168 c8 added 'curve_resolution_U' option
169 c8 added context_sensitivity for some UI-buttons
170 c8 bugfix ELLIPSE rotation, added closed_variant and caps
171 c7 rebuild UI: new layout, grouping and meta-buttons
172 c6 rewritten support for ELLIPSE mesh & curve representation
173 c6 restore selector-buttons for DXF-drawTypes: LINE & Co
174 c6 change header of INI/INF-files: # at begin
175 c6 apply scale(1,1,1) after glob.Scale for all mesh objects, not for curve objects.
176 c5 fixing 'material_on' option
177 c4 added "analyze DXF-file" UI-option: print LAYER/BLOCK-dependences into a textfile
178 c3 human-formating of data in INI-Files
179 c2 added "caps" for closed Bezier-curves
180 c2 added "set elevation" UI-option
181 c1 rewrite POLYLINE2d-arc-segments Bezier-interpreter
183 b9 rewrite POLYLINE2d-arc-segments trimming (clean-trim)
184 b8 added "import from frozen layers" UI-option
185 b8 added "import from paper space" UI-option
186 b8 support Bezier curves for LINEs incl.thickness(0.0-10.0)
187 b8 added meshSmooth_on for circle/arc/polyline
188 b8 added vertexGroups for circle/arc
189 b7 added width_force for ARCs/CIRCLEs = "thin_box" option
190 b3 cleanup code, rename f_drawArc/Bulg->f_calcArc/Bulg
191 b2 fixing material assignment by LAYER+COLOR
192 b1 fixing Bezier curves representation of POLYLINEs-arc-segments
193 b0 added global_scale_presets: "yard/feet/inch to meter"
195 v1.0.10: 2007.10.18 by migius
196 a6 bugfix CircleDrawCaps for OSX
197 a5 added two "curve_res" UI-buttons for Bezier curves representation
198 a5 improved Bezier curves representation of circles/arcs: correct handlers
199 a4 try to fix malformed endpoints of Blender curves of ARC/POLYLINE-arc segments.
200 a3 bugfix: open-POLYLINEs with end_point.loc==start_point.loc
201 a2 bugfix: f_transform for OCS=(0,0,-1) oriented objects
202 a1 added "fill_on=caps" option to draw top and bottom sides of CIRCLEs and ELLIPSEs
203 a1 rewrite f_CIRCLE.Draw: from Mesh.Primitive to Mesh
204 a1 bugfix "newScene"-mode: all Cylinders/Arcs were drawn at <0,0,0>location
206 v1.0.beta09: 2007.09.02 by migius
207 g5 redesign UI: grouping of buttons
208 g3 update multi-import-mode: <*.*> button
209 g- added multi-import-mode: (path/*) for importing many dxf-files at once
210 g- added import into newScene
211 g- redesign UI: user presets, into newScene-import
213 f- bugfix: thickness for Bezier/Bsplines into Blender-curves
214 f- BlenderWiki documentation, on-line Manual
215 f- added import POLYLINE-Bsplines into Blender-NURBSCurves
216 f- added import POLYLINE-arc-segments into Blender-BezierCurves
217 f- added import POLYLINE-Bezier-curves into Blender-Curves
218 d5 rewrite: Optimization Levels, added 'directDrawing'
219 d4 added: f_set_thick(controlled by ini-parameters)
220 d4 bugfix: face-normals in objects with minus thickness
221 d4 added: placeholder'Empty'-size in f_Insert.draw
222 d3 rewrite f_Text.Draw: added support for all Text's parameters
223 d2 redesign: progressbar
224 e- tuning by ideasman42: better use of the Py API.
225 c- tuning by ideasman42
226 b- rewrite f_Text.Draw rotation/transform
227 b- bugfix: POLYLINE-segment-intersection more reliable now
228 b- bugfix: circle:_thic, 'Empties':no material_assignment
229 b- added material assignment (from layer and/or color)
230 a- added empty, cylinder and UVsphere for POINTs
231 a- added support for 2d-POLYLINE: splines, fitted curves, fitted surfaces
232 a- redesign f_Drawer for block_definitions
233 a- rewrite import into Blender-Curve-Object
235 v1.0.beta08 - 2007.07.27 by migius: "full 3d"-release
236 l- bugfix: solid_vgroups, clean:scene.objects.new()
237 l- redesign UI to standard Draw.Register+FileSelector, advanced_config_option
238 k- bugfix UI:fileSelect() for MacOSX os.listdir()
239 k- added reset/save/load for config-data
240 k- redesign keywords/drawTypes/Draw.Create_Buttons
241 j- new UI using UIBlock() with own FileSelector, cause problem Window.FileSelector()
242 i- rewritten Class:Settings for better config-parameter management
243 h- bugfix: face-normals in objects with minus thickness
244 h- added Vertex-Groups in POLYLINE and SOLID meshes, for easy material assignment
245 h- beautify code, whitespace->tabs
246 h- added settings.thic_force switch for forcing thickness
247 h- added "one Mesh" option for all entities from the same Layer, sorted in<br>
248 Vertex-Groups(color_name) (fewer objects = better import performance)
249 g- rewrote: insert-point-handle-object is a small tetrahedron
250 e- bugfix: closed-polymesh3d
251 - rewrote: UI, type_map.keys, f_drawer, all class_f_draw(added "settings" as attribut)
252 - added 2d/3d-support for Polyline_Width incl. angle intersection
253 beta07: 2007.06.19 by migius
254 - added 3d-support for LWPolylines
255 - added 2d/3d-support for Points
256 beta06: 2007.06.15 by migius
258 - added 2d/3d-support for MINSERT=BlockArray in f_drawer, added f_rotXY_Vec
259 beta05: 2007.06.14 by migius
260 - added 2d/3d-support for 3d-PolyLine, PolyMesh and PolyFace
261 - added Global-Scale for size control of imported scenes
262 beta04: 2007.06.12 by migius
263 - rewrote the f_drawBulge for correct import the arc-segments of Polylines
264 beta03: 2007.06.10 by migius
266 beta02: 2007.06.09 by migius
267 - added 3d-support for Arcs and Circles
268 - added support for Object_Thickness(=height)
269 beta01: 2007.06.08 by migius
270 - added 3d-support for Blocks/Inserts within nested-structures
271 - rewrote f_transform for correct 3d-location/3d-rotation
272 - added 3d-support Lines, 3dFaces
273 - added 2d+3d-support for Solids and Traces
275 v0.9 - 2007.01 by kitsu: (for 2.43)
276 - first draft of true POLYLINE import
279 v0.8 - 2006.12 by kitsu:
280 - first draft of object space coordinates OCS import
283 v0.5b - 2006.10 by kitsu: (for 2.42a)
289 # --------------------------------------------------------------------------
290 # DXF Import v1.0 by Ed Blake (AKA kitsu) and Remigiusz Fiedler (AKA migius)
291 # --------------------------------------------------------------------------
292 # ***** BEGIN GPL LICENSE BLOCK *****
294 # This program is free software; you can redistribute it and/or
295 # modify it under the terms of the GNU General Public License
296 # as published by the Free Software Foundation; either version 2
297 # of the License, or (at your option) any later version.
299 # This program is distributed in the hope that it will be useful,
300 # but WITHOUT ANY WARRANTY; without even the implied warranty of
301 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
302 # GNU General Public License for more details.
304 # You should have received a copy of the GNU General Public License
305 # along with this program; if not, write to the Free Software Foundation,
306 # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
308 # ***** END GPL LICENCE BLOCK *****
309 # --------------------------------------------------------------------------
312 from Blender import Mathutils, BezTriple, Draw, Registry, sys,\
313 Text3d, Window, Mesh, Material, Group
314 #from Blender.Mathutils import Vector, Matrix
315 #import bpy #not used yet
318 from dxfReader import readDXF
319 #from dxfReader import get_name, get_layer
320 from dxfReader import Object as dxfObject
321 from dxfColorMap import color_map
322 from math import log10, sqrt, radians, degrees, atan, cos, sin
324 # osx-patch by Blinkozo
325 #todo: avoid additional modules, prefer Blender-build-in test routines
327 #if platform.python_version() < '2.4':
328 # from sets import Set as set
329 #from sys import version_info
330 #ver = '%s.%s' % version_info[0:2]
338 psyco.log(Blender.Get('tempdir')+"/blender.log-psyco")
340 psyco.full(memory=100)
341 psyco.profile(0.05, memory=100)
343 #print 'psyco imported'
345 print 'psyco not imported'
350 print 'DXF/DWG-Importer v%s *** start ***' %(__version__) #---------------------
353 WORLDX = Mathutils.Vector((1,0,0))
354 WORLDY = Mathutils.Vector((0,1,0))
355 WORLDZ = Mathutils.Vector((0,0,1))
357 G_SCALE = 1.0 #(0.0001-1000) global scaling factor for all dxf data
358 G_ORIGIN_X = 0.0 #global translation-vector (x,y,z) in DXF units
361 MIN_DIST = 0.001 #cut-off value for sort out short-distance polyline-"duoble_vertex"
362 ARC_RESOLUTION = 64 #(4-500) arc/circle resolution - number of segments
363 ARC_RADIUS = 1.0 #(0.01-100) arc/circle radius for number of segments algorithm
364 CURV_RESOLUTION = 12 #(1-128) Bezier curves U-resolution
365 CURVARC_RESOLUTION = 4 #(3-32) resolution of circle represented as Bezier curve
366 THIN_RESOLUTION = 8 #(4-64) thin_cylinder arc_resolution - number of segments
367 MIN_THICK = MIN_DIST * 10.0 #minimal thickness by forced thickness
368 MIN_WIDTH = MIN_DIST * 10.0 #minimal width by forced width
369 TRIM_LIMIT = 3.0 #limit for triming of polylines-wide-segments (values:0.0 - 5.0)
370 ELEVATION = 0.0 #standard elevation = coordinate Z value
374 TARGET_LAYER = 3 #target blender_layer
375 GROUP_BYLAYER = 0 #(0/1) all entities from same layer import into one blender-group
376 LAYER_DEF_NAME = 'AAAA' #default layer name
377 LAYER_DEF_COLOR = 4 #default layer color
379 LAB = "*) parts under construction"
382 FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE)
383 MAX_NAMELENGTH = 17 #max_effective_obnamelength in blender =21=17+(.001)
384 INIFILE_DEFAULT_NAME = 'importDXF'
385 INIFILE_EXTENSION = '.ini'
386 INIFILE_HEADER = '#ImportDXF.py ver.1.0 config data'
387 INFFILE_HEADER = '#ImportDXF.py ver.1.0 analyze of DXF-data'
389 AUTO = BezTriple.HandleTypes.AUTO
390 FREE = BezTriple.HandleTypes.FREE
391 VECT = BezTriple.HandleTypes.VECT
392 ALIGN = BezTriple.HandleTypes.ALIGN
394 UI_MODE = True #activates UI-popup-print, if not multiple files imported
397 #-------- DWG support ------------------------------------------
399 extCONV = 'DConvertCon.exe'
400 extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV)
401 if not os.path.isfile(extCONV_PATH):
403 extCONV_TEXT = 'DWG-Importer cant find external DWG-converter (%s) in Blender script directory.|\
404 More details in online Help.' %extCONV
406 if not os.sys.platform.startswith('win'):
407 # check if Wine installed:
408 if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip():
409 extCONV_PATH = 'wine %s'%extCONV_PATH
412 extCONV_TEXT = 'The external DWG-converter (%s) needs Wine installed on your system.|\
413 More details in online Help.' %extCONV
414 #print 'extCONV_PATH = ', extCONV_PATH
418 class View: #-----------------------------------------------------------------
419 """Class for objects representing dxf VIEWs.
421 def __init__(self, obj, active=None):
422 """Expects an object of type VIEW as input.
424 if not obj.type == 'view':
425 raise TypeError, "Wrong type %s for VIEW object!" %obj.type
428 self.name = obj.get_type(2)[0]
429 # self.data = obj.data[:]
432 self.centerX = getit(obj, 10, 0.0) #view center pointX (in DCS)
433 self.centerY = getit(obj, 20, 0.0) #view center pointY (in DCS)
434 self.height = obj.get_type(40)[0] #view height (in DCS)
435 self.width = obj.get_type(41)[0] #view width (in DCS)
438 self.dir[0] = getit(obj, 11, 0.0) #view directionX from target (in WCS)
439 self.dir[1] = getit(obj, 21, 0.0) #
440 self.dir[2] = getit(obj, 31, 0.0) #
442 self.target = [0,0,0]
443 self.target[0] = getit(obj, 12, 0.0) #target pointX(in WCS)
444 self.target[1] = getit(obj, 22, 0.0) #
445 self.target[2] = getit(obj, 32, 0.0) #
447 self.length = obj.get_type(42)[0] #Lens length
448 self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
449 self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
450 self.twist = obj.get_type(50)[0] #view twist angle in degrees
452 self.flags = getit(obj, 70, 0)
453 self.paperspace = self.flags & 1 #
455 self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
458 return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
461 def draw(self, settings):
462 """for VIEW: generate Blender_camera.
464 obname = 'vw_%s' %self.name # create camera object name
465 #obname = 'ca_%s' %self.name # create camera object name
466 obname = obname[:MAX_NAMELENGTH]
468 if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
469 cam= Camera.New('ortho', obname)
470 ob= SCENE.objects.new(cam)
472 cam.scale = 1.0 # for ortho cameras
474 cam= Camera.New('persp', obname)
475 ob= SCENE.objects.new(cam)
477 cam.angle = 60.0 # for persp cameras
479 #cam.angle = 2 * atan(17.5/self.length) * 180/pi
480 cam.lens = self.length #for persp cameras
481 # hack to update Camera>Lens setting (inaccurate as a focal length)
482 #curLens = cam.lens; cam.lens = curLens
483 # AutoCAD gets clip distance from target:
484 dist = Mathutils.Vector(self.dir).length
485 cam.clipEnd = dist - self.clip_back
486 cam.clipStart = dist - self.clip_front
491 v = Mathutils.Vector(self.dir)
492 # print 'deb:view cam:', cam #------------
493 # print 'deb:view self.target:', self.target #------------
494 # print 'deb:view self.dir:', self.dir #------------
495 # print 'deb:view self.twist:', self.twist #------------
496 # print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
497 transform(v.normalize(), -self.twist, ob)
498 ob.loc = Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
502 class Vport: #-----------------------------------------------------------------
503 """Class for objects representing dxf VPORTs.
505 def __init__(self, obj, active=None):
506 """Expects an object of type VPORT as input.
508 if not obj.type == 'vport':
509 raise TypeError, "Wrong type %s for VPORT object!" %obj.type
512 self.name = obj.get_type(2)[0]
513 # self.data = obj.data[:]
514 #print 'deb:vport name, data:', self.name #-------
515 #print 'deb:vport data:', self.data #-------
517 self.height = obj.get_type(40)[0] #vport height (in DCS)
518 self.centerX = getit(obj, 12, 0.0) #vport center pointX (in DCS)
519 self.centerY = getit(obj, 22, 0.0) #vport center pointY (in DCS)
520 self.width = self.height * obj.get_type(41)[0] #vport aspect ratio - width (in DCS)
523 self.dir[0] = getit(obj, 16, 0.0) #vport directionX from target (in WCS)
524 self.dir[1] = getit(obj, 26, 0.0) #
525 self.dir[2] = getit(obj, 36, 0.0) #
527 self.target = [0,0,0]
528 self.target[0] = getit(obj, 17, 0.0) #target pointX(in WCS)
529 self.target[1] = getit(obj, 27, 0.0) #
530 self.target[2] = getit(obj, 37, 0.0) #
532 self.length = obj.get_type(42)[0] #Lens length
533 self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point)
534 self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point)
535 self.twist = obj.get_type(51)[0] #view twist angle
537 self.flags = getit(obj, 70, 0)
538 self.paperspace = self.flags & 1 #
540 self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable)
543 return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length)
545 def draw(self, settings):
546 """for VPORT: generate Blender_camera.
548 obname = 'vp_%s' %self.name # create camera object name
549 #obname = 'ca_%s' %self.name # create camera object name
550 obname = obname[:MAX_NAMELENGTH]
552 if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0:
553 cam= Camera.New('ortho', obname)
554 ob= SCENE.objects.new(cam)
556 cam.scale = 1.0 # for ortho cameras
558 cam= Camera.New('persp', obname)
559 ob= SCENE.objects.new(cam)
561 cam.angle = 60.0 # for persp cameras
563 #cam.angle = 2 * atan(17.5/self.length) * 180/pi
564 cam.lens = self.length #for persp cameras
565 # hack to update Camera>Lens setting (inaccurate as a focal length)
566 #curLens = cam.lens; cam.lens = curLens
567 # AutoCAD gets clip distance from target:
568 dist = Mathutils.Vector(self.dir).length
569 cam.clipEnd = dist - self.clip_back
570 cam.clipStart = dist - self.clip_front
575 v = Mathutils.Vector(self.dir)
576 # print 'deb:view cam:', cam #------------
577 # print 'deb:view self.target:', self.target #------------
578 # print 'deb:view self.dir:', self.dir #------------
579 # print 'deb:view self.twist:', self.twist #------------
580 # print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------
581 transform(v.normalize(), -self.twist, ob)
582 ob.loc = Mathutils.Vector(self.target) + Mathutils.Vector(self.dir)
587 class Layer: #-----------------------------------------------------------------
588 """Class for objects representing dxf LAYERs.
590 def __init__(self, obj, name=None, color=None, frozen=None):
591 """Expects an dxfobject of type layer as input.
592 if no dxfobject - creates surogate layer with default parameters
597 if name: self.name = name
598 else: self.name = LAYER_DEF_NAME
600 if color: self.color = color
601 else: self.color = LAYER_DEF_COLOR
603 if frozen!=None: self.frozen = frozen
604 else: self.frozen = 0
606 if obj.type=='layer':
608 #self.data = obj.data[:]
609 if name: self.name = name
610 #self.bfname = name #--todo---see layernamesmap in f_getLayersmap ---
611 else: self.name = obj.get_type(2)[0] #layer name of object
613 if color: self.color = color
614 else: self.color = obj.get_type(62)[0] #color of object
616 if frozen!=None: self.frozen = frozen
618 self.flags = obj.get_type(70)[0]
619 self.frozen = self.flags & 1
622 return "%s: name - %s, color - %s" %(self.__class__.__name__, self.name, self.color)
626 def getit(obj, typ, default=None): #------------------------------------------
627 """Universal procedure for geting data from list/objects.
630 if type(obj) == list: #if obj is a list, then searching in a list
632 #print 'deb:getit item, type(item)', item, type(item)
636 break #as soon as the first found
638 # --todo-- I found one case where item was a text instance
639 # that failed with no __getitem__
641 else: #else searching in Object with get_type-Methode
642 item = obj.get_type(typ)
645 #print 'deb:getit:typ, it', typ, it #----------
650 def get_extrusion(data): #-------------------------------------------------
651 """Find the axis of extrusion.
653 Used to get from object_data the objects Object_Coordinate_System (ocs).
655 #print 'deb:get_extrusion: data: \n', data #---------------
657 vec[0] = getit(data, 210, 0) # 210 = x
658 vec[1] = getit(data, 220, 0) # 220 = y
659 vec[2] = getit(data, 230, 1) # 230 = z
660 #print 'deb:get_extrusion: vec: ', vec #---------------
664 #------------------------------------------
665 def getSceneChild(name):
666 dudu = [i for i in SCENE.objects if i.name==name]
667 # dudu = [i for i in SCENE.getChildren() if i.name==name]
668 #print 'deb:getSceneChild %s -result: %s:' %(name,dudu) #-----------------
669 if dudu!=[]: return dudu[0]
673 class Solid: #-----------------------------------------------------------------
674 """Class for objects representing dxf SOLID or TRACE.
676 def __init__(self, obj):
677 """Expects an entity object of type solid or trace as input.
679 if obj.type == 'trace':
681 if not obj.type == 'solid':
682 raise TypeError, "Wrong type \'%s\' for solid/trace object!" %obj.type
685 # self.data = obj.data[:]
687 self.space = getit(obj, 67, 0)
688 self.thic = getit(obj, 39, 0)
689 self.color_index = getit(obj, 62, BYLAYER)
691 self.layer = getit(obj, 8, None)
692 self.extrusion = get_extrusion(obj)
693 self.points = self.get_points(obj)
697 def get_points(self, data):
698 """Gets start and end points for a solid type object.
700 Solids have 3 or 4 points and fixed codes for each value.
703 # start x, y, z and end x, y, z = 0
708 a[0] = getit(data, 10, None) # 10 = x
709 a[1] = getit(data, 20, None) # 20 = y
710 a[2] = getit(data, 30, 0) # 30 = z
711 b[0] = getit(data, 11, None)
712 b[1] = getit(data, 21, None)
713 b[2] = getit(data, 31, 0)
714 c[0] = getit(data, 12, None)
715 c[1] = getit(data, 22, None)
716 c[2] = getit(data, 32, 0)
719 d[0] = getit(data, 13, None)
721 d[1] = getit(data, 23, None)
722 d[2] = getit(data, 33, 0)
724 #print 'deb:solid.vertices:---------\n', out #-----------------------
729 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
732 def draw(self, settings):
733 """for SOLID: generate Blender_geometry.
736 if not points: return
737 edges, faces = [], []
740 obname = 'so_%s' %self.layer # create object name from layer name
741 obname = obname[:MAX_NAMELENGTH]
743 vg_left, vg_right, vg_top, vg_bottom, vg_start, vg_end = [], [], [], [], [], []
744 thic = set_thick(self.thic, settings)
746 thic_points = [[v[0], v[1], v[2] + thic] for v in points[:]]
748 thic_points.extend(points)
751 points.extend(thic_points)
754 faces = [[0,1,3,2], [4,6,7,5], [0,4,5,1],
755 [1,5,7,3], [3,7,6,2], [2,6,4,0]]
759 vg_bottom = [0,1,3,2]
763 faces = [[0,1,2], [3,5,4], [0,3,4,1], [1,4,5,2], [2,5,3,0]]
769 elif l == 2: faces = [[0,1,3,2]]
771 if l == 4: faces = [[0,1,3,2]]
772 elif l == 3: faces = [[0,1,2]]
773 elif l == 2: edges = [[0,1]]
775 if M_OBJ: obname, me, ob = makeNewObject()
777 me = Mesh.New(obname) # create a new mesh
778 ob = SCENE.objects.new(me) # create a new mesh_object
779 me.verts.extend(points) # add vertices to mesh
780 if faces: me.faces.extend(faces) # add faces to the mesh
781 if edges: me.edges.extend(edges) # add faces to the mesh
783 if settings.var['vGroup_on'] and not M_OBJ:
784 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
785 replace = Mesh.AssignModes.ADD #or .AssignModes.ADD/REPLACE
786 if vg_left: me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
787 if vg_right:me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
788 if vg_top: me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
789 if vg_bottom:me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
790 if vg_start:me.addVertGroup('side.start') ; me.assignVertsToGroup('side.start', vg_start, 1.0, replace)
791 if vg_end: me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', vg_end, 1.0, replace)
793 transform(self.extrusion, 0, ob)
797 class Line: #-----------------------------------------------------------------
798 """Class for objects representing dxf LINEs.
800 def __init__(self, obj):
801 """Expects an entity object of type line as input.
803 if not obj.type == 'line':
804 raise TypeError, "Wrong type \'%s\' for line object!" %obj.type
806 # self.data = obj.data[:]
808 self.space = getit(obj, 67, 0)
809 self.thic = getit(obj, 39, 0)
810 #print 'deb:self.thic: ', self.thic #---------------------
811 self.color_index = getit(obj, 62, BYLAYER)
813 self.layer = getit(obj, 8, None)
814 self.extrusion = get_extrusion(obj)
815 self.points = self.get_points(obj)
818 def get_points(self, data):
819 """Gets start and end points for a line type object.
821 Lines have a fixed number of points (two) and fixed codes for each value.
823 # start x,y,z and end x,y,z = 0
826 a[0] = getit(data, 10, None) # 10 = x
827 a[1] = getit(data, 20, None) # 20 = y
828 a[2] = getit(data, 30, 0) # 30 = z
829 b[0] = getit(data, 11, None)
830 b[1] = getit(data, 21, None)
831 b[2] = getit(data, 31, 0)
837 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
840 def draw(self, settings):
841 """for LINE: generate Blender_geometry.
843 # Generate the geometery
844 #settings.var['curves_on']=False
847 thic = set_thick(self.thic, settings)
849 if settings.var['lines_as'] == 4: # as thin_box
850 thic = settings.var['thick_min']
851 width = settings.var['width_min']
852 elif settings.var['lines_as'] == 3: # as thin cylinder
853 cyl_rad = 0.5 * settings.var['width_min']
855 elif settings.var['lines_as'] == 5: # LINE curve representation-------------------------
856 obname = 'li_%s' %self.layer # create object name from layer name
857 obname = obname[:MAX_NAMELENGTH]
859 c = Curve.New(obname) # create new curve data
860 curve = c.appendNurb(BezTriple.New(points[0]))
861 curve.append(BezTriple.New(points[1]))
863 point.handleTypes = [VECT, VECT]
865 curve.flagU = 0 # 0 sets the curve not cyclic=open
866 c.setResolu(settings.var['curve_res'])
867 c.update() #important for handles calculation
869 ob = SCENE.objects.new(c) # create a new curve_object
871 #if False: # --todo-- better support for 210-group
872 if thic != 0.0: #hack: Blender2.45 curve-extrusion
874 if abs(t) > 5.0: t = 5.0 * cmp(t,0) # Blender2.45 accepts only (0.0 - 5.0)
876 c.setExt1(abs(t)) # curve-extrusion
880 #c.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
881 #ob.LocZ = t + self.loc[2]
885 else: # LINE mesh representation ------------------------------
886 global activObjectLayer
887 global activObjectName
888 #print 'deb:draw:line.ob IN activObjectName: ', activObjectName #---------------------
890 if M_OBJ: obname, me, ob = makeNewObject()
892 if activObjectLayer == self.layer and settings.var['one_mesh_on']:
893 obname = activObjectName
894 #print 'deb:line.draw obname from activObjectName: ', obname #---------------------
895 ob = getSceneChild(obname) # open an existing mesh_object
896 #ob = SCENE.getChildren(obname) # open an existing mesh_object
897 #me = Mesh.Get(ob.name) # open objects mesh data
898 me = ob.getData(name_only=False, mesh=True)
900 obname = 'li_%s' %self.layer # create object name from layer name
901 obname = obname[:MAX_NAMELENGTH]
902 me = Mesh.New(obname) # create a new mesh
903 ob = SCENE.objects.new(me) # create a new mesh_object
904 activObjectName = ob.name
905 activObjectLayer = self.layer
906 #print ('deb:line.draw new line.ob+mesh:"%s" created!' %ob.name) #---------------------
908 faces, edges = [], []
911 #if settings.var['width_force']: #--todo-----------
914 t, e = thic, self.extrusion
915 #print 'deb:thic, extr: ', t, e #---------------------
916 points.extend([[v[0]+t*e[0], v[1]+t*e[1], v[2]+t*e[2]] for v in points[:]])
917 faces = [[0+n, 1+n, 3+n, 2+n]]
921 me.verts.extend(points) # adds vertices to global mesh
922 if faces: me.faces.extend(faces) # add faces to the mesh
923 if edges: me.edges.extend(edges) # add faces to the mesh
925 if settings.var['vGroup_on'] and not M_OBJ:
926 # entities with the same color build one vertexGroup for easier material assignment ----
927 ob.link(me) # link mesh to that object
928 vG_name = 'color_%s' %self.color_index
929 if edges: faces = edges
930 replace = Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD
932 me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
933 #print 'deb: existed vGroup:', vG_name #---------------------
935 me.addVertGroup(vG_name)
936 me.assignVertsToGroup(vG_name, faces[0], 1.0, replace)
937 #print 'deb: create new vGroup:', vG_name #---------------------
940 #print 'deb:draw:line.ob OUT activObjectName: ', activObjectName #---------------------
945 class Point: #-----------------------------------------------------------------
946 """Class for objects representing dxf POINTs.
948 def __init__(self, obj):
949 """Expects an entity object of type point as input.
951 if not obj.type == 'point':
952 raise TypeError, "Wrong type %s for point object!" %obj.type
954 # self.data = obj.data[:]
956 self.space = getit(obj, 67, 0)
957 self.thic = getit(obj, 39, 0)
958 #print 'deb:self.thic: ', self.thic #---------------------
959 self.color_index = getit(obj, 62, BYLAYER)
961 self.layer = getit(obj, 8, None)
962 self.extrusion = get_extrusion(obj)
963 self.points = self.get_points(obj)
966 def get_points(self, data):
967 """Gets coordinates for a point type object.
969 Points have fixed codes for each value.
972 a[0] = getit(data, 10, None) # 10 = x
973 a[1] = getit(data, 20, None) # 20 = y
974 a[2] = getit(data, 30, 0) # 30 = z
980 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
983 def draw(self, settings):
984 """for POINT: generate Blender_geometry.
987 obname = 'po_%s' %self.layer # create object name from layer name
988 obname = obname[:MAX_NAMELENGTH]
989 points_as = settings.var['points_as']
990 thic = settings.var['thick_min']
991 if thic < settings.var['dist_min']: thic = settings.var['dist_min']
993 if points_as in [1,3,4,5]:
994 if points_as in [1,5]: # as 'empty'
996 elif points_as == 3: # as 'thin sphere'
997 res = settings.var['thin_res']
998 c = Mesh.Primitives.UVsphere(res,res,thic)
999 elif points_as == 4: # as 'thin box'
1000 c = Mesh.Primitives.Cube(thic)
1001 ob = SCENE.objects.new(c, obname) # create a new object
1002 transform(self.extrusion, 0, ob)
1003 ob.loc = tuple(points[0])
1005 elif points_as == 2: # as 'vertex'
1006 global activObjectLayer
1007 global activObjectName
1008 #print 'deb:draw:point.ob IN activObjectName: ', activObjectName #---------------------
1009 if M_OBJ: obname, me, ob = makeNewObject()
1011 if activObjectLayer == self.layer and settings.var['one_mesh_on']:
1012 obname = activObjectName
1013 #print 'deb:draw:point.ob obname from activObjectName: ', obname #---------------------
1014 ob = getSceneChild(obname) # open an existing mesh_object
1015 #ob = SCENE.getChildren(obname) # open an existing mesh_object
1016 me = ob.getData(name_only=False, mesh=True)
1017 #me = Mesh.Get(ob.name) # open objects mesh data
1019 me = Mesh.New(obname) # create a new mesh
1020 ob = SCENE.objects.new(me) # create a new mesh_object
1021 activObjectName = ob.name
1022 activObjectLayer = self.layer
1023 #print ('deb:draw:point new point.ob+mesh:"%s" created!' %ob.name) #---------------------
1024 me.verts.extend(points) # add vertices to mesh
1030 class Polyline: #-----------------------------------------------------------------
1031 """Class for objects representing dxf POLYLINEs.
1033 def __init__(self, obj):
1034 """Expects an entity object of type polyline as input.
1036 #print 'deb:polyline.init.START:----------------' #------------------------
1037 if not obj.type == 'polyline':
1038 raise TypeError, "Wrong type %s for polyline object!" %obj.type
1039 self.type = obj.type
1040 # self.data = obj.data[:]
1042 self.space = getit(obj, 67, 0)
1043 self.elevation = getit(obj, 30, 0)
1044 #print 'deb:elevation: ', self.elevation #---------------
1045 self.thic = getit(obj, 39, 0)
1046 self.color_index = getit(obj, 62, BYLAYER)
1048 self.flags = getit(obj, 70, 0)
1049 self.closed = self.flags & 1 # closed in the M direction
1050 self.curved = self.flags & 2 # Bezier-curve-fit vertices have been added
1051 self.spline = self.flags & 4 # NURBS-curve-fit vertices have been added
1052 self.poly3d = self.flags & 8 # 3D-polyline
1053 self.plmesh = self.flags & 16 # 3D-polygon mesh
1054 self.closeN = self.flags & 32 # closed in the N direction
1055 self.plface = self.flags & 64 # 3D-polyface mesh
1056 self.contin = self.flags & 128 # the linetype pattern is generated continuously
1058 self.pltype='poly2d' # default is a 2D-polyline
1059 if self.poly3d: self.pltype='poly3d'
1060 elif self.plface: self.pltype='plface'
1061 elif self.plmesh: self.pltype='plmesh'
1063 self.swidth = getit(obj, 40, 0) # default start width
1064 self.ewidth = getit(obj, 41, 0) # default end width
1065 #self.bulge = getit(obj, 42, None) # bulge of the segment
1066 self.vectorsM = getit(obj, 71, None) # PolyMesh: expansion in M-direction / PolyFace: number of the vertices
1067 self.vectorsN = getit(obj, 72, None) # PolyMesh: expansion in M-direction / PolyFace: number of faces
1068 #self.resolM = getit(obj, 73, None) # resolution of surface in M direction
1069 #self.resolN = getit(obj, 74, None) # resolution of surface in N direction
1070 self.curvNoFitted = False
1071 self.curvQuadrati = False
1072 self.curvCubicBsp = False
1073 self.curvBezier = False
1074 curvetype = getit(obj, 75, 0) # type of curve/surface: 0=None/5=Quadric/6=Cubic/8=Bezier
1075 if curvetype == 0: self.curvNoFitted = True
1076 elif curvetype == 5: self.curvQuadrati = True
1077 elif curvetype == 6: self.curvCubicBsp = True
1078 elif curvetype == 8: self.curvBezier = True
1080 self.layer = getit(obj, 8, None)
1081 self.extrusion = get_extrusion(obj)
1083 self.points = [] #list with vertices coordinats
1084 self.faces = [] #list with vertices assigment to faces
1085 #print 'deb:polyline.init.ENDinit:----------------' #------------
1090 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
1094 def doubles_out(self, settings, d_points):
1095 """routine to sort out of double.vertices-----------------------------
1097 minimal_dist = settings.var['dist_min'] * 0.1
1100 for i in xrange(len(d_points)-1):
1102 point2 = d_points[i+1]
1103 #print 'deb:double.vertex p1,p2', point, point2 #------------------------
1104 delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
1105 if delta.length > minimal_dist:
1106 temp_points.append(point)
1109 #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
1110 temp_points.append(d_points[-1]) #------ incl. last vertex -------------
1111 #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
1112 d_points = temp_points #-----vertex.list without "double.vertices"
1113 #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1117 def tribles_out(self, settings, d_points):
1118 """routine to sort out of three_in_place.vertices-----------------------------
1120 minimal_dist = settings.var['dist_min'] * 0.1
1123 for i in xrange(len(d_points)-2):
1124 point1 = d_points[i]
1125 point2 = d_points[i+1]
1126 point3 = d_points[i+2]
1127 #print 'deb:double.vertex p1,p2', point, point2 #------------------------
1128 delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
1129 delta23 = Mathutils.Vector(point3.loc) - Mathutils.Vector(point2.loc)
1130 if delta12.length < minimal_dist and delta23.length < minimal_dist:
1133 temp_points.append(point1)
1134 #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------
1135 point1 = d_points[-2]
1136 point2 = d_points[-1]
1137 delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc)
1138 if delta12.length > minimal_dist:
1139 temp_points.append(d_points[-2]) #------ incl. 2last vertex -------------
1140 temp_points.append(d_points[-1]) #------ incl. 1last vertex -------------
1141 #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
1142 d_points = temp_points #-----vertex.list without "double.vertices"
1143 #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1147 def draw(self, settings): #-------------%%%% DRAW POLYLINE %%%---------------
1148 """for POLYLINE: generate Blender_geometry.
1150 #print 'deb:drawPOLYLINE.START:----------------' #------------------------
1151 #print 'deb:POLYLINEdraw self.pltype:', self.pltype #------------------------
1152 #print 'deb:POLYLINEdraw self.points:\n', self.points #------------------------
1154 #---- 3dPolyFace - mesh with free topology
1155 if self.pltype=='plface' and settings.drawTypes['plmesh']:
1156 ob = self.drawPlFace(settings)
1157 #---- 3dPolyMesh - mesh with ortogonal topology
1158 elif self.pltype=='plmesh' and settings.drawTypes['plmesh']:
1159 ob = self.drawPlMesh(settings)
1161 #---- 2dPolyline - plane polyline with arc/wide/thic segments
1162 elif self.pltype=='poly2d' and settings.drawTypes['polyline']:
1163 if settings.var['plines_as'] in [5,6]: # and self.spline:
1164 ob = self.drawPolyCurve(settings)
1166 ob = self.drawPoly2d(settings)
1168 #---- 3dPolyline - non-plane polyline (thin segments = without arc/wide/thic)
1169 elif self.pltype=='poly3d' and settings.drawTypes['pline3']:
1170 if settings.var['plines3_as'] in [5,6]: # and self.spline:
1171 ob = self.drawPolyCurve(settings)
1173 ob = self.drawPoly2d(settings)
1175 #---- Spline - curved polyline (thin segments = without arc/wide/thic)
1176 elif self.pltype=='spline' and settings.drawTypes['spline']:
1177 if settings.var['splines_as'] in [5,6]:
1178 ob = self.drawPolyCurve(settings)
1180 ob = self.drawPoly2d(settings)
1184 def drawPlFace(self, settings): #---- 3dPolyFace - mesh with free topology
1185 """Generate the geometery of polyface.
1187 #print 'deb:drawPlFace.START:----------------' #------------------------
1190 #print 'deb:len of pointsList ====== ', len(self.points) #------------------------
1191 for point in self.points:
1193 faces.append(point.face)
1195 points.append(point.loc)
1197 if settings.var['plmesh_flip']: # ----------------------
1200 face = [face[-1]] + face[:-1]
1202 #print 'deb:drawPlFace: len of points_list:\n', len(points) #-----------------------
1203 #print 'deb:drawPlFace: len of faces_list:\n', len(faces) #-----------------------
1204 #print 'deb:drawPlFace: points_list:\n', points #-----------------------
1205 #print 'deb:drawPlFace: faces_list:\n', faces #-----------------------
1206 obname = 'pf_%s' %self.layer # create object name from layer name
1207 obname = obname[:MAX_NAMELENGTH]
1208 me = Mesh.New(obname) # create a new mesh
1209 ob = SCENE.objects.new(me) # create a new mesh_object
1210 me.verts.extend(points) # add vertices to mesh
1211 me.faces.extend(faces) # add faces to the mesh
1212 if settings.var['normals_out']: # ----------------------
1216 #print 'deb:drawPlFace: len of me.faces:\n', len(me.faces) #-----------------------
1218 if settings.var['meshSmooth_on']: # ----------------------
1219 for i in xrange(len(me.faces)):
1220 me.faces[i].smooth = True
1221 #me.Mode(AUTOSMOOTH)
1222 transform(self.extrusion, 0, ob)
1223 #print 'deb:drawPlFace.END:----------------' #------------------------
1228 def drawPlMesh(self, settings): #---- 3dPolyMesh - mesh with orthogonal topology
1229 """Generate the geometery of polymesh.
1231 #print 'deb:polymesh.draw.START:----------------' #------------------------
1233 #print 'deb:len of pointsList ====== ', len(self.points) #------------------------
1237 for j in xrange(m - 1):
1238 for i in xrange(n - 1):
1240 faces.append([nn+i, nn+i+1, nn+n+i+1, nn+n+i])
1242 if self.closed: #mesh closed in N-direction
1244 for i in xrange(n - 1):
1245 faces.append([nn+i, nn+i+1, i+1, i])
1247 if self.closeN: #mesh closed in M-direction
1248 for j in xrange(m-1):
1250 faces.append([nn+n-1, nn, nn+n, nn+n-1+n])
1252 if self.closed and self.closeN: #mesh closed in M/N-direction
1253 faces.append([ (n*m)-1, (m-1)*n, 0, n-1])
1255 #print 'deb:len of points_list:\n', len(points) #-----------------------
1256 #print 'deb:faces_list:\n', faces #-----------------------
1257 obname = 'pm_%s' %self.layer # create object name from layer name
1258 obname = obname[:MAX_NAMELENGTH]
1259 me = Mesh.New(obname) # create a new mesh
1260 ob = SCENE.objects.new(me) # create a new mesh_object
1261 me.verts.extend([point.loc for point in self.points]) # add vertices to mesh
1262 me.faces.extend(faces) # add faces to the mesh
1263 if settings.var['normals_out']: # ----------------------
1267 if settings.var['meshSmooth_on']: # ----------------------
1268 for i in xrange(len(faces)):
1269 me.faces[i].smooth = True
1270 #me.Mode(AUTOSMOOTH)
1272 transform(self.extrusion, 0, ob)
1273 #print 'deb:polymesh.draw.END:----------------' #------------------------
1277 def drawPolyCurve(self, settings): #---- Polyline - draw as Blender-curve
1278 """Generate the geometery of polyline as Blender-curve.
1280 #print 'deb:polyline2dCurve.draw.START:----------------' #---
1281 if len(self.points) < 2:
1282 #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
1285 if self.spline: pline_typ = 'ps' # Polyline-NURBSpline
1286 elif self.curved: pline_typ = 'pc' # Polyline-BezierCurve
1287 else: pline_typ = 'pl' # Polyline classic
1288 obname = '%s_%s' %(pline_typ, self.layer) # create object_name from layer name
1289 obname = obname[:MAX_NAMELENGTH]
1292 if settings.var['Z_force_on']:
1293 self.elevation = settings.var['Z_elev']
1294 for point in self.points:
1295 point.loc[2] = self.elevation
1296 d_points.append(point)
1297 else: #for DXFr10-format: update all points[].loc[2] == None -> 0.0
1298 for point in self.points:
1299 if point.loc[2] == None:
1300 point.loc[2] = self.elevation
1301 d_points.append(point)
1303 #d_points = self.tribles_out(settings, d_points)
1304 #d_points = self.doubles_out(settings, d_points)
1305 #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1307 thic = set_thick(self.thic, settings)
1308 if thic != 0.0: #hack: Blender<2.45 curve-extrusion
1309 LocZ = d_points[0].loc[2]
1311 for point in d_points:
1313 temp_points.append(point)
1314 d_points = temp_points
1316 #print 'deb:polyline2dCurve.draw d_points=', d_points #---------------
1317 pline = Curve.New(obname) # create new curve data
1318 #pline.setResolu(24) #--todo-----
1320 if self.spline: # NURBSplines-----OK-----
1321 #print 'deb:polyline2dCurve.draw self.spline!' #---------------
1325 pkt.append(d.weight)
1326 nurbs_points.append(pkt)
1327 firstpoint = nurbs_points[0]
1328 curve = pline.appendNurb(firstpoint)
1329 curve.setType(4) # set curve_type NURBS
1330 print 'deb: dir(curve):', dir(curve[-1]) #----------------
1331 for point in nurbs_points[1:]:
1333 #TODO: what is the trick for bevel radius? curve[-1].radius = 1.0
1335 curve.flagU = 1+0 # Set curve cyclic=close and uni
1337 curve.flagU = 0+2 # Set curve not cyclic=open
1338 try: curve.orderU = 5 # works only with >2.46svn080625
1339 except AttributeError: pass
1340 #print 'deb: dir(curve):', dir(curve) #----------------
1342 elif self.curved: #--SPLINE as Bezier-curves---wip------
1343 #print 'deb:polyline2dCurve.draw self.curved!' #---------------
1344 begtangent, endtangent = None, None
1345 if d_points[0].tangent:
1346 begtangent = d_points[0]
1347 d_points = d_points[1:]
1348 if d_points[-1].tangent:
1349 endtangent = d_points[-1]
1350 d_points = d_points[:-1]
1351 curve = pline.appendNurb(BezTriple.New(d_points[0]))
1352 for p in d_points[1:]:
1353 curve.append(BezTriple.New(p))
1355 point.handleTypes = [AUTO, AUTO]
1357 #curve.setType(1) #Bezier curve
1359 curve.flagU = 5 #1 # Set curve cyclic=close
1361 curve.flagU = 4 #0 # Set curve not cyclic=open
1363 #print 'deb:polyline2dCurve.draw curve[0].vec:', curve[0].vec #-----
1364 #print 'deb:polyline2dCurve.draw begtangent:', begtangent #-----
1365 p0h1,p0,p0h2 = curve[0].vec
1366 p0h1 = [p0h1[i]+begtangent[i] for i in range(3)]
1367 curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
1368 curve[0].handleTypes = [FREE, ALIGN] #remi--todo-----
1369 curve[0].radius = 1.0
1371 #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
1372 #print 'deb:polyline2dCurve.draw endtangent:', endtangent #-----
1373 p0h1,p0,p0h2 = curve[-1].vec
1374 p0h2 = [p0h2[i]+endtangent[i] for i in range(3)]
1375 #print 'deb:drawPlineCurve: p0h2:', p0h2 #----------
1376 curve.__setitem__(-1,BezTriple.New(p0h1+p0+p0h2))
1377 #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #-----
1378 curve[-1].handleTypes = [ALIGN, FREE] #remi--todo-----
1379 curve[-1].radius = 1.0
1383 else: #-- only straight line- and arc-segments----OK------
1384 #print 'deb:polyline2dCurve.draw curve:', curve #-----
1386 arc_res = settings.var['curve_arc']
1387 prevHandleType = VECT
1388 #d_points.append(d_points[0]) #------ first vertex added at the end of list --------
1389 #curve.setType(0) #polygon_type of Blender_curve
1390 for i in xrange(len(d_points)):
1391 point1 = d_points[i]
1392 #point2 = d_points[i+1]
1393 #----- optimised Bezier-Handles calculation --------------------------------
1394 #print 'deb:drawPlineCurve: i:', i #---------
1395 if point1.bulge and not (i == len(d_points)-1 and point1.bulge and not self.closed):
1396 if i == len(d_points)-1: point2 = d_points[0]
1397 else: point2 = d_points[i+1]
1400 # calculate additional points for bulge
1401 VectorTriples = calcBulge(point1, point2, arc_res, triples=True)
1403 if prevHandleType == FREE:
1404 #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
1405 VectorTriples[0][:3] = prevHandleVect
1406 #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
1408 if i == 0: curve = pline.appendNurb(BezTriple.New(VectorTriples[0]))
1409 else: curve.append(BezTriple.New(VectorTriples[0]))
1410 curve[-1].handleTypes = [prevHandleType, FREE]
1411 curve[-1].radius = 1.0
1413 for p in VectorTriples[1:-1]:
1414 curve.append(BezTriple.New(p))
1415 curve[-1].handleTypes = [FREE, FREE]
1416 curve[-1].radius = 1.0
1418 prevHandleVect = VectorTriples[-1][:3]
1419 prevHandleType = FREE
1420 #print 'deb:drawPlineCurve: prevHandleVect:', prevHandleVect #---------
1422 #print 'deb:drawPlineCurve: else' #----------
1423 if prevHandleType == FREE:
1424 VectorTriples = prevHandleVect + list(point1) + list(point1)
1425 #print 'deb:drawPlineCurve: VectorTriples:', VectorTriples #---------
1426 curve.append(BezTriple.New(VectorTriples))
1427 curve[-1].handleTypes = [FREE, VECT]
1428 prevHandleType = VECT
1429 curve[-1].radius = 1.0
1431 if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
1432 else: curve.append(BezTriple.New(point1.loc))
1433 curve[-1].handleTypes = [VECT, VECT]
1434 curve[-1].radius = 1.0
1435 #print 'deb:drawPlineCurve: curve[-1].vec[0]', curve[-1].vec[0] #----------
1438 curve.flagU = 1 # Set curve cyclic=close
1439 if prevHandleType == FREE:
1440 #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
1441 #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
1442 prevHandleType2 = curve[0].handleTypes[1]
1443 p0h1,p0,p0h2 = curve[0].vec
1444 #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
1445 p0h1 = prevHandleVect
1447 #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #----------
1448 #curve[0].vec = [p0h1,p0,p0h2]
1449 curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2))
1451 curve[0].handleTypes = [FREE,prevHandleType2]
1452 curve[0].radius = 1.0
1453 #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #----------
1454 #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #----------
1456 curve[0].handleTypes[0] = VECT
1457 curve[0].radius = 1.0
1459 curve.flagU = 0 # Set curve not cyclic=open
1461 if settings.var['fill_on']:
1462 pline.setFlag(6) # 2+4 set top and button caps
1464 pline.setFlag(pline.getFlag() & ~6) # dont set top and button caps
1466 pline.setResolu(settings.var['curve_res'])
1468 ob = SCENE.objects.new(pline) # create a new curve_object
1470 if thic != 0.0: #hack: Blender<2.45 curve-extrusion
1472 pline.setExt1(1.0) # curve-extrusion accepts only (0.0 - 2.0)
1473 ob.LocZ = thic + LocZ
1475 transform(self.extrusion, 0, ob)
1477 ob.SizeZ *= abs(thic)
1479 #print 'deb:polyline2dCurve.draw.END:----------------' #-----
1483 def drawPoly2d(self, settings): #---- 2dPolyline - plane lines/arcs with wide/thic
1484 """Generate the geometery of regular polyline.
1486 #print 'deb:polyline2d.draw.START:----------------' #------------------------
1491 swidth_default = self.swidth #default start width of POLYLINEs segments
1492 ewidth_default = self.ewidth #default end width of POLYLINEs segments
1493 #print 'deb:drawPoly2d self.swidth=', self.swidth #------------------------
1494 thic = set_thick(self.thic, settings)
1495 if self.spline: pline_typ = 'ps'
1496 elif self.curved: pline_typ = 'pc'
1497 else: pline_typ = 'pl'
1498 obname = '%s_%s' %(pline_typ, self.layer) # create object_name from layer name
1499 obname = obname[:MAX_NAMELENGTH]
1501 if len(self.points) < 2:
1502 #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #---------
1505 if settings.var['Z_force_on']:
1506 self.elevation = settings.var['Z_elev']
1507 for point in self.points:
1508 point.loc[2] = self.elevation
1509 d_points.append(point)
1510 else: #for DXFr10-format: update all non-existing LocZ points[].loc[2] == None -> 0.0 elevation
1511 for point in self.points:
1512 if point.loc[2] == None:
1513 point.loc[2] = self.elevation
1514 d_points.append(point)
1515 #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1516 #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
1519 #if closed polyline, add duplic of the first vertex at the end of pointslist
1520 if self.closed: #new_b8
1521 if d_points[-1].loc != d_points[0].loc: # if not equal, then set the first at the end of pointslist
1522 d_points.append(d_points[0])
1524 if d_points[-1].loc == d_points[0].loc: # if equal, then set to closed, and modify the last point
1525 d_points[-1] = d_points[0]
1527 #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1528 #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------
1530 d_points = self.doubles_out(settings, d_points)
1531 #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
1533 #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
1534 if len(d_points) < 2: #if too few vertex, then return
1535 #print 'deb:drawPoly2d corrupted Vertices' #---------
1538 # analyze of straight- and bulge-segments
1539 # generation of additional points for bulge segments
1540 arc_res = settings.var['arc_res']/sqrt(settings.var['arc_rad'])
1541 wide_segment_exist = False
1542 bulg_points = [] # for each point set None (or center for arc-subPoints)
1543 for i in xrange(len(d_points)-1):
1544 point1 = d_points[i]
1545 point2 = d_points[i+1]
1546 #print 'deb:drawPoly2d_bulg tocalc.point1:', point1 #------------------------
1547 #print 'deb:drawPoly2d_bulg tocalc.point2:', point2 #------------------------
1549 swidth = point1.swidth
1550 ewidth = point1.ewidth
1551 #print 'deb:drawPoly2d point1.swidth=', swidth #------------------------
1552 if swidth == None: swidth = swidth_default
1553 if ewidth == None: ewidth = ewidth_default
1554 if swidth != 0.0 or ewidth != 0.0: wide_segment_exist = True
1555 #print 'deb:drawPoly2d vertex_swidth=', swidth #------------------------
1557 if settings.var['width_force']: # force minimal width for thin segments
1558 width_min = settings.var['width_min']
1559 if swidth < width_min: swidth = width_min
1560 if ewidth < width_min: ewidth = width_min
1561 if not settings.var['width_on']: # then force minimal width for all segments
1565 #if point1.bulge and (i < (len(d_points)-1) or self.closed):
1566 if point1.bulge and i < (len(d_points)-1): #10_b8
1567 verts, center = calcBulge(point1, point2, arc_res) #calculate additional points for bulge
1568 points.extend(verts)
1569 delta_width = (ewidth - swidth) / len(verts)
1570 width_list = [swidth + (delta_width * ii) for ii in xrange(len(verts)+1)]
1571 swidths.extend(width_list[:-1])
1572 ewidths.extend(width_list[1:])
1573 bulg_list = [center for ii in xrange(len(verts))]
1574 #the last point in bulge has index False for better indexing of bulg_end!
1575 bulg_list[-1] = None
1576 bulg_points.extend(bulg_list)
1579 points.append(point1.loc)
1580 swidths.append(swidth)
1581 ewidths.append(ewidth)
1582 bulg_points.append(None)
1583 points.append(d_points[-1].loc)
1586 #--calculate width_vectors: left-side- and right-side-points ----------------
1587 # 1.level:IF width ---------------------------------------
1588 if (settings.var['width_on'] and wide_segment_exist) or settings.var['width_force']:
1589 #new_b8 points.append(d_points[0].loc) #temporarly add first vertex at the end (for better loop)
1590 dist_min05 = 0.5 * settings.var['dist_min'] #minimal width for zero_witdh
1592 pointsLs = [] # list of left-start-points
1593 pointsLe = [] # list of left-end-points
1594 pointsRs = [] # list of right-start-points
1595 pointsRe = [] # list of right-end-points
1596 pointsW = [] # list of all border-points
1597 #rotMatr90 = Mathutils.Matrix(rotate 90 degree around Z-axis) = normalvectorXY
1598 rotMatr90 = Mathutils.Matrix([0, -1, 0], [1, 0, 0], [0, 0, 1])
1600 last_bulg_point = False
1601 for i in xrange(len(points)-1):
1603 point2 = points[i+1]
1604 point1vec = Mathutils.Vector(point1)
1605 point2vec = Mathutils.Vector(point2)
1606 swidth05 = swidths[i] * 0.5
1607 ewidth05 = ewidths[i] * 0.5
1608 if swidth05 == 0: swidth05 = dist_min05
1609 if ewidth05 == 0: ewidth05 = dist_min05
1610 normal_vector = rotMatr90 * (point2vec-point1vec).normalize()
1612 last_bulg_point = False
1614 elif bulg_points[i] != None:
1615 centerVec = Mathutils.Vector(bulg_points[i])
1616 if bulg_points[i+1] == None: last_bulg_point = True
1618 else: bulg_in = False
1621 #makes clean intersections for arc-segments
1622 radius1vec = point1vec - centerVec
1623 radius2vec = point2vec - centerVec
1624 angle = Mathutils.AngleBetweenVecs(normal_vector, radius1vec)
1626 normal_vector1 = radius1vec.normalize()
1627 normal_vector2 = radius2vec.normalize()
1629 normal_vector1 = - radius1vec.normalize()
1630 normal_vector2 = - radius2vec.normalize()
1632 swidth05vec = swidth05 * normal_vector1
1633 ewidth05vec = ewidth05 * normal_vector2
1634 pointsLs.append(point1vec + swidth05vec) #vertex left start
1635 pointsRs.append(point1vec - swidth05vec) #vertex right start
1636 pointsLe.append(point2vec + ewidth05vec) #vertex left end
1637 pointsRe.append(point2vec - ewidth05vec) #vertex right end
1640 swidth05vec = swidth05 * normal_vector
1641 ewidth05vec = ewidth05 * normal_vector
1642 pointsLs.append(point1vec + swidth05vec) #vertex left start
1643 pointsRs.append(point1vec - swidth05vec) #vertex right start
1644 pointsLe.append(point2vec + ewidth05vec) #vertex left end
1645 pointsRe.append(point2vec - ewidth05vec) #vertex right end
1647 # additional last point is also calculated
1648 #pointsLs.append(pointsLs[0])
1649 #pointsRs.append(pointsRs[0])
1650 #pointsLe.append(pointsLe[0])
1651 #pointsRe.append(pointsRe[0])
1653 pointsLc, pointsRc = [], [] # lists Left/Right corners = intersection points
1655 # 2.level:IF width and corner-trim
1656 if settings.var['pl_trim_on']: #optional clean corner-intersections
1658 # set STARTpoints of the first point points[0]
1660 pointsLc.append(pointsLs[0])
1661 pointsRc.append(pointsRs[0])
1663 pointsLs.append(pointsLs[0])
1664 pointsRs.append(pointsRs[0])
1665 pointsLe.append(pointsLe[0])
1666 pointsRe.append(pointsRe[0])
1667 points.append(points[0])
1668 vecL3, vecL4 = pointsLs[0], pointsLe[0]
1669 vecR3, vecR4 = pointsRs[0], pointsRe[0]
1670 lenL = len(pointsLs)-1
1671 #print 'deb:drawPoly2d pointsLs():\n', pointsLs #----------------
1672 #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs) #----------------
1674 last_bulg_point = False
1676 # LOOP: makes (ENDpoints[i],STARTpoints[i+1])
1677 for i in xrange(lenL):
1678 if bulg_points[i] != None:
1679 if bulg_points[i+1] == None: #makes clean intersections for arc-segments
1680 last_bulg_point = True
1683 #pointsLc.extend((points[i], pointsLs[i]))
1684 #pointsRc.extend((points[i], pointsRs[i]))
1685 vecL1, vecL2 = vecL3, vecL4
1686 vecR1, vecR2 = vecR3, vecR4
1687 vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
1688 vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
1689 #compute left- and right-cornerpoints
1690 #cornerpointL = Geometry.LineIntersect2D(vec1, vec2, vec3, vec4)
1691 cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
1692 cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
1693 #print 'deb:drawPoly2d cornerpointL: ', cornerpointL #-------------
1694 #print 'deb:drawPoly2d cornerpointR: ', cornerpointR #-------------
1696 # IF not cornerpoint THEN check if identic start-endpoints (=collinear segments)
1697 if cornerpointL == None or cornerpointR == None:
1698 if vecL2 == vecL3 and vecR2 == vecR3:
1699 #print 'deb:drawPoly2d pointVec: ####### identic ##########' #----------------
1700 pointsLc.append(pointsLe[i])
1701 pointsRc.append(pointsRe[i])
1703 pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1704 pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1706 cornerpointL = cornerpointL[0] # because Mathutils.LineIntersect() -> (pkt1,pkt2)
1707 cornerpointR = cornerpointR[0]
1708 #print 'deb:drawPoly2d cornerpointL: ', cornerpointL #-------------
1709 #print 'deb:drawPoly2d cornerpointR: ', cornerpointR #-------------
1710 pointVec0 = Mathutils.Vector(points[i])
1711 pointVec = Mathutils.Vector(points[i+1])
1712 pointVec2 = Mathutils.Vector(points[i+2])
1713 #print 'deb:drawPoly2d pointVec0: ', pointVec0 #-------------
1714 #print 'deb:drawPoly2d pointVec: ', pointVec #-------------
1715 #print 'deb:drawPoly2d pointVec2: ', pointVec2 #-------------
1716 # if diststance(cornerL-center-cornerR) < limiter * (seg1_endWidth + seg2_startWidth)
1717 max_cornerDist = (vecL2 - vecR2).length + (vecL3 - vecR3).length
1718 is_cornerDist = (cornerpointL - pointVec).length + (cornerpointR - pointVec).length
1719 #corner_angle = Mathutils.AngleBetweenVecs((pointVec0 - pointVec),(pointVec - pointVec2))
1720 #print 'deb:drawPoly2d corner_angle: ', corner_angle #-------------
1721 #print 'deb:drawPoly2d max_cornerDist, is_cornerDist: ', max_cornerDist, is_cornerDist #-------------
1722 #if abs(corner_angle) < 90.0:
1723 # intersection --------- limited by TRIM_LIMIT (1.0 - 5.0)
1724 if is_cornerDist < max_cornerDist * settings.var['pl_trim_max']:
1725 # clean corner intersection
1726 pointsLc.append(cornerpointL)
1727 pointsRc.append(cornerpointR)
1729 pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1730 pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1732 pointsLc.append(pointsLe[-1])
1733 pointsRc.append(pointsRe[-1])
1735 # 2.level:IF width but no-trim
1738 # set STARTpoints of the first point points[0]
1740 pointsLc.append(pointsLs[0])
1741 pointsRc.append(pointsRs[0])
1743 pointsLs.append(pointsLs[0])
1744 pointsRs.append(pointsRs[0])
1745 pointsLe.append(pointsLe[0])
1746 pointsRe.append(pointsRe[0])
1747 points.append(points[0])
1748 vecL3, vecL4 = pointsLs[0], pointsLe[0]
1749 vecR3, vecR4 = pointsRs[0], pointsRe[0]
1750 lenL = len(pointsLs)-1
1751 #print 'deb:drawPoly2d pointsLs():\n', pointsLs #----------------
1752 #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs) #----------------
1754 last_bulg_point = False
1756 # LOOP: makes (ENDpoints[i],STARTpoints[i+1])
1757 for i in xrange(lenL):
1758 vecL1, vecL2 = vecL3, vecL4
1759 vecR1, vecR2 = vecR3, vecR4
1760 vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1]
1761 vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
1762 if bulg_points[i] != None:
1763 #compute left- and right-cornerpoints
1764 cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
1765 cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
1766 pointsLc.append(cornerpointL[0])
1767 pointsRc.append(cornerpointR[0])
1769 pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
1770 pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
1772 pointsLc.append(pointsLe[-1])
1773 pointsRc.append(pointsRe[-1])
1775 len1 = len(pointsLc)
1776 #print 'deb:drawPoly2d len1:', len1 #-----------------------
1777 #print 'deb:drawPoly2d len1 len(pointsLc),len(pointsRc):', len(pointsLc),len(pointsRc) #-----------------------
1778 pointsW = pointsLc + pointsRc # all_points_List = left_side + right_side
1779 #print 'deb:drawPoly2d pointsW():\n', pointsW #----------------
1781 # 2.level:IF width and thickness ---------------------
1784 thic_pointsW.extend([[point[0], point[1], point[2]+thic] for point in pointsW])
1786 thic_pointsW.extend(pointsW)
1787 pointsW = thic_pointsW
1789 pointsW.extend(thic_pointsW)
1791 f_start, f_end = [], []
1792 f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
1793 f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
1794 f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
1795 f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
1798 f_bottom.append([len1-1, 0, len1, len1+len1-1]) #bottom face
1799 f_top.append( [len1+len1+len1-1, len1+len1+len1+len1-1, len1+len1+len1, len1+len1+0]) #top face
1800 f_left.append( [0, len1-1, len1+len1+len1-1, len1+len1]) #left face
1801 f_right.append( [len1, len1+len1+len1, len1+len1+len1+len1-1, len1+len1-1]) #right face
1803 f_start = [[0, len1, len1+len1+len1, len1+len1]]
1804 f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
1806 faces = f_left + f_right + f_bottom + f_top + f_start + f_end
1807 #faces = f_bottom + f_top
1808 #faces = f_left + f_right + f_start + f_end
1809 #print 'deb:faces_list:\n', faces #-----------------------
1810 if M_OBJ: obname, me, ob = makeNewObject()
1812 me = Mesh.New(obname) # create a new mesh
1813 ob = SCENE.objects.new(me) # create a new mesh_object
1814 me.verts.extend(pointsW) # add vertices to mesh
1815 me.faces.extend(faces) # add faces to the mesh
1817 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
1818 # The mesh must first be linked to an object so the method knows which object to update.
1819 # This is because vertex groups in Blender are stored in the object -- not in the mesh,
1820 # which may be linked to more than one object.
1821 if settings.var['vGroup_on'] and not M_OBJ:
1822 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
1823 replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD
1824 vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
1825 for v in f_left: vg_left.extend(v)
1826 for v in f_right: vg_right.extend(v)
1827 for v in f_top: vg_top.extend(v)
1828 for v in f_bottom: vg_bottom.extend(v)
1829 me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
1830 me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
1831 me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
1832 me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
1834 me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
1835 me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace)
1837 if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
1838 #if self.spline or self.curved:
1839 smooth_len = len(f_left) + len(f_right)
1840 for i in xrange(smooth_len):
1841 me.faces[i].smooth = True
1842 #me.Modes(AUTOSMOOTH)
1844 # 2.level:IF width, but no-thickness ---------------------
1847 faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)]
1849 faces.append([len1, 0, len1-1, len1+len1-1])
1850 if M_OBJ: obname, me, ob = makeNewObject()
1852 me = Mesh.New(obname) # create a new mesh
1853 ob = SCENE.objects.new(me) # create a new mesh_object
1854 me.verts.extend(pointsW) # add vertices to mesh
1855 me.faces.extend(faces) # add faces to the mesh
1858 # 1.level:IF no-width, but thickness ---------------------
1862 thic_points.extend([[point[0], point[1], point[2]+thic] for point in points])
1864 thic_points.extend(points)
1865 points = thic_points
1867 points.extend(thic_points)
1869 faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
1871 faces.append([len1-1, 0, len1, 2*len1-1])
1872 if M_OBJ: obname, me, ob = makeNewObject()
1874 me = Mesh.New(obname) # create a new mesh
1875 ob = SCENE.objects.new(me) # create a new mesh_object
1876 me.verts.extend(points) # add vertices to mesh
1877 me.faces.extend(faces) # add faces to the mesh
1879 if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
1880 #if self.spline or self.curved:
1881 for i in xrange(len(faces)):
1882 me.faces[i].smooth = True
1883 #me.Modes(AUTOSMOOTH)
1885 # 1.level:IF no-width and no-thickness ---------------------
1887 edges = [[num, num+1] for num in xrange(len(points)-1)]
1889 edges.append([len(points)-1, 0])
1890 if M_OBJ: obname, me, ob = makeNewObject()
1892 me = Mesh.New(obname) # create a new mesh
1893 ob = SCENE.objects.new(me) # create a new mesh_object
1894 me.verts.extend(points) # add vertices to mesh
1895 me.edges.extend(edges) # add edges to the mesh
1897 transform(self.extrusion, 0, ob)
1898 #print 'deb:polyline.draw.END:----------------' #-----------------------
1904 class Vertex(object): #-----------------------------------------------------------------
1905 """Generic vertex object used by POLYLINEs, (and maybe others).
1906 also used by class_LWPOLYLINEs but without obj-parameter
1909 def __init__(self, obj=None):
1910 """Initializes vertex data.
1912 The optional obj arg is an entity object of type vertex.
1914 #print 'deb:Vertex.init.START:----------------' #-----------------------
1917 self.swidth = None #0
1918 self.ewidth = None #0
1920 self.tangent = False
1923 if not obj.type == 'vertex':
1924 raise TypeError, "Wrong type %s for vertex object!" %obj.type
1925 self.type = obj.type
1926 # self.data = obj.data[:]
1930 #print 'deb:Vertex.init.END:----------------' #------------------------
1933 def get_props(self, data):
1934 """Gets coords for a VERTEX type object.
1936 Each vert can have a number of properties.
1937 Verts should be coded as
1944 self.x = getit(data, 10, None)
1945 self.y = getit(data, 20, None)
1946 self.z = getit(data, 30, None)
1948 self.flags = getit(data, 70, 0) # flags
1949 self.curved = self.flags&1 # Bezier-curve-fit:additional-vertex
1950 self.curved_t = self.flags&2 # Bezier-curve-fit:tangent exists
1951 self.spline = self.flags&8 # NURBSpline-fit:additional-vertex
1952 self.spline_c = self.flags&16 # NURBSpline-fit:control-vertex
1953 self.poly3d = self.flags&32 # polyline3d:control-vertex
1954 self.plmesh = self.flags&64 # polymesh3d:control-vertex
1955 self.plface = self.flags&128 # polyface
1957 # if PolyFace.Vertex with Face_definition
1959 self.curve_tangent = getit(data, 50, None) # curve_tangent
1960 if not self.curve_tangent==None:
1962 #elif self.spline_c: # NURBSpline:control-vertex
1963 # self.weight = getit(data, 41, 1.0) # weight od control point
1965 elif self.plface and not self.plmesh:
1966 v1 = getit(data, 71, 0) # polyface:Face.vertex 1.
1967 v2 = getit(data, 72, 0) # polyface:Face.vertex 2.
1968 v3 = getit(data, 73, 0) # polyface:Face.vertex 3.
1969 v4 = getit(data, 74, None) # polyface:Face.vertex 4.
1970 self.face = [abs(v1)-1,abs(v2)-1,abs(v3)-1]
1972 if abs(v4) != abs(v1):
1973 self.face.append(abs(v4)-1)
1974 else: #--parameter for polyline2d
1975 self.swidth = getit(data, 40, None) # start width
1976 self.ewidth = getit(data, 41, None) # end width
1977 self.bulge = getit(data, 42, 0) # bulge of segment
1984 def __getitem__(self, key):
1985 return self.loc[key]
1988 def __setitem__(self, key, value):
1994 return self.loc.__iter__()
1998 return str(self.loc)
2002 return "Vertex %s, swidth=%s, ewidth=%s, bulge=%s, face=%s" %(self.loc, self.swidth, self.ewidth, self.bulge, self.face)
2007 def setx(self, value):
2009 x = property(getx, setx)
2014 def sety(self, value):
2016 y = property(gety, sety)
2021 def setz(self, value):
2023 z = property(getz, setz)
2027 class Spline(Polyline): #-----------------------------------------------------------------
2028 """Class for objects representing dxf SPLINEs.
2030 """Expects an entity object of type spline as input.
2031 100 - Subclass marker (AcDbSpline)
2032 210,220, 230 - Normal vector (omitted if the spline is nonplanar) X,Y,Z values of normal vector
2033 70 - Spline flag (bit coded):
2038 16 = Linear (planar bit is also set)
2039 71 - Degree of the spline curve
2040 72 - Number of knots
2041 73 - Number of control points
2042 74 - Number of fit points (if any)
2043 42 - Knot tolerance (default = 0.0000001)
2044 43 - Control-point tolerance (default = 0.0000001)
2045 44 - Fit tolerance (default = 0.0000000001)
2046 12,22,32 - Start tangent--may be omitted (in WCS). X,Y,Z values of start tangent--may be omitted (in WCS).
2047 13,23, 33 - End tangent--may be omitted (in WCS). X,Y,Z values of end tangent--may be omitted (in WCS)
2048 40 - Knot value (one entry per knot)
2049 41 - Weight (if not 1); with multiple group pairs, are present if all are not 1
2050 10,20, 30 - Control points (in WCS) one entry per control point.
2051 DXF: X value; APP: 3D point, Y and Z values of control points (in WCS) (one entry per control point)
2052 11,21, 31 - Fit points (in WCS) one entry per fit point.
2053 X,Y,Z values of fit points (in WCS) (one entry per fit point)
2055 def __init__(self, obj):
2056 #print 'deb:Spline.START:----------------' #------------------------
2057 if not obj.type == 'spline':
2058 raise TypeError, "Wrong type %s for spline object!" %obj.type
2059 self.type = obj.type
2060 # self.data = obj.data[:]
2063 self.num_points = obj.get_type(73)[0]
2065 # optional data (with defaults)
2066 self.space = getit(obj, 67, 0)
2068 self.color_index = getit(obj, 62, BYLAYER)
2070 #self.elevation = getit(obj, 30, 0)
2071 self.thic = 0 # getit(obj, 39, 0)
2074 self.swidth = width # default start width
2075 self.ewidth = width # default end width
2077 self.flags = getit(obj, 70, 0)
2078 self.closed = self.flags & 1 # closed spline
2079 self.period = self.flags & 2 # Periodic spline
2080 self.ration = self.flags & 4 # Rational spline
2081 self.planar = self.flags & 8 # Planar
2082 self.linear = self.flags & 16 # Linear (and Planar)
2084 self.curvNoFitted = False
2085 self.curvQuadrati = False
2086 self.curvCubicBsp = False
2087 self.curvBezier = False
2088 self.degree = getit(obj, 71, 0) # Degree of the spline curve
2089 if self.degree == 0: self.curvNoFitted = True
2090 elif self.degree == 1: self.curvQuadrati = True
2091 elif self.degree == 2: self.curvCubicBsp = True
2092 #elif self.degree == 3: self.curvBezier = True
2093 #elif self.degree == 3: self.spline = True
2095 self.knotpk_len = getit(obj, 72, 0) # Number of knots
2096 self.ctrlpk_len = getit(obj, 73, 0) # Number of control points
2097 self.fit_pk_len = getit(obj, 74, 0) # Number of fit points (if any)
2099 #TODO: import SPLINE as Bezier curve directly, possible?
2100 #print 'deb:Spline self.fit_pk_len=', self.fit_pk_len #------------------------
2101 #self.fit_pk_len = 0 # temp for debug
2102 if self.fit_pk_len and settings.var['splines_as']==5:
2109 self.knotpk_tol = getit(obj, 42, 0.0000001) # Knot tolerance (default = 0.0000001)
2110 self.ctrlpk_tol = getit(obj, 43, 0.0000001) # Control-point tolerance (default = 0.0000001)
2111 self.fit_pk_tol = getit(obj, 44, 0.0000000001) # Fit tolerance (default = 0.0000000001)
2113 self.layer = getit(obj, 8, None)
2114 self.extrusion = get_extrusion(obj)
2116 self.pltype = 'spline' # spline is a 2D- or 3D-polyline
2118 self.points = self.get_points(obj.data)
2119 #self.knots_val = self.get_knots_val(obj.data) # 40 - Knot value (one entry per knot)
2120 #self.knots_wgh = self.get_knots_wgh(obj.data) # 41 - Weight (default 1)
2122 #print 'deb:Spline obj.data:\n', obj.data #------------------------
2123 #print 'deb:Spline self.points:\n', self.points #------------------------
2124 #print 'deb:Spline.ENDinit:----------------' #------------------------
2127 def get_points(self, data):
2128 """Gets points for a spline type object.
2130 Splines have fixed number of verts, and
2131 each vert can have a number of properties.
2132 Verts should be coded as
2141 if self.spline: # NURBSpline definition
2143 #print 'deb:Spline.get_points spilne_item:', item #------------------------
2144 if item[0] == 10: # control point
2145 if point: points.append(point)
2149 elif item[0] == 20: # 20 = y
2151 elif item[0] == 30: # 30 = z
2153 elif item[0] == 41: # 41 = weight
2154 point.weight = item[1]
2155 #print 'deb:Spline.get_points control point:', point #------------------------
2157 elif self.curved: # Bezier definition
2159 #print 'deb:Spline.get_points curved_item:', item #------------------------
2160 if item[0] == 11: # fit point
2161 if point: points.append(point)
2163 point.tangent = False
2165 elif item[0] == 21: # 20 = y
2167 elif item[0] == 31: # 30 = z
2169 #print 'deb:Spline.get_points fit point:', point #------------------------
2171 elif item[0] == 12: # start tangent
2172 if point: points.append(point)
2174 point.tangent = True
2176 elif item[0] == 22: # = y
2178 elif item[0] == 32: # = z
2180 #print 'deb:Spline.get_points fit begtangent:', point #------------------------
2182 elif item[0] == 13: # end tangent
2183 if point: points.append(point)
2185 pointend.tangent = True
2186 pointend.x = item[1]
2187 elif item[0] == 23: # 20 = y
2188 pointend.y = item[1]
2189 elif item[0] == 33: # 30 = z
2190 pointend.z = item[1]
2191 #print 'deb:Spline.get_points fit endtangent:', pointend #------------------------
2192 points.append(point)
2193 if self.curved and pointend:
2194 points.append(pointend)
2195 #print 'deb:Spline points:\n', points #------------------------
2199 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
2203 class LWpolyline(Polyline): #-------------------------------------------------------------
2204 """Class for objects representing dxf LWPOLYLINEs.
2206 def __init__(self, obj):
2207 """Expects an entity object of type lwpolyline as input.
2209 #print 'deb:LWpolyline.START:----------------' #------------------------
2210 if not obj.type == 'lwpolyline':
2211 raise TypeError, "Wrong type %s for polyline object!" %obj.type
2212 self.type = obj.type
2213 # self.data = obj.data[:]
2216 self.num_points = obj.get_type(90)[0]
2218 # optional data (with defaults)
2219 self.space = getit(obj, 67, 0)
2220 self.elevation = getit(obj, 38, 0)
2221 self.thic = getit(obj, 39, 0)
2222 self.color_index = getit(obj, 62, BYLAYER)
2223 width = getit(obj, 43, 0)
2224 self.swidth = width # default start width
2225 self.ewidth = width # default end width
2226 #print 'deb:LWpolyline width=', width #------------------------
2227 #print 'deb:LWpolyline elevation=', self.elevation #------------------------
2229 self.flags = getit(obj, 70, 0)
2230 self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen
2232 self.layer = getit(obj, 8, None)
2233 self.extrusion = get_extrusion(obj)
2235 self.points = self.get_points(obj.data)
2237 self.pltype = 'poly2d' # LW-polyline is a 2D-polyline
2242 #print 'deb:LWpolyline.obj.data:\n', obj.data #------------------------
2243 #print 'deb:LWpolyline.ENDinit:----------------' #------------------------
2246 def get_points(self, data):
2247 """Gets points for a polyline type object.
2249 LW-Polylines have no fixed number of verts, and
2250 each vert can have a number of properties.
2251 Verts should be coded as
2259 num = self.num_points
2263 if item[0] == 10: # 10 = x
2265 points.append(point)
2268 point.z = self.elevation
2269 elif item[0] == 20: # 20 = y
2271 elif item[0] == 40: # 40 = start width
2272 point.swidth = item[1]
2273 elif item[0] == 41: # 41 = end width
2274 point.ewidth = item[1]
2275 elif item[0] == 42: # 42 = bulge
2276 point.bulge = item[1]
2277 points.append(point)
2282 return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
2285 class Text: #-----------------------------------------------------------------
2286 """Class for objects representing dxf TEXT.
2288 def __init__(self, obj):
2289 """Expects an entity object of type text as input.
2291 if not obj.type == 'text':
2292 raise TypeError, "Wrong type %s for text object!" %obj.type
2293 self.type = obj.type
2294 # self.data = obj.data[:]
2297 self.height = 1.7 * obj.get_type(40)[0] #text.height
2298 self.value = obj.get_type(1)[0] #The text string value
2300 # optional data (with defaults)
2301 self.space = getit(obj, 67, 0)
2302 self.color_index = getit(obj, 62, BYLAYER)
2303 self.thic = getit(obj, 39, 0)
2305 self.rotation = getit(obj, 50, 0) # radians
2306 self.width_factor = getit(obj, 41, 1) # Scaling factor along local x axis
2307 self.oblique = getit(obj, 51, 0) # oblique angle: skew in degrees -90 <= oblique <= 90
2309 #self.style = getit(obj, 7, 'STANDARD') # --todo---- Text style name (optional, default = STANDARD)
2311 #Text generation flags (optional, default = 0):
2312 #2 = backward (mirrored in X),
2313 #4 = upside down (mirrored in Y)
2314 self.flags = getit(obj, 71, 0)
2315 self.mirrorX, self.mirrorY = 1.0, 1.0
2316 if self.flags&2: self.mirrorX = - 1.0
2317 if self.flags&4: self.mirrorY = - 1.0
2319 # vertical.alignment: 0=baseline, 1=bottom, 2=middle, 3=top
2320 self.valignment = getit(obj, 73, 0)
2321 #Horizontal text justification type (optional, default = 0) integer codes (not bit-coded)
2322 #0=left, 1=center, 2=right
2323 #3=aligned, 4=middle, 5=fit
2324 self.halignment = getit(obj, 72, 0)
2326 self.layer = getit(obj, 8, None)
2327 self.loc1, self.loc2 = self.get_loc(obj)
2328 if self.loc2[0] != None and self.halignment != 5:
2329 self.loc = self.loc2
2331 self.loc = self.loc1
2332 self.extrusion = get_extrusion(obj)
2335 def get_loc(self, data):
2336 """Gets adjusted location for text type objects.
2338 If group 72 and/or 73 values are nonzero then the first alignment point values
2339 are ignored and AutoCAD calculates new values based on the second alignment
2340 point and the length and height of the text string itself (after applying the
2341 text style). If the 72 and 73 values are zero or missing, then the second
2342 alignment point is meaningless.
2343 I don't know how to calc text size...
2345 # bottom left x, y, z and justification x, y, z = 0
2346 #x, y, z, jx, jy, jz = 0, 0, 0, 0, 0, 0
2347 x = getit(data, 10, None) #First alignment point (in OCS).
2348 y = getit(data, 20, None)
2349 z = getit(data, 30, 0.0)
2350 jx = getit(data, 11, None) #Second alignment point (in OCS).
2351 jy = getit(data, 21, None)
2352 jz = getit(data, 31, 0.0)
2353 return [x, y, z],[jx, jy, jz]
2357 return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
2360 def draw(self, settings):
2361 """for TEXTs: generate Blender_geometry.
2363 obname = 'tx_%s' %self.layer # create object name from layer name
2364 obname = obname[:MAX_NAMELENGTH]
2365 txt = Text3d.New(obname)
2366 ob = SCENE.objects.new(txt) # create a new text_object
2368 txt.setText(self.value)
2369 txt.setSize(1.0) #Blender<2.45 accepts only (0.0 - 5.0)
2370 #txt.setSize(self.height)
2371 #txt.setWidth(self.bold)
2372 #setLineSeparation(sep)
2373 txt.setShear(self.oblique/90)
2375 thic = set_thick(self.thic, settings)
2377 thic = self.thic * 0.5
2379 txt.setExtrudeDepth(1.0) #Blender<2.45 accepts only (0.1 - 10.0)
2380 if self.halignment == 0:
2382 elif self.halignment == 1:
2383 align = Text3d.MIDDLE
2384 elif self.halignment == 2:
2385 align = Text3d.RIGHT
2388 txt.setAlignment(align)
2390 if self.valignment == 1:
2392 elif self.valignment == 2:
2393 txt.setYoffset(- self.height * 0.5)
2394 elif self.valignment == 3:
2395 txt.setYoffset(- self.height)
2397 # move the object center to the text location
2398 ob.loc = tuple(self.loc)
2399 transform(self.extrusion, self.rotation, ob)
2401 # flip it and scale it to the text width
2402 ob.SizeX *= self.height * self.width_factor * self.mirrorX
2403 ob.SizeY *= self.height * self.mirrorY
2404 if thic != 0.0: ob.SizeZ *= abs(thic)
2409 def set_thick(thickness, settings):
2410 """Set thickness relative to settings variables.
2412 Set thickness relative to settings variables:
2413 'thick_on','thick_force','thick_min'.
2414 Accepted also minus values of thickness
2415 python trick: sign(x)=cmp(x,0)
2417 if settings.var['thick_force']:
2418 if settings.var['thick_on']:
2419 if abs(thickness) < settings.var['thick_min']:
2420 thic = settings.var['thick_min'] * cmp(thickness,0)
2421 else: thic = thickness
2422 else: thic = settings.var['thick_min']
2424 if settings.var['thick_on']: thic = thickness
2431 class Mtext: #-----------------------------------------------------------------
2432 """Class for objects representing dxf MTEXT.
2435 def __init__(self, obj):
2436 """Expects an entity object of type mtext as input.
2438 if not obj.type == 'mtext':
2439 raise TypeError, "Wrong type %s for mtext object!" %obj.type
2440 self.type = obj.type
2441 # self.data = obj.data[:]
2444 self.height = obj.get_type(40)[0]
2445 self.width = obj.get_type(41)[0]
2446 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
2447 self.value = self.get_text(obj) # The text string value
2449 # optional data (with defaults)
2450 self.space = getit(obj, 67, 0)
2451 self.color_index = getit(obj, 62, BYLAYER)
2452 self.rotation = getit(obj, 50, 0) # radians
2454 self.width_factor = getit(obj, 42, 1) # Scaling factor along local x axis
2455 self.line_space = getit(obj, 44, 1) # percentage of default
2457 self.layer = getit(obj, 8, None)
2458 self.loc = self.get_loc(obj)
2459 self.extrusion = get_extrusion(obj)
2462 def get_text(self, data):
2463 """Reconstructs mtext data from dxf codes.
2468 if item[0] == 1: # There should be only one primary...
2470 elif item[0] == 3: # There may be any number of extra strings (in order)
2471 secondary.append(item[1])
2473 #raise ValueError, "Empty Mtext Object!"
2474 string = "Empty Mtext Object!"
2476 string = primary.replace(r'\P', '\n')
2478 string = ''.join(secondary)+primary
2479 string = string.replace(r'\P', '\n')
2483 def get_loc(self, data):
2484 """Gets location for a mtext type objects.
2486 Mtext objects have only one point indicating
2489 loc[0] = getit(data, 10, None)
2490 loc[1] = getit(data, 20, None)
2491 loc[2] = getit(data, 30, 0.0)
2496 return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
2499 def draw(self, settings):
2500 """for MTEXTs: generate Blender_geometry.
2502 # Now Create an object
2503 obname = 'tm_%s' %self.layer # create object name from layer name
2504 obname = obname[:MAX_NAMELENGTH]
2505 txt = Text3d.New(obname)
2506 ob = SCENE.objects.new(txt) # create a new text_object
2509 # Blender doesn't give access to its text object width currently
2510 # only to the text3d's curve width...
2511 #txt.setWidth(text.width/10)
2512 txt.setLineSeparation(self.line_space)
2513 txt.setExtrudeDepth(0.5)
2514 txt.setText(self.value)
2516 # scale it to the text size
2517 ob.SizeX = self.height * self.width_factor
2518 ob.SizeY = self.height
2519 ob.SizeZ = self.height
2521 # move the object center to the text location
2522 ob.loc = tuple(self.loc)
2523 transform(self.extrusion, self.rotation, ob)
2528 class Circle: #-----------------------------------------------------------------
2529 """Class for objects representing dxf CIRCLEs.
2532 def __init__(self, obj):
2533 """Expects an entity object of type circle as input.
2535 if not obj.type == 'circle':
2536 raise TypeError, "Wrong type %s for circle object!" %obj.type
2537 self.type = obj.type
2538 # self.data = obj.data[:]
2541 self.radius = obj.get_type(40)[0]
2543 # optional data (with defaults)
2544 self.space = getit(obj, 67, 0)
2545 self.thic = getit(obj, 39, 0)
2546 self.color_index = getit(obj, 62, BYLAYER)
2548 self.layer = getit(obj, 8, None)
2549 self.loc = self.get_loc(obj)
2550 self.extrusion = get_extrusion(obj)
2554 def get_loc(self, data):
2555 """Gets the center location for circle type objects.
2557 Circles have a single coord location.
2560 loc[0] = getit(data, 10, None)
2561 loc[1] = getit(data, 20, None)
2562 loc[2] = getit(data, 30, 0.0)
2568 return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
2571 def draw(self, settings):
2572 """for CIRCLE: generate Blender_geometry.
2574 obname = 'ci_%s' %self.layer # create object name from layer name
2575 obname = obname[:MAX_NAMELENGTH]
2576 radius = self.radius
2578 thic = set_thick(self.thic, settings)
2580 if settings.var['lines_as'] == 4: # as thin_box
2581 thic = settings.var['thick_min']
2582 width = settings.var['width_min']
2583 if settings.var['lines_as'] == 3: # as thin cylinder
2584 cyl_rad = 0.5 * settings.var['width_min']
2586 if settings.var['lines_as'] == 5: # draw CIRCLE as curve -------------
2587 arc_res = settings.var['curve_arc']
2589 start, end = 0.0, 360.0
2590 VectorTriples = calcArc(None, radius, start, end, arc_res, True)
2591 c = Curve.New(obname) # create new curve data
2592 curve = c.appendNurb(BezTriple.New(VectorTriples[0]))
2593 for p in VectorTriples[1:-1]:
2594 curve.append(BezTriple.New(p))
2596 point.handleTypes = [FREE, FREE]
2598 curve.flagU = 1 # 1 sets the curve cyclic=closed
2599 if settings.var['fill_on']:
2600 c.setFlag(6) # 2+4 set top and button caps
2602 c.setFlag(c.getFlag() & ~6) # dont set top and button caps
2604 c.setResolu(settings.var['curve_res'])
2607 #--todo-----to check---------------------------
2608 ob = SCENE.objects.new(c) # create a new curve_object
2609 ob.loc = tuple(self.loc)
2610 if thic != 0.0: #hack: Blender<2.45 curve-extrusion
2612 c.setExt1(1.0) # curve-extrusion accepts only (0.0 - 2.0)
2613 ob.LocZ = thic + self.loc[2]
2614 transform(self.extrusion, 0, ob)
2616 ob.SizeZ *= abs(thic)
2619 else: # draw CIRCLE as mesh -----------------------------------------------
2620 if M_OBJ: obname, me, ob = makeNewObject()
2622 me = Mesh.New(obname) # create a new mesh
2623 ob = SCENE.objects.new(me) # create a new mesh_object
2624 # set a number of segments in entire circle
2625 arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
2626 start, end = 0.0 , 360.0
2627 verts = calcArc(None, radius, start, end, arc_res, False)
2628 verts = verts[:-1] #list without last point/edge (cause by circle it is equal to the first point)
2629 #print 'deb:circleDraw: verts:', verts #---------------
2634 thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
2636 thic_verts.extend(verts)
2639 verts.extend(thic_verts)
2641 f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)]
2642 #f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1)]
2643 f_band.append([len1 - 1, 0, len1, len1 + len1 -1])
2645 smooth_len = len(f_band)
2646 if settings.var['fill_on']:
2648 verts.append([0,0,thic]) #center of top side
2649 verts.append([0,0,0]) #center of bottom side
2651 verts.append([0,0,0]) #center of bottom side
2652 verts.append([0,0,thic]) #center of top side
2653 center1 = len(verts)-2
2654 center2 = len(verts)-1
2655 f_bottom = [[num+1, num, center1] for num in xrange(len1 - 1)]
2656 f_bottom.append([0, len1 - 1, center1])
2657 f_top = [[num+len1, num+1+len1, center2] for num in xrange(len1 - 1)]
2658 f_top.append([len1-1+len1, 0+len1, center2])
2659 #print 'deb:circleDraw:verts:', verts #---------------
2660 faces = f_band + f_bottom + f_top
2661 #print 'deb:circleDraw:faces:', faces #---------------
2662 me.verts.extend(verts) # add vertices to mesh
2663 me.faces.extend(faces) # add faces to the mesh
2665 if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
2666 for i in xrange(smooth_len):
2667 me.faces[i].smooth = True
2668 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
2669 if settings.var['vGroup_on'] and not M_OBJ:
2670 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
2671 replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD
2672 vg_band, vg_top, vg_bottom = [], [], []
2673 for v in f_band: vg_band.extend(v)
2674 me.addVertGroup('side.band') ; me.assignVertsToGroup('side.band', vg_band, 1.0, replace)
2676 if settings.var['fill_on']:
2677 for v in f_top: vg_top.extend(v)
2678 for v in f_bottom: vg_bottom.extend(v)
2679 me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
2680 me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
2682 else: # if thic == 0
2683 if settings.var['fill_on']:
2685 verts.append([0,0,0]) #center of circle
2688 faces.extend([[num, num+1, center1] for num in xrange(len1)])
2689 faces.append([len1-1, 0, center1])
2690 #print 'deb:circleDraw:verts:', verts #---------------
2691 #print 'deb:circleDraw:faces:', faces #---------------
2692 me.verts.extend(verts) # add vertices to mesh
2693 me.faces.extend(faces) # add faces to the mesh
2695 me.verts.extend(verts) # add vertices to mesh
2696 edges = [[num, num+1] for num in xrange(len(verts))]
2697 edges[-1][1] = 0 # it points the "new" last edge to the first vertex
2698 me.edges.extend(edges) # add edges to the mesh
2700 ob.loc = tuple(self.loc)
2701 transform(self.extrusion, 0, ob)
2705 class Arc: #-----------------------------------------------------------------
2706 """Class for objects representing dxf ARCs.
2709 def __init__(self, obj):
2710 """Expects an entity object of type arc as input.
2712 if not obj.type == 'arc':
2713 raise TypeError, "Wrong type %s for arc object!" %obj.type
2714 self.type = obj.type
2715 # self.data = obj.data[:]
2718 self.radius = obj.get_type(40)[0]
2719 self.start_angle = obj.get_type(50)[0]
2720 self.end_angle = obj.get_type(51)[0]
2722 # optional data (with defaults)
2723 self.space = getit(obj, 67, 0)
2724 self.thic = getit(obj, 39, 0)
2725 self.color_index = getit(obj, 62, BYLAYER)
2727 self.layer = getit(obj, 8, None)
2728 self.loc = self.get_loc(obj)
2729 self.extrusion = get_extrusion(obj)
2730 #print 'deb:Arc__init__: center, radius, start, end:\n', self.loc, self.radius, self.start_angle, self.end_angle #---------
2734 def get_loc(self, data):
2735 """Gets the center location for arc type objects.
2737 Arcs have a single coord location.
2740 loc[0] = getit(data, 10, None)
2741 loc[1] = getit(data, 20, None)
2742 loc[2] = getit(data, 30, 0.0)
2748 return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
2751 def draw(self, settings):
2752 """for ARC: generate Blender_geometry.
2754 obname = 'ar_%s' %self.layer # create object name from layer name
2755 obname = obname[:MAX_NAMELENGTH]
2758 radius = self.radius
2759 start = self.start_angle
2760 end = self.end_angle
2761 #print 'deb:calcArcPoints:\n center, radius, start, end:\n', center, radius, start, end #---------
2762 thic = set_thick(self.thic, settings)
2764 if settings.var['lines_as'] == 4: # as thin_box
2765 thic = settings.var['thick_min']
2766 width = settings.var['width_min']
2767 if settings.var['lines_as'] == 3: # as thin cylinder
2768 cyl_rad = 0.5 * settings.var['width_min']
2770 if settings.var['lines_as'] == 5: # draw ARC as curve -------------
2771 arc_res = settings.var['curve_arc']
2773 VectorTriples = calcArc(None, radius, start, end, arc_res, triples)
2774 arc = Curve.New(obname) # create new curve data
2775 curve = arc.appendNurb(BezTriple.New(VectorTriples[0]))
2776 for p in VectorTriples[1:]:
2777 curve.append(BezTriple.New(p))
2779 point.handleTypes = [FREE, FREE]
2781 curve.flagU = 0 # 0 sets the curve not cyclic=open
2782 arc.setResolu(settings.var['curve_res'])
2784 arc.update() #important for handles calculation
2786 ob = SCENE.objects.new(arc) # create a new curve_object
2787 ob.loc = tuple(self.loc)
2788 if thic != 0.0: #hack: Blender<2.45 curve-extrusion
2790 arc.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0)
2791 ob.LocZ = thic + self.loc[2]
2792 transform(self.extrusion, 0, ob)
2794 ob.SizeZ *= abs(thic)
2797 else: # draw ARC as mesh --------------------
2798 if M_OBJ: obname, me, ob = makeNewObject()
2800 me = Mesh.New(obname) # create a new mesh
2801 ob = SCENE.objects.new(me) # create a new mesh_object
2802 # set a number of segments in entire circle
2803 arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad'])
2805 verts = calcArc(None, radius, start, end, arc_res, False)
2806 #verts = [list(point) for point in verts]
2808 #print 'deb:len1:', len1 #-----------------------
2810 radius_out = radius + (0.5 * width)
2811 radius_in = radius - (0.5 * width)
2812 if radius_in <= 0.0:
2813 radius_in = settings.var['dist_min']
2818 pointVec = Mathutils.Vector(point)
2819 pointVec = pointVec.normalize()
2820 verts_in.append(list(radius_in * pointVec)) #vertex inside
2821 verts_out.append(list(radius_out * pointVec)) #vertex outside
2822 verts = verts_in + verts_out
2824 #print 'deb:verts:', verts #---------------------
2827 thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts])
2829 thic_verts.extend(verts)
2832 verts.extend(thic_verts)
2833 f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)]
2834 f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)]
2835 f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)]
2836 f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)]
2837 f_start = [[0, len1, len1+len1+len1, len1+len1]]
2838 f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]]
2839 faces = f_left + f_right + f_bottom + f_top + f_start + f_end
2841 me.verts.extend(verts) # add vertices to mesh
2842 me.faces.extend(faces) # add faces to the mesh
2844 if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
2845 smooth_len = len(f_left) + len(f_right)
2846 for i in xrange(smooth_len):
2847 me.faces[i].smooth = True
2848 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
2849 if settings.var['vGroup_on'] and not M_OBJ:
2850 # each MeshSide becomes vertexGroup for easier material assignment ---------------------
2851 replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD
2852 vg_left, vg_right, vg_top, vg_bottom = [], [], [], []
2853 for v in f_left: vg_left.extend(v)
2854 for v in f_right: vg_right.extend(v)
2855 for v in f_top: vg_top.extend(v)
2856 for v in f_bottom: vg_bottom.extend(v)
2857 me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
2858 me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
2859 me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
2860 me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
2861 me.addVertGroup('side.start')