Draft: Removed draftlibs

Removed the contents of the draftlibs folder (dxf import-export) for license
reasons. These files are now hosted on
https://github.com/yorikvanhavre/Draft-dxf-importer and will be downloaded
automatically by FreeCAD on first use.
This commit is contained in:
Yorik van Havre 2013-06-22 14:48:58 -03:00
parent 1dc122dc9a
commit 2d180fac38
6 changed files with 17 additions and 2898 deletions

View File

@ -1 +0,0 @@
# this is the init file of the draftlibs library

View File

@ -1,282 +0,0 @@
# dictionary mapping AutoCAD color indexes with Blender colors
# --------------------------------------------------------------------------
# color_map.py Final by Ed Blake (AKA Kitsu)
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
color_map = {
0:[0.0, 0.0, 0.0],
1:[0.99609375, 0.0, 0.0],
2:[0.99609375, 0.99609375, 0.0],
3:[0.0, 0.99609375, 0.0],
4:[0.0, 0.99609375, 0.99609375],
5:[0.0, 0.0, 0.99609375],
6:[0.99609375, 0.0, 0.99609375],
7:[0.99609375, 0.99609375, 0.99609375],
8:[0.25390625, 0.25390625, 0.25390625],
9:[0.5, 0.5, 0.5],
10:[0.99609375, 0.0, 0.0],
11:[0.99609375, 0.6640625, 0.6640625],
12:[0.73828125, 0.0, 0.0],
13:[0.73828125, 0.4921875, 0.4921875],
14:[0.50390625, 0.0, 0.0],
15:[0.50390625, 0.3359375, 0.3359375],
16:[0.40625, 0.0, 0.0],
17:[0.40625, 0.26953125, 0.26953125],
18:[0.30859375, 0.0, 0.0],
19:[0.30859375, 0.20703125, 0.20703125],
20:[0.99609375, 0.24609375, 0.0],
21:[0.99609375, 0.74609375, 0.6640625],
22:[0.73828125, 0.1796875, 0.0],
23:[0.73828125, 0.55078125, 0.4921875],
24:[0.50390625, 0.12109375, 0.0],
25:[0.50390625, 0.375, 0.3359375],
26:[0.40625, 0.09765625, 0.0],
27:[0.40625, 0.3046875, 0.26953125],
28:[0.30859375, 0.07421875, 0.0],
29:[0.30859375, 0.23046875, 0.20703125],
30:[0.99609375, 0.49609375, 0.0],
31:[0.99609375, 0.828125, 0.6640625],
32:[0.73828125, 0.3671875, 0.0],
33:[0.73828125, 0.61328125, 0.4921875],
34:[0.50390625, 0.25, 0.0],
35:[0.50390625, 0.41796875, 0.3359375],
36:[0.40625, 0.203125, 0.0],
37:[0.40625, 0.3359375, 0.26953125],
38:[0.30859375, 0.15234375, 0.0],
39:[0.30859375, 0.2578125, 0.20703125],
40:[0.99609375, 0.74609375, 0.0],
41:[0.99609375, 0.9140625, 0.6640625],
42:[0.73828125, 0.55078125, 0.0],
43:[0.73828125, 0.67578125, 0.4921875],
44:[0.50390625, 0.375, 0.0],
45:[0.50390625, 0.4609375, 0.3359375],
46:[0.40625, 0.3046875, 0.0],
47:[0.40625, 0.37109375, 0.26953125],
48:[0.30859375, 0.23046875, 0.0],
49:[0.30859375, 0.28515625, 0.20703125],
50:[0.99609375, 0.99609375, 0.0],
51:[0.99609375, 0.99609375, 0.6640625],
52:[0.73828125, 0.73828125, 0.0],
53:[0.73828125, 0.73828125, 0.4921875],
54:[0.50390625, 0.50390625, 0.0],
55:[0.50390625, 0.50390625, 0.3359375],
56:[0.40625, 0.40625, 0.0],
57:[0.40625, 0.40625, 0.26953125],
58:[0.30859375, 0.30859375, 0.0],
59:[0.30859375, 0.30859375, 0.20703125],
60:[0.74609375, 0.99609375, 0.0],
61:[0.9140625, 0.99609375, 0.6640625],
62:[0.55078125, 0.73828125, 0.0],
63:[0.67578125, 0.73828125, 0.4921875],
64:[0.375, 0.50390625, 0.0],
65:[0.4609375, 0.50390625, 0.3359375],
66:[0.3046875, 0.40625, 0.0],
67:[0.37109375, 0.40625, 0.26953125],
68:[0.23046875, 0.30859375, 0.0],
69:[0.28515625, 0.30859375, 0.20703125],
70:[0.49609375, 0.99609375, 0.0],
71:[0.828125, 0.99609375, 0.6640625],
72:[0.3671875, 0.73828125, 0.0],
73:[0.61328125, 0.73828125, 0.4921875],
74:[0.25, 0.50390625, 0.0],
75:[0.41796875, 0.50390625, 0.3359375],
76:[0.203125, 0.40625, 0.0],
77:[0.3359375, 0.40625, 0.26953125],
78:[0.15234375, 0.30859375, 0.0],
79:[0.2578125, 0.30859375, 0.20703125],
80:[0.24609375, 0.99609375, 0.0],
81:[0.74609375, 0.99609375, 0.6640625],
82:[0.1796875, 0.73828125, 0.0],
83:[0.55078125, 0.73828125, 0.4921875],
84:[0.12109375, 0.50390625, 0.0],
85:[0.375, 0.50390625, 0.3359375],
86:[0.09765625, 0.40625, 0.0],
87:[0.3046875, 0.40625, 0.26953125],
88:[0.07421875, 0.30859375, 0.0],
89:[0.23046875, 0.30859375, 0.20703125],
90:[0.0, 0.99609375, 0.0],
91:[0.6640625, 0.99609375, 0.6640625],
92:[0.0, 0.73828125, 0.0],
93:[0.4921875, 0.73828125, 0.4921875],
94:[0.0, 0.50390625, 0.0],
95:[0.3359375, 0.50390625, 0.3359375],
96:[0.0, 0.40625, 0.0],
97:[0.26953125, 0.40625, 0.26953125],
98:[0.0, 0.30859375, 0.0],
99:[0.20703125, 0.30859375, 0.20703125],
100:[0.0, 0.99609375, 0.24609375],
101:[0.6640625, 0.99609375, 0.74609375],
102:[0.0, 0.73828125, 0.1796875],
103:[0.4921875, 0.73828125, 0.55078125],
104:[0.0, 0.50390625, 0.12109375],
105:[0.3359375, 0.50390625, 0.375],
106:[0.0, 0.40625, 0.09765625],
107:[0.26953125, 0.40625, 0.3046875],
108:[0.0, 0.30859375, 0.07421875],
109:[0.20703125, 0.30859375, 0.23046875],
110:[0.0, 0.99609375, 0.49609375],
111:[0.6640625, 0.99609375, 0.828125],
112:[0.0, 0.73828125, 0.3671875],
113:[0.4921875, 0.73828125, 0.61328125],
114:[0.0, 0.50390625, 0.25],
115:[0.3359375, 0.50390625, 0.41796875],
116:[0.0, 0.40625, 0.203125],
117:[0.26953125, 0.40625, 0.3359375],
118:[0.0, 0.30859375, 0.15234375],
119:[0.20703125, 0.30859375, 0.2578125],
120:[0.0, 0.99609375, 0.74609375],
121:[0.6640625, 0.99609375, 0.9140625],
122:[0.0, 0.73828125, 0.55078125],
123:[0.4921875, 0.73828125, 0.67578125],
124:[0.0, 0.50390625, 0.375],
125:[0.3359375, 0.50390625, 0.4609375],
126:[0.0, 0.40625, 0.3046875],
127:[0.26953125, 0.40625, 0.37109375],
128:[0.0, 0.30859375, 0.23046875],
129:[0.20703125, 0.30859375, 0.28515625],
130:[0.0, 0.99609375, 0.99609375],
131:[0.6640625, 0.99609375, 0.99609375],
132:[0.0, 0.73828125, 0.73828125],
133:[0.4921875, 0.73828125, 0.73828125],
134:[0.0, 0.50390625, 0.50390625],
135:[0.3359375, 0.50390625, 0.50390625],
136:[0.0, 0.40625, 0.40625],
137:[0.26953125, 0.40625, 0.40625],
138:[0.0, 0.30859375, 0.30859375],
139:[0.20703125, 0.30859375, 0.30859375],
140:[0.0, 0.74609375, 0.99609375],
141:[0.6640625, 0.9140625, 0.99609375],
142:[0.0, 0.55078125, 0.73828125],
143:[0.4921875, 0.67578125, 0.73828125],
144:[0.0, 0.375, 0.50390625],
145:[0.3359375, 0.4609375, 0.50390625],
146:[0.0, 0.3046875, 0.40625],
147:[0.26953125, 0.37109375, 0.40625],
148:[0.0, 0.23046875, 0.30859375],
149:[0.20703125, 0.28515625, 0.30859375],
150:[0.0, 0.49609375, 0.99609375],
151:[0.6640625, 0.828125, 0.99609375],
152:[0.0, 0.3671875, 0.73828125],
153:[0.4921875, 0.61328125, 0.73828125],
154:[0.0, 0.25, 0.50390625],
155:[0.3359375, 0.41796875, 0.50390625],
156:[0.0, 0.203125, 0.40625],
157:[0.26953125, 0.3359375, 0.40625],
158:[0.0, 0.15234375, 0.30859375],
159:[0.20703125, 0.2578125, 0.30859375],
160:[0.0, 0.24609375, 0.99609375],
161:[0.6640625, 0.74609375, 0.99609375],
162:[0.0, 0.1796875, 0.73828125],
163:[0.4921875, 0.55078125, 0.73828125],
164:[0.0, 0.12109375, 0.50390625],
165:[0.3359375, 0.375, 0.50390625],
166:[0.0, 0.09765625, 0.40625],
167:[0.26953125, 0.3046875, 0.40625],
168:[0.0, 0.07421875, 0.30859375],
169:[0.20703125, 0.23046875, 0.30859375],
170:[0.0, 0.0, 0.99609375],
171:[0.6640625, 0.6640625, 0.99609375],
172:[0.0, 0.0, 0.73828125],
173:[0.4921875, 0.4921875, 0.73828125],
174:[0.0, 0.0, 0.50390625],
175:[0.3359375, 0.3359375, 0.50390625],
176:[0.0, 0.0, 0.40625],
177:[0.26953125, 0.26953125, 0.40625],
178:[0.0, 0.0, 0.30859375],
179:[0.20703125, 0.20703125, 0.30859375],
180:[0.24609375, 0.0, 0.99609375],
181:[0.74609375, 0.6640625, 0.99609375],
182:[0.1796875, 0.0, 0.73828125],
183:[0.55078125, 0.4921875, 0.73828125],
184:[0.12109375, 0.0, 0.50390625],
185:[0.375, 0.3359375, 0.50390625],
186:[0.09765625, 0.0, 0.40625],
187:[0.3046875, 0.26953125, 0.40625],
188:[0.07421875, 0.0, 0.30859375],
189:[0.23046875, 0.20703125, 0.30859375],
190:[0.49609375, 0.0, 0.99609375],
191:[0.828125, 0.6640625, 0.99609375],
192:[0.3671875, 0.0, 0.73828125],
193:[0.61328125, 0.4921875, 0.73828125],
194:[0.25, 0.0, 0.50390625],
195:[0.41796875, 0.3359375, 0.50390625],
196:[0.203125, 0.0, 0.40625],
197:[0.3359375, 0.26953125, 0.40625],
198:[0.15234375, 0.0, 0.30859375],
199:[0.2578125, 0.20703125, 0.30859375],
200:[0.74609375, 0.0, 0.99609375],
201:[0.9140625, 0.6640625, 0.99609375],
202:[0.55078125, 0.0, 0.73828125],
203:[0.67578125, 0.4921875, 0.73828125],
204:[0.375, 0.0, 0.50390625],
205:[0.4609375, 0.3359375, 0.50390625],
206:[0.3046875, 0.0, 0.40625],
207:[0.37109375, 0.26953125, 0.40625],
208:[0.23046875, 0.0, 0.30859375],
209:[0.28515625, 0.20703125, 0.30859375],
210:[0.99609375, 0.0, 0.99609375],
211:[0.99609375, 0.6640625, 0.99609375],
212:[0.73828125, 0.0, 0.73828125],
213:[0.73828125, 0.4921875, 0.73828125],
214:[0.50390625, 0.0, 0.50390625],
215:[0.50390625, 0.3359375, 0.50390625],
216:[0.40625, 0.0, 0.40625],
217:[0.40625, 0.26953125, 0.40625],
218:[0.30859375, 0.0, 0.30859375],
219:[0.30859375, 0.20703125, 0.30859375],
220:[0.99609375, 0.0, 0.74609375],
221:[0.99609375, 0.6640625, 0.9140625],
222:[0.73828125, 0.0, 0.55078125],
223:[0.73828125, 0.4921875, 0.67578125],
224:[0.50390625, 0.0, 0.375],
225:[0.50390625, 0.3359375, 0.4609375],
226:[0.40625, 0.0, 0.3046875],
227:[0.40625, 0.26953125, 0.37109375],
228:[0.30859375, 0.0, 0.23046875],
229:[0.30859375, 0.20703125, 0.28515625],
230:[0.99609375, 0.0, 0.49609375],
231:[0.99609375, 0.6640625, 0.828125],
232:[0.73828125, 0.0, 0.3671875],
233:[0.73828125, 0.4921875, 0.61328125],
234:[0.50390625, 0.0, 0.25],
235:[0.50390625, 0.3359375, 0.41796875],
236:[0.40625, 0.0, 0.203125],
237:[0.40625, 0.26953125, 0.3359375],
238:[0.30859375, 0.0, 0.15234375],
239:[0.30859375, 0.20703125, 0.2578125],
240:[0.99609375, 0.0, 0.24609375],
241:[0.99609375, 0.6640625, 0.74609375],
242:[0.73828125, 0.0, 0.1796875],
243:[0.73828125, 0.4921875, 0.55078125],
244:[0.50390625, 0.0, 0.12109375],
245:[0.50390625, 0.3359375, 0.375],
246:[0.40625, 0.0, 0.09765625],
247:[0.40625, 0.26953125, 0.3046875],
248:[0.30859375, 0.0, 0.07421875],
249:[0.30859375, 0.20703125, 0.23046875],
250:[0.19921875, 0.19921875, 0.19921875],
251:[0.3125, 0.3125, 0.3125],
252:[0.41015625, 0.41015625, 0.41015625],
253:[0.5078125, 0.5078125, 0.5078125],
254:[0.7421875, 0.7421875, 0.7421875],
255:[0.99609375, 0.99609375, 0.99609375],
}

