Skip to content
Snippets Groups Projects
Commit 1dd571ef authored by Remigiusz Fiedler's avatar Remigiusz Fiedler
Browse files

DXF-exporter script moved from addons_contrib to official addons folder

parent 891ce020
No related branches found
No related tags found
No related merge requests found
Showing
with 2674 additions and 0 deletions
# ***** 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 3 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, see <http://www.gnu.org/licenses/>.
# All rights reserved.
# ***** GPL LICENSE BLOCK *****
bl_info = {
"name": "Export Autocad DXF Format (.dxf)",
"author": "Remigiusz Fiedler (AKA migius), Vaclav Klecanda",
"version": (2, 1, 3),
"blender": (2, 6, 3),
"location": "File > Export > Autodesk (.dxf)",
"description": "The script exports Blender geometry to DXF format r12 version.",
"warning": "Under construction! Visit Wiki for details.",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/DXF_Exporter",
"tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=28469",
"category": "Import-Export"
}
import bpy
from .operator import DXFExporter
def menu_func(self, context):
self.layout.operator(DXFExporter.bl_idname, text="Autocad (.dxf)")
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_export.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_export.remove(menu_func)
if __name__ == "__main__":
register()
""" NOTE:
This stuff was in original code but it seems it will be no longer needed.
NOT USED now.
"""
#-----------------------------------------------------
def mesh_drawBlender(vertList, edgeList, faceList, name="dxfMesh", flatten=False, AT_CUR=True, link=True):
#print 'deb:mesh_drawBlender started XXXXXXXXXXXXXXXXXX' #---------
ob = Object.New("Mesh",name)
me = Mesh.New(name)
#print 'deb: vertList=\n', vertList #---------
#print 'deb: edgeList=\n', edgeList #---------
#print 'deb: faceList=\n', faceList #---------
me.verts.extend(vertList)
if edgeList: me.edges.extend(edgeList)
if faceList: me.faces.extend(faceList)
if flatten:
for v in me.verts: v.co.z = 0.0
ob.link(me)
if link:
sce = Scene.getCurrent()
sce.objects.link(ob)
#me.triangleToQuad()
if AT_CUR:
cur_loc = Window.GetCursorPos()
ob.setLocation(cur_loc)
Blender.Redraw()
#return ob
#-----------------------------------------------------
def curve_drawBlender(vertList, org_point=[0.0,0.0,0.0], closed=0, name="dxfCurve", flatten=False, AT_CUR=True, link=True):
#print 'deb:curve_drawBlender started XXXXXXXXXXXXXXXXXX' #---------
ob = Object.New("Curve",name)
cu = Curve.New(name)
#print 'deb: vertList=\n', vertList #---------
curve = cu.appendNurb(BezTriple.New(vertList[0][0]))
for p in vertList[1:]:
curve.append(BezTriple.New(p[0]))
for point in curve:
#point.handleTypes = [VECT, VECT]
point.handleTypes = [FREE, FREE]
point.radius = 1.0
curve.flagU = closed # 0 sets the curve not cyclic=open
cu.setResolu(6)
cu.update() #important for handles calculation
if flatten:
for v in cu.verts: v.co.z = 0.0
ob.link(cu)
if link:
sce = Scene.getCurrent()
sce.objects.link(ob)
#me.triangleToQuad()
if AT_CUR:
cur_loc = Window.GetCursorPos()
ob.setLocation(cur_loc)
elif org_point:
cur_loc=org_point
ob.setLocation(cur_loc)
Blender.Redraw()
#return ob
#-----------------------------------------------------
def drawClipBox(clip_box):
"""debug tool: draws Clipping-Box of a Camera View
"""
min_X1, max_X1, min_Y1, max_Y1,\
min_X2, max_X2, min_Y2, max_Y2,\
min_Z, max_Z = clip_box
verts = []
verts.append([min_X1, min_Y1, min_Z])
verts.append([max_X1, min_Y1, min_Z])
verts.append([max_X1, max_Y1, min_Z])
verts.append([min_X1, max_Y1, min_Z])
verts.append([min_X2, min_Y2, max_Z])
verts.append([max_X2, min_Y2, max_Z])
verts.append([max_X2, max_Y2, max_Z])
verts.append([min_X2, max_Y2, max_Z])
faces = [[0,1,2,3],[4,5,6,7]]
newmesh = Mesh.New()
newmesh.verts.extend(verts)
newmesh.faces.extend(faces)
plan = Object.New('Mesh','clip_box')
plan.link(newmesh)
sce = Scene.GetCurrent()
sce.objects.link(plan)
plan.setMatrix(sce.objects.camera.matrix)
import os
import mathutils
DEBUG = os.environ.get('BLENDER_DEBUG', False) #activates debug mode
if DEBUG:
import sys
sys.path.append(os.environ['PYDEV_DEBUG_PATH'])
import pydevd
from .model.migiusModel import MigiusDXFLibDrawing
SUPPORTED_TYPES = ('MESH')#,'CURVE','EMPTY','TEXT','CAMERA','LAMP')
def exportDXF(context, filePath, settings):
"""
Main entry point into export facility.
"""
print("----------\nExporting to {}".format(filePath))
import time
time1 = time.clock()
if settings['verbose']:
print("Generating Object list for export... (Root parents only)")
scene = context.scene
if settings['onlySelected'] is True:
objects = (ob for ob in scene.objects if ob.is_visible(scene) and ob.select and ob.type in SUPPORTED_TYPES)
else:
objects = (ob for ob in scene.objects if ob.is_visible(scene) and ob.type in SUPPORTED_TYPES)
if DEBUG: pydevd.settrace()
mw = get_view_projection_matrix(context, settings)
try:
# add Entities --------------------
#todo: fixme: seems to be the reason for missing BLOCK-export
#if APPLY_MODIFIERS: tmp_me = Mesh.New('tmp')
#else: tmp_me = None
drawing = MigiusDXFLibDrawing()
exported = 0
for o in objects:
if _exportItem(context, o, mw, drawing, settings):
exported +=1
if not drawing.isEmpty():
# NOTE: Only orthographic projection used now.
# if PERSPECTIVE: # generate view border - passepartout
# from .primitive_exporters.viewborder_exporter import ViewBorderDXFExporter
# e = ViewBorderDXFExporter(settings)
# e.export(drawing, ob, mx, mw)
drawing.convert(filePath)
duration = time.clock() - time1
print('%s objects exported in %.2f seconds. -----DONE-----' %\
(exported, duration))
except IOError:
print('DXF Exporter: Write Error: ', filePath)
except Exception as e:
print('Nothing exported. Error: %s' % str(e))
print("Finished")
#-------------------------------------------------
def getCommons(ob, settings):
"""set up common attributes for output style:
color=None
extrusion=None
layer='0',
lineType=None
lineTypeScale=None
lineWeight=None
thickness=None
parent=None
"""
BYBLOCK=0 #DXF-attribute: assign property to BLOCK defaults
BYLAYER=None #256 #DXF-attribute: assign property to LAYER defaults
LAYERNAME_DEF='' #default layer name
LAYERCOLOR_DEF=7 #default layer color index
LAYERLTYPE_DEF=0 #'CONTINUOUS' - default layer lineType
ENTITYLAYER_DEF=LAYERNAME_DEF #default entity color index
ENTITYCOLOR_DEF=BYLAYER #default entity color index
ENTITYLTYPE_DEF=BYLAYER #default entity lineType
layers = ob.layers #gives a list e.g.[1,5,19]
if layers: ob_layer_nr = layers[0]
if DEBUG: print('ob_layer_nr=', ob_layer_nr) #--------------
materials = ob.material_slots
if materials:
ob_material = materials[0]
ob_mat_color = ob_material.material.diffuse_color
else: ob_mat_color, ob_material = None, None
if DEBUG:
print('ob_mat_color, ob_material=', ob_mat_color, ob_material) #--------------
data_materials = ob.material_slots
if data_materials:
data_material = data_materials[0]
data_mat_color = data_material.material.diffuse_color
else: data_mat_color, data_material = None, None
if DEBUG:
print('data_mat_color, data_material=', data_mat_color, data_material) #--------------
entitylayer = ENTITYLAYER_DEF
c = settings['entitylayer_from']
#["default_LAYER","obj.name","obj.layer","obj.material","obj.data.name","obj.data.material","..vertexgroup","..group","..map_table"]
if c=="default_LAYER":
entitylayer = LAYERNAME_DEF
elif c=="obj.layer" and ob_layer_nr:
entitylayer = 'LAYER'+ str(ob_layer_nr)
elif c=="obj.material" and ob_material:
entitylayer = ob_material.name
elif c=="obj.name":
entitylayer = ob.name
elif c=="obj.data.material" and ob_material:
entitylayer = data_material.name
elif c=="obj.data.name":
entitylayer = ob.data.name
entitycolor = ENTITYCOLOR_DEF
cfrom = settings['entitycolor_from']
if cfrom=="default_COLOR":
entitycolor = LAYERCOLOR_DEF
elif cfrom=="BYLAYER":
entitycolor = BYLAYER
elif cfrom=="BYBLOCK":
entitycolor = BYBLOCK
elif cfrom=="obj.layer" and ob_layer_nr:
entitycolor = ob_layer_nr
elif cfrom=="obj.color" and ob.color:
entitycolor = ob.color
elif cfrom=="obj.material" and ob_mat_color:
entitycolor = ob_mat_color
elif cfrom=="obj.data.material" and data_mat_color:
entitycolor = data_mat_color
entityltype = ENTITYLTYPE_DEF
etype = settings['entityltype_from']
if etype=="default_LTYPE":
entityltype = LAYERLTYPE_DEF
elif etype=="BYLAYER":
entityltype = BYLAYER
elif etype=="BYBLOCK":
entityltype = BYBLOCK
elif etype:
entityltype = etype
return entitylayer, entitycolor, entityltype
def getCameraMatrix(cam):
raise NotImplementedError()
# camProps = cam.data
# mc0 = act_camera.matrix.copy()
# #print 'deb: camera.Matrix=\n', mc0 #------------------
# camera = Camera.Get(act_camera.getData(name_only=True))
# #print 'deb: camera=', dir(camera) #------------------
# if camera.type=='persp': PERSPECTIVE = 1
# elif camera.type=='ortho': PERSPECTIVE = 0
# # mcp is matrix.camera.perspective
# clip_box, mcp = getClipBox(camera)
## if PERSPECTIVE:
## # get border
## # lens = camera.lens
## min_X1, max_X1, min_Y1, max_Y1,\
## min_X2, max_X2, min_Y2, max_Y2,\
## min_Z, max_Z = clip_box
## verts = []
## verts.append([min_X1, min_Y1, min_Z])
## verts.append([max_X1, min_Y1, min_Z])
## verts.append([max_X1, max_Y1, min_Z])
## verts.append([min_X1, max_Y1, min_Z])
## border=verts
# mw = mc0.copy().invert()
# #ViewVector = mathutils.Vector(Window.GetViewVector())
# #print 'deb: ViewVector=\n', ViewVector #------------------
# #TODO: what is Window.GetViewOffset() for?
# #print 'deb: Window.GetViewOffset():', Window.GetViewOffset() #---------
# #Window.SetViewOffset([0,0,0])
# mw0 = Window.GetViewMatrix()
# #print 'deb: mwOrtho =\n', mw0 #---------
# mwp = Window.GetPerspMatrix() #TODO: how to get it working?
# #print 'deb: mwPersp =\n', mwp #---------
# mw = mw0.copy()
projectionMapping = {
'TOP' : mathutils.Vector((0, 0, -1)),
'BOTTOM' : mathutils.Vector((0, 0, 1)),
'LEFT' : mathutils.Vector((0, 1, 0)),
'RIGHT' : mathutils.Vector((0, -1, 0)),
'FRONT' : mathutils.Vector((-1, 0, 0)),
'REAR' : mathutils.Vector((1, 0, 0))
}
#-----------------------------------------------------
def get_view_projection_matrix(context, settings):
"""
Returns view projection matrix.
Projection matrix is either identity if 3d export is selected or
camera projection if a camera or view is selected.
Currently only orthographic projection is used. (Subject to discussion).
"""
cam = settings['projectionThrough']
if cam == None:
mw = mathutils.Matrix()
mw.identity()
elif cam in projectionMapping.keys():
projection = mathutils.Matrix.OrthoProjection(projectionMapping[cam], 4)
mw = projection
else: # get camera with given name
c = context.scene.objects[cam]
mw = getCameraMatrix(c)
return mw
def _exportItem(ctx, o, mw, drawing, settings):
"""
Export one item from export list.
mw - modelview
"""
if settings['verbose']: print('Exporting %s' % o)
#mx = ob.matrix.copy()
#print 'deb: ob =', ob #---------
#print 'deb: ob.type =', ob.type #---------
#print 'deb: mx =\n', mx #---------
#print 'deb: mw0 =\n', mw0 #---------
#mx_n is trans-matrix for normal_vectors for front-side faces
mx = o.matrix_world
viewRotation = mw.to_euler().to_matrix()
mx_n = o.rotation_euler.to_matrix() * viewRotation
mx *= mw
#mx_inv = mx.copy().invert()
elayer, ecolor, eltype = getCommons(o, settings)
if settings['verbose']:
print('elayer=%s, ecolor=%s, eltype=%s' % (elayer, ecolor, eltype))
#TODO: use o.boundBox for drawing extends ??
if elayer != None and not drawing.containsLayer(elayer):
if ecolor!=None: tempcolor = ecolor
else: tempcolor = settings['layercolor_def']
drawing.addLayer(elayer, tempcolor)
if DEBUG: pydevd.settrace()
if (o.type == 'MESH') and settings['mesh_as']:
from .primitive_exporters.mesh_exporter import MeshDXFExporter
e = MeshDXFExporter(settings)
elif (o.type == 'CURVE') and settings['curve_as']:
from .primitive_exporters.curve_exporter import CurveDXFExporter
e = CurveDXFExporter(settings)
elif (o.type == 'EMPTY') and settings['empty_as']:
from .primitive_exporters.empty_exporter import EmptyDXFExporter
e = EmptyDXFExporter(settings)
elif (o.type == 'TEXT') and settings['text_as']:
from .primitive_exporters.text_exporter import TextDXFExporter
e = TextDXFExporter(settings)
elif (o.type == 'CAMERA') and settings['camera_as']:
from .primitive_exporters.camera_exporter import CameraDXFExporter
e = CameraDXFExporter(settings)
elif (o.type == 'LAMP') and settings['lamp_as']:
from .primitive_exporters.lamp_exporter import LampDXFExporter
e = LampDXFExporter(settings)
return e.export(ctx, drawing, o, mx, mx_n, color=ecolor, layer=elayer, lineType=eltype)
This diff is collapsed.
"""
Created on Sep 2, 2011
@author: vencax
"""
from .model import DxfDrawing
try:
from . import dxfLibrary as DXF
#reload(DXF)
#reload(dxfLibrary)
#from dxfLibrary import *
except Exception:
raise Exception("No dxfLibrary.py module in Blender script folder found!")
#------------------------------------------------------
#def col2RGB(color):
# return [int(floor(255*color[0])),
# int(floor(255*color[1])),
# int(floor(255*color[2]))]
#
#global dxfColors
#dxfColors=None
#
##------------------------------------------------------
#def col2DXF(rgbcolor):
# global dxfColors
# if dxfColors is None:
# from dxfColorMap import color_map
# dxfColors = [(tuple(color),idx) for idx, color in color_map.iteritems()]
# dxfColors.sort()
# entry = (tuple(rgbcolor), -1)
# dxfColors.append(entry)
# dxfColors.sort()
# i = dxfColors.index(entry)
# dxfColors.pop(i)
# return dxfColors[i-1][1]
"""
v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\
28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,58,59,60,61,62,63,64,91,92,93,94,96,\
123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,\
151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,\
171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,\
191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,\
211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,\
231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254]
invalid = ''.join([chr(i) for i in v])
del v, i
"""
#TODO: validDXFr14 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.'
validDXFr12 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'
NAMELENGTH_MAX = 80 #max_obnamelength in DXF, (limited to 256? )
#------------------------------------------------------
def cleanName(name, valid):
validname = ''
for ch in name:
if ch not in valid: ch = '_'
validname += ch
return validname
#------------------------------------------------------
def validDXFr12name(str_name):
dxfname = str(str_name)
dxfname = dxfname[:NAMELENGTH_MAX].upper()
dxfname = cleanName(dxfname, validDXFr12)
return dxfname
class MigiusDXFLibDrawing(DxfDrawing):
""" Drawing that can convert itself into MIGIUS DXFLib stuff objects """
def convert(self, file, **kwargs):
drawing = self._write()
for type, ents in self._entities.items():
self._processEntityArray(drawing, type, ents)
for v in self._views:
drawing.views.append(DXF.View(**v))
for v in self._vports:
drawing.vports.append(DXF.VPort(**v))
# for l in self._layers:
drawing.saveas(file)
def _write(self):
# init Drawing ---------------------
d=DXF.Drawing()
# add Tables -----------------
# initialized automatic: d.blocks.append(b) #section BLOCKS
# initialized automatic: d.styles.append(DXF.Style()) #table STYLE
#table LTYPE ---------------
#d.linetypes.append(DXF.LineType(name='CONTINUOUS',description='--------',elements=[0.0]))
d.linetypes.append(DXF.LineType(name='DOT',description='. . . . . . .',elements=[0.25, 0.0, -0.25]))
d.linetypes.append(DXF.LineType(name='DASHED',description='__ __ __ __ __',elements=[0.8, 0.5, -0.3]))
d.linetypes.append(DXF.LineType(name='DASHDOT',description='__ . __ . __ .',elements=[1.0, 0.5, -0.25, 0.0, -0.25]))
d.linetypes.append(DXF.LineType(name='DIVIDE',description='____ . . ____ . . ',elements=[1.25, 0.5, -0.25, 0.0, -0.25, 0.0, -0.25]))
d.linetypes.append(DXF.LineType(name='BORDER',description='__ __ . __ __ . ',elements=[1.75, 0.5, -0.25, 0.5, -0.25, 0.0, -0.25]))
d.linetypes.append(DXF.LineType(name='HIDDEN',description='__ __ __ __ __',elements=[0.4, 0.25, -0.25]))
d.linetypes.append(DXF.LineType(name='CENTER',description='____ _ ____ _ __',elements=[2.0, 1.25, -0.25, 0.25, -0.25]))
#d.vports.append(DXF.VPort('*ACTIVE'))
d.vports.append(DXF.VPort('*ACTIVE',center=(-5.0,1.0),height=10.0))
#d.vports.append(DXF.VPort('*ACTIVE',leftBottom=(-100.0,-60.0),rightTop=(100.0,60.0)))
#d.views.append(DXF.View('Normal')) #table view
d.views.append(DXF.ViewByWindow('BF_TOPVIEW',leftBottom=(-100,-60),rightTop=(100,60))) #idem
return d
def _processEntityArray(self, drawing, type, ents):
if type=='Point':
for e in ents:
drawing.append(DXF.Point(**e))
elif type=='Line':
for e in ents:
drawing.append(DXF.Line(**e))
elif type=='PolyLine':
for e in ents:
drawing.append(DXF.PolyLine(**e))
elif type=='Face':
for e in ents:
drawing.append(DXF.Face(**e))
class DxfDrawing(object):
"""
Represents intermediate model of DXF drawing. It is useful in iterating
through exported object and for easy change the DXF handling library.
"""
def __init__(self):
self._entities = {}
self._layers = {}
self._views = []
self._vports = []
self._blocks = []
def isEmpty(self):
return len(self._entities) == 0
def addEntity(self, type, **kwargs):
if type not in self._entities:
self._entities[type] = []
self._entities[type].append(kwargs)
def addLayer(self, name, color):
self._layers[name] = color
def containsLayer(self, name):
return name in self._layers
def addBlock(self, block):
self._blocks.append(block)
def containsBlock(self, blockname):
return blockname in self._blocks
def convert(self, **kwargs):
""" Converts this drawing into DXF representation object """
raise NotImplementedError()
import bpy
from bpy.props import StringProperty, EnumProperty, BoolProperty
class DXFExporter(bpy.types.Operator):
"""
Export to the Autocad model format (.dxf)
"""
bl_idname = "export.dxf"
bl_label = "Export DXF"
filepath = StringProperty(subtype='FILE_PATH')
entitylayer_from_items = (
('default_LAYER', 'Default Layer', ''),
('obj.name', 'Object name', ''),
('obj.layer', 'Object layer', ''),
('obj.material', 'Object material', ''),
('obj.data.name', 'Object\' data name', ''),
# ('obj.data.material', 'Material of data', ''),
('..vertexgroup', 'Vertex Group', ''),
('..group', 'Group', ''),
('..map_table', 'Table', '')
)
layerColorFromItems = (
('default_COLOR', 'Vertex Group', ''),
('BYLAYER', 'BYLAYER', ''),
('BYBLOCK', 'BYBLOCK', ''),
('obj.layer', 'Object Layer', ''),
('obj.color', 'Object Color', ''),
('obj.material', 'Object material', ''),
# I don'd know ?
# ('obj.data.material', 'Vertex Group', ''),
# ('..map_table', 'Vertex Group', ''),
)
layerNameFromItems = (
('LAYERNAME_DEF', 'Default Name', ''),
('drawing_name', 'From Drawing name', ''),
('scene_name', 'From scene name', '')
)
exportModeItems = (
('ALL', 'All Objects', ''),
('SELECTION', 'Selected Objects', ''),
)
# spaceItems = (
# ('1', 'Paper-Space', ''),
# ('2', 'Model-Space', '')
# )
entityltype_fromItems = (
('default_LTYPE', 'default_LTYPE', ''),
('BYLAYER', 'BYLAYER', ''),
('BYBLOCK', 'BYBLOCK', ''),
('CONTINUOUS', 'CONTINUOUS', ''),
('DOT', 'DOT', ''),
('DASHED', 'DASHED', ''),
('DASHDOT', 'DASHDOT', ''),
('BORDER', 'BORDER', ''),
('HIDDEN', 'HIDDEN', '')
)
material_toItems = (
('NO', 'Do not export', ''),
('COLOR', 'COLOR', ''),
('LAYER', 'LAYER', ''),
('..LINESTYLE', '..LINESTYLE', ''),
('..BLOCK', '..BLOCK', ''),
('..XDATA', '..XDATA', ''),
('..INI-File', '..INI-File', '')
)
projectionItems=(
('NO', 'No projection', 'Export 3D scene without any 2D projection'),
('TOP', 'TOP view', 'Use TOP view for projection'),
('BOTTOM', 'BOTTOM view', 'Use BOTTOM view for projection'),
('LEFT', 'LEFT view', 'Use LEFT view for projection'),
('RIGHT', 'RIGHT view', 'Use RIGHT view for projection'),
('FRONT', 'FRONT view', 'Use FRONT view for projection'),
('REAR', 'REAR view', 'Use REAR view for projection')
)
mesh_asItems = (
('NO', 'Do not export', ''),
('3DFACEs', '3DFACEs', ''),
('POLYFACE', 'POLYFACE', ''),
('POLYLINE', 'POLYLINE', ''),
('LINEs', 'LINEs', 'export Mesh as multiple LINEs'),
('POINTs', 'POINTs', 'Export Mesh as multiple POINTs')
)
# curve_asItems = (
# ('NO', 'Do not export', ''),
# ('LINEs', 'LINEs', ''),
# ('POLYLINE', 'POLYLINE', ''),
# ('..LWPOLYLINE r14', '..LWPOLYLINE r14', ''),
# ('..SPLINE r14', '..SPLINE r14', ''),
# ('POINTs', 'POINTs', '')
# )
# surface_asItems = (
# ('NO', 'Do not export', ''),
# ('..3DFACEs', '..3DFACEs', ''),
# ('..POLYFACE', '..POLYFACE', ''),
# ('..POINTs', '..POINTs', ''),
# ('..NURBS', '..NURBS', '')
# )
# meta_asItems = (
# ('NO', 'Do not export', ''),
# ('..3DFACEs', '..3DFACEs', ''),
# ('..POLYFACE', '..POLYFACE', ''),
# ('..3DSOLID', '..3DSOLID', '')
# )
# text_asItems = (
# ('NO', 'Do not export', ''),
# ('TEXT', 'TEXT', ''),
# ('..MTEXT', '..MTEXT', ''),
# ('..ATTRIBUT', '..ATTRIBUT', '')
# )
# empty_asItems = (
# ('NO', 'Do not export', ''),
# ('POINT', 'POINT', ''),
# ('..INSERT', '..INSERT', ''),
# ('..XREF', '..XREF', '')
# )
# group_asItems = (
# ('NO', 'Do not export', ''),
# ('..GROUP', '..GROUP', ''),
# ('..BLOCK', '..BLOCK', ''),
# ('..ungroup', '..ungroup', '')
# )
## parent_asItems = ['..BLOCK','..ungroup'] # ???
# proxy_asItems = (
# ('NO', 'Do not export', ''),
# ('..BLOCK','..BLOCK', ''),
# ('..XREF', '..XREF', ''),
# ('..ungroup', '..ungroup', ''),
# ('..POINT', '..POINT', '')
# )
# camera_asItems = (
# ('NO', 'Do not export', ''),
# ('..BLOCK', '..BLOCK', ''),
# ('..A_CAMERA', '..A_CAMERA', ''),
# ('VPORT', 'VPORT', ''),
# ('VIEW', 'VIEW', ''),
# ('POINT', 'POINT', '')
# )
# lamp_asItems = (
# ('NO', 'Do not export', ''),
# ('..BLOCK', '..BLOCK', ''),
# ('..A_LAMP', '..A_LAMP', ''),
# ('POINT', 'POINT', '')
# )
# --------- CONTROL PROPERTIES --------------------------------------------
projectionThrough = EnumProperty(name="Projection", default="NO",
description="Select camera for use to 2D projection",
items=projectionItems)
onlySelected = BoolProperty(name="Only selected", default=True,
description="What object will be exported? Only selected / all objects.")
apply_modifiers = BoolProperty(name="Apply modifiers", default=True,
description="Shall be modifiers applied during export?")
# GUI_B -----------------------------------------
mesh_as = EnumProperty( name="Export Mesh As", default='3DFACEs',
description="Select representation of a mesh",
items=mesh_asItems)
# curve_as = EnumProperty( name="Export Curve As:", default='NO',
# description="Select representation of a curve",
# items=curve_asItems)
# surface_as = EnumProperty( name="Export Surface As:", default='NO',
# description="Select representation of a surface",
# items=surface_asItems)
# meta_as = EnumProperty( name="Export meta As:", default='NO',
# description="Select representation of a meta",
# items=meta_asItems)
# text_as = EnumProperty( name="Export text As:", default='NO',
# description="Select representation of a text",
# items=text_asItems)
# empty_as = EnumProperty( name="Export empty As:", default='NO',
# description="Select representation of a empty",
# items=empty_asItems)
# group_as = EnumProperty( name="Export group As:", default='NO',
# description="Select representation of a group",
# items=group_asItems)
## parent_as = EnumProperty( name="Export parent As:", default='NO',
## description="Select representation of a parent",
## items=parent_asItems)
# proxy_as = EnumProperty( name="Export proxy As:", default='NO',
# description="Select representation of a proxy",
# items=proxy_asItems)
# camera_as = EnumProperty( name="Export camera As:", default='NO',
# description="Select representation of a camera",
# items=camera_asItems)
# lamp_as = EnumProperty( name="Export lamp As:", default='NO',
# description="Select representation of a lamp",
# items=lamp_asItems)
# ----------------------------------------------------------
entitylayer_from = EnumProperty(name="Entity Layer", default="obj.data.name",
description="Entity LAYER assigned to?",
items=entitylayer_from_items)
entitycolor_from = EnumProperty(name="Entity Color", default="default_COLOR",
description="Entity COLOR assigned to?",
items=layerColorFromItems)
entityltype_from = EnumProperty(name="Entity Linetype", default="CONTINUOUS",
description="Entity LINETYPE assigned to?",
items=entityltype_fromItems)
layerName_from = EnumProperty(name="Layer Name", default="LAYERNAME_DEF",
description="From where will layer name be taken?",
items=layerNameFromItems)
# GUI_A -----------------------------------------
# layFrozen_on = BoolProperty(name="LAYER.frozen status", description="(*todo) Support LAYER.frozen status on/off", default=False)
# materialFilter_on = BoolProperty(name="Material filtering", description="(*todo) Material filtering on/off", default=False)
# colorFilter_on = BoolProperty(name="Color filtering", description="(*todo) Color filtering on/off", default=False)
# groupFilter_on = BoolProperty(name="Group filtering", description="(*todo) Group filtering on/off", default=False)
# objectFilter_on = BoolProperty(name="Object filtering", description="(*todo) Object filtering on/off", default=False)
# paper_space_on = EnumProperty(name="Space of export:", default="2",
# description="Select space that will be taken for export.",
# items=spaceItems)
# material_to = EnumProperty(name="Material assigned to?:", default="NO",
# description="Material assigned to?.",
# items=material_toItems)
# prefix_def = StringProperty(name="Prefix for LAYERs", default="DX_",
# description='Type Prefix for LAYERs')
# layername_def = StringProperty(name="default LAYER name", default="DEF_LAY",
# description='Type default LAYER name')
# layercolor_def = StringProperty(name="Default layer color:", default="1",
# description='Set default COLOR. (0=BYBLOCK,256=BYLAYER)')
# layerltype_def = StringProperty(name="Default LINETYPE", default="DEF_LAY_TYPE",
# description='Set default LINETYPE')
verbose = BoolProperty(name="Verbose", default=False,
description="Run the exporter in debug mode. Check the console for output.")
def execute(self, context):
filePath = bpy.path.ensure_ext(self.filepath, ".dxf")
config = {
'projectionThrough' : self._checkNO(self.projectionThrough),
'onlySelected' : self.onlySelected,
'apply_modifiers' : self.apply_modifiers,
# GUI B
'mesh_as' : self._checkNO(self.mesh_as),
# 'curve_as' : self._checkNO(self.curve_as),
# 'surface_as' : self._checkNO(self.surface_as),
# 'meta_as' : self._checkNO(self.meta_as),
# 'text_as' : self._checkNO(self.text_as),
# 'empty_as' : self._checkNO(self.empty_as),
# 'group_as' : self._checkNO(self.group_as),
# 'proxy_as' : self._checkNO(self.proxy_as),
# 'camera_as' : self._checkNO(self.camera_as),
# 'lamp_as' : self._checkNO(self.lamp_as),
'entitylayer_from' : self.entitylayer_from,
'entitycolor_from' : self.entitycolor_from,
'entityltype_from' : self.entityltype_from,
'layerName_from' : self.layerName_from,
# NOT USED
# 'layFrozen_on' : self.layFrozen_on,
# 'materialFilter_on' : self.materialFilter_on,
# 'colorFilter_on' : self.colorFilter_on,
# 'groupFilter_on' : self.groupFilter_on,
# 'objectFilter_on' : self.objectFilter_on,
# 'paper_space_on' : self.paper_space_on,
# 'layercolor_def' : self.layercolor_def,
# 'material_to' : self.material_to,
'verbose' : self.verbose
}
from .export_dxf import exportDXF
exportDXF(context, filePath, config)
return {'FINISHED'}
def _checkNO(self, val):
if val == 'NO': return None
else: return val
def invoke(self, context, event):
if not self.filepath:
self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".dxf")
WindowManager = context.window_manager
WindowManager.fileselect_add(self)
return {'RUNNING_MODAL'}
"""
This package contains actual primitive exporter classes.
They are imported and instantiated according object type
that is being exported from export_dxf.py in ../
NOTE: Only MESH exporter has been ported since it is imho
mostly used. I am not specialist on Autocad so I cannot
guest how many time the other primitive are used. That's
why they are left unported.
"""
import mathutils
class BasePrimitiveDXFExporter(object):
INSTANCES = False
PROJECTION = False
HIDDEN_LINES = False
def __init__(self, settings):
self._settings = settings
def projected_co(self, verts, matrix):
""" converts coordinates of points from OCS to WCS->ScreenCS
needs matrix: a projection matrix
needs verts: a list of vectors[x,y,z]
returns a list of [x,y,z]
"""
#print 'deb:projected_co() verts=', verts #---------
temp_verts = [matrix*mathutils.Vector(v) for v in verts]
#print 'deb:projected_co() temp_verts=', temp_verts #---------
# if GUI_A['Z_force_on'].val: locZ = GUI_A['Z_elev'].val
# else:locZ = 0.0
locZ = 0.0
if self.PROJECTION:
if self.PERSPECTIVE:
clipStart = 10.0
for v in temp_verts:
coef = - clipStart / v[2]
v[0] *= coef
v[1] *= coef
v[2] = locZ
for v in temp_verts:
v[2] = locZ
temp_verts = [v[:3] for v in temp_verts]
#print 'deb:projected_co() out_verts=', temp_verts #---------
return temp_verts
def isLeftHand(self, matrix):
#Is the matrix a left-hand-system, or not?
ma = matrix.to_euler().to_matrix()
crossXY = self.M_CrossVecs(ma[0], ma[1])
check = self.M_DotVecs(ma[2], crossXY)
if check < 0.00001: return 1
return 0
#-----------------------------------------------------
def hidden_status(self, faces, mx, mx_n):
# sort out back-faces = with normals pointed away from camera
#print 'HIDDEN_LINES: caution! not full implemented yet'
front_faces = []
front_edges = []
for f in faces:
#print 'deb: face=', f #---------
#print 'deb: dir(face)=', dir(f) #---------
# get its normal-vector in localCS
vec_normal = f.no.copy()
#print 'deb: vec_normal=', vec_normal #------------------
# must be transfered to camera/view-CS
vec_normal *= mx_n
#vec_normal *= mb.rotationPart()
#print 'deb:2vec_normal=', vec_normal #------------------
#vec_normal *= mw0.rotationPart()
#print 'deb:3vec_normal=', vec_normal, '\n' #------------------
frontFace = False
if not self.PERSPECTIVE: #for ortho mode ----------
# normal must point the Z direction-hemisphere
if vec_normal[2] > 0.00001:
frontFace = True
else:
v = f.verts[0]
vert = mathutils.Vector(v.co) * mx
if mathutils.DotVecs(vert, vec_normal) < 0.00001:
frontFace = True
if frontFace:
front_faces.append(f.index)
for key in f.edge_keys:
#this test can be done faster with set()
if key not in front_edges:
front_edges.append(key)
#print 'deb: amount of visible faces=', len(front_faces) #---------
#print 'deb: visible faces=', front_faces #---------
#print 'deb: amount of visible edges=', len(front_edges) #---------
#print 'deb: visible edges=', front_edges #---------
return front_faces, front_edges
#-----------------------------------------------------
def toGlobalOrigin(self, points):
"""relocates points to the new location
needs a list of points [x,y,z]
"""
# if GUI_A['g_origin_on'].val:
# for p in points:
# p[0] += G_ORIGIN[0]
# p[1] += G_ORIGIN[1]
# p[2] += G_ORIGIN[2]
return points
#---- migration to 2.49-------------------------------------------------
#Draw.PupMenu('DXF exporter: Abort%t|This script version works for Blender up 2.49 only!')
def M_CrossVecs(self, v1,v2):
if 'cross' in dir(mathutils.Vector()):
return v1.cross(v2) #for up2.49
else:
return mathutils.CrossVecs(v1,v2) #for pre2.49
def M_DotVecs(self, v1,v2):
if 'cross' in dir(mathutils.Vector()):
return v1.dot(v2) #for up2.49
else:
return mathutils.DotVecs(v1,v2) #for pre2.49
#-----------------------------------------------------
def getExtrusion(self, matrix):
""" calculates DXF-Extrusion = Arbitrary Xaxis and Zaxis vectors """
AZaxis = matrix[2].copy().resize3D().normalize() # = ArbitraryZvector
Extrusion = [AZaxis[0],AZaxis[1],AZaxis[2]]
if AZaxis[2]==1.0:
Extrusion = None
AXaxis = matrix[0].copy().resize3D() # = ArbitraryXvector
else:
threshold = 1.0 / 64.0
if abs(AZaxis[0]) < threshold and abs(AZaxis[1]) < threshold:
# AXaxis is the intersection WorldPlane and ExtrusionPlane
AXaxis = self.M_CrossVecs(WORLDY,AZaxis)
else:
AXaxis = self.M_CrossVecs(WORLDZ,AZaxis)
#print 'deb:\n' #-------------
#print 'deb:getExtrusion() Extrusion=', Extrusion #---------
return Extrusion, AXaxis.normalize()
#-----------------------------------------------------
# def getZRotation(AXaxis, rot_matrix_invert):
# """calculates ZRotation = angle between ArbitraryXvector and obj.matrix.Xaxis
#
# """
# # this works: Xaxis is the obj.matrix-Xaxis vector
# # but not correct for all orientations
# #Xaxis = matrix[0].copy().resize3D() # = ArbitraryXvector
# ##Xaxis.normalize() # = ArbitraryXvector
# #ZRotation = - mathutils.AngleBetweenVecs(Xaxis,AXaxis) #output in radians
#
# # this works for all orientations, maybe a bit faster
# # transform AXaxis into OCS:Object-Coord-System
# #rot_matrix = normalizeMat(matrix.rotationPart())
# #rot_matrix_invert = rot_matrix.invert()
# vec = AXaxis * rot_matrix_invert
# ##vec = AXaxis * matrix.copy().invert()
# ##vec.normalize() # not needed for atan2()
# #print '\ndeb:getExtrusion() vec=', vec #---------
# ZRotation = - atan2(vec[1],vec[0]) #output in radians
#
# #print 'deb:ZRotation() ZRotation=', ZRotation*r2d #---------
# return ZRotation
#
#
# #-----------------------------------------------------
# def getTargetOrientation(mx,Extrusion,AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ):
# """given
# """
# if 1:
# rot_matrix = normalizeMat(mx.to_euler().to_matrix())
# #TODO: workaround for blender negative-matrix.invert()
# # partially done: works only for rotX,rotY==0.0
# if sizeX<0.0: rot_matrix[0] *= -1
# if sizeY<0.0: rot_matrix[1] *= -1
# #if sizeZ<0.0: rot_matrix[2] *= -1
# rot_matrix_invert = rot_matrix.invert()
# else: #TODO: to check, why below rot_matrix_invert is not equal above one
# rot_euler_matrix = euler2matrix(rotX,rotY,rotZ)
# rot_matrix_invert = euler2matrix(-rotX,-rotY,-rotZ)
#
# # OCS_origin is Global_Origin in ObjectCoordSystem
# OCS_origin = mathutils.Vector(WCS_loc) * rot_matrix_invert
# #print 'deb: OCS_origin=', OCS_origin #---------
#
# ZRotation = rotZ
# if Extrusion!=None:
# ZRotation = getZRotation(AXaxis,rot_matrix_invert)
# #Zrotmatrix = mathutils.RotationMatrix(-ZRotation, 3, "Z")
# rs, rc = sin(ZRotation), cos(ZRotation)
# Zrotmatrix = mathutils.Matrix([rc, rs,0.0],[-rs,rc,0.0],[0.0,0.0,1.0])
# #print 'deb: Zrotmatrix=\n', Zrotmatrix #--------------
#
# # ECS_origin is Global_Origin in EntityCoordSystem
# ECS_origin = OCS_origin * Zrotmatrix
# #print 'deb: ECS_origin=', ECS_origin #---------
# #TODO: it doesnt work yet for negative scaled curve-objects!
# return ZRotation,Zrotmatrix,OCS_origin,ECS_origin
from .base_exporter import BasePrimitiveDXFExporter
class CameraDXFExporter(BasePrimitiveDXFExporter):
pass
#-----------------------------------------------------
def exportCamera(ob, mx, mw, **common):
"""converts Camera-Object to desired projection and representation(DXF-Entity type)
"""
location = mathutils.Vector(ob.loc)
[location] = projected_co([location], mx)
[location] = toGlobalOrigin([location])
view_name=validDXFr12name(('CAM_'+ ob.name))
camera = Camera.Get(ob.getData(name_only=True))
#print 'deb: camera=', dir(camera) #------------------
if camera.type=='persp':
mode = 1+2+4+16
# mode flags: 1=persp, 2=frontclip, 4=backclip,16=FrontZ
elif camera.type=='ortho':
mode = 0+2+4+16
leftBottom=(0.0,0.0) # default
rightTop=(1.0,1.0) # default
center=(0.0,0.0) # default
direction = mathutils.Vector(0.0,0.0,1.0) * mx.to_euler().to_matrix() # in W-C-S
direction.normalize()
target=mathutils.Vector(ob.loc) - direction # in W-C-S
#ratio=1.0
width=height= camera.scale # for ortho-camera
lens = camera.lens # for persp-camera
frontClipping = -(camera.clipStart - 1.0)
backClipping = -(camera.clipEnd - 1.0)
entities, vport, view = [], None, None
c = camera_as_list[GUI_A['camera_as'].val]
if c=="POINT": # export as POINT
dxfPOINT = DXF.Point(points=[location],**common)
entities.append(dxfPOINT)
elif c=="VIEW": # export as VIEW
view = DXF.View(name=view_name,
center=center, width=width, height=height,
frontClipping=frontClipping,backClipping=backClipping,
direction=direction,target=target,lens=lens,mode=mode
)
elif c=="VPORT": # export as VPORT
vport = DXF.VPort(name=view_name,
center=center, ratio=1.0, height=height,
frontClipping=frontClipping,backClipping=backClipping,
direction=direction,target=target,lens=lens,mode=mode
)
return entities, vport, view
from .base_exporter import BasePrimitiveDXFExporter
class CurveDXFExporter(BasePrimitiveDXFExporter):
pass
#-----------------------------------------------------
def exportCurve(ob, mx, mw, **common):
"""converts Curve-Object to desired projection and representation(DXF-Entity type)
"""
entities = []
block = None
curve = ob.getData()
#print 'deb: curve=', dir(curve) #---------
# TODO: should be: if curve.users>1 and not (PERSPECTIVE or (PROJECTION and HIDDEN_MODE):
if INSTANCES and curve.users>1 and not PROJECTION:
if curve.name in BLOCKREGISTRY.keys():
insert_name = BLOCKREGISTRY[curve.name]
# write INSERT to entities
entities = exportInsert(ob, mx,insert_name, **common)
else:
# generate geom_output in ObjectCS
imx = mathutils.Matrix().identity()
WCS_loc = [0,0,0] # WCS_loc is object location in WorldCoordSystem
#print 'deb: WCS_loc=', WCS_loc #---------
sizeX = sizeY = sizeZ = 1.0
rotX = rotY = rotZ = 0.0
Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
ZRotation,Zrotmatrix,OCS_origin,ECS_origin = None,None,None,None
AXaxis = imx[0].copy().resize3D() # = ArbitraryXvector
OCS_origin = [0,0,0]
if not PROJECTION:
#Extrusion, ZRotation, Elevation = getExtrusion(mx)
Extrusion, AXaxis = getExtrusion(imx)
# no thickness/width for POLYLINEs converted into Screen-C-S
#print 'deb: curve.ext1=', curve.ext1 #---------
if curve.ext1: Thickness = curve.ext1 * sizeZ
if curve.ext2 and sizeX==sizeY:
Width = curve.ext2 * sizeX
if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE
ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(imx,Extrusion,\
AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
entities = writeCurveEntities(curve, imx,
Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix,
WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ,
**common)
if entities: # if not empty block
# write BLOCK definition and INSERT entity
# BLOCKREGISTRY = dictionary 'blender_name':'dxf_name'.append(me.name)
BLOCKREGISTRY[curve.name]=validDXFr12name(('CU_'+ curve.name))
insert_name = BLOCKREGISTRY[curve.name]
block = DXF.Block(insert_name,flag=0,base=(0,0,0),entities=entities)
# write INSERT as entity
entities = exportInsert(ob, mx, insert_name, **common)
else: # no other instances, so go the standard way
WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
#print 'deb: WCS_loc=', WCS_loc #---------
sizeX = ob.SizeX
sizeY = ob.SizeY
sizeZ = ob.SizeZ
rotX = ob.RotX
rotY = ob.RotY
rotZ = ob.RotZ
#print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
ZRotation,Zrotmatrix,OCS_origin,ECS_origin = None,None,None,None
AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
OCS_origin = [0,0,0]
if not PROJECTION:
#Extrusion, ZRotation, Elevation = getExtrusion(mx)
Extrusion, AXaxis = getExtrusion(mx)
# no thickness/width for POLYLINEs converted into Screen-C-S
#print 'deb: curve.ext1=', curve.ext1 #---------
if curve.ext1: Thickness = curve.ext1 * sizeZ
if curve.ext2 and sizeX==sizeY:
Width = curve.ext2 * sizeX
if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE
ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
entities = writeCurveEntities(curve, mx,
Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix,
WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ,
**common)
return entities, block
#-------------------------------------------------
def writeCurveEntities(curve, mx,
Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix,
WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ,
**common):
"""help routine for exportCurve()
"""
entities = []
width1,width2 = None, None
if 1:
for cur in curve:
#print 'deb: START cur=', cur #--------------
#print 'deb: dir(curve):',dir(cur) #---------
#print 'deb: curve.type:',cur.type #---------
points = []
flags = []
pflag70, pflag75 = 0,0
if cur.type==4: # is NURBS
#if cur.isNurb():
#print 'deb:isNurb --------------' #---------
pflag70 = 4
orderU = cur.orderU
# curve type:
# 0: curvNoFitted
# 5: curvQuadraticBspline
# 6: curvCubicBspline
# 8: curvBezier
if orderU<=4: pflag75 = 5
elif orderU>=5: pflag75 = 6
vflag70 = 16
i = -2
for point in cur:
#print 'deb:isNurb point=', point #---------
i+=1
if i==orderU-1: i = 0
if i:
flags.append([16, [width1,width2]])
else:
flags.append([8, [width1,width2]])
vec = point[0:3]
#print 'deb: vec=', vec #---------
pkt = mathutils.Vector(vec)
#print 'deb: pkt=', pkt #---------
points.append(pkt)
if not cur.isCyclic():
points = points[1:-1]
flags = flags[1:-1]
elif cur.type==1: # is Bezier
#print 'deb:isBezier --------------' #---------
pflag75 = 8
vflag70 = 1
for point in cur:
#print 'deb:isBezier point=', point #---------
#print 'deb:isBezier point=', point.getTriple() #---------
ptan1,pfit,ptan2 = point.getTriple()
#print 'deb: point=', pt #---------
ptan1 = mathutils.Vector(ptan1)
pfit = mathutils.Vector(pfit)
ptan2 = mathutils.Vector(ptan2)
#print 'deb: pkt=', pkt #---------
points.append(ptan1)
flags.append([2, [width1,width2]])
points.append(pfit)
flags.append([1, [width1,width2]])
points.append(ptan2)
flags.append([2, [width1,width2]])
if not cur.isCyclic():
points = points[1:-1]
flags = flags[1:-1]
elif cur.type==0: # is Polygon
#print 'deb:isPolygon --------------' #---------
#pflag70 = 4
pflag75 = 0
for point in cur:
#print 'deb:isPoly point=', point #---------
vec = point[0:3]
#print 'deb: vec=', vec #---------
pkt = mathutils.Vector(vec)
#print 'deb: pkt=', pkt #---------
points.append(pkt)
flags.append([None, [width1,width2]])
#print 'deb: points', points #--------------
if len(points)>1:
c = curve_as_list[GUI_A['curve_as'].val]
if c=="POLYLINE": # export Curve as POLYLINE
if not PROJECTION:
# recalculate points(2d=X,Y) into Entity-Coords-System
for p in points: # list of vectors
p[0] *= sizeX
p[1] *= sizeY
p2 = p * Zrotmatrix
p2[0] += ECS_origin[0]
p2[1] += ECS_origin[1]
p[0],p[1] = p2[0],p2[1]
else:
points = projected_co(points, mx)
#print 'deb: points', points #--------------
if cur.isCyclic(): closed = 1
else: closed = 0
points = toGlobalOrigin(points)
points_temp = []
for p,f in zip(points,flags):
points_temp.append([p,f[0],f[1]])
points = points_temp
#print 'deb: points', points #--------------
if DEBUG: curve_drawBlender(points,OCS_origin,closed) #deb: draw to scene
common['extrusion']= Extrusion
##common['rotation']= ZRotation
##common['elevation']= Elevation
common['thickness']= Thickness
#print 'deb: common=', common #------------------
flag70, flag75 = pflag70+closed, pflag75
if 0: #DEBUG
p=AXaxis[:3]
entities.append(DXF.Line([[0,0,0], p],**common))
p=ECS_origin[:3]
entities.append(DXF.Line([[0,0,0], p],**common))
common['color']= 5
p=OCS_origin[:3]
entities.append(DXF.Line([[0,0,0], p],**common))
#OCS_origin=[0,0,0] #only debug----------------
dxfPLINE = DXF.PolyLine(points,OCS_origin, flag70=flag70, flag75=flag70, width=0.0,**common)
entities.append(dxfPLINE)
dxfPLINE = DXF.PolyLine(points,OCS_origin, flag70=flag70, flag75=flag70, width=0.0,**common)
entities.append(dxfPLINE)
if Thickness:
common['thickness']= -Thickness
dxfPLINE = DXF.PolyLine(points,OCS_origin, flag70=flag70, flag75=flag70, width=0.0,**common)
entities.append(dxfPLINE)
elif c=="LINEs": # export Curve as multiple LINEs
points = projected_co(points, mx)
if cur.isCyclic(): points.append(points[0])
#print 'deb: points', points #--------------
points = toGlobalOrigin(points)
if DEBUG: curve_drawBlender(points,WCS_loc,closed) #deb: draw to scene
common['extrusion']= Extrusion
common['elevation']= Elevation
common['thickness']= Thickness
#print 'deb: common=', common #------------------
for i in range(len(points)-1):
linepoints = [points[i], points[i+1]]
dxfLINE = DXF.Line(linepoints,**common)
entities.append(dxfLINE)
if Thickness:
common['thickness']= -Thickness
for i in range(len(points)-1):
linepoints = [points[i], points[i+1]]
dxfLINE = DXF.Line(linepoints,**common)
entities.append(dxfLINE)
elif c=="POINTs": # export Curve as multiple POINTs
points = projected_co(points, mx)
for p in points:
dxfPOINT = DXF.Point(points=[p],**common)
entities.append(dxfPOINT)
return entities
from .base_exporter import BasePrimitiveDXFExporter
class EmptyDXFExporter(BasePrimitiveDXFExporter):
pass
#-----------------------------------------------------
def exportEmpty(ob, mx, mw, **common):
"""converts Empty-Object to desired projection and representation(DXF-Entity type)
"""
p = mathutils.Vector(ob.loc)
[p] = projected_co([p], mx)
[p] = toGlobalOrigin([p])
entities = []
c = empty_as_list[GUI_A['empty_as'].val]
if c=="POINT": # export Empty as POINT
dxfPOINT = DXF.Point(points=[p],**common)
entities.append(dxfPOINT)
return entities
from .base_exporter import BasePrimitiveDXFExporter
class InsertDXFExporter(BasePrimitiveDXFExporter):
pass
#-----------------------------------------------------
def exportInsert(ob, mx, insert_name, **common):
"""converts Object to DXF-INSERT in given orientation
"""
WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
sizeX = ob.SizeX
sizeY = ob.SizeY
sizeZ = ob.SizeZ
rotX = ob.RotX
rotY = ob.RotY
rotZ = ob.RotZ
#print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
if not PROJECTION:
#Extrusion, ZRotation, Elevation = getExtrusion(mx)
Extrusion, AXaxis = getExtrusion(mx)
entities = []
if 1:
if not PROJECTION:
ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
ZRotation *= r2d
point = ECS_origin
else: #TODO: fails correct location
point1 = mathutils.Vector(ob.loc)
[point] = projected_co([point1], mx)
if PERSPECTIVE:
clipStart = 10.0
coef = -clipStart / (point1*mx)[2]
#print 'deb: coef=', coef #--------------
#TODO: ? sizeX *= coef
#sizeY *= coef
#sizeZ *= coef
#print 'deb: point=', point #--------------
[point] = toGlobalOrigin([point])
#if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene
common['extrusion']= Extrusion
#common['elevation']= Elevation
#print 'deb: common=', common #------------------
if 0: #DEBUG
#linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]]
linepoints = [[0,0,0], point]
dxfLINE = DXF.Line(linepoints,**common)
entities.append(dxfLINE)
xscale=sizeX
yscale=sizeY
zscale=sizeZ
cols=None
colspacing=None
rows=None
rowspacing=None
dxfINSERT = DXF.Insert(insert_name,point=point,rotation=ZRotation,\
xscale=xscale,yscale=yscale,zscale=zscale,\
cols=cols,colspacing=colspacing,rows=rows,rowspacing=rowspacing,\
**common)
entities.append(dxfINSERT)
return entities
from .base_exporter import BasePrimitiveDXFExporter
class LampDXFExporter(BasePrimitiveDXFExporter):
pass
#-----------------------------------------------------
def exportLamp(ob, mx, mw, **common):
"""converts Lamp-Object to desired projection and representation(DXF-Entity type)
"""
p = mathutils.Vector(ob.loc)
[p] = projected_co([p], mx)
[p] = toGlobalOrigin([p])
entities = []
c = lamp_as_list[GUI_A['lamp_as'].val]
if c=="POINT": # export as POINT
dxfPOINT = DXF.Point(points=[p],**common)
entities.append(dxfPOINT)
return entities
import mathutils
from .base_exporter import BasePrimitiveDXFExporter
import copy
class MeshDXFExporter(BasePrimitiveDXFExporter):
def export(self, ctx, drawing, ob, mx, mx_n, **kwargs):
"""
Converts Mesh-Object to desired projection and representation(DXF-Entity type)
"""
me = self._getMeshData(ctx, ob, self._settings)
# idea: me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state
# the .transform-method is fast, but bad, cause invasive:
# it manipulates original geometry and by retransformation lefts back rounding-errors
# we dont want to manipulate original data!
#temp_verts = me.verts[:] #doesn't work on ubuntu(Yorik), bug?
if me.vertices:
# check if there are more instances of this mesh (if used by other objects), then write to BLOCK/INSERT
if self.INSTANCES and me.users>1 and not self.PROJECTION and not (ob.modifiers and self._settings['apply_modifiers']):
if drawing.containsBlock(me.name):
entities = self._writeInsert(drawing, ob, mx, me.name)
else:
# generate geom_output in ObjectCS
allpoints = [v.co for v in me.vertices]
identity_matrix = mathutils.Matrix().identity()
allpoints = self.projected_co(allpoints, identity_matrix)
#allpoints = toGlobalOrigin(allpoints)
faces=[]
edges=[]
for e in me.edges: edges.append(e.key)
faces = [[v.index for v in f.verts] for f in me.faces]
entities = self._writeMeshEntities(allpoints, edges, faces, **kwargs)
if entities: # if not empty block
# write BLOCK definition and INSERT entity
# BLOCKREGISTRY = dictionary 'blender_name':'dxf_name'.append(me.name)
# BLOCKREGISTRY[me.name]=self.validDXFr12name(('ME_'+ me.name))
# insert_name = BLOCKREGISTRY[me.name]
drawing.addBlock(me.name, flag=0,base=(0,0,0),entities=entities)
# block = DXF.Block(insert_name,flag=0,base=(0,0,0),entities=entities)
# write INSERT as entity
entities = self._writeInsert(ob, mx, me.name, **(kwargs))
else: # no other instances, so go the standard way
return self._standard_way(drawing, me, mx, mx_n)
def _writeInsert(self, drawing, ob, mx, insert_name, **kwargs):
from insert_exporter import InsertDXFExporter
ex = InsertDXFExporter(self._settings)
ex.export(drawing, ob, mx, insert_name, **(kwargs))
def _getMeshData(self, ctx, obj, settings):
if obj.modifiers and settings['apply_modifiers']:
#this gets mesh with applied modifiers
data = obj.to_mesh(ctx.scene, True, 'PREVIEW')
else:
# me = ob.getData(mesh=1) # is a Mesh if mesh>0 (otherwise it is a NMesh)
data = obj.data
return data
def _standard_way(self, drawing, me, mx, mx_n, **kwargs):
allpoints = [v.co for v in me.vertices]
allpoints = self.projected_co(allpoints, mx)
allpoints = self.toGlobalOrigin(allpoints)
faces=[]
edges=[]
me.update(calc_tessface=True)
me_faces = me.tessfaces
#print('deb: allpoints=\n', allpoints) #---------
#print('deb: me_faces=\n', me_faces) #---------
if me_faces and self.PROJECTION and self.HIDDEN_LINES:
#if DEBUG: print 'deb:exportMesh HIDDEN_LINES mode' #---------
faces, edges = self.hidden_status(me_faces, mx, mx_n)
faces = [[v.index for v in me_faces[f_nr].vertices] for f_nr in faces]
else:
#if DEBUG: print 'deb:exportMesh STANDARD mode' #---------
for e in me.edges: edges.append(e.key)
#faces = [f.index for f in me.faces]
##faces = [[v.index for v in f.vertices] for f in me.faces]
faces = me_faces
#faces = [[allpoints[v.index] for v in f.vertices] for f in me.faces]
#print('deb: allpoints=\n', allpoints) #---------
#print('deb: edges=\n', edges) #---------
#print('deb: faces=\n', faces) #---------
if self.isLeftHand(mx): # then change vertex-order in every face
for f in faces:
f.reverse()
#f = [f[-1]] + f[:-1] #TODO: might be needed
#print('deb: faces=\n', faces) #---------
entities = self._writeMeshEntities(allpoints, edges, faces, **kwargs)
# TODO: rewrite
for type, args in entities:
drawing.addEntity(type, **(args))
return True
def _writeMeshEntities(self, allpoints, edges, faces, **kwargs):
"""help routine for exportMesh()
"""
entities = []
c = self._settings['mesh_as']
if c=='POINTs': # export Mesh as multiple POINTs
for p in allpoints:
args = copy.copy(kwargs)
args['points'] = [p]
entities.append(('Point', args))
elif c=='LINEs' or (not faces):
if edges and allpoints:
# if exportsettings['verbose']:
# mesh_drawBlender(allpoints, edges, None) #deb: draw to blender scene
for e in edges:
points = [allpoints[e[0]], allpoints[e[1]]]
args = copy.copy(kwargs)
args['points'] = points
entities.append(('Line', args))
elif c in ('POLYFACE','POLYLINE'):
if faces and allpoints:
#TODO: purge allpoints: left only vertices used by faces
# if exportsettings['verbose']:
# mesh_drawBlender(allpoints, None, faces) #deb: draw to scene
if not (self.PROJECTION and self.HIDDEN_LINES):
faces = [[v+1 for v in f.vertices] for f in faces]
else:
# for back-Faces-mode remove face-free vertices
map=verts_state= [0]*len(allpoints)
for f in faces:
for v in f:
verts_state[v]=1
if 0 in verts_state: # if dirty state
i,newverts=0,[]
for used_i,used in enumerate(verts_state):
if used:
newverts.append(allpoints[used_i])
map[used_i]=i
i+=1
allpoints = newverts
faces = [[map[v]+1 for v in f] for f in faces]
args = copy.copy(kwargs)
args['flag70'] = 64
args['flag75'] = 0
args['width'] = 0.0
args['points'] = [allpoints, faces]
entities.append(('PolyLine', args))
elif c=='3DFACEs':
if faces and allpoints:
# if exportsettings['verbose']:
# mesh_drawBlender(allpoints, None, faces) #deb: draw to scene
for f in faces:
points = [allpoints[v_id] for v_id in f.vertices]
args = copy.copy(kwargs)
args['points'] = points
# print(args)
entities.append(('Face', args))
return entities
from .base_exporter import BasePrimitiveDXFExporter
class TextDXFExporter(BasePrimitiveDXFExporter):
pass
#-----------------------------------------------------
def exportText(ob, mx, mw, **common):
"""converts Text-Object to desired projection and representation(DXF-Entity type)
"""
text3d = ob.getData()
textstr = text3d.getText()
WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
sizeX = ob.SizeX
sizeY = ob.SizeY
sizeZ = ob.SizeZ
rotX = ob.RotX
rotY = ob.RotY
rotZ = ob.RotZ
#print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
if not PROJECTION:
#Extrusion, ZRotation, Elevation = getExtrusion(mx)
Extrusion, AXaxis = getExtrusion(mx)
# no thickness/width for TEXTs converted into ScreenCS
if text3d.getExtrudeDepth():
Thickness = text3d.getExtrudeDepth() * sizeZ
#Horizontal text justification type, code 72, (optional, default = 0)
# integer codes (not bit-coded)
#0=left, 1=center, 2=right
#3=aligned, 4=middle, 5=fit
Alignment = None
alignment = text3d.getAlignment().value
if alignment in (1,2): Alignment = alignment
textHeight = text3d.getSize() / 1.7
textFlag = 0
if sizeX < 0.0: textFlag |= 2 # set flag for horizontal mirrored
if sizeZ < 0.0: textFlag |= 4 # vertical mirrored
entities = []
c = text_as_list[GUI_A['text_as'].val]
if c=="TEXT": # export text as TEXT
if not PROJECTION:
ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
ZRotation *= r2d
point = ECS_origin
else: #TODO: fails correct location
point1 = mathutils.Vector(ob.loc)
[point] = projected_co([point1], mx)
if PERSPECTIVE:
clipStart = 10.0
coef = -clipStart / (point1*mx)[2]
textHeight *= coef
#print 'deb: coef=', coef #--------------
#print 'deb: point=', point #--------------
[point] = toGlobalOrigin([point])
point2 = point
#if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene
common['extrusion']= Extrusion
#common['elevation']= Elevation
common['thickness']= Thickness
#print 'deb: common=', common #------------------
if 0: #DEBUG
#linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]]
linepoints = [[0,0,0], point]
dxfLINE = DXF.Line(linepoints,**common)
entities.append(dxfLINE)
dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\
flag=textFlag,height=textHeight,justifyhor=Alignment,**common)
entities.append(dxfTEXT)
if Thickness:
common['thickness']= -Thickness
dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\
flag=textFlag,height=textHeight,justifyhor=Alignment,**common)
entities.append(dxfTEXT)
return entities
from base_exporter import BasePrimitiveDXFExporter
class ViewBorderDXFExporter(BasePrimitiveDXFExporter):
def export(self, ob, mx, mw, **common):
"""converts Lamp-Object to desired projection and representation(DXF-Entity type)
"""
identity_matrix = mathutils.Matrix().identity()
points = projected_co(border, identity_matrix)
closed = 1
points = toGlobalOrigin(points)
c = settings['curve_as']
if c=="LINEs": # export Curve as multiple LINEs
for i in range(len(points)-1):
linepoints = [points[i], points[i+1]]
dxfLINE = DXF.Line(linepoints,paperspace=espace,color=LAYERCOLOR_DEF)
entities.append(dxfLINE)
else:
fag70, flag75 = closed, 0
dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag70=flag70, flag75=flag70, width=0.0, paperspace=espace, color=LAYERCOLOR_DEF)
#dxfPLINE = DXF.PolyLine(points,points[0],[closed,0,0], paperspace=espace, color=LAYERCOLOR_DEF)
d.append(dxfPLINE)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment