Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Musgrove <LetterRip@gmail.com>2007-01-10 14:37:19 +0300
committerTom Musgrove <LetterRip@gmail.com>2007-01-10 14:37:19 +0300
commit20413f17bb75905b2604c0a8f5b2489cadf047c3 (patch)
treed7b1ea9e681672673329ef0ab174ade445f56f9b /release
parent3625d23afa51c04925e1ceb042447a7a3cfe8265 (diff)
= dxf update =
update by the script author - may have killed some changes cambo did to the previous version but the layout of the script is too significantly different to merge them.
Diffstat (limited to 'release')
-rw-r--r--release/scripts/bpymodules/dxfReader.py84
-rw-r--r--release/scripts/import_dxf.py2309
2 files changed, 1835 insertions, 558 deletions
diff --git a/release/scripts/bpymodules/dxfReader.py b/release/scripts/bpymodules/dxfReader.py
index f0635e00613..d4a39cf63d6 100644
--- a/release/scripts/bpymodules/dxfReader.py
+++ b/release/scripts/bpymodules/dxfReader.py
@@ -5,7 +5,7 @@
"""
# --------------------------------------------------------------------------
-# DXF Reader v0.8 by Ed Blake (AKA Kitsu)
+# DXF Reader v0.9 by Ed Blake (AKA Kitsu)
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
@@ -26,11 +26,40 @@
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
-# development
-#import dxfImportObjects
-#reload(dxfImportObjects)
-from dxfImportObjects import *
+#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
@@ -72,6 +101,33 @@ class StateMachine:
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:
@@ -144,9 +200,9 @@ def handleObject(infile):
def handleTable(table, infile):
"""Special handler for dealing with nested table objects."""
- item, name, item_index = get_name(table.data)
+ item, name = get_name(table.data)
if name: # We should always find a name
- del table.data[item_index]
+ 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
@@ -165,10 +221,10 @@ def handleTable(table, infile):
def handleBlock(block, infile):
"""Special handler for dealing with nested table objects."""
- item, name, item_index = get_name(block.data)
+ item, name = get_name(block.data)
if name: # We should always find a name
- del block.data[item_index]
- block.name = name.lower()
+ 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:
@@ -271,7 +327,7 @@ def error(cargo):
print err
return False
-def readDXF(filename):
+def readDXF(filename, objectify):
"""Given a file name try to read it as a dxf file.
Output is an object with the following structure
@@ -305,12 +361,12 @@ def readDXF(filename):
if drawing:
drawing.name = filename
for obj in drawing.data:
- item, name, item_index = get_name(obj.data)
+ item, name = get_name(obj.data)
if name:
- del obj.data[item_index]
+ obj.data.remove(item)
obj.name = name.lower()
setattr(drawing, name.lower(), obj)
- # Call the objectify function from dxfImportObjects to cast
+ # Call the objectify function to cast
# raw objects into the right types of object
obj.data = objectify(obj.data)
#print obj.name
diff --git a/release/scripts/import_dxf.py b/release/scripts/import_dxf.py
index 535d762ffaa..a4e4e69b366 100644
--- a/release/scripts/import_dxf.py
+++ b/release/scripts/import_dxf.py
@@ -7,7 +7,7 @@
# Tooltip: 'Import DXF file.'
# """
__author__ = 'Kitsu (Ed Blake)'
-__version__ = '0.8 1/2007'
+__version__ = '0.9 1/2007'
__url__ = ["elysiun.com", "BlenderArtists.org"]
__email__ = ["Kitsune_e@yahoo.com"]
__bpydoc__ = """\
@@ -48,7 +48,7 @@ Notes:<br>
"""
# --------------------------------------------------------------------------
-# DXF Import v0.8 by Ed Blake (AKA Kitsu)
+# DXF Import v0.9 by Ed Blake (AKA Kitsu)
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
@@ -72,23 +72,12 @@ Notes:<br>
import Blender
from Blender import *
Sys = sys
-try:
- from dxfReader import readDXF
-except ImportError:
- import sys
- curdir = Sys.dirname(Blender.Get('filename'))
- sys.path.append(curdir)
-
-# development
-#import dxfReader
-#reload(dxfReader)
-from dxfReader import readDXF
+from dxfReader import readDXF, get_name, get_layer
+from dxfReader import Object as dxfObject
from dxfColorMap import color_map
from math import *
-
-
try:
import os
if os.name:# != 'mac':
@@ -104,15 +93,1558 @@ SCENE = Scene.GetCurrent()
WORLDX = Mathutils.Vector((1,0,0))
AUTO = BezTriple.HandleTypes.AUTO
BYLAYER=256
+"""This module provides wrapper objects for dxf entities.
+
+ The wrappers expect a "dxf object" as input. The dxf object is
+ an object with a type and a data attribute. Type is a lowercase
+ string matching the 0 code of a dxf entity. Data is a list containing
+ dxf objects or lists of [code, data] pairs.
+
+ This module is not general, and is only for dxf import.
+"""
+
+# from Stani's dxf writer v1.1 (c)www.stani.be (GPL)
+#---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
class Layer:
- """Dummy layer object."""
- def __init__(self, name, color, frozen):
- self.name = name
- self.color = color
- self.frozen = frozen
+ """Class for objects representing dxf layers."""
+
+ def __init__(self, obj, name=None, color=None, frozen=None):
+ """Expects an entity object of type line as input."""
+ self.type = obj.type
+ self.data = obj.data[:]
+
+ if name:
+ self.name = name
+ else:
+ self.name = obj.get_type(2)[0]
+ if color:
+ self.color = color
+ else:
+ self.color = obj.get_type(62)[0]
+ if frozen:
+ self.frozen = frozen
+ else:
+ self.flags = obj.get_type(70)[0]
+ self.frozen = self.flags&1
+
+ def __repr__(self):
+ return "%s: name - %s, color - %s" %(self.__class__.__name__, self.name, self.color)
+
+
+
+class Line:
+ """Class for objects representing dxf lines."""
+
+ def __init__(self, obj):
+ """Expects an entity object of type line as input."""
+ if not obj.type == 'line':
+ raise TypeError, "Wrong type %s for line object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+
+ self.space = obj.get_type(67)
+ if self.space:
+ self.space = self.space[0]
+ else:
+ self.space = 0
+
+ self.color_index = obj.get_type(62)
+ if self.color_index:
+ self.color_index = self.color_index[0]
+ else:
+ self.color_index = BYLAYER
+
+ discard, self.layer = get_layer(obj.data)
+ obj.data.remove(discard)
+ self.points = self.get_points(obj.data)
+
+
+
+
+ def get_points(self, data):
+ """Gets start and end points for a line type object.
+
+ Lines have a fixed number of points (two) and fixed codes for each value.
+ """
+
+ # start x, y, z and end x, y, z = 0
+ sx, sy, sz, ex, ey, ez = 0, 0, 0, 0, 0, 0
+ for item in data:
+ if item[0] == 10: # 10 = x
+ sx = item[1]
+ elif item[0] == 20: # 20 = y
+ sy = item[1]
+ elif item[0] == 30: # 30 = z
+ sz = item[1]
+ elif item[0] == 11: # 11 = x
+ ex = item[1]
+ elif item[0] == 21: # 21 = y
+ ey = item[1]
+ elif item[0] == 31: # 31 = z
+ ez = item[1]
+ return [[sx, sy, sz], [ex, ey, ez]]
+
+
+
+ def __repr__(self):
+ return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
+
+
+ def draw(self, curves=False):
+ """Do all the specific things needed to import lines into Blender."""
+ # Generate the geometery
+ points = self.points
+ edges = [[0, 1]]
+
+ me = Mesh.New('line') # create a new mesh
+
+ me.verts.extend(points) # add vertices to mesh
+ me.edges.extend(edges) # add edges to the mesh
+
+ # Now Create an object
+ ob = Object.New('Mesh', 'line') # link mesh to an object
+ ob.link(me)
+
+ return ob
+
+
+
+
+class LWpolyline:
+ """Class for objects representing dxf LWpolylines."""
+
+ def __init__(self, obj):
+ """Expects an entity object of type lwpolyline as input."""
+ if not obj.type == 'lwpolyline':
+ raise TypeError, "Wrong type %s for polyline object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+
+ # required data
+ self.num_points = obj.get_type(90)[0]
+
+ # optional data (with defaults)
+ self.space = obj.get_type(67)
+ if self.space:
+ self.space = self.space[0]
+ else:
+ self.space = 0
+
+ self.color_index = obj.get_type(62)
+ if self.color_index:
+ self.color_index = self.color_index[0]
+ else:
+ self.color_index = BYLAYER
+
+ self.elevation = obj.get_type(38)
+ if self.elevation:
+ self.elevation = self.elevation[0]
+ else:
+ self.elevation = 0
+
+ self.flags = obj.get_type(70)
+ if self.flags:
+ self.flags = self.flags[0]
+ else:
+ self.flags = 0
+
+ self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen
+ discard, self.layer = get_layer(obj.data)
+ obj.data.remove(discard)
+ self.points = self.get_points(obj.data)
+ self.extrusion = self.get_extrusion(obj.data)
+
+
+
+
+
+
+ def get_points(self, data):
+ """Gets points for a polyline type object.
+
+ Polylines have no fixed number of verts, and
+ each vert can have a number of properties.
+ Verts should be coded as
+ 10:xvalue
+ 20:yvalue
+ 40:startwidth or 0
+ 41:endwidth or 0
+ 42:bulge or 0
+ for each vert
+ """
+ num = self.num_points
+ point = None
+ points = []
+ for item in data:
+ if item[0] == 10: # 10 = x
+ if point:
+ points.append(point)
+ point = Vertex()
+ point.x = item[1]
+ elif item[0] == 20: # 20 = y
+ point.y = item[1]
+ elif item[0] == 40: # 40 = start width
+ point.swidth = item[1]
+ elif item[0] == 41: # 41 = end width
+ point.ewidth = item[1]
+ elif item[0] == 42: # 42 = bulge
+ point.bulge = item[1]
+ points.append(point)
+ return points
+
+
+ def get_extrusion(self, data):
+ """Find the axis of extrusion.
+
+ Used to get the objects Object Coordinate System (ocs).
+ """
+ vec = [0,0,1]
+ for item in data:
+ if item[0] == 210: # 210 = x
+ vec[0] = item[1]
+ elif item[0] == 220: # 220 = y
+ vec[1] = item[1]
+ elif item[0] == 230: # 230 = z
+ vec[2] = item[1]
+ return vec
+
+
+ def __repr__(self):
+ return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
+
+
+ def draw(self, curves=False):
+ """Do all the specific things needed to import plines into Blender."""
+ # Generate the geometery
+ points = []
+ for i in range(len(self.points)):
+ point = self.points[i]
+ if not point.bulge:
+ points.append(point.loc)
+ elif point.bulge and i < len(self.points)-1:# > 0:
+ center, radius, start, end = solveBulge(point, self.points[i+1])
+ #print center, radius, start, end
+ verts, nosense = drawArc(center, radius, start, end)
+ verts.pop(0) # remove first
+ verts.pop() #remove last
+ if point.bulge >= 0:
+ verts.reverse()
+ points.extend(verts)
+ edges = [[num, num+1] for num in range(len(points)-1)]
+ if self.closed:
+ edges.append([len(self.points)-1, 0])
+
+ me = Mesh.New('lwpline') # create a new mesh
+
+ me.verts.extend(points) # add vertices to mesh
+ me.edges.extend(edges) # add edges to the mesh
+
+ # Now Create an object
+ ob = Object.New('Mesh', 'lwpline') # link mesh to an object
+ ob.link(me)
+ transform(self.extrusion, ob)
+ ob.LocZ = self.elevation
+
+ return ob
+
+
+
+class Polyline:
+ """Class for objects representing dxf LWpolylines."""
+
+ def __init__(self, obj):
+ """Expects an entity object of type polyline as input."""
+ if not obj.type == 'polyline':
+ raise TypeError, "Wrong type %s for polyline object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+ self.points = []
+
+ # optional data (with defaults)
+ self.space = obj.get_type(67)
+ if self.space:
+ self.space = self.space[0]
+ else:
+ self.space = 0
+
+ self.color_index = obj.get_type(62)
+ if self.color_index:
+ self.color_index = self.color_index[0]
+ else:
+ self.color_index = BYLAYER
+
+ self.elevation = obj.get_type(30)
+ if self.elevation:
+ self.elevation = self.elevation[0]
+ else:
+ self.elevation = 0
+
+ self.flags = obj.get_type(70)
+ if self.flags:
+ self.flags = self.flags[0]
+ else:
+ self.flags = 0
+
+ self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen
+
+ discard, self.layer = get_layer(obj.data)
+ obj.data.remove(discard)
+ self.extrusion = self.get_extrusion(obj.data)
+
+
+
+
+
+ def get_extrusion(self, data):
+ """Find the axis of extrusion.
+
+ Used to get the objects Object Coordinate System (ocs).
+ """
+ vec = [0,0,1]
+ for item in data:
+ if item[0] == 210: # 210 = x
+ vec[0] = item[1]
+ elif item[0] == 220: # 220 = y
+ vec[1] = item[1]
+ elif item[0] == 230: # 230 = z
+ vec[2] = item[1]
+ return vec
+
+
+ def __repr__(self):
+ return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
+
+
+ def draw(self, curves=False):
+ """Do all the specific things needed to import plines into Blender."""
+ # Generate the geometery
+ points = []
+ for i in range(len(self.points)):
+ point = self.points[i]
+ if not point.bulge:
+ points.append(point.loc)
+ elif point.bulge and i < len(self.points)-1:# > 0:
+ center, radius, start, end = solveBulge(point, self.points[i+1])
+ #print center, radius, start, end
+ verts, nosense = drawArc(center, radius, start, end)
+ verts.pop(0) # remove first
+ verts.pop() #remove last
+ if point.bulge >= 0:
+ verts.reverse()
+ points.extend(verts)
+ edges = [[num, num+1] for num in range(len(points)-1)]
+ if self.closed:
+ edges.append([len(self.points)-1, 0])
+
+ me = Mesh.New('pline') # create a new mesh
+
+ me.verts.extend(points) # add vertices to mesh
+ me.edges.extend(edges) # add edges to the mesh
+
+ # Now Create an object
+ ob = Object.New('Mesh', 'pline') # link mesh to an object
+ ob.link(me)
+ transform(self.extrusion, ob)
+ ob.LocZ = self.elevation
+
+ return ob
+
+
+
+
+class Vertex(object):
+ """Generic vertex object used by polylines (and maybe others)."""
+
+ def __init__(self, obj=None):
+ """Initializes vertex data.
+
+ The optional obj arg is an entity object of type vertex.
+ """
+ self.loc = [0,0,0]
+ self.bulge = 0
+ self.swidth = 0
+ self.ewidth = 0
+ self.flags = 0
+
+ if obj is not None:
+ if not obj.type == 'vertex':
+ raise TypeError, "Wrong type %s for vertex object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+
+ self.get_props(obj.data)
+
+
+ def get_props(self, data):
+ """Gets coords for a vertex type object.
+
+ Each vert can have a number of properties.
+ Verts should be coded as
+ 10:xvalue
+ 20:yvalue
+ 40:startwidth or 0
+ 41:endwidth or 0
+ 42:bulge or 0
+ """
+ for item in data:
+ if item[0] == 10: # 10 = x
+ self.x = item[1]
+ elif item[0] == 20: # 20 = y
+ self.y = item[1]
+ elif item[0] == 30: # 30 = z
+ self.z = item[1]
+ elif item[0] == 40: # 40 = start width
+ self.swidth = item[1]
+ elif item[0] == 41: # 41 = end width
+ self.ewidth = item[1]
+ elif item[0] == 42: # 42 = bulge
+ self.bulge = item[1]
+ elif item[0] == 70: # 70 = vert flags
+ self.flags = item[1]
+
+
+ def __len__(self):
+ return 3
+
+
+ def __getitem__(self, key):
+ return self.loc[key]
+
+
+ def __setitem__(self, key, value):
+ if key in [0,1,2]:
+ self.loc[key]
+
+
+ def __iter__(self):
+ return self.loc.__iter__()
+
+
+ def __str__(self):
+ return str(self.loc)
+
+
+ def __repr__(self):
+ return "Vertex %s, swidth=%s, ewidth=%s, bulge=%s" %(self.loc, self.swidth, self.ewidth, self.bulge)
+
+
+ def getx(self):
+ return self.loc[0]
+
+ def setx(self, value):
+ self.loc[0] = value
+
+ x = property(getx, setx)
+
+
+ def gety(self):
+ return self.loc[1]
+
+ def sety(self, value):
+ self.loc[1] = value
+
+ y = property(gety, sety)
+
+
+ def getz(self):
+ return self.loc[2]
+
+ def setz(self, value):
+ self.loc[2] = value
+
+ z = property(getz, setz)
+
+
+
+class Text:
+ """Class for objects representing dxf Text."""
+
+ def __init__(self, obj):
+ """Expects an entity object of type text as input."""
+ if not obj.type == 'text':
+ raise TypeError, "Wrong type %s for text object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+
+ # required data
+ self.height = obj.get_type(40)[0]
+ self.value = obj.get_type(1)[0] # The text string value
+
+ # optional data (with defaults)
+ self.space = obj.get_type(67)
+ if self.space:
+ self.space = self.space[0]
+ else:
+ self.space = 0
+
+ self.color_index = obj.get_type(62)
+ if self.color_index:
+ self.color_index = self.color_index[0]
+ else:
+ self.color_index = BYLAYER
+
+ self.rotation = obj.get_type(50) # radians?
+ if not self.rotation:
+ self.rotation = 0
+ else:
+ self.rotation = self.rotation[0]
+
+ self.width_factor = obj.get_type(41) # Scaling factor along local x axis
+ if not self.width_factor:
+ self.width_factor = 1
+ else:
+ self.width_factor = self.width_factor[0]
+
+ self.oblique = obj.get_type(51) # skew in degrees -90 <= oblique <= 90
+ if not self.oblique:
+ self.oblique = 0
+ else:
+ self.oblique = self.oblique[0]
+
+ self.halignment = obj.get_type(72) # horiz. alignment
+ if not self.halignment: # 0=left, 1=center, 2=right, 3=aligned, 4=middle, 5=fit
+ self.halignment = 0
+ else:
+ self.halignment = self.halignment[0]
+
+ self.valignment = obj.get_type(73) # vert. alignment
+ if not self.valignment: # 0=baseline, 1=bottom, 2=middle, 3=top
+ self.valignment = 0
+ else:
+ self.valignment = self.valignment[0]
+
+ discard, self.layer = get_layer(obj.data)
+ obj.data.remove(discard)
+ self.loc = self.get_loc(obj.data, self.halignment, self.valignment)
+ self.extrusion = self.get_extrusion(obj.data)
+
+
+
+
+ def get_loc(self, data, halign, valign):
+ """Gets adjusted location for text type objects.
+
+ If group 72 and/or 73 values are nonzero then the first alignment point values
+ are ignored and AutoCAD calculates new values based on the second alignment
+ point and the length and height of the text string itself (after applying the
+ text style). If the 72 and 73 values are zero or missing, then the second
+ alignment point is meaningless.
+
+ I don't know how to calc text size...
+ """
+ # bottom left x, y, z and justification x, y, z = 0
+ x, y, z, jx, jy, jz = 0, 0, 0, 0, 0, 0
+ for item in data:
+ if item[0] == 10: # 10 = x
+ x = item[1]
+ elif item[0] == 20: # 20 = y
+ y = item[1]
+ elif item[0] == 30: # 30 = z
+ z = item[1]
+ elif item[0] == 11: # 11 = x
+ jx = item[1]
+ elif item[0] == 21: # 21 = y
+ jy = item[1]
+ elif item[0] == 31: # 31 = z
+ jz = item[1]
+
+ if halign or valign:
+ x, y, z = jx, jy, jz
+ return [x, y, z]
+
+ def get_extrusion(self, data):
+ """Find the axis of extrusion.
+
+ Used to get the objects Object Coordinate System (ocs).
+ """
+ vec = [0,0,1]
+ for item in data:
+ if item[0] == 210: # 210 = x
+ vec[0] = item[1]
+ elif item[0] == 220: # 220 = y
+ vec[1] = item[1]
+ elif item[0] == 230: # 230 = z
+ vec[2] = item[1]
+ return vec
+
+
+ def __repr__(self):
+ return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
+
+
+ def draw(self, curves=False):
+ """Do all the specific things needed to import texts into Blender."""
+ # Generate the geometery
+ txt = Text3d.New("text")
+ txt.setSize(1)
+ txt.setShear(self.oblique/90)
+ txt.setExtrudeDepth(0.5)
+ if self.halignment == 0:
+ align = Text3d.LEFT
+ elif self.halignment == 1:
+ align = Text3d.MIDDLE
+ elif self.halignment == 2:
+ align = Text3d.RIGHT
+ elif self.halignment == 3:
+ align = Text3d.FLUSH
+ else:
+ align = Text3d.MIDDLE
+ txt.setAlignment(align)
+ txt.setText(self.value)
+
+ # Now Create an object
+ ob = Object.New('Text', 'text') # link mesh to an object
+ ob.link(txt)
+
+ transform(self.extrusion, ob)
+
+ # move the object center to the text location
+ ob.loc = tuple(self.loc)
+ # scale it to the text size
+ ob.SizeX = self.height*self.width_factor
+ ob.SizeY = self.height
+ ob.SizeZ = self.height
+ # and rotate it around z
+ ob.RotZ = radians(self.rotation)
+
+ return ob
+
+
+
+
+class Mtext:
+ """Class for objects representing dxf Mtext."""
+
+ def __init__(self, obj):
+ """Expects an entity object of type mtext as input."""
+ if not obj.type == 'mtext':
+ raise TypeError, "Wrong type %s for mtext object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+
+ # required data
+ self.height = obj.get_type(40)[0]
+ self.width = obj.get_type(41)[0]
+ 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
+ self.value = self.get_text(obj.data) # The text string value
+
+ # optional data (with defaults)
+ self.space = obj.get_type(67)
+ if self.space:
+ self.space = self.space[0]
+ else:
+ self.space = 0
+
+ self.color_index = obj.get_type(62)
+ if self.color_index:
+ self.color_index = self.color_index[0]
+ else:
+ self.color_index = BYLAYER
+
+ self.rotation = obj.get_type(50) # radians
+ if not self.rotation:
+ self.rotation = 0
+ else:
+ self.rotation = self.rotation[0]
+
+ self.width_factor = obj.get_type(42) # Scaling factor along local x axis
+ if not self.width_factor:
+ self.width_factor = 1
+ else:
+ self.width_factor = self.width_factor[0]
+
+ self.line_space = obj.get_type(44) # percentage of default
+ if not self.line_space:
+ self.line_space = 1
+ else:
+ self.line_space = self.line_space[0]
+
+ discard, self.layer = get_layer(obj.data)
+ obj.data.remove(discard)
+ self.loc = self.get_loc(obj.data)
+ self.extrusion = self.get_extrusion(obj.data)
+
+
+
+
+
+ def get_text(self, data):
+ """Reconstructs mtext data from dxf codes."""
+ primary = ''
+ secondary = []
+ for item in data:
+ if item[0] == 1: # There should be only one primary...
+ primary = item[1]
+ elif item[0] == 3: # There may be any number of extra strings (in order)
+ secondary.append(item[1])
+ if not primary:
+ #raise ValueError, "Empty Mtext Object!"
+ string = "Empty Mtext Object!"
+ if not secondary:
+ string = primary.replace(r'\P', '\n')
+ else:
+ string = ''.join(secondary)+primary
+ string = string.replace(r'\P', '\n')
+ return string
+ def get_loc(self, data):
+ """Gets location for a mtext type objects.
+
+ Mtext objects have only one point indicating location.
+ """
+ loc = [0,0,0]
+ for item in data:
+ if item[0] == 10: # 10 = x
+ loc[0] = item[1]
+ elif item[0] == 20: # 20 = y
+ loc[1] = item[1]
+ elif item[0] == 30: # 30 = z
+ loc[2] = item[1]
+ return loc
+
+
+
+
+ def get_extrusion(self, data):
+ """Find the axis of extrusion.
+
+ Used to get the objects Object Coordinate System (ocs).
+ """
+ vec = [0,0,1]
+ for item in data:
+ if item[0] == 210: # 210 = x
+ vec[0] = item[1]
+ elif item[0] == 220: # 220 = y
+ vec[1] = item[1]
+ elif item[0] == 230: # 230 = z
+ vec[2] = item[1]
+ return vec
+
+
+ def __repr__(self):
+ return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
+
+
+ def draw(self, curves=False):
+ """Do all the specific things needed to import mtexts into Blender."""
+ # Generate the geometery
+ txt = Text3d.New("mtext")
+ txt.setSize(1)
+ # Blender doesn't give access to its text object width currently
+ # only to the text3d's curve width...
+ #txt.setWidth(text.width/10)
+ txt.setLineSeparation(self.line_space)
+ txt.setExtrudeDepth(0.5)
+ txt.setText(self.value)
+
+ # Now Create an object
+ ob = Object.New('Text', 'mtext') # link mesh to an object
+ ob.link(txt)
+
+ transform(self.extrusion, ob)
+
+ # move the object center to the text location
+ ob.loc = tuple(self.loc)
+ # scale it to the text size
+ ob.SizeX = self.height*self.width_factor
+ ob.SizeY = self.height
+ ob.SizeZ = self.height
+ # and rotate it around z
+ ob.RotZ = radians(self.rotation)
+
+ return ob
+
+
+
+
+
+
+class Circle:
+ """Class for objects representing dxf Circles."""
+
+ def __init__(self, obj):
+ """Expects an entity object of type circle as input."""
+ if not obj.type == 'circle':
+ raise TypeError, "Wrong type %s for circle object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+
+ # required data
+ self.radius = obj.get_type(40)[0]
+
+ # optional data (with defaults)
+ self.space = obj.get_type(67)
+ if self.space:
+ self.space = self.space[0]
+ else:
+ self.space = 0
+
+ self.color_index = obj.get_type(62)
+ if self.color_index:
+ self.color_index = self.color_index[0]
+ else:
+ self.color_index = BYLAYER
+
+ discard, self.layer = get_layer(obj.data)
+ obj.data.remove(discard)
+ self.loc = self.get_loc(obj.data)
+ self.extrusion = self.get_extrusion(obj.data)
+
+
+
+
+
+ def get_loc(self, data):
+ """Gets the center location for circle type objects.
+
+ Circles have a single coord location.
+ """
+ loc = [0, 0, 0]
+ for item in data:
+ if item[0] == 10: # 10 = x
+ loc[0] = item[1]
+ elif item[0] == 20: # 20 = y
+ loc[1] = item[1]
+ elif item[0] == 30: # 30 = z
+ loc[2] = item[1]
+ return loc
+
+
+
+ def get_extrusion(self, data):
+ """Find the axis of extrusion.
+
+ Used to get the objects Object Coordinate System (ocs).
+ """
+ vec = [0,0,1]
+ for item in data:
+ if item[0] == 210: # 210 = x
+ vec[0] = item[1]
+ elif item[0] == 220: # 220 = y
+ vec[1] = item[1]
+ elif item[0] == 230: # 230 = z
+ vec[2] = item[1]
+ return vec
+
+
+ def __repr__(self):
+ return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
+
+
+ def draw(self, curves=False):
+ """Do all the specific things needed to import circles into Blender."""
+ # Generate the geometery
+ # Now Create an object
+ if curves:
+ ob = drawCurveCircle(self)
+ else:
+ center = self.loc
+ radius = self.radius
+
+ circ = 2 * pi * radius
+ if circ < 65: # if circumfrance is too small
+ verts = 32 # set a fixed number of 32 verts
+ else:
+ verts = circ/.5 # figure out how many verts we need
+ if verts > 100: # Blender only accepts values
+ verts = 100 # [3:100]
+
+ c = Mesh.Primitives.Circle(int(verts), radius*2)
+
+ ob = Object.New('Mesh', 'circle')
+ ob.link(c) # link curve data with this object
+
+ ob.loc = tuple(center)
+ transform(self.extrusion, ob)
+
+ return ob
+
+
+
+
+class Arc:
+ """Class for objects representing dxf arcs."""
+
+ def __init__(self, obj):
+ """Expects an entity object of type arc as input."""
+ if not obj.type == 'arc':
+ raise TypeError, "Wrong type %s for arc object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+
+ # required data
+ self.radius = obj.get_type(40)[0]
+ self.start_angle = obj.get_type(50)[0]
+ self.end_angle = obj.get_type(51)[0]
+
+ # optional data (with defaults)
+ self.space = obj.get_type(67)
+ if self.space:
+ self.space = self.space[0]
+ else:
+ self.space = 0
+
+ self.color_index = obj.get_type(62)
+ if self.color_index:
+ self.color_index = self.color_index[0]
+ else:
+ self.color_index = BYLAYER
+
+ discard, self.layer = get_layer(obj.data)
+ obj.data.remove(discard)
+ self.loc = self.get_loc(obj.data)
+ self.extrusion = self.get_extrusion(obj.data)
+
+
+
+
+
+ def get_loc(self, data):
+ """Gets the center location for arc type objects.
+
+ Arcs have a single coord location.
+ """
+ loc = [0, 0, 0]
+ for item in data:
+ if item[0] == 10: # 10 = x
+ loc[0] = item[1]
+ elif item[0] == 20: # 20 = y
+ loc[1] = item[1]
+ elif item[0] == 30: # 30 = z
+ loc[2] = item[1]
+ return loc
+
+
+
+ def get_extrusion(self, data):
+ """Find the axis of extrusion.
+
+ Used to get the objects Object Coordinate System (ocs).
+ """
+ vec = [0,0,1]
+ for item in data:
+ if item[0] == 210: # 210 = x
+ vec[0] = item[1]
+ elif item[0] == 220: # 220 = y
+ vec[1] = item[1]
+ elif item[0] == 230: # 230 = z
+ vec[2] = item[1]
+ return vec
+
+
+ def __repr__(self):
+ return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
+
+
+ def draw(self, curves=False):
+ """Do all the specific things needed to import arcs into Blender."""
+ # Generate the geometery
+ # Now Create an object
+ if curves:
+ ob = drawCurveArc(self)
+ else:
+ center = self.loc
+ radius = self.radius
+ start = self.start_angle
+ end = self.end_angle
+ verts, edges = drawArc(None, radius, start, end)
+
+ a = Mesh.New('arc')
+
+ a.verts.extend(verts) # add vertices to mesh
+ a.edges.extend(edges) # add edges to the mesh
+
+ ob = Object.New('Mesh', 'arc')
+ ob.link(a) # link curve data with this object
+ ob.loc = tuple(center)
+ ob.RotX = radians(180)
+
+ transform(self.extrusion, ob)
+ ob.size = (1,1,1)
+
+ return ob
+
+
+class BlockRecord:
+ """Class for objects representing dxf block_records."""
+
+ def __init__(self, obj):
+ """Expects an entity object of type block_record as input."""
+ if not obj.type == 'block_record':
+ raise TypeError, "Wrong type %s for block_record object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+
+ # required data
+ self.name = obj.get_type(2)[0]
+
+ # optional data (with defaults)
+ self.insertion_units = obj.get_type(70)
+ if not self.insertion_units:
+ self.insertion_units = None
+ else:
+ self.insertion_units = self.insertion_units[0]
+
+ self.insert_units = obj.get_type(1070)
+ if not self.insert_units:
+ self.insert_units = None
+ else:
+ self.insert_units = self.insert_units[0]
+
+
+
+
+
+
+ def __repr__(self):
+ return "%s: name - %s, insert units - %s" %(self.__class__.__name__, self.name, self.insertion_units)
+
+
+
+
+class Block:
+ """Class for objects representing dxf blocks."""
+
+ def __init__(self, obj):
+ """Expects an entity object of type block as input."""
+ if not obj.type == 'block':
+ raise TypeError, "Wrong type %s for block object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+ self.name = obj.name
+
+ # required data
+ self.flags = obj.get_type(70)[0]
+ self.entities = dxfObject('block_contents')
+ self.entities.data = objectify([ent for ent in obj.data if type(ent) != list])
+
+ # optional data (with defaults)
+ self.path = obj.get_type(1)
+ if self.path:
+ self.path = self.path[0]
+ else:
+ self.path = ''
+
+ self.discription = obj.get_type(4)
+ if self.discription:
+ self.discription = self.discription[0]
+ else:
+ self.discription = ''
+
+ discard, self.layer = get_layer(obj.data)
+ obj.data.remove(discard)
+ self.loc = self.get_loc(obj.data)
+
+
+
+
+ def get_loc(self, data):
+ """Gets the insert point of the block."""
+ loc = [0, 0, 0]
+ for item in data:
+ if type(item) != list:
+ continue
+ if item[0] == 10: # 10 = x
+ loc[0] = item[1]
+ elif item[0] == 20: # 20 = y
+ loc[1] = item[1]
+ elif item[0] == 30: # 30 = z
+ loc[2] = item[1]
+ return loc
+
+
+
+ def __repr__(self):
+ return "%s: name - %s, description - %s, xref-path - %s" %(self.__class__.__name__, self.name, self.discription, self.path)
+
+
+class Insert:
+ """Class for objects representing dxf inserts."""
+
+ def __init__(self, obj):
+ """Expects an entity object of type insert as input."""
+ if not obj.type == 'insert':
+ raise TypeError, "Wrong type %s for insert object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+
+ # required data
+ self.block = obj.get_type(2)[0]
+
+ # optional data (with defaults)
+ self.rotation = obj.get_type(50)
+ if self.rotation:
+ self.rotation = self.rotation[0]
+ else:
+ self.rotation = 0
+
+ self.space = obj.get_type(67)
+ if self.space:
+ self.space = self.space[0]
+ else:
+ self.space = 0
+
+ self.color_index = obj.get_type(62)
+ if self.color_index:
+ self.color_index = self.color_index[0]
+ else:
+ self.color_index = BYLAYER
+
+ discard, self.layer = get_layer(obj.data)
+ obj.data.remove(discard)
+ self.loc = self.get_loc(obj.data)
+ self.scale = self.get_scale(obj.data)
+ self.rows, self.columns = self.get_array(obj.data)
+ self.extrusion = self.get_extrusion(obj.data)
+
+
+
+
+
+ def get_loc(self, data):
+ """Gets the center location for circle type objects.
+
+ Circles have a single coord location.
+ """
+ loc = [0, 0, 0]
+ for item in data:
+ if item[0] == 10: # 10 = x
+ loc[0] = item[1]
+ elif item[0] == 20: # 20 = y
+ loc[1] = item[1]
+ elif item[0] == 30: # 30 = z
+ loc[2] = item[1]
+ return loc
+
+
+
+ def get_scale(self, data):
+ """Gets the x/y/z scale factor for the block.
+ """
+ scale = [1, 1, 1]
+ for item in data:
+ if item[0] == 41: # 41 = x scale
+ scale[0] = item[1]
+ elif item[0] == 42: # 42 = y scale
+ scale[1] = item[1]
+ elif item[0] == 43: # 43 = z scale
+ scale[2] = item[1]
+ return scale
+
+
+
+ def get_array(self, data):
+ """Returns the pair (row number, row spacing), (column number, column spacing)."""
+ columns = 1
+ rows = 1
+ cspace = 0
+ rspace = 0
+ for item in data:
+ if item[0] == 70: # 70 = columns
+ columns = item[1]
+ elif item[0] == 71: # 71 = rows
+ rows = item[1]
+ if item[0] == 44: # 44 = columns
+ cspace = item[1]
+ elif item[0] == 45: # 45 = rows
+ rspace = item[1]
+ return (rows, rspace), (columns, cspace)
+
+
+
+ def get_extrusion(self, data):
+ """Find the axis of extrusion.
+
+ Used to get the objects Object Coordinate System (ocs).
+ """
+ vec = [0,0,1]
+ for item in data:
+ if item[0] == 210: # 210 = x
+ vec[0] = item[1]
+ elif item[0] == 220: # 220 = y
+ vec[1] = item[1]
+ elif item[0] == 230: # 230 = z
+ vec[2] = item[1]
+ return vec
+
+
+ def __repr__(self):
+ return "%s: layer - %s, block - %s" %(self.__class__.__name__, self.layer, self.block)
+
+
+ def draw(self, handle, settings):
+ """Do all the specific things needed to import blocks into Blender.
+
+ Blocks are made of three objects:
+ the block_record in the tables section
+ the block in the blocks section
+ the insert object in the entities section
+
+ block_records give the insert units, blocks provide the objects drawn in the
+ block, and the insert object gives the location/scale/rotation of the block
+ instances. To draw a block you must first get a group with all the
+ blocks entities drawn in it, then scale the entities to match the world
+ units, then dupligroup that data to an object matching each insert object."""
+
+ # Create an object
+ ob = Object.New('Mesh', self.block)
+ ob.link(handle) # Give the object a handle
+
+ if settings.drawTypes['blocks']:
+ # get our block group
+ block = settings.blocks(self.block)
+
+ ob.DupGroup = block
+ ob.enableDupGroup = True
+
+ ob.loc = tuple(self.loc)
+ transform(self.extrusion, ob)
+ ob.RotZ += radians(self.rotation)
+ ob.size = tuple(self.scale)
+
+ return ob
+
+
+
+
+class Ellipse:
+ """Class for objects representing dxf ellipses."""
+
+ def __init__(self, obj):
+ """Expects an entity object of type ellipse as input."""
+ if not obj.type == 'ellipse':
+ raise TypeError, "Wrong type %s for ellipse object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+
+ # required data
+ self.ratio = obj.get_type(40)[0]
+ self.start_angle = obj.get_type(41)[0]
+ self.end_angle = obj.get_type(42)[0]
+
+ # optional data (with defaults)
+ self.space = obj.get_type(67)
+ if self.space:
+ self.space = self.space[0]
+ else:
+ self.space = 0
+
+ self.color_index = obj.get_type(62)
+ if self.color_index:
+ self.color_index = self.color_index[0]
+ else:
+ self.color_index = BYLAYER
+
+ discard, self.layer = get_layer(obj.data)
+ obj.data.remove(discard)
+ self.loc = self.get_loc(obj.data)
+ self.major = self.get_major(obj.data)
+ self.extrusion = self.get_extrusion(obj.data)
+ self.radius = sqrt(self.major[0]**2 + self.major[0]**2 + self.major[0]**2)
+
+
+
+
+ def get_loc(self, data):
+ """Gets the center location for arc type objects.
+
+ Arcs have a single coord location.
+ """
+ loc = [0, 0, 0]
+ for item in data:
+ if item[0] == 10: # 10 = x
+ loc[0] = item[1]
+ elif item[0] == 20: # 20 = y
+ loc[1] = item[1]
+ elif item[0] == 30: # 30 = z
+ loc[2] = item[1]
+ return loc
+
+
+
+ def get_major(self, data):
+ """Gets the major axis for ellipse type objects.
+
+ The ellipse major axis defines the rotation of the ellipse and its radius.
+ """
+ loc = [0, 0, 0]
+ for item in data:
+ if item[0] == 11: # 11 = x
+ loc[0] = item[1]
+ elif item[0] == 21: # 21 = y
+ loc[1] = item[1]
+ elif item[0] == 31: # 31 = z
+ loc[2] = item[1]
+ return loc
+
+
+
+ def get_extrusion(self, data):
+ """Find the axis of extrusion.
+
+ Used to get the objects Object Coordinate System (ocs).
+ """
+ vec = [0,0,1]
+ for item in data:
+ if item[0] == 210: # 210 = x
+ vec[0] = item[1]
+ elif item[0] == 220: # 220 = y
+ vec[1] = item[1]
+ elif item[0] == 230: # 230 = z
+ vec[2] = item[1]
+ return vec
+
+
+ def __repr__(self):
+ return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
+
+
+ def draw(self, curves=False):
+ """Do all the specific things needed to import ellipses into Blender."""
+ # Generate the geometery
+ # Now Create an object
+ if curves:
+ ob = drawCurveArc(self)
+ else:
+ major = Mathutils.Vector(self.major)
+ delta = Mathutils.AngleBetweenVecs(major, WORLDX)
+ center = self.loc
+ radius = major.length
+ start = degrees(self.start_angle)
+ end = degrees(self.end_angle)
+ verts, edges = drawArc(None, radius, start, end)
+
+ e = Mesh.New('ellipse')
+
+ e.verts.extend(verts) # add vertices to mesh
+ e.edges.extend(edges) # add edges to the mesh
+
+
+ ob = Object.New('Mesh', 'arc')
+ ob.link(e) # link curve data with this object
+ ob.loc = tuple(center)
+ ob.SizeY = self.ratio
+ #ob.RotZ = radians(delta)
+ ob.RotX = radians(180)
+
+
+ transform(self.extrusion, ob)
+ ob.RotZ = radians(delta)
+
+ return ob
+
+
+
+class Face:
+ """Class for objects representing dxf 3d faces."""
+
+ def __init__(self, obj):
+ """Expects an entity object of type 3dfaceplot as input."""
+ if not obj.type == '3dface':
+ raise TypeError, "Wrong type %s for 3dface object!" %obj.type
+ self.type = obj.type
+ self.data = obj.data[:]
+
+ # optional data (with defaults)
+ self.space = obj.get_type(67)
+ if self.space:
+ self.space = self.space[0]
+ else:
+ self.space = 0
+
+ self.color_index = obj.get_type(62)
+ if self.color_index:
+ self.color_index = self.color_index[0]
+ else:
+ self.color_index = BYLAYER
+
+ discard, self.layer = get_layer(obj.data)
+ obj.data.remove(discard)
+ self.points = self.get_points(obj.data)
+
+
+
+
+ def get_points(self, data):
+ """Gets 3-4 points for a 3d face type object.
+
+ Faces have three or optionally four verts.
+ """
+
+ a = [0, 0, 0]
+ b = [0, 0, 0]
+ c = [0, 0, 0]
+ d = False
+ for item in data:
+ # ----------- a -------------
+ if item[0] == 10: # 10 = x
+ a[0] = item[1]
+ elif item[0] == 20: # 20 = y
+ a[1] = item[1]
+ elif item[0] == 30: # 30 = z
+ a[2] = item[1]
+ # ----------- b -------------
+ elif item[0] == 11: # 11 = x
+ b[0] = item[1]
+ elif item[0] == 21: # 21 = y
+ b[1] = item[1]
+ elif item[0] == 31: # 31 = z
+ b[2] = item[1]
+ # ----------- c -------------
+ elif item[0] == 12: # 12 = x
+ c[0] = item[1]
+ elif item[0] == 22: # 22 = y
+ c[1] = item[1]
+ elif item[0] == 32: # 32 = z
+ c[2] = item[1]
+ # ----------- d -------------
+ elif item[0] == 13: # 13 = x
+ d = [0, 0, 0]
+ d[0] = item[1]
+ elif item[0] == 23: # 23 = y
+ d[1] = item[1]
+ elif item[0] == 33: # 33 = z
+ d[2] = item[1]
+ out = [a,b,c]
+ if d:
+ out.append(d)
+ return out
+
+
+ def __repr__(self):
+ return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
+
+
+ def draw(self, curves=False):
+ """Do all the specific things needed to import 3d faces into Blender."""
+ # Generate the geometery
+ points = self.points
+ if len(self.points) > 3:
+ faces = [[0, 1, 2, 3]]
+ else:
+ faces = [[0, 1, 2]]
+
+ me = Mesh.New('3dface') # create a new mesh
+
+ me.verts.extend(points) # add vertices to mesh
+ me.faces.extend(faces) # add faces to the mesh
+
+ # Now Create an object
+ ob = Object.New('Mesh', '3dface') # link mesh to an object
+ ob.link(me)
+
+ return ob
+
+
+
+# type to object map
+type_map = {
+ 'line':Line,
+ 'lwpolyline':LWpolyline,
+ 'text':Text,
+ 'mtext':Mtext,
+ 'circle':Circle,
+ 'arc':Arc,
+ 'layer':Layer,
+ 'block_record':BlockRecord,
+ 'block':Block,
+ 'insert':Insert,
+ 'ellipse':Ellipse,
+ '3dface':Face
+}
+
+def objectify(data):
+ """Expects a section type object's data as input.
+
+ Maps object data to the correct object type.
+ """
+ objects = [] # colector for finished objects
+ known_types = type_map.keys() # so we don't have to call foo.keys() every iteration
+ index = 0
+ while index < len(data):
+ item = data[index]
+ if type(item) != list and item.type in known_types:
+ # proccess the object and append the resulting object
+ objects.append(type_map[item.type](item))
+ elif type(item) != list and item.type == 'table':
+ item.data = objectify(item.data) # tables have sub-objects
+ objects.append(item)
+ elif type(item) != list and item.type == 'polyline':
+ pline = Polyline(item)
+ while 1:
+ index += 1
+ item = data[index]
+ if item.type == 'vertex':
+ v = Vertex(item)
+ pline.points.append(v)
+ elif item.type == 'seqend':
+ break
+ else:
+ print "Error: non-vertex found before seqend!"
+ index -= 1
+ break
+ objects.append(pline)
+ else:
+ # we will just let the data pass un-harrased
+ objects.append(item)
+ index += 1
+ return objects
+
class MatColors:
"""A smart container for color based materials.
@@ -144,7 +1676,7 @@ class MatColors:
self.map[color] = layer
color = 0
color = abs(color)
- if color not in self.colors: # .keys()
+ if color not in self.colors.keys():
self.add(color)
return self.colors[color]
@@ -186,7 +1718,7 @@ class Blocks:
"""
if not name:
return self.blocks
- if name not in self.blocks: # .keys():
+ if name not in self.blocks.keys():
self.add(name)
return self.blocks[name]
@@ -194,14 +1726,12 @@ class Blocks:
def add(self, name):
"""Create a new block group for the block with name."""
- optimization = self.settings.optimization
+ write = self.settings.write
group = Group.New(name)
block = self.map[name]
- if optimization <= 1:
- print "\nDrawing %s block entities..." %name
+ write("\nDrawing %s block entities..." %name)
drawEntities(block.entities, self.settings, group)
- if optimization <= 1:
- print "Done!"
+ write("Done!")
self.blocks[name] = group
@@ -216,69 +1746,73 @@ class Settings:
# Optimization constants
MIN = 0
MID = 1
- MAX = 2
+ PRO = 2
+ MAX = 3
- def __init__(self, drawing, curves):
+ def __init__(self, drawing, curves, optimization, **kwds):
"""Given the drawing initialize all the important settings used by the draw functions."""
self.curves = curves
+ self.optimization = optimization
+ print "Setting optimization level %s!" %optimization
+ self.drawTypes = kwds
self.layers = True
self.blocks = True
- self.optimization = self.getOpt()
# First sort out all the sections
sections = dict([(item.name, item) for item in drawing.data])
# The header section may be omited
- if self.optimization <= self.MID:
- if 'header' in sections: #.keys():
- print "Found header!"
- else:
- print "File contains no header!"
+ if 'header' in sections.keys():
+ self.write("Found header!")
+ else:
+ self.write("File contains no header!")
# The tables section may be partialy or completely missing.
- if 'tables' in sections: # .keys():
- if self.optimization <= self.MID:
- print "Found tables!"
+ if 'tables' in sections.keys():
+ self.write("Found tables!")
tables = dict([(item.name, item) for item in sections["tables"].data])
- if 'layer' in tables: # .keys():
- if self.optimization <= self.MID:
- print "Found layers!"
+ if 'layer' in tables.keys():
+ self.write("Found layers!")
# Read the layers table and get the layer colors
self.colors = getLayers(drawing)
else:
- if self.optimization <= self.MID:
- print "File contains no layers table!"
+ self.write("File contains no layers table!")
self.layers = False
self.colors = MatColors({})
else:
- if self.optimization <= self.MID:
- print "File contains no tables!"
- print "File contains no layers table!"
+ self.write("File contains no tables!")
+ self.write("File contains no layers table!")
self.layers = False
self.colors = MatColors({})
# The blocks section may be omited
- if 'blocks' in sections: #.keys():
- if self.optimization <= self.MID:
- print "Found blocks!"
+ if 'blocks' in sections.keys():
+ self.write("Found blocks!")
# Read the block definitions and build our block object
- self.blocks = getBlocks(drawing, self)
+ if self.drawTypes['blocks']:
+ self.blocks = getBlocks(drawing, self)
else:
- if self.optimization <= self.MID:
- print "File contains no blocks!"
- self.blocks = False
+ self.write("File contains no blocks!")
+ self.drawTypes['blocks'] = False
+ def write(self, text, newline=True):
+ """Wraps the built-in print command in a optimization check."""
+ if self.optimization <= self.MID:
+ if newline:
+ print text
+ else:
+ print text,
+
+ def redraw(self):
+ """Update Blender if optimization level is low enough."""
+ if self.optimization <= self.MIN:
+ Blender.Redraw()
- def getOpt(self):
- """Ask the user for update optimization level."""
- Window.WaitCursor(False)
+ def progress(self, done, text):
+ """Wrapper for Blender.Window.DrawProgressBar."""
+ if self.optimization <= self.PRO:
+ Window.DrawProgressBar(done, text)
- retval = Draw.PupIntInput('optimization: ', 1, 0, 2)
- print "Setting optimization level %s!" %retval
-
- Window.WaitCursor(True)
- return retval
-
def isOff(self, name):
"""Given a layer name look up the layer object and return its visable status."""
@@ -296,112 +1830,7 @@ class Settings:
-class Drawer:
- """Super 'function' for all the entitiy drawing functions.
-
- The code for the drawing functions was very repetitive, each differing
- by only a few lines at most. So here is a callable class with methods
- for each part of the import proccess.
- """
-
- def __init__(self, block=False):
- self.block = block
-
-
-
- def __call__(self, entities, settings, group=None):
- """Call with a list of entities and a settings object to generate Blender geometry."""
- if entities and settings.optimization <= settings.MID:
- print "Drawing %ss..." %entities[0].type,
-
- if self.block:
- # create one 'handle' data block to use with all blocks
- handle = Mesh.New('insert')
- handle.verts.extend(
- [(-0.01,0,0),
- (0.01,0,0),
- (0,-0.01,0),
- (0,0.01,0),
- (0,0,-0.01),
- (0,0,0.01)]
- )
- handle.edges.extend([(0,1),(2,3),(4,5)])
-
- # For now we only want model-space objects
- entities = [entity for entity in entities if entity.space == 0]
-
- if group:
- block_def = True
- else:
- block_def = False
-
- for entity in entities:
- if settings.optimization <= settings.MID:
- print '\b.',
- # First get the layer group
- if not block_def:
- group = self.getGroup('layer %s' %entity.layer) # add overhead just to make things a little cleaner
-
- if not self.block:
- ob = self.draw(entity, settings.curves)
- else:
- ob = self.draw(entity, handle, settings)
-
- self.setColor(entity, ob, settings)
- # Link it to the scene and add it to the correct group
- SCENE.link(ob)
- self.setGroup(group, ob)
-
- # Set the visability
- if settings.isOff(entity.layer):
- ob.Layers = 1<<19 # [20]
- elif block_def:
- ob.Layers = (1<<18) # [19]
- else:
- ob.Layers = (1<<20)-1 # [i+1 for i in xrange(20)] # all layers
-
- # # Set the visability
- # if settings.isOff(entity.layer) or block_def:
- # ob.restrictDisplay = True
- # ob.restrictRender = True
-
- if settings.optimization == settings.MIN:
- # I know it's slow to have Blender redraw after each entity type is drawn
- # But is it really slower than the progress bar?
- Blender.Redraw()
- if entities and settings.optimization <= settings.MID:
- print "\nFinished drawing %ss!" %entities[0].type
- def getGroup(self, name):
- """Returns a Blender group object."""
- try:
- group = Group.Get(name)
- except: # What is the exception?
- group = Group.New(name)
- return group
- def draw(self, entity):
- """Dummy method to be over written in subclasses."""
- pass
-
-
- def setColor(self, entity, ob, settings):
- # Set the color
- if entity.color_index == BYLAYER:
- mat = settings.colors(entity.layer)
- else:
- mat = settings.colors(entity.color_index)
- try:
- ob.setMaterials([mat])
- except ValueError:
- print "material error - %s!" %mat
- ob.colbits = 0x01 # Set OB materials.
- def setGroup(self, group, it):
- try:
- group.objects.link(it)
- except:
- group.objects.append(it)
-
-
-def main(filename):
+def main(filename=None):
editmode = Window.EditMode() # are we in edit mode? If so ...
if editmode: Window.EditMode(0) # leave edit mode before
Window.WaitCursor(True) # Let the user know we are thinking
@@ -414,9 +1843,8 @@ def main(filename):
except IOError:
print "DXF import: error finding default test file, exiting..."
return None
- if filename:
- drawing = readDXF(filename)
- drawDrawing(drawing)
+ drawing = readDXF(filename, objectify)
+ drawDrawing(drawing)
finally:
# restore state even if things didn't work
Window.WaitCursor(False)
@@ -498,121 +1926,183 @@ def getBlocks(drawing, settings):
def drawDrawing(drawing):
"""Given a drawing object recreate the drawing in Blender."""
print "Getting settings..."
- # The settings object controls how dxf entities are drawn
- settings = Settings(drawing, curves=False)
+ Window.WaitCursor(False)
+ #width, height = Window.GetScreenSize()
+ Window.SetMouseCoords()
+
+ # Create a PupBlock to get user preferences
+ lines = Draw.Create(1)
+ arcs = Draw.Create(1)
+ circles = Draw.Create(1)
+ polylines = Draw.Create(1)
+ text = Draw.Create(1)
+ blocks = Draw.Create(1)
+ faces = Draw.Create(1)
+ optim = Draw.Create(1)
+
+ block = []
+ block.append("Draw Options:")
+ block.append(("Lines", lines, "Toggle drawing of lines"))
+ block.append(("Arcs", arcs, "Toggle drawing of arcs"))
+ block.append(("Circles", circles, "Toggle drawing of circles"))
+ block.append(("Polylines", polylines, "Toggle drawing of polylines"))
+ block.append(("Text", text, "Toggle drawing of text"))
+ block.append(("Blocks", blocks, "Toggle drawing of blocks"))
+ block.append(("Faces", faces, "Toggle drawing of faces"))
+ block.append("Update Optimization:")
+ block.append(("Level: ", optim, 0, 3))
+
+ retval = Draw.PupBlock("DXF Import", block)
- if settings.optimization <= settings.MID:
- print "Drawings entities..."
+ Window.WaitCursor(True) # Let the user know we are thinking
+ # The settings object controls how dxf entities are drawn
+ settings = Settings(drawing, curves=False,
+ optimization=int(optim.val),
+ lines=bool(lines.val),
+ arcs=bool(arcs.val),
+ circles=bool(circles.val),
+ polylines=bool(polylines.val),
+ text=bool(text.val),
+ blocks=bool(blocks.val),
+ faces=bool(faces.val)
+ )
+
+ settings.write("Drawings entities...")
# Draw all the know entity types in the current scene
drawEntities(drawing.entities, settings)
# Set the visable layers
- SCENE.setLayers([i+1 for i in xrange(18)]) # SCENE.Layers = 262143 or (1<<18)
+ SCENE.setLayers([i+1 for i in range(18)])
Blender.Redraw(-1)
- if settings.optimization <= settings.MID:
- print "Done!"
+ settings.write("Done!")
+
+
def drawEntities(entities, settings, group=None):
"""Draw every kind of thing in the entity list.
If provided 'group' is the Blender group new entities are to be added to.
"""
- for _type, drawer in type_map.iteritems():
+ for _type in type_map.keys():
# for each known type get a list of that type and call the associated draw function
- drawer(entities.get_type(_type), settings, group)
-
-
-drawLines = Drawer()
-def drawLine(line, curves=False):
- """Do all the specific things needed to import lines into Blender."""
- # Generate the geometery
- points = line.points
- edges = [[0, 1]]
-
- me = Mesh.New('line') # create a new mesh
-
- me.verts.extend(points) # add vertices to mesh
- me.edges.extend(edges) # add edges to the mesh
+ drawer(_type, entities.get_type(_type), settings, group)
- # Now Create an object
- ob = Object.New('Mesh', 'line') # link mesh to an object
- ob.link(me)
-
- return ob
-drawLines.draw = drawLine
-
-drawLWpolylines = Drawer()
-def drawLWpolyline(pline, curves=False):
- """Do all the specific things needed to import plines into Blender."""
- # Generate the geometery
- points = []
- for i in xrange(len(pline.points)):
- point = pline.points[i]
- if not point.bulge:
- points.append(point.loc)
- elif point.bulge and i < len(pline.points)-1:# > 0:
- center, radius, start, end = solveBulge(point, pline.points[i+1])
- #print center, radius, start, end
- verts, nosense = drawArc(center, radius, start, end)
- verts.pop(0) # remove first
- verts.pop() #remove last
- if point.bulge >= 0:
- verts.reverse()
- points.extend(verts)
- edges = [[num, num+1] for num in xrange(len(points)-1)]
- if pline.closed:
- edges.append([len(pline.points)-1, 0])
-
- me = Mesh.New('lwpline') # create a new mesh
-
- me.verts.extend(points) # add vertices to mesh
- me.edges.extend(edges) # add edges to the mesh
-
- # Now Create an object
- ob = Object.New('Mesh', 'lwpline') # link mesh to an object
- ob.link(me)
- transform(pline.extrusion, ob)
- ob.LocZ = pline.elevation
-
- return ob
-drawLWpolylines.draw = drawLWpolyline
-
-drawPolylines = Drawer()
-def drawPolyline(pline, curves=False):
- """Do all the specific things needed to import plines into Blender."""
- # Generate the geometery
- points = []
- for i in xrange(len(pline.points)):
- point = pline.points[i]
- if not point.bulge:
- points.append(point.loc)
- elif point.bulge and i < len(pline.points)-1:# > 0:
- center, radius, start, end = solveBulge(point, pline.points[i+1])
- #print center, radius, start, end
- verts, nosense = drawArc(center, radius, start, end)
- verts.pop(0) # remove first
- verts.pop() #remove last
- if point.bulge >= 0:
- verts.reverse()
- points.extend(verts)
- edges = [[num, num+1] for num in xrange(len(points)-1)]
- if pline.closed:
- edges.append([len(pline.points)-1, 0])
-
- me = Mesh.New('pline') # create a new mesh
-
- me.verts.extend(points) # add vertices to mesh
- me.edges.extend(edges) # add edges to the mesh
-
- # Now Create an object
- ob = Object.New('Mesh', 'pline') # link mesh to an object
- ob.link(me)
- transform(pline.extrusion, ob)
- ob.LocZ = pline.elevation
+def drawer(_type, entities, settings, group):
+ """Call with a list of entities and a settings object to generate Blender geometry."""
+ if entities:
+ # Break out early if settings says we aren't drawing the current type
+ block = False
+ skip = False
+ if _type == 'block_record':
+ skip = True
+ if _type == 'line' and not settings.drawTypes['lines']:
+ skip = True
+ elif _type == 'arc' and not settings.drawTypes['arcs']:
+ skip = True
+ elif _type == 'circle' and not settings.drawTypes['circles']:
+ skip = True
+ elif _type in ['lwpolyline', 'polyline'] and not settings.drawTypes['polylines']:
+ skip = True
+ elif _type in ['text', 'mtext'] and not settings.drawTypes['text']:
+ skip = True
+ elif _type == 'insert':
+ if not settings.drawTypes['blocks']:
+ skip = True
+ block = True
+ elif _type == '3dface' and not settings.drawTypes['faces']:
+ skip = True
+ if skip:
+ settings.write("Skipping %s type entities!" %_type)
+ return
+
+ message = "Drawing %ss..." %_type
+ settings.write(message, False)
+ settings.progress(0, message)
+
+ if block:
+ # create one 'handle' data block to use with all blocks
+ handle = Mesh.New('insert')
+ handle.verts.extend(
+ [(-0.01,0,0),
+ (0.01,0,0),
+ (0,-0.01,0),
+ (0,0.01,0),
+ (0,0,-0.01),
+ (0,0,0.01)]
+ )
+ handle.edges.extend([(0,1),(2,3),(4,5)])
+
+ # For now we only want model-space objects
+ entities = [entity for entity in entities if entity.space == 0]
+
+ if group:
+ block_def = True
+ else:
+ block_def = False
+
+ tot = len(entities)
+ cur = 1.0
+ for entity in entities:
+ settings.write('\b.', False)
+ settings.progress(cur/tot, message)
+ cur += 1
+
+ # First get the layer group
+ if not block_def:
+ group = getGroup('layer %s' %entity.layer) # add overhead just to make things a little cleaner
+
+ if block:
+ ob = entity.draw(handle, settings)
+ else:
+ ob = entity.draw(settings.curves)
+
+ setColor(entity, ob, settings)
+ # Link it to the scene and add it to the correct group
+ SCENE.link(ob)
+ setGroup(group, ob)
+
+ # Set the visability
+ if settings.isOff(entity.layer):
+ ob.layers = [20]
+ elif block_def:
+ ob.layers = [19]
+ else:
+ ob.layers = [i+1 for i in range(20)]
+
+ # # Set the visability
+ # if settings.isOff(entity.layer) or block_def:
+ # ob.restrictDisplay = True
+ # ob.restrictRender = True
+
+ settings.redraw()
+ message = "\nFinished drawing %ss!" %entities[0].type
+ settings.write(message)
+ settings.progress(1, message)
+
- return ob
-drawPolylines.draw = drawPolyline
-
+def getGroup(name):
+ """Returns a Blender group object."""
+ try:
+ group = Group.Get(name)
+ except: # What is the exception?
+ group = Group.New(name)
+ return group
+def setColor(entity, ob, settings):
+ # Set the color
+ if entity.color_index == BYLAYER:
+ mat = settings.colors(entity.layer)
+ else:
+ mat = settings.colors(entity.color_index)
+ try:
+ ob.setMaterials([mat])
+ except ValueError:
+ settings.write("material error - %s!" %mat)
+ ob.colbits = 0x01 # Set OB materials.
+def setGroup(group, it):
+ try:
+ group.objects.link(it)
+ except:
+ group.objects.append(it)
def solveBulge(p1, p2):
"""return the center, radius, start angle, and end angle given two points.
@@ -662,147 +2152,14 @@ def solveBulge(p1, p2):
# the end angle is just 'angle' more than start angle
end = start + angle
return list(center), radius, start, end
-drawTexts = Drawer()
-def drawText(text, curves=False):
- """Do all the specific things needed to import texts into Blender."""
- # Generate the geometery
- txt = Text3d.New("text")
- txt.setSize(1)
- txt.setShear(text.oblique/90)
- txt.setExtrudeDepth(0.5)
- if text.halignment == 0:
- align = Text3d.LEFT
- elif text.halignment == 1:
- align = Text3d.MIDDLE
- elif text.halignment == 2:
- align = Text3d.RIGHT
- elif text.halignment == 3:
- align = Text3d.FLUSH
- else:
- align = Text3d.MIDDLE
- txt.setAlignment(align)
- txt.setText(text.value)
-
- # Now Create an object
- ob = Object.New('Text', 'text') # link mesh to an object
- ob.link(txt)
-
- transform(text.extrusion, ob)
-
- # move the object center to the text location
- ob.loc = tuple(text.loc)
- # scale it to the text size
- ob.SizeX = text.height*text.width_factor
- ob.SizeY = text.height
- ob.SizeZ = text.height
- # and rotate it around z
- ob.RotZ = radians(text.rotation)
-
- return ob
-drawTexts.draw = drawText
-
-drawMtexts = Drawer()
-def drawMtext(text, curves=False):
- """Do all the specific things needed to import mtexts into Blender."""
- # Generate the geometery
- txt = Text3d.New("mtext")
- txt.setSize(1)
- # Blender doesn't give access to its text object width currently
- # only to the text3d's curve width...
- #txt.setWidth(text.width/10)
- txt.setLineSeparation(text.line_space)
- txt.setExtrudeDepth(0.5)
- txt.setText(text.value)
-
- # Now Create an object
- ob = Object.New('Text', 'mtext') # link mesh to an object
- ob.link(txt)
-
- transform(text.extrusion, ob)
-
- # move the object center to the text location
- ob.loc = tuple(text.loc)
- # scale it to the text size
- ob.SizeX = text.height*text.width_factor
- ob.SizeY = text.height
- ob.SizeZ = text.height
- # and rotate it around z
- ob.RotZ = radians(text.rotation)
-
- return ob
-drawMtexts.draw = drawMtext
-
-
-
-drawCircles = Drawer()
-def drawCircle(circle, curves=False):
- """Do all the specific things needed to import circles into Blender."""
- # Generate the geometery
- # Now Create an object
- if curves:
- ob = drawCurveCircle(circle)
- else:
- center = circle.loc
- radius = circle.radius
-
- circ = 2 * pi * radius
- if circ < 65: # if circumfrance is too small
- verts = 32 # set a fixed number of 32 verts
- else:
- verts = circ/.5 # figure out how many verts we need
- if verts > 100: # Blender only accepts values
- verts = 100 # [3:100]
-
- c = Mesh.Primitives.Circle(int(verts), radius*2)
-
- ob = Object.New('Mesh', 'circle')
- ob.link(c) # link curve data with this object
-
- ob.loc = tuple(center)
- transform(circle.extrusion, ob)
-
- return ob
-drawCircles.draw = drawCircle
-
-drawArcs = Drawer()
-def drawArc(arc, curves=False):
- """Do all the specific things needed to import arcs into Blender."""
- # Generate the geometery
- # Now Create an object
- if curves:
- ob = drawCurveArc(arc)
- else:
- center = arc.loc
- radius = arc.radius
- start = arc.start_angle
- end = arc.end_angle
- verts, edges = drawArc(None, radius, start, end)
-
- a = Mesh.New('arc')
-
- a.verts.extend(verts) # add vertices to mesh
- a.edges.extend(edges) # add edges to the mesh
-
- ob = Object.New('Mesh', 'arc')
- ob.link(a) # link curve data with this object
- ob.loc = tuple(center)
- ob.RotX = radians(180)
-
- transform(arc.extrusion, ob)
- ob.size = (1,1,1)
-
- return ob
-drawArcs.draw = drawArc
-
-
def drawArc(center, radius, start, end, step=0.5):
"""Draw a mesh arc with the given parameters."""
# center is currently set by object
# if start > end:
# start = start - 360
- # if end > 360:
- # end = end%360
+ if end > 360:
+ end = end%360
startmatrix = Mathutils.RotationMatrix(start, 3, "Z")
startpoint = startmatrix * Mathutils.Vector((radius, 0, 0))
endmatrix = Mathutils.RotationMatrix(end, 3, "Z")
@@ -824,107 +2181,16 @@ def drawArc(center, radius, start, end, step=0.5):
stepmatrix = Mathutils.RotationMatrix(step, 3, "Z")
point = Mathutils.Vector(startpoint)
- for i in xrange(int(pieces)):
+ for i in range(int(pieces)):
point = stepmatrix * point
points.append(point)
points.append(endpoint)
if center:
points = [[point[0]+center[0], point[1]+center[1], point[2]+center[2]] for point in points]
- edges = [[num, num+1] for num in xrange(len(points)-1)]
+ edges = [[num, num+1] for num in range(len(points)-1)]
return points, edges
-drawEllipses = Drawer()
-def drawEllipse(ellipse, curves=False):
- """Do all the specific things needed to import ellipses into Blender."""
- # Generate the geometery
- # Now Create an object
- if curves:
- ob = drawCurveArc(ellipse)
- else:
- major = Mathutils.Vector(ellipse.major)
- delta = Mathutils.AngleBetweenVecs(major, WORLDX)
- center = ellipse.loc
- radius = major.length
- start = degrees(ellipse.start_angle)
- end = degrees(ellipse.end_angle)
- verts, edges = drawArc(None, radius, start, end)
-
- e = Mesh.New('ellipse')
-
- e.verts.extend(verts) # add vertices to mesh
- e.edges.extend(edges) # add edges to the mesh
-
-
- ob = Object.New('Mesh', 'arc')
- ob.link(e) # link curve data with this object
- ob.loc = tuple(center)
- ob.SizeY = ellipse.ratio
- #ob.RotZ = radians(delta)
- ob.RotX = radians(180)
-
-
- transform(ellipse.extrusion, ob)
- ob.RotZ = radians(delta)
-
- return ob
-drawEllipses.draw = drawEllipse
-drawBlocks = Drawer(True)
-def drawBlock(insert, handle, settings):
- """recursivly draw block objects.
-
- Blocks are made of three objects:
- the block_record in the tables section
- the block in the blocks section
- the insert object in the entities section
-
- block_records give the insert units, blocks provide the objects drawn in the
- block, and the insert object gives the location/scale/rotation of the block
- instances. To draw a block you must first get a group with all the
- blocks entities drawn in it, then scale the entities to match the world
- units, then dupligroup that data to an object matching each insert object."""
- if settings.blocks:
- # get our block group
- block = settings.blocks(insert.block)
-
- # Now Create an object
- ob = Object.New('Mesh', insert.block)
- ob.link(handle) # Give the object a handle
- ob.DupGroup = block
- ob.enableDupGroup = True
- else:
- ob = Object.New('Mesh')
-
- ob.loc = tuple(insert.loc)
- transform(insert.extrusion, ob)
- ob.RotZ += radians(insert.rotation)
- ob.size = tuple(insert.scale)
-
- return ob
-drawBlocks.draw = drawBlock
-
-
-drawFaces = Drawer()
-def drawFace(face, curves=False):
- """Do all the specific things needed to import 3d faces into Blender."""
- # Generate the geometery
- points = face.points
- if len(face.points) > 3:
- faces = [[0, 1, 2, 3]]
- else:
- faces = [[0, 1, 2]]
-
- me = Mesh.New('line') # create a new mesh
-
- me.verts.extend(points) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
-
- # Now Create an object
- ob = Object.New('Mesh', '3dface') # link mesh to an object
- ob.link(me)
-
- return ob
-drawFaces.draw = drawFace
# Here are some alternate drawing functions for creating curve geometery.
def drawCurveCircle(circle):
@@ -994,50 +2260,5 @@ def drawCurveArc(arc):
return ob
-type_map = {
- 'line':drawLines,
- 'lwpolyline':drawLWpolylines,
- 'polyline':drawPolylines,
- 'text':drawTexts,
- 'mtext':drawMtexts,
- 'circle':drawCircles,
- 'arc':drawArcs,
- 'ellipse':drawEllipses,
- 'insert':drawBlocks,
- '3dface':drawFaces
-}
-
-
if __name__ == "__main__":
Window.FileSelector(main, 'Import a DXF file', '*.dxf')
-
-
-"""
-# For testing compatibility
-if 1:
- # DEBUG ONLY
- TIME= Blender.sys.time()
- import os
- print 'Searching for files'
- os.system('find /metavr/ -iname "*.dxf" > /tmp/tempdxf_list')
- print '...Done'
- file= open('/tmp/tempdxf_list', 'r')
- lines= file.readlines()
- file.close()
-
- def between(v,a,b):
- if v <= max(a,b) and v >= min(a,b):
- return True
- return False
-
- for i, _file in enumerate(lines):
- if between(i, 50,60):
- _file= _file[:-1]
- print 'Importing', _file, '\nNUMBER', i, 'of', len(lines)
- _file_name= _file.split('/')[-1].split('\\')[-1]
- newScn= Scene.New(_file_name)
- newScn.makeCurrent()
- main(_file)
-
- print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
-""" \ No newline at end of file