File diff suppressed because it is too large Load Diff

View File

@ -1,896 +0,0 @@
#dxfLibrary.py : provides functions for generating DXF files
# --------------------------------------------------------------------------
__version__ = "v1.33 - 2009.06.16"
__author__ = "Stani Michiels(Stani), Remigiusz Fiedler(migius)"
__license__ = "GPL"
__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf"
__bpydoc__ ="""The library to export geometry data to DXF format r12 version.
Copyright %s
Version %s
License %s
Homepage %s
See the homepage for documentation.
Dedicated thread on BlenderArtists: http://blenderartists.org/forum/showthread.php?t=136439
IDEAs:
-
TODO:
- add support for DXFr14 (needs extended file header)
- add support for SPLINEs (possible first in DXFr14 version)
- add user preset for floating point precision (3-16?)
History
v1.33 - 2009.06.16 by migius
- modif _point(): converts all coords to floats
- modif LineType class: implement elements
- added VPORT class, incl. defaults
- fix Insert class
v1.32 - 2009.06.06 by migius
- modif Style class: changed defaults to widthFactor=1.0, obliqueAngle=0.0
- modif Text class: alignment parameter reactivated
v1.31 - 2009.06.02 by migius
- modif _Entity class: added paperspace,elevation
v1.30 - 2009.05.28 by migius
- bugfix 3dPOLYLINE/POLYFACE: VERTEX needs x,y,z coordinates, index starts with 1 not 0
v1.29 - 2008.12.28 by Yorik
- modif POLYLINE to support bulge segments
v1.28 - 2008.12.13 by Steeve/BlenderArtists
- bugfix for EXTMIN/EXTMAX to suit Cycas-CAD
v1.27 - 2008.10.07 by migius
- beautifying output code: keys whitespace prefix
- refactoring DXF-strings format: NewLine moved to the end of
v1.26 - 2008.10.05 by migius
- modif POLYLINE to support POLYFACE
v1.25 - 2008.09.28 by migius
- modif FACE class for r12
v1.24 - 2008.09.27 by migius
- modif POLYLINE class for r12
- changing output format from r9 to r12(AC1009)
v1.1 (20/6/2005) by www.stani.be/python/sdxf
- Python library to generate dxf drawings
______________________________________________________________
""" % (__author__,__version__,__license__,__url__)
# --------------------------------------------------------------------------
# DXF Library: copyright (C) 2005 by Stani Michiels (AKA Stani)
# 2008/2009 modif by Remigiusz Fiedler (AKA migius)
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
#import Blender
#from Blender import Mathutils, Window, Scene, sys, Draw
#import BPyMessages
try:
import copy
#from struct import pack
except:
copy = None
####1) Private (only for developpers)
_HEADER_POINTS=['insbase','extmin','extmax']
#---helper functions-----------------------------------
def _point(x,index=0):
"""Convert tuple to a dxf point"""
#print 'deb: _point=', x #-------------
return '\n'.join([' %s\n%s'%((i+1)*10+index,float(x[i])) for i in range(len(x))])
def _points(plist):
"""Convert a list of tuples to dxf points"""
out = '\n'.join([_point(plist[i],i)for i in range(len(plist))])
return out
#---base classes----------------------------------------
class _Call:
"""Makes a callable class."""
def copy(self):
"""Returns a copy."""
return copy.deepcopy(self)
def __call__(self,**attrs):
"""Returns a copy with modified attributes."""
copied=self.copy()
for attr in attrs:setattr(copied,attr,attrs[attr])
return copied
#-------------------------------------------------------
class _Entity(_Call):
"""Base class for _common group codes for entities."""
def __init__(self,paperspace=None,color=None,layer='0',
lineType=None,lineTypeScale=None,lineWeight=None,
extrusion=None,elevation=None,thickness=None,
parent=None):
"""None values will be omitted."""
self.paperspace = paperspace
self.color = color
self.layer = layer
self.lineType = lineType
self.lineTypeScale = lineTypeScale
self.lineWeight = lineWeight
self.extrusion = extrusion
self.elevation = elevation
self.thickness = thickness
#self.visible = visible
self.parent = parent
def _common(self):
"""Return common group codes as a string."""
if self.parent:parent=self.parent
else:parent=self
result =''
if parent.paperspace==1: result+=' 67\n1\n'
if parent.layer!=None: result+=' 8\n%s\n'%parent.layer
if parent.color!=None: result+=' 62\n%s\n'%parent.color
if parent.lineType!=None: result+=' 6\n%s\n'%parent.lineType
# TODO: if parent.lineWeight!=None: result+='370\n%s\n'%parent.lineWeight
# TODO: if parent.visible!=None: result+='60\n%s\n'%parent.visible
if parent.lineTypeScale!=None: result+=' 48\n%s\n'%parent.lineTypeScale
if parent.elevation!=None: result+=' 38\n%s\n'%parent.elevation
if parent.thickness!=None: result+=' 39\n%s\n'%parent.thickness
if parent.extrusion!=None: result+='%s\n'%_point(parent.extrusion,200)
return result
#--------------------------
class _Entities:
"""Base class to deal with composed objects."""
def __dxf__(self):
return []
def __str__(self):
return ''.join([str(x) for x in self.__dxf__()])
#--------------------------
class _Collection(_Call):
"""Base class to expose entities methods to main object."""
def __init__(self,entities=[]):
self.entities=copy.copy(entities)
#link entities methods to drawing
for attr in dir(self.entities):
if attr[0]!='_':
attrObject=getattr(self.entities,attr)
if callable(attrObject):
setattr(self,attr,attrObject)
####2) Constants
#---color values
BYBLOCK=0
BYLAYER=256
#---block-type flags (bit coded values, may be combined):
ANONYMOUS =1 # This is an anonymous block generated by hatching, associative dimensioning, other internal operations, or an application
NON_CONSTANT_ATTRIBUTES =2 # This block has non-constant attribute definitions (this bit is not set if the block has any attribute definitions that are constant, or has no attribute definitions at all)
XREF =4 # This block is an external reference (xref)
XREF_OVERLAY =8 # This block is an xref overlay
EXTERNAL =16 # This block is externally dependent
RESOLVED =32 # This is a resolved external reference, or dependent of an external reference (ignored on input)
REFERENCED =64 # This definition is a referenced external reference (ignored on input)
#---mtext flags
#attachment point
TOP_LEFT = 1
TOP_CENTER = 2
TOP_RIGHT = 3
MIDDLE_LEFT = 4
MIDDLE_CENTER = 5
MIDDLE_RIGHT = 6
BOTTOM_LEFT = 7
BOTTOM_CENTER = 8
BOTTOM_RIGHT = 9
#drawing direction
LEFT_RIGHT = 1
TOP_BOTTOM = 3
BY_STYLE = 5 #the flow direction is inherited from the associated text style
#line spacing style (optional):
AT_LEAST = 1 #taller characters will override
EXACT = 2 #taller characters will not override
#---polyline flags
CLOSED =1 # This is a closed polyline (or a polygon mesh closed in the M direction)
CURVE_FIT =2 # Curve-fit vertices have been added
SPLINE_FIT =4 # Spline-fit vertices have been added
POLYLINE_3D =8 # This is a 3D polyline
POLYGON_MESH =16 # This is a 3D polygon mesh
CLOSED_N =32 # The polygon mesh is closed in the N direction
POLYFACE_MESH =64 # The polyline is a polyface mesh
CONTINOUS_LINETYPE_PATTERN =128 # The linetype pattern is generated continuously around the vertices of this polyline
#---text flags
#horizontal
LEFT = 0
CENTER = 1
RIGHT = 2
ALIGNED = 3 #if vertical alignment = 0
MIDDLE = 4 #if vertical alignment = 0
FIT = 5 #if vertical alignment = 0
#vertical
BASELINE = 0
BOTTOM = 1
MIDDLE = 2
TOP = 3
####3) Classes
#---entitities -----------------------------------------------
#--------------------------
class Arc(_Entity):
"""Arc, angles in degrees."""
def __init__(self,center=(0,0,0),radius=1,
startAngle=0.0,endAngle=90,**common):
"""Angles in degrees."""
_Entity.__init__(self,**common)
self.center=center
self.radius=radius
self.startAngle=startAngle
self.endAngle=endAngle
def __str__(self):
return ' 0\nARC\n%s%s\n 40\n%s\n 50\n%s\n 51\n%s\n'%\
(self._common(),_point(self.center),
self.radius,self.startAngle,self.endAngle)
#-----------------------------------------------
class Circle(_Entity):
"""Circle"""
def __init__(self,center=(0,0,0),radius=1,**common):
_Entity.__init__(self,**common)
self.center=center
self.radius=radius
def __str__(self):
return ' 0\nCIRCLE\n%s%s\n 40\n%s\n'%\
(self._common(),_point(self.center),self.radius)
#-----------------------------------------------
class Face(_Entity):
"""3dface"""
def __init__(self,points,**common):
_Entity.__init__(self,**common)
while len(points)<4: #fix for r12 format
points.append(points[-1])
self.points=points
def __str__(self):
out = ' 0\n3DFACE\n%s%s\n' %(self._common(),_points(self.points))
#print 'deb:out=', out #-------------------
return out
#-----------------------------------------------
class Insert(_Entity):
"""Block instance."""
def __init__(self,name,point=(0,0,0),
xscale=None,yscale=None,zscale=None,
cols=None,colspacing=None,rows=None,rowspacing=None,
rotation=None,
**common):
_Entity.__init__(self,**common)
self.name=name
self.point=point
self.xscale=xscale
self.yscale=yscale
self.zscale=zscale
self.cols=cols
self.colspacing=colspacing
self.rows=rows
self.rowspacing=rowspacing
self.rotation=rotation
def __str__(self):
result=' 0\nINSERT\n 2\n%s\n%s%s\n'%\
(self.name,self._common(),_point(self.point))
if self.xscale!=None:result+=' 41\n%s\n'%self.xscale
if self.yscale!=None:result+=' 42\n%s\n'%self.yscale
if self.zscale!=None:result+=' 43\n%s\n'%self.zscale
if self.rotation:result+=' 50\n%s\n'%self.rotation
if self.cols!=None:result+=' 70\n%s\n'%self.cols
if self.colspacing!=None:result+=' 44\n%s\n'%self.colspacing
if self.rows!=None:result+=' 71\n%s\n'%self.rows
if self.rowspacing!=None:result+=' 45\n%s\n'%self.rowspacing
return result
#-----------------------------------------------
class Line(_Entity):
"""Line"""
def __init__(self,points,**common):
_Entity.__init__(self,**common)
self.points=points
def __str__(self):
return ' 0\nLINE\n%s%s\n' %(
self._common(), _points(self.points))
#-----------------------------------------------
class PolyLine(_Entity):
def __init__(self,points,org_point=[0,0,0],flag=0,width=None,**common):
#width = number, or width = list [width_start=None, width_end=None]
#for 2d-polyline: points = [ [x, y, z, width_start=None, width_end=None, bulge=0 or None], ...]
#for 3d-polyline: points = [ [x, y, z], ...]
#for polyface: points = [points_list, faces_list]
_Entity.__init__(self,**common)
self.points=points
self.org_point=org_point
self.flag=flag
self.polyface = False
self.polyline2d = False
self.faces = [] # dummy value
self.width= None # dummy value
if self.flag & POLYFACE_MESH:
self.polyface=True
self.points=points[0]
self.faces=points[1]
self.p_count=len(self.points)
self.f_count=len(self.faces)
elif not self.flag & POLYLINE_3D:
self.polyline2d = True
if width:
if type(width)!='list':
width=[width,width]
self.width=width
def __str__(self):
result= ' 0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.flag)
result+=' 66\n1\n'
result+='%s\n' %_point(self.org_point)
if self.polyface:
result+=' 71\n%s\n' %self.p_count
result+=' 72\n%s\n' %self.f_count
elif self.polyline2d:
if self.width!=None: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1])
for point in self.points:
result+=' 0\nVERTEX\n'
result+=' 8\n%s\n' %self.layer
if self.polyface:
result+='%s\n' %_point(point[0:3])
result+=' 70\n192\n'
elif self.polyline2d:
result+='%s\n' %_point(point[0:2])
if len(point)>4:
width1, width2 = point[3], point[4]
if width1!=None: result+=' 40\n%s\n' %width1
if width2!=None: result+=' 41\n%s\n' %width2
if len(point)==6:
bulge = point[5]
if bulge: result+=' 42\n%s\n' %bulge
else:
result+='%s\n' %_point(point[0:3])
for face in self.faces:
result+=' 0\nVERTEX\n'
result+=' 8\n%s\n' %self.layer
result+='%s\n' %_point(self.org_point)
result+=' 70\n128\n'
result+=' 71\n%s\n' %face[0]
result+=' 72\n%s\n' %face[1]
result+=' 73\n%s\n' %face[2]
if len(face)==4: result+=' 74\n%s\n' %face[3]
result+=' 0\nSEQEND\n'
result+=' 8\n%s\n' %self.layer
return result
#-----------------------------------------------
class Point(_Entity):
"""Point."""
def __init__(self,points=None,**common):
_Entity.__init__(self,**common)
self.points=points
def __str__(self): # TODO:
return ' 0\nPOINT\n%s%s\n' %(self._common(),
_points(self.points)
)
#-----------------------------------------------
class Solid(_Entity):
"""Colored solid fill."""
def __init__(self,points=None,**common):
_Entity.__init__(self,**common)
self.points=points
def __str__(self):
return ' 0\nSOLID\n%s%s\n' %(self._common(),
_points(self.points[:2]+[self.points[3],self.points[2]])
)
#-----------------------------------------------
class Dimension(_Entity):
"""Basic dimension entity"""
def __init__(self,point,start,end,**common):
_Entity.__init__(self,**common)
self.points=[point,start,end]
def __str__(self):
result = ' 0\nDIMENSION\n%s' %(self._common())
result+=' 3\nStandard\n'
result+=' 70\n1\n'
result+='%s\n' %_point(self.points[0])
result+='%s\n' %_point(self.points[1],3)
result+='%s\n' %_point(self.points[2],4)
print result
return result
#-----------------------------------------------
class Text(_Entity):
"""Single text line."""
def __init__(self,text='',point=(0,0,0),alignment=None,
flag=None,height=1,justifyhor=None,justifyver=None,
rotation=None,obliqueAngle=None,style=None,xscale=None,**common):
_Entity.__init__(self,**common)
self.text=text
self.point=point
self.alignment=alignment
self.flag=flag
self.height=height
self.justifyhor=justifyhor
self.justifyver=justifyver
self.rotation=rotation
self.obliqueAngle=obliqueAngle
self.style=style
self.xscale=xscale
def __str__(self):
result= ' 0\nTEXT\n%s%s\n 40\n%s\n 1\n%s\n'%\
(self._common(),_point(self.point),self.height,self.text)
if self.rotation: result+=' 50\n%s\n'%self.rotation
if self.xscale: result+=' 41\n%s\n'%self.xscale
if self.obliqueAngle: result+=' 51\n%s\n'%self.obliqueAngle
if self.style: result+=' 7\n%s\n'%self.style
if self.flag: result+=' 71\n%s\n'%self.flag
if self.justifyhor: result+=' 72\n%s\n'%self.justifyhor
if self.alignment: result+='%s\n'%_point(self.alignment,1)
if self.justifyver: result+=' 73\n%s\n'%self.justifyver
return result
#-----------------------------------------------
class Mtext(Text):
"""Surrogate for mtext, generates some Text instances."""
def __init__(self,text='',point=(0,0,0),width=250,spacingFactor=1.5,down=0,spacingWidth=None,**options):
Text.__init__(self,text=text,point=point,**options)
if down:spacingFactor*=-1
self.spacingFactor=spacingFactor
self.spacingWidth=spacingWidth
self.width=width
self.down=down
def __str__(self):
texts=self.text.replace('\r\n','\n').split('\n')
if not self.down:texts.reverse()
result=''
x=y=0
if self.spacingWidth:spacingWidth=self.spacingWidth
else:spacingWidth=self.height*self.spacingFactor
for text in texts:
while text:
result+='%s\n'%Text(text[:self.width],
point=(self.point[0]+x*spacingWidth,
self.point[1]+y*spacingWidth,
self.point[2]),
alignment=self.alignment,flag=self.flag,height=self.height,
justifyhor=self.justifyhor,justifyver=self.justifyver,
rotation=self.rotation,obliqueAngle=self.obliqueAngle,
style=self.style,xscale=self.xscale,parent=self
)
text=text[self.width:]
if self.rotation:x+=1
else:y+=1
return result[1:]
#-----------------------------------------------
##class _Mtext(_Entity):
## """Mtext not functioning for minimal dxf."""
## def __init__(self,text='',point=(0,0,0),attachment=1,
## charWidth=None,charHeight=1,direction=1,height=100,rotation=0,
## spacingStyle=None,spacingFactor=None,style=None,width=100,
## xdirection=None,**common):
## _Entity.__init__(self,**common)
## self.text=text
## self.point=point
## self.attachment=attachment
## self.charWidth=charWidth
## self.charHeight=charHeight
## self.direction=direction
## self.height=height
## self.rotation=rotation
## self.spacingStyle=spacingStyle
## self.spacingFactor=spacingFactor
## self.style=style
## self.width=width
## self.xdirection=xdirection
## def __str__(self):
## input=self.text
## text=''
## while len(input)>250:
## text+='3\n%s\n'%input[:250]
## input=input[250:]
## text+='1\n%s\n'%input
## result= '0\nMTEXT\n%s\n%s\n40\n%s\n41\n%s\n71\n%s\n72\n%s%s\n43\n%s\n50\n%s\n'%\
## (self._common(),_point(self.point),self.charHeight,self.width,
## self.attachment,self.direction,text,
## self.height,
## self.rotation)
## if self.style:result+='7\n%s\n'%self.style
## if self.xdirection:result+='%s\n'%_point(self.xdirection,1)
## if self.charWidth:result+='42\n%s\n'%self.charWidth
## if self.spacingStyle:result+='73\n%s\n'%self.spacingStyle
## if self.spacingFactor:result+='44\n%s\n'%self.spacingFactor
## return result
#---tables ---------------------------------------------------
#-----------------------------------------------
class Block(_Collection):
"""Use list methods to add entities, eg append."""
def __init__(self,name,layer='0',flag=0,base=(0,0,0),entities=[]):
self.entities=copy.copy(entities)
_Collection.__init__(self,entities)
self.layer=layer
self.name=name
self.flag=0
self.base=base
def __str__(self): # TODO:
e=''.join([str(x)for x in self.entities])
return ' 0\nBLOCK\n 8\n%s\n 2\n%s\n 70\n%s\n%s\n 3\n%s\n%s 0\nENDBLK\n'%\
(self.layer,self.name.upper(),self.flag,_point(self.base),self.name.upper(),e)
#-----------------------------------------------
class Layer(_Call):
"""Layer"""
def __init__(self,name='pydxf',color=7,lineType='continuous',flag=64):
self.name=name
self.color=color
self.lineType=lineType
self.flag=flag
def __str__(self):
return ' 0\nLAYER\n 2\n%s\n 70\n%s\n 62\n%s\n 6\n%s\n'%\
(self.name.upper(),self.flag,self.color,self.lineType)
#-----------------------------------------------
class LineType(_Call):
"""Custom linetype"""
def __init__(self,name='CONTINUOUS',description='Solid line',elements=[0.0],flag=0):
self.name=name
self.description=description
self.elements=copy.copy(elements)
self.flag=flag
def __str__(self):
result = ' 0\nLTYPE\n 2\n%s\n 70\n%s\n 3\n%s\n 72\n65\n'%\
(self.name.upper(),self.flag,self.description)
if self.elements:
elements = ' 73\n%s\n' %(len(self.elements)-1)
elements += ' 40\n%s\n' %(self.elements[0])
for e in self.elements[1:]:
elements += ' 49\n%s\n' %e
result += elements
return result
#-----------------------------------------------
class Style(_Call):
"""Text style"""
def __init__(self,name='standard',flag=0,height=0,widthFactor=1.0,obliqueAngle=0.0,
mirror=0,lastHeight=1,font='arial.ttf',bigFont=''):
self.name=name
self.flag=flag
self.height=height
self.widthFactor=widthFactor
self.obliqueAngle=obliqueAngle
self.mirror=mirror
self.lastHeight=lastHeight
self.font=font
self.bigFont=bigFont
def __str__(self):
return ' 0\nSTYLE\n 2\n%s\n 70\n%s\n 40\n%s\n 41\n%s\n 50\n%s\n 71\n%s\n 42\n%s\n 3\n%s\n 4\n%s\n'%\
(self.name.upper(),self.flag,self.flag,self.widthFactor,
self.obliqueAngle,self.mirror,self.lastHeight,
self.font.upper(),self.bigFont.upper())
#-----------------------------------------------
class VPort(_Call):
def __init__(self,name,flag=0,
leftBottom=(0.0,0.0),
rightTop=(1.0,1.0),
center=(0.5,0.5),
snap_base=(0.0,0.0),
snap_spacing=(0.1,0.1),
grid_spacing=(0.1,0.1),
direction=(0.0,0.0,1.0),
target=(0.0,0.0,0.0),
height=1.0,
ratio=1.0,
lens=50,
frontClipping=0,
backClipping=0,
snap_rotation=0,
twist=0,
mode=0,
circle_zoom=100,
fast_zoom=1,
ucsicon=1,
snap_on=0,
grid_on=0,
snap_style=0,
snap_isopair=0
):
self.name=name
self.flag=flag
self.leftBottom=leftBottom
self.rightTop=rightTop
self.center=center
self.snap_base=snap_base
self.snap_spacing=snap_spacing
self.grid_spacing=grid_spacing
self.direction=direction
self.target=target
self.height=float(height)
self.ratio=float(ratio)
self.lens=float(lens)
self.frontClipping=float(frontClipping)
self.backClipping=float(backClipping)
self.snap_rotation=float(snap_rotation)
self.twist=float(twist)
self.mode=mode
self.circle_zoom=circle_zoom
self.fast_zoom=fast_zoom
self.ucsicon=ucsicon
self.snap_on=snap_on
self.grid_on=grid_on
self.snap_style=snap_style
self.snap_isopair=snap_isopair
def __str__(self):
output = [' 0', 'VPORT',
' 2', self.name,
' 70', self.flag,
_point(self.leftBottom),
_point(self.rightTop,1),
_point(self.center,2), # View center point (in DCS)
_point(self.snap_base,3),
_point(self.snap_spacing,4),
_point(self.grid_spacing,5),
_point(self.direction,6), #view direction from target (in WCS)
_point(self.target,7),
' 40', self.height,
' 41', self.ratio,
' 42', self.lens,
' 43', self.frontClipping,
' 44', self.backClipping,
' 50', self.snap_rotation,
' 51', self.twist,
' 71', self.mode,
' 72', self.circle_zoom,
' 73', self.fast_zoom,
' 74', self.ucsicon,
' 75', self.snap_on,
' 76', self.grid_on,
' 77', self.snap_style,
' 78', self.snap_isopair
]
output_str = ''
for s in output:
output_str += '%s\n' %s
return output_str
#-----------------------------------------------
class View(_Call):
def __init__(self,name,flag=0,
width=1,
height=1,
center=(0.5,0.5),
direction=(0,0,1),
target=(0,0,0),
lens=50,
frontClipping=0,
backClipping=0,
twist=0,mode=0
):
self.name=name
self.flag=flag
self.width=float(width)
self.height=float(height)
self.center=center
self.direction=direction
self.target=target
self.lens=float(lens)
self.frontClipping=float(frontClipping)
self.backClipping=float(backClipping)
self.twist=float(twist)
self.mode=mode
def __str__(self):
output = [' 0', 'VIEW',
' 2', self.name,
' 70', self.flag,
' 40', self.height,
_point(self.center),
' 41', self.width,
_point(self.direction,1),
_point(self.target,2),
' 42', self.lens,
' 43', self.frontClipping,
' 44', self.backClipping,
' 50', self.twist,
' 71', self.mode
]
output_str = ''
for s in output:
output_str += '%s\n' %s
return output_str
#-----------------------------------------------
def ViewByWindow(name,leftBottom=(0,0),rightTop=(1,1),**options):
width=abs(rightTop[0]-leftBottom[0])
height=abs(rightTop[1]-leftBottom[1])
center=((rightTop[0]+leftBottom[0])*0.5,(rightTop[1]+leftBottom[1])*0.5)
return View(name=name,width=width,height=height,center=center,**options)
#---drawing
#-----------------------------------------------
class Drawing(_Collection):
"""Dxf drawing. Use append or any other list methods to add objects."""
def __init__(self,insbase=(0.0,0.0,0.0),extmin=(0.0,0.0,0.0),extmax=(0.0,0.0,0.0),
layers=[Layer()],linetypes=[LineType()],styles=[Style()],blocks=[],
views=[],vports=[],entities=None,fileName='test.dxf'):
# TODO: replace list with None,arial
if not entities:
entities=[]
_Collection.__init__(self,entities)
self.insbase=insbase
self.extmin=extmin
self.extmax=extmax
self.layers=copy.copy(layers)
self.linetypes=copy.copy(linetypes)
self.styles=copy.copy(styles)
self.views=copy.copy(views)
self.vports=copy.copy(vports)
self.blocks=copy.copy(blocks)
self.fileName=fileName
#private
#self.acadver='9\n$ACADVER\n1\nAC1006\n'
self.acadver=' 9\n$ACADVER\n 1\nAC1009\n'
"""DXF AutoCAD-Release format codes
AC1021 2008, 2007
AC1018 2006, 2005, 2004
AC1015 2002, 2000i, 2000
AC1014 R14,14.01
AC1012 R13
AC1009 R12,11
AC1006 R10
AC1004 R9
AC1002 R2.6
AC1.50 R2.05
"""
def _name(self,x):
"""Helper function for self._point"""
return ' 9\n$%s\n' %x.upper()
def _point(self,name,x):
"""Point setting from drawing like extmin,extmax,..."""
return '%s%s' %(self._name(name),_point(x))
def _section(self,name,x):
"""Sections like tables,blocks,entities,..."""
if x: xstr=''.join(x)
else: xstr=''
return ' 0\nSECTION\n 2\n%s\n%s 0\nENDSEC\n'%(name.upper(),xstr)
def _table(self,name,x):
"""Tables like ltype,layer,style,..."""
if x: xstr=''.join(x)
else: xstr=''
return ' 0\nTABLE\n 2\n%s\n 70\n%s\n%s 0\nENDTAB\n'%(name.upper(),len(x),xstr)
def __str__(self):
"""Returns drawing as dxf string."""
header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS]
header=self._section('header',header)
tables=[self._table('vport',[str(x) for x in self.vports]),
self._table('ltype',[str(x) for x in self.linetypes]),
self._table('layer',[str(x) for x in self.layers]),
self._table('style',[str(x) for x in self.styles]),
self._table('view',[str(x) for x in self.views]),
]
tables=self._section('tables',tables)
blocks=self._section('blocks',[str(x) for x in self.blocks])
entities=self._section('entities',[str(x) for x in self.entities])
all=''.join([header,tables,blocks,entities,' 0\nEOF\n'])
return all
def saveas(self,fileName):
self.fileName=fileName
self.save()
def save(self):
test=open(self.fileName,'w')
test.write(str(self))
test.close()
#---extras
#-----------------------------------------------
class Rectangle(_Entity):
"""Rectangle, creates lines."""
def __init__(self,point=(0,0,0),width=1,height=1,solid=None,line=1,**common):
_Entity.__init__(self,**common)
self.point=point
self.width=width
self.height=height
self.solid=solid
self.line=line
def __str__(self):
result=''
points=[self.point,(self.point[0]+self.width,self.point[1],self.point[2]),
(self.point[0]+self.width,self.point[1]+self.height,self.point[2]),
(self.point[0],self.point[1]+self.height,self.point[2]),self.point]
if self.solid:
result+= Solid(points=points[:-1],parent=self.solid)
if self.line:
for i in range(4):
result+= Line(points=[points[i],points[i+1]],parent=self)
return result[1:]
#-----------------------------------------------
class LineList(_Entity):
"""Like polyline, but built of individual lines."""
def __init__(self,points=[],org_point=[0,0,0],closed=0,**common):
_Entity.__init__(self,**common)
self.closed=closed
self.points=copy.copy(points)
def __str__(self):
if self.closed:points=self.points+[self.points[0]]
else: points=self.points
result=''
for i in range(len(points)-1):
result+= Line(points=[points[i],points[i+1]],parent=self)
return result[1:]
#-----------------------------------------------------
def test():
#Blocks
b=Block('test')
b.append(Solid(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=1))
b.append(Arc(center=(1,0,0),color=2))
#Drawing
d=Drawing()
#tables
d.blocks.append(b) #table blocks
d.styles.append(Style()) #table styles
d.views.append(View('Normal')) #table view
d.views.append(ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem
#entities
d.append(Circle(center=(1,1,0),color=3))
d.append(Face(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=4))
d.append(Insert('test',point=(3,3,3),cols=5,colspacing=2))
d.append(Line(points=[(0,0,0),(1,1,1)]))
d.append(Mtext('Click on Ads\nmultiple lines with mtext',point=(1,1,1),color=5,rotation=90))
d.append(Text('Please donate!',point=(3,0,1)))
#d.append(Rectangle(point=(2,2,2),width=4,height=3,color=6,solid=Solid(color=2)))
d.append(Solid(points=[(4,4,0),(5,4,0),(7,8,0),(9,9,0)],color=3))
#d.append(PolyLine(points=[(1,1,1),(2,1,1),(2,2,1),(1,2,1)],flag=1,color=1))
#d.saveas('c:\\test.dxf')
d.saveas('test.dxf')
#-----------------------------------------------------
if __name__=='__main__':
if not copy:
Draw.PupMenu('Error%t|This script requires a full python install')
else: test()

View File

@ -1,384 +0,0 @@
"""This module provides a function for reading dxf files and parsing them into a useful tree of objects and data.
The convert function is called by the readDXF fuction to convert dxf strings into the correct data based
on their type code. readDXF expects a (full path) file name as input.
"""
# --------------------------------------------------------------------------
# DXF Reader v0.9 by Ed Blake (AKA Kitsu)
# 2008.05.08 modif.def convert() by Remigiusz Fiedler (AKA migius)
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
from dxfImportObjects import *
class Object:
"""Empty container class for dxf objects"""
def __init__(self, _type='', block=False):
"""_type expects a string value."""
self.type = _type
self.name = ''
self.data = []
def __str__(self):
if self.name:
return self.name
else:
return self.type
def __repr__(self):
return str(self.data)
def get_type(self, kind=''):
"""Despite the name, this method actually returns all objects of type 'kind' from self.data."""
if type:
objects = []
for item in self.data:
if type(item) != list and item.type == kind:
# we want this type of object
objects.append(item)
elif type(item) == list and item[0] == kind:
# we want this type of data
objects.append(item[1])
return objects
class InitializationError(Exception): pass
class StateMachine:
"""(finite) State Machine from the great David Mertz's great Charming Python article."""
def __init__(self):
self.handlers = []
self.startState = None
self.endStates = []
def add_state(self, handler, end_state=0):
"""All states and handlers are functions which return
a state and a cargo."""
self.handlers.append(handler)
if end_state:
self.endStates.append(handler)
def set_start(self, handler):
"""Sets the starting handler function."""
self.startState = handler
def run(self, cargo=None):
if not self.startState:
raise InitializationError,\
"must call .set_start() before .run()"
if not self.endStates:
raise InitializationError, \
"at least one state must be an end_state"
handler = self.startState
while 1:
(newState, cargo) = handler(cargo)
#print cargo
if newState in self.endStates:
return newState(cargo)
#break
elif newState not in self.handlers:
raise RuntimeError, "Invalid target %s" % newState
else:
handler = newState
def get_name(data):
"""Get the name of an object from its object data.
Returns a pair of (data_item, name) where data_item is the list entry where the name was found
(the data_item can be used to remove the entry from the object data). Be sure to check
name not None before using the returned values!
"""
value = None
for item in data:
if item[0] == 2:
value = item[1]
break
return item, value
def get_layer(data):
"""Expects object data as input.
Returns (entry, layer_name) where entry is the data item that provided the layer name.
"""
value = None
for item in data:
if item[0] == 8:
value = item[1]
break
return item, value
def convert(code, value):
"""Convert a string to the correct Python type based on its dxf code.
code types:
ints = 60-79, 170-179, 270-289, 370-389, 400-409, 1060-1070
longs = 90-99, 420-429, 440-459, 1071
floats = 10-39, 40-59, 110-139, 140-149, 210-239, 460-469, 1010-1059
hex = 105, 310-379, 390-399
strings = 0-9, 100, 102, 300-309, 410-419, 430-439, 470-479, 999, 1000-1009
"""
if 59 < code < 80 or 169 < code < 180 or 269 < code < 290 or 369 < code < 390 or 399 < code < 410 or 1059 < code < 1071:
value = int(float(value))
elif 89 < code < 100 or 419 < code < 430 or 439 < code < 460 or code == 1071:
value = long(float(value))
elif 9 < code < 60 or 109 < code < 150 or 209 < code < 240 or 459 < code < 470 or 1009 < code < 1060:
value = float(value)
elif code == 105 or 309 < code < 380 or 389 < code < 400:
try:
value = int(value, 16) # should be left as string?
except:
pass
else: # it's already a string so do nothing
pass
return value
def findObject(infile, kind=''):
"""Finds the next occurance of an object."""
obj = False
while 1:
line = infile.readline()
if not line: # readline returns '' at eof
return False
if not obj: # We're still looking for our object code
if line.lower().strip() == '0':
obj = True # found it
else: # we are in an object definition
if kind: # if we're looking for a particular kind
if line.lower().strip() == kind:
obj = Object(line.lower().strip())
break
else: # otherwise take anything non-numeric
if line.lower().strip() not in string.digits:
obj = Object(line.lower().strip())
break
obj = False # whether we found one or not it's time to start over
return obj
def handleObject(infile):
"""Add data to an object until end of object is found."""
line = infile.readline()
if line.lower().strip() == 'section':
return 'section' # this would be a problem
elif line.lower().strip() == 'endsec':
return 'endsec' # this means we are done with a section
else: # add data to the object until we find a new object
obj = Object(line.lower().strip())
obj.name = obj.type
done = False
data = []
while not done:
line = infile.readline()
if not data:
if line.lower().strip() == '0':
#we've found an object, time to return
return obj
else:
# first part is always an int
data.append(int(line.lower().strip()))
else:
data.append(convert(data[0], line.strip()))
obj.data.append(data)
data = []
def handleTable(table, infile):
"""Special handler for dealing with nested table objects."""
item, name = get_name(table.data)
if name: # We should always find a name
table.data.remove(item)
table.name = name.lower()
# This next bit is from handleObject
# handleObject should be generalized to work with any section like object
while 1:
obj = handleObject(infile)
if obj.type == 'table':
print "Warning: previous table not closed!"
return table
elif obj.type == 'endtab':
return table # this means we are done with the table
else: # add objects to the table until one of the above is found
table.data.append(obj)
def handleBlock(block, infile):
"""Special handler for dealing with nested table objects."""
item, name = get_name(block.data)
if name: # We should always find a name
# block.data.remove(item)
block.name = name
# This next bit is from handleObject
# handleObject should be generalized to work with any section like object
while 1:
obj = handleObject(infile)
if obj.type == 'block':
print "Warning: previous block not closed!"
return block
elif obj.type == 'endblk':
return block # this means we are done with the table
else: # add objects to the table until one of the above is found
block.data.append(obj)
"""These are the states/functions used in the State Machine.
states:
start - find first section
start_section - add data, find first object
object - add obj-data, watch for next obj (called directly by start_section)
end_section - look for next section or eof
end - return results
"""
def start(cargo):
"""Expects the infile as cargo, initializes the cargo."""
#print "Entering start state!"
infile = cargo
drawing = Object('drawing')
section = findObject(infile, 'section')
if section:
return start_section, (infile, drawing, section)
else:
return error, (infile, "Failed to find any sections!")
def start_section(cargo):
"""Expects [infile, drawing, section] as cargo, builds a nested section object."""
#print "Entering start_section state!"
infile = cargo[0]
drawing = cargo[1]
section = cargo[2]
# read each line, if it is an object declaration go to object mode
# otherwise create a [index, data] pair and add it to the sections data.
done = False
data = []
while not done:
line = infile.readline()
if not data: # if we haven't found a dxf code yet
if line.lower().strip() == '0':
# we've found an object
while 1: # no way out unless we find an end section or a new section
obj = handleObject(infile)
if obj == 'section': # shouldn't happen
print "Warning: failed to close previous section!"
return end_section, (infile, drawing)
elif obj == 'endsec': # This section is over, look for the next
drawing.data.append(section)
return end_section, (infile, drawing)
elif obj.type == 'table': # tables are collections of data
obj = handleTable(obj, infile) # we need to find all there contents
section.data.append(obj) # before moving on
elif obj.type == 'block': # the same is true of blocks
obj = handleBlock(obj, infile) # we need to find all there contents
section.data.append(obj) # before moving on
else: # found another sub-object
section.data.append(obj)
else:
data.append(int(line.lower().strip()))
else: # we have our code, now we just need to convert the data and add it to our list.
data.append(convert(data[0], line.strip()))
section.data.append(data)
data = []
def end_section(cargo):
"""Expects (infile, drawing) as cargo, searches for next section."""
#print "Entering end_section state!"
infile = cargo[0]
drawing = cargo[1]
section = findObject(infile, 'section')
if section:
return start_section, (infile, drawing, section)
else:
return end, (infile, drawing)
def end(cargo):
"""Expects (infile, drawing) as cargo, called when eof has been reached."""
#print "Entering end state!"
infile = cargo[0]
drawing = cargo[1]
#infile.close()
return drawing
def error(cargo):
"""Expects a (infile, string) as cargo, called when there is an error during processing."""
#print "Entering error state!"
infile = cargo[0]
err = cargo[1]
infile.close()
print "There has been an error:"
print err
return False
def readDXF(filename):
"""Given a file name try to read it as a dxf file.
Output is an object with the following structure
drawing
header
header data
classes
class data
tables
table data
blocks
block data
entities
entity data
objects
object data
where foo data is a list of sub-objects. True object data
is of the form [code, data].
"""
infile = open(filename)
sm = StateMachine()
sm.add_state(error, True)
sm.add_state(end, True)
sm.add_state(start_section)
sm.add_state(end_section)
sm.add_state(start)
sm.set_start(start)
try:
drawing = sm.run(infile)
if drawing:
drawing.name = filename
for obj in drawing.data:
item, name = get_name(obj.data)
if name:
obj.data.remove(item)
obj.name = name.lower()
setattr(drawing, name.lower(), obj)
# Call the objectify function to cast
# raw objects into the right types of object
obj.data = objectify(obj.data)
#print obj.name
finally:
infile.close()
return drawing
if __name__ == "__main__":
filename = r".\examples\block-test.dxf"
drawing = readDXF(filename)
for item in drawing.entities.data:
print item

View File

@ -39,9 +39,7 @@ lines, polylines, lwpolylines, circles, arcs,
texts, colors,layers (from groups)
'''
import FreeCAD, os, Part, math, re, string, Mesh, Draft, DraftVecUtils, DraftGeomUtils
from draftlibs import dxfColorMap, dxfLibrary
from draftlibs.dxfReader import readDXF
import sys, FreeCAD, os, Part, math, re, string, Mesh, Draft, DraftVecUtils, DraftGeomUtils
from Draft import _Dimension, _ViewProviderDimension
from FreeCAD import Vector
@ -51,9 +49,23 @@ else: gui = True
try: draftui = FreeCADGui.draftToolBar
except: draftui = None
files = ['dxfColorMap.py','dxfImportObjects.py','dxfLibrary.py','dxfReader.py']
baseurl = 'https://raw.github.com/yorikvanhavre/Draft-dxf-importer/master/'
for f in files:
p = os.path.join(FreeCAD.ConfigGet("UserAppData"),f)
if not os.path.exists(p):
import ArchCommands
p = None
p = ArchCommands.download(baseurl+f)
if not p:
FreeCAD.Console.PrintWarning("Download of dxf libraries failed. Please download them manually from https://github.com/yorikvanhavre/Draft-dxf-importer")
sys.exit()
sys.path.append(FreeCAD.ConfigGet("UserAppData"))
import dxfColorMap, dxfLibrary, dxfReader
if open.__module__ == '__builtin__':
pythonopen = open # to distinguish python built-in open function from the one declared here
def prec():
"returns the current Draft precision level"
return Draft.getParam("precision")
@ -771,7 +783,7 @@ def processdxf(document,filename):
"this does the translation of the dxf contents into FreeCAD Part objects"
global drawing # for debugging - so drawing is still accessible to python after the script
FreeCAD.Console.PrintMessage("opening "+filename+"...\n")
drawing = readDXF(filename)
drawing = dxfReader.readDXF(filename)
global layers
layers = []
global doc