diff --git a/release/scripts/bpymodules/dxfLibrary.py b/release/scripts/bpymodules/dxfLibrary.py index 55907e03bc1..1e190fec772 100644 --- a/release/scripts/bpymodules/dxfLibrary.py +++ b/release/scripts/bpymodules/dxfLibrary.py @@ -1,6 +1,6 @@ #dxfLibrary.py : provides functions for generating DXF files # -------------------------------------------------------------------------- -__version__ = "v1.29beta - 2008.12.28" +__version__ = "v1.30 - 2009.05.28" __author__ = "Stani Michiels(Stani), Remigiusz Fiedler(migius)" __license__ = "GPL" __url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" @@ -18,9 +18,12 @@ IDEAs: - TODO: -- add support for SPLINEs, (bad idea, cause DXF r14 object :( +- add support for DXFr14 (new file header) +- add support for SPLINEs, although it is DXFr14 object History +v1.30 - 2009.05.28 by migius +- bugfix 3dPOLYLINE/POLYFACE: VERTEX needs x,y,z coordinates, index starts with 1 not 0 v1.29 - 2008.12.28 by Yorik - modif POLYLINE to support bulge segments v1.28 - 2008.12.13 by Steeve/BlenderArtists @@ -42,7 +45,7 @@ ______________________________________________________________ # -------------------------------------------------------------------------- # DXF Library: copyright (C) 2005 by Stani Michiels (AKA Stani) -# 2008 modif by Remigiusz Fiedler (AKA migius) +# 2008/2009 modif by Remigiusz Fiedler (AKA migius) # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # @@ -85,7 +88,6 @@ def _point(x,index=0): def _points(plist): """Convert a list of tuples to dxf points""" out = '\n'.join([_point(plist[i],i)for i in range(len(plist))]) - #print 'deb: points=\n', out #------------------- return out #---base classes---------------------------------------- @@ -326,7 +328,6 @@ class PolyLine(_Entity): def __str__(self): result= ' 0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.flag) - #print 'deb: self._common()', self._common() #---------- result+=' 66\n1\n' result+='%s\n' %_point(self.org_point) if self.polyface: @@ -337,10 +338,11 @@ class PolyLine(_Entity): for point in self.points: result+=' 0\nVERTEX\n' result+=' 8\n%s\n' %self.layer - result+='%s\n' %_point(point[0:2]) if self.polyface: + result+='%s\n' %_point(point[0:3]) result+=' 70\n192\n' elif self.polyline2d: + result+='%s\n' %_point(point[0:2]) if len(point)>4: width1, width2 = point[3], point[4] if width1!=None: result+=' 40\n%s\n' %width1 @@ -348,6 +350,8 @@ class PolyLine(_Entity): if len(point)==6: bulge = point[5] if bulge: result+=' 42\n%s\n' %bulge + else: + result+='%s\n' %_point(point[0:3]) for face in self.faces: result+=' 0\nVERTEX\n' result+=' 8\n%s\n' %self.layer diff --git a/release/scripts/export_dxf.py b/release/scripts/export_dxf.py index 84a173c1e7d..5f7a6ecad37 100644 --- a/release/scripts/export_dxf.py +++ b/release/scripts/export_dxf.py @@ -1,47 +1,76 @@ #!BPY """ - Name: 'Autodesk (.dxf .dwg)' - Blender: 247 + Name: 'Autodesk DXF (.dxf)' + Blender: 249 Group: 'Export' - Tooltip: 'Export geometry to Autocad DXF/DWG-r12 (Drawing eXchange Format).' + Tooltip: 'Export geometry to DXF/DWG-r12 (Drawing eXchange Format).' """ -__version__ = "v1.29 - 2009.04.11" -__author__ = "Remigiusz Fiedler (AKA migius), Alexandros Sigalas (AKA alxarch), Stani Michiels" +__version__ = "1.34 - 2009.05.28" +__author__ = "Remigiusz Fiedler (AKA migius)" __license__ = "GPL" -__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" +__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" __bpydoc__ ="""The script exports Blender geometry to DXF format r12 version. Version %s Copyright %s License %s -extern dependances: dxfLibrary.py +extern dependances: dxfLibrary.py, (optionaly: DConvertCon.exe) + +CONTRIBUTORS: +Remigiusz Fiedler (AKA migius) +Alexandros Sigalas (AKA alxarch) +Stani Michiels (AKA stani) See the homepage for documentation. url: %s IDEAs: - - correct normals for POLYLINE-POLYFACE via proper point-order - - HPGL output for 2d and flattened 3d content - +- correct normals for POLYLINE-POLYFACE via proper vertex-order +- HPGL output, especially usefull for correct scaled printing of 2d drawings + TODO: - export dupligroups and dupliverts as blocks ( option for the user to decide ) -- optimize back-faces removal (probably needs matrix transform) - optimize POLYFACE routine: remove double-vertices - optimize POLYFACE routine: remove unused vertices - support hierarchies: groups, instances, parented structures - support 210-code (3d orientation vector) -- presets for architectural scales - write drawing extends for automatic view positioning in CAD +- support mapping: materials to DXF-styles History -v1.29 - 2009.04.11 by migius +v1.34 - 2009.05.28 by migius +- bugfix POLYFACE export, synchronized with dxfLibrary.py +- changed to the new 2.49 method Vector.cross() +- output style manager (first try) +v1.33 - 2009.05.25 by migius +- bugfix flipping normals in mirrored objects +- added UI-Button for future Shadow Generator +- support curve objects in projection-2d mode +- UI stuff: camera selector/manager +v1.32 - 2009.05.22 by migius +- debug mode for curve-objects: output pass to Blender +- wip support 210-code(extrusion) calculation +- default settings for 2D and 3D export +v1.31 - 2009.05.18 by migius +- globals translated to GUI_A/B dictionary +- optimizing back-faces removal for "hidden-lines" mode +- presets for global location and scale (architecture) +- UI layout: scrollbars, pan with MMB/WHEEL, dynamic width +- new GUI with Draw.Register() from DXF-importer.py +v1.30 - 2008.12.14 by migius +- started work on GUI with Draw.Register() +v1.29 - 2009.04.11 by stani - added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter -v1.28 - 2009.02.05 by alxarch +v1.28 - 2009.02.05 by Alexandros Sigalas (alxarch) - added option to apply modifiers on exported meshes - added option to also export duplicates (from dupliverts etc) +v1.28 - 2008.10.22 by migius +- workaround for PVert-bug on ubuntu (reported by Yorik) +- add support for FGons - ignore invisible_tagged edges +- add support for camera: ortho and perspective v1.27 - 2008.10.07 by migius - exclude Stani's DXF-Library to extern module v1.26 - 2008.10.05 by migius @@ -92,46 +121,161 @@ ______________________________________________________________ import Blender -from Blender import Mathutils, Window, Scene, sys, Draw, Mesh -import BPyMessages -try: import os -except: os = None -try: import subprocess -except: subprocess = None -try: import copy -except: copy = None +from Blender import Mathutils, Window, Scene, Draw, Camera, BezTriple +from Blender import Registry, Object, Mesh +import os +import subprocess -#print os.sys.platform -#print dir(os.sys.version) - -#import dxfLibrary +import dxfLibrary as DXF +#reload(DXF) #reload(dxfLibrary) -if copy and os: - from dxfLibrary import * - #-------- DWG support ------------------------------------------ - extCONV_OK = True - extCONV = 'DConvertCon.exe' - extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV) - if not os.path.isfile(extCONV_PATH): - extCONV_OK = False - extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ - Copy first %s into Blender script directory.|\ - More details in online Help.' %extCONV - else: - if not os.sys.platform.startswith('win'): - # check if Wine installed: - if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip(): - extCONV_PATH = 'wine %s'%extCONV_PATH - else: - extCONV_OK = False - extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ - The external DWG-converter (%s) needs Wine installed on your system.|\ - More details in online Help.' %extCONV - #print 'extCONV_PATH = ', extCONV_PATH +#from dxfLibrary import * + +import math +from math import atan, log10 + +#pi = math.pi +#pi = 3.14159265359 +d2r = math.pi / 180.0 +#note: d2r * angle == math.radians(angle) + +print '\n\n\n' +print 'DXF-Exporter v%s *** start ***' %(__version__) #--------------------- + +#DEBUG = True #activets debug mode +#----globals------------------------------------------ +ONLYSELECTED = 1 # 0/1 = False/True +POLYLINES = 1 # prefer POLYLINEs not LINEs +POLYFACES = 1 # prefer POLYFACEs not 3DFACEs +PROJECTION = 0 # flatten output geometry to Z = 0.0 +HIDDEN_LINES = 0 #filter out hidden geometry +SHADOWS = 0 # sun/shadows simulation +CAMERA = 1 # view from active camera or from 3d-view +PERSPECTIVE = 0 #perspective camera +APPLY_MODIFIERS = 1 +INCLUDE_DUPLIS = 0 +OUTPUT_DWG = 0 #optional save to DWG with extern converter -#----------------------------------------------------- +G_SCALE = 1.0 #(0.0001-1000) global scaling factor for output dxf data +G_ORIGIN = [0.0,0.0,0.0] #global translation-vector (x,y,z) in Blender units +ELEVATION = 0.0 #standard elevation = coordinate Z value in Blender units + +MIN_DIST = 0.001 #cut-off value for sort out short-distance polyline-"duoble_vertex" +CURV_RESOLUTION = 12 #(1-128) Bezier curves U-resolution +CURVARC_RESOLUTION = 4 #(3-32) resolution of circle represented as Bezier curve +THIN_RESOLUTION = 8 #(4-64) thin_cylinder arc_resolution - number of segments +MIN_THICK = MIN_DIST * 10.0 #minimal thickness by forced thickness +MIN_WIDTH = MIN_DIST * 10.0 #minimal width by forced width + +BYBLOCK = 0 #DXF-attribute: assign property to BLOCK defaults +BYLAYER = None #256 #DXF-attribute: assign property to LAYER defaults +PREFIX = 'BF_' #used as prefix for DXF names +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 +E_M = 0 +LAB = "scroll MMB/WHEEL . wip .. todo" #"*) parts under construction" +M_OBJ = 0 + +FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE) +MAX_NAMELENGTH = 17 #max_effective_obnamelength in blender =21=17+(.001) +INIFILE_DEFAULT_NAME = 'exportDXF' +INIFILE_EXTENSION = '.ini' +INIFILE_HEADER = '#ExportDXF.py ver.1.0 config data' +INFFILE_HEADER = '#ExportDXF.py ver.1.0 analyze of DXF-data' + +SCENE = None +WORLDX = Mathutils.Vector((1,0,0)) +#TODO: a bug? WORLDY = Mathutils.Vector((1,1,0)) +WORLDY = Mathutils.Vector((0,1,0)) +WORLDZ = Mathutils.Vector((0,0,1)) + +AUTO = BezTriple.HandleTypes.AUTO +FREE = BezTriple.HandleTypes.FREE +VECT = BezTriple.HandleTypes.VECT +ALIGN = BezTriple.HandleTypes.ALIGN + + +#-------- DWG support ------------------------------------------ +extCONV_OK = True +extCONV = 'DConvertCon.exe' +extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV) +if not os.path.isfile(extCONV_PATH): + extCONV_OK = False + extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ +Copy first %s into Blender script directory.|\ +More details in online Help.' %extCONV +else: + if not os.sys.platform.startswith('win'): + # check if Wine installed: + if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip(): + extCONV_PATH = 'wine %s'%extCONV_PATH + else: + extCONV_OK = False + extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ +The external DWG-converter (%s) needs Wine installed on your system.|\ +More details in online Help.' %extCONV +#print 'extCONV_PATH = ', extCONV_PATH + + +#---------------------------------------------- +def updateMenuCAMERA(): + global CAMERAS + global MenuCAMERA + global MenuLIGHT + + scn = Scene.GetCurrent() + objs = scn.getChildren() + currcam = scn.getCurrentCamera() + if currcam: currcam = currcam.getName() + maincams = [] + MenuCAMERA = "Select Camera%t" + for cam in objs: + if cam.getType() == 'Camera': + if cam.getName()[0:4] != "Temp": + maincams.append(cam.getName()) + maincams.sort() + maincams.reverse() + CAMERAS = maincams + for i, cam in enumerate(CAMERAS): + if cam==currcam: + MenuCAMERA += "|* " + cam + else: MenuCAMERA += "| " + cam + MenuCAMERA += "|current 3d-View" + MenuLIGHT = "Select Sun%t| *todo" + + +#---------------------------------------------- +def updateCAMERA(): + global CAMERA, GUI_A + #CAMERA = 1 + scn = Scene.GetCurrent() + currcam = scn.getCurrentCamera() + if currcam: currcam = currcam.getName() + if currcam in CAMERAS: + CAMERA = CAMERAS.index(currcam)+1 + GUI_A['camera_on'].val = CAMERA + +#---------------------------------------------- +def gotoCAMERA(): + cam = Object.Get(CAMERAS[CAMERA-1]) + print 'deb: CAMERA, cam',CAMERA, cam + if cam.getType() != 'Camera': + sure = Draw.PupMenu("Info: %t| It is not a Camera Object.") + else: + scn = Scene.getCurrent() + scn.setCurrentCamera(cam) + Window.CameraView(0) + Window.Redraw() + updateMenuCAMERA() + + +#------- Duplicats support ---------------------------------------------- def dupTest(object): """ Checks objects for duplicates enabled (any type) @@ -160,7 +304,7 @@ def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False): result = [] for ob in oblist: - if dupTest(ob): + if INCLUDE_DUPLIS and dupTest(ob): dup_obs=ob.DupObjects if len(dup_obs): for dup_ob, dup_mx in dup_obs: @@ -185,39 +329,52 @@ def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False): return result #----------------------------------------------------- -def hidden_status(faces, mx_n): - #print 'HIDDEN_MODE: caution! not full implemented yet' - ok_faces = [] - ok_edges = [] - #sort out back-faces = with normals pointed away from camera +def hidden_status(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 + # 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' #------------------ - # normal must point the Z direction-hemisphere - if vec_normal[2] > 0.0 : - ok_faces.append(f.index) + + frontFace = False + if not 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 ok_edges: - ok_edges.append(key) - #print 'deb: amount of visible faces=', len(ok_faces) #--------- - #print 'deb: visible faces=', ok_faces #--------- - #print 'deb: amount of visible edges=', len(ok_edges) #--------- - #print 'deb: visible edges=', ok_edges #--------- - return ok_faces, ok_edges + 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 projected_co(vec, mw): +#--------not used------------------------------------- +def projected_co0(vec, mw): # convert the world coordinates of vector to screen coordinates #co = vec.co.copy().resize4D() co = vec.copy().resize4D() @@ -235,181 +392,580 @@ def flatten(points, mw): #print 'deb: flatten points=', points #--------- return points + #----------------------------------------------------- -def exportMesh(ob, mx, mx_n,me=None): - entities = [] +def getExtrusion(matrix): + + print 'deb:getExtrusion() matrix=\n', matrix #--------- + ma = matrix.copy().normalize() + AZaxis = ma[2] # = ArbitraryZvector + ArbitraryZaxis = [AZaxis[0],AZaxis[1],AZaxis[2]] + threshold = 1.0 / 64.0 + if abs(Zaxis[0]) < threshold or abs(Zaxis[1]) < threshold: + #AXaxis = Mathutils.CrossVecs(WORLDY,AZaxis) #for<2.49 + AXaxis = WORLDY.cross(AZaxis) + else: + #AXaxis = Mathutils.CrossVecs(WORLDZ,AZaxis) #for<2.49 + AXaxis = WORLDZ.cross(AZaxis) + + Rotation = Mathutils.AngleBetweenVecs(WORLDX,AXaxis) #output in degrees + Elevation = 1.0 + + return ArbitraryZaxis, Rotation, Elevation + + +#----------------------------------------------------- +def projected_co(verts, mx): + # converts world coordinates of points to screen coordinates + temp_verts = [] + for v in verts: + #temp_verts.append(Blender.Mesh.MVert(v.co)) + temp_verts.append(Mesh.MVert(v)) + #print 'deb: temp_verts=', temp_verts #--------- + + if GUI_A['Z_force_on'].val: locZ = GUI_A['Z_elev'].val + else: locZ = 0.0 + + for v in temp_verts: + v.co *= mx + if PROJECTION: + if PERSPECTIVE: + clipStart = 10.0 + for v in temp_verts: + coef = - clipStart / v.co[2] + v.co[0] *= coef + v.co[1] *= coef + v.co[2] = locZ + for v in temp_verts: + v.co[2] = locZ + temp_verts = [v.co[:3] for v in temp_verts] + return temp_verts + + +#----------------------------------------------------- +def isLeftHand(matrix): + #Is the matrix a left-hand-system, or not? + ma = matrix.rotationPart() + #crossXY = Mathutils.CrossVecs(ma[0], ma[1]) #for<2.49 + crossXY = ma[0].cross(ma[1]) + #check = Mathutils.DotVecs(ma[2], crossXY) #for<2.49 + check = ma[2].dot(crossXY) + if check < 0.00001: return 1 + return 0 + + +#----------------------------------------------------- +def exportMesh(ob, mx, mx_n, me=None, **common): global APPLY_MODIFIERS - if me is None: + entities = [] + #print 'deb:exportMesh() common=', common #--------- + if me is None: # me means mesh me = ob.getData(mesh=1) else: me.getFromObject(ob) - #me.transform(mx) + # me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state # above is eventualy faster, but bad, cause - # directly transforms origin geometry and write back rounding errors - me_verts = me.verts[:] #we dont want manipulate origin data - #print 'deb: me_verts=', me_verts #--------- - #me.transform(mx_inv) #counterpart to - back to the origin state - for v in me_verts: - v.co *= mx - faces=[] - edges=[] - if HIDDEN_MODE: - ok_faces, ok_edges = hidden_status(me.faces, mx_n) - - #if (not FLATTEN) and len(me.faces)>0 and ONLYFACES: - if ONLYFACES: - if POLYFACES: #export 3D as POLYFACEs - allpoints = [] - allfaces = [] - allpoints = [v.co[:3] for v in me_verts] - for f in me.faces: - #print 'deb: face=', f #--------- - if not HIDDEN_MODE or \ - (HIDDEN_MODE and f.index in ok_faces): - if 1: - points = f.verts - face = [p.index+1 for p in points] - #print 'deb: face=', face #--------- - allfaces.append(face) - else: #bad, cause create multiple vertex instances - points = f.verts - points = [ me_verts[p.index].co[:3] for p in points] - #points = [p.co[:3] for p in points] - #print 'deb: points=', points #--------- - index = len(allpoints)+1 - face = [index+i for i in range(len(points))] - allpoints.extend(points) - allfaces.append(face) - if allpoints and allfaces: - #print 'deb: allpoints=', allpoints #--------- - #print 'deb: allfaces=', allfaces #--------- - dxfPOLYFACE = PolyLine([allpoints, allfaces], flag=64) - entities.append(dxfPOLYFACE) - else: #export 3D as 3DFACEs - for f in me.faces: - #print 'deb: face=', f #--------- - if not HIDDEN_MODE or \ - (HIDDEN_MODE and f.index in ok_faces): - points = f.verts - points = [ me_verts[p.index].co[:3] for p in points] - #points = [p.co[:3] for p in points] - #print 'deb: points=', points #--------- - dxfFACE = Face(points) - entities.append(dxfFACE) - - else: #export 3D as LINEs - if HIDDEN_MODE and len(me.faces)!=0: - for e in ok_edges: - points = [ me_verts[key].co[:3] for key in e] - dxfLINE = Line(points) - entities.append(dxfLINE) - + # invasive: directly transforms origin geometry and write back rounding errors + #we dont want to manipulate origin data + #temp_verts = me.verts[:] #doesn't work on ubuntu(Yorik), bug? + if me.verts: + #print 'deb:exportMesh() started' #--------- + allpoints = [v.co for v in me.verts] + allpoints = projected_co(allpoints, mx) + if GUI_A['g_origin_on'].val: #TODO: scale and object orientation + for p in allpoints: + p[0] += G_ORIGIN[0] + p[1] += G_ORIGIN[1] + p[2] += G_ORIGIN[2] + faces=[] + edges=[] + if me.faces and HIDDEN_LINES: + if DEBUG: print 'deb:exportMesh HIDDEN_LINES mode' #--------- + faces, edges = hidden_status(me.faces, mx, mx_n) + faces = [[v.index for v in me.faces[f_nr].verts] for f_nr in faces] else: - for e in me.edges: - #print 'deb: edge=', e #--------- - points=[] - #points = [e.v1.co*mx, e.v2.co*mx] - points = [ me_verts[key].co[:3] for key in e.key] - #print 'deb: points=', points #--------- - dxfLINE = Line(points) - entities.append(dxfLINE) + 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.verts] for f in me.faces] + #faces = [[allpoints[v.index] for v in f.verts] for f in me.faces] + #print 'deb: allpoints=\n', allpoints #--------- + #print 'deb: edges=\n', edges #--------- + #print 'deb: faces=\n', faces #--------- + if 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 #--------- + + c = mesh_as_list[GUI_A['mesh_as'].val] + if 'POINTs'==c: # export Mesh as multiple POINTs + for p in allpoints: + dxfPOINT = DXF.Point(p, **common) + entities.append(dxfPOINT) + elif 'LINEs'==c or (not faces): + if edges and allpoints: + if DEBUG: mesh_drawBlender(allpoints, edges, None) #deb: draw to blender scene + for e in edges: + points = [allpoints[e[0]], allpoints[e[1]]] + dxfLINE = DXF.Line(points, **common) + entities.append(dxfLINE) + elif faces: + if c in ('POLYFACE','POLYLINE'): + if allpoints: + #TODO: purge allpoints: left only vertices used by faces + if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene + faces = [[v+1 for v in f] for f in faces] + dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag=64, **common) + #dxfPOLYFACE = DXF.PolyLine([allpoints, faces],org_point=[0,0,0], flag=64,width=None, **common) + #dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag=64) + #print '\n deb: dxfPOLYFACE=',dxfPOLYFACE #------------- + entities.append(dxfPOLYFACE) + elif '3DFACEs'==c: + if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene + for f in faces: + #print 'deb: face=', f #--------- + points = [allpoints[key] for key in f] + #points = [p.co[:3] for p in points] + #print 'deb: pointsXX=\n', points #--------- + dxfFACE = DXF.Face(points, **common) + entities.append(dxfFACE) + + return entities + +#----------------------------------------------------- +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])) + for p in vertList[1:]: + curve.append(BezTriple.New(p)) + 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 exportEmpty(ob, mx, mw, _common=None): + entities = [] + + if GUI_A['empty_as'].val==1: # export Empty as POINT + p = ob.loc + dxfPOINT = Point(p) + entities.append(dxfPOINT) return entities #----------------------------------------------------- -def exportCurve(ob, mx): +def exportCurve(ob, mx, mw, _common=None): entities = [] curve = ob.getData() + + """ if not PROJECTION: + Extrusion, Rotation, Elevation = getExtrusion(mx) + else: + Extrusion = None + """ + for cur in curve: - #print 'deb: START cur=', cur #-------------- - if 1: #not cur.isNurb(): - #print 'deb: START points' #-------------- - points = [] - org_point = [0.0,0.0,0.0] + print 'deb: START cur=', cur #-------------- + org_point = [0.0,0.0,0.0] + points = [] + if cur.isNurb(): for point in cur: - #print 'deb: point=', point #--------- - if cur.isNurb(): - vec = point[0:3] - else: - point = point.getTriple() - #print 'deb: point=', point #--------- - vec = point[1] + #print 'deb:isNurb point=', point #--------- + vec = point[0:3] #print 'deb: vec=', vec #--------- - pkt = Mathutils.Vector(vec) * mx + pkt = Mathutils.Vector(vec) #print 'deb: pkt=', pkt #--------- - #pkt *= SCALE_FACTOR - if 0: #FLATTEN: - pkt = projected_co(pkt, mw) points.append(pkt) + else: + for point in cur: + #point = point.getTriple() + #print 'deb:isBezier point=', point #--------- + vec = point.getTriple()[1] + #print 'deb: vec=', vec #--------- + pkt = Mathutils.Vector(vec) + #print 'deb: pkt=', pkt #--------- + points.append(pkt) + if len(points)>1: + #print 'deb: points', points #-------------- + points = projected_co(points, mx) if cur.isCyclic(): closed = 1 else: closed = 0 - if len(points)>1: - #print 'deb: points', points #-------------- - if POLYLINES: dxfPLINE = PolyLine(points,org_point,closed) - else: dxfPLINE = LineList(points,org_point,closed) + if DEBUG: curve_drawBlender(points,org_point,closed) #deb: draw to scene + if GUI_A['curve_as'].val==2: # export Curve as POLYLINE + dxfPLINE = DXF.PolyLine(points,org_point,closed,**common) entities.append(dxfPLINE) + elif GUI_A['curve_as'].val==1: # export Curve as multiple LINEs + dxfPLINE = DXF.LineList(points,org_point,closed,**common) + entities.append(dxfPLINE) + elif GUI_A['curve_as'].val==5: # export Curve as multiple POINTs + for p in points: + dxfPOINT = DXF.Point(p,**common) + entities.append(dxfPOINT) return entities +#----------------------------------------------------- +def getClipBox(camera): + sce = Scene.GetCurrent() + context = sce.getRenderingContext() + #print 'deb: context=\n', context #------------------ + #print 'deb: context=\n', dir(context) #------------------ + sizeX = context.sizeX + sizeY = context.sizeY + ratioXY = sizeX/float(sizeY) + #print 'deb: size X,Y, ratio=', sizeX, sizeY, ratioXY #------------------ + + clip1_Z = - camera.clipStart + clip2_Z = - camera.clipEnd + #print 'deb: clip Start=', camera.clipStart #------------------ + #print 'deb: clip End=', camera.clipEnd #------------------ + + if camera.type=='ortho': + scale = camera.scale + #print 'deb: camscale=', scale #------------------ + clip1shiftX = clip2shiftX = camera.shiftX * scale + clip1shiftY = clip2shiftY = camera.shiftY * scale + clip1_X = scale * 0.5 + clip1_Y = scale * 0.5 + if ratioXY > 1.0: clip1_Y /= ratioXY + else: clip1_X *= ratioXY + clip2_X = clip1_X + clip2_Y = clip1_Y + + near = clip1_Z + far = clip2_Z + right, left = clip1_X, -clip1_X + top, bottom = clip1_Y, -clip1_Y + + scaleX = 2.0/float(right - left) + x3 = -float(right + left)/float(right - left) + scaleY = 2.0/float(top - bottom) + y3 = -float(top + bottom)/float(top - bottom) + scaleZ = 1.0/float(far - near) + z3 = -float(near)/float(far - near) + + matr = Mathutils.Matrix( [scaleX, 0.0, 0.0, x3], + [0.0, scaleY, 0.0, y3], + [0.0, 0.0, scaleZ, z3], + [0.0, 0.0, 0.0, 1.0]) + + elif camera.type=='persp': + #viewpoint = [0.0, 0.0, 0.0] #camera's coordinate system, hehe + #lens = camera.lens + angle = camera.angle + #print 'deb: cam angle=', angle #------------------ + shiftX = camera.shiftX + shiftY = camera.shiftY + fov_coef = atan(angle * d2r) + fov_coef *= 1.3 #incl. passpartou + clip1_k = clip1_Z * fov_coef + clip2_k = clip2_Z * fov_coef + clip1shiftX = - camera.shiftX * clip1_k + clip2shiftX = - camera.shiftX * clip2_k + clip1shiftY = - camera.shiftY * clip1_k + clip2shiftY = - camera.shiftY * clip2_k + clip1_X = clip1_Y = clip1_k * 0.5 + clip2_X = clip2_Y = clip2_k * 0.5 + if ratioXY > 1.0: + clip1_Y /= ratioXY + clip2_Y /= ratioXY + else: + clip1_X *= ratioXY + clip2_X *= ratioXY + + near = clip1_Z + far = clip2_Z + right, left = clip1_X, -clip1_X + top, bottom = clip1_Y, -clip1_Y + #return Matrix( [scaleX, 0.0, x2, 0.0], + #[0.0, scaleY, y2, 0.0], + #[0.0, 0.0, scaleZ, wZ], + #[0.0, 0.0, -1.0, 0.0]) + matr = Mathutils.Matrix( [(2.0 * near)/float(right - left), 0.0, float(right + left)/float(right - left), 0.0], + [0.0, (2.0 * near)/float(top - bottom), float(top + bottom)/float(top - bottom), 0.0], + [0.0, 0.0, -float(far + near)/float(far - near), -(2.0 * far * near)/float(far - near)], + [0.0, 0.0, -1.0, 0.0]) + + + clip_box = [ + -clip1_X + clip1shiftX, clip1_X + clip1shiftX, + -clip1_Y + clip1shiftY, clip1_Y + clip1shiftY, + -clip2_X + clip2shiftX, clip2_X + clip2shiftX, + -clip2_Y + clip2shiftY, clip2_Y + clip2shiftY, + clip1_Z, clip2_Z] + #print 'deb: clip_box=\n', clip_box #------------------ + #drawClipBox(clip_box) + return clip_box, matr + + +#----------------------------------------------------- +def drawClipBox(clip_box): + 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]] + nme = Mesh.New() + nme.verts.extend(verts) + nme.faces.extend(faces) + + plan = Object.New('Mesh','clip_box') + plan.link(nme) + sce = Scene.GetCurrent() + sce.objects.link(plan) + plan.setMatrix(sce.objects.camera.matrix) + + +#------------------------------------------------- +def getCommons(ob): + #set up common attributes for output style: + # color=None + # extrusion=None + # layer='0', + # lineType=None + # lineTypeScale=None + # lineWeight=None + # thickness=None + # parent=None + + layers = ob.layers #gives a list e.g.[1,5,19] + if layers: ob_layer_nr = layers[0] + #print 'ob_layer_nr=', ob_layer_nr #-------------- + + materials = ob.getMaterials() + if materials: + ob_material = materials[0] + ob_mat_color = ob_material.rgbCol + else: ob_mat_color, ob_material = None, None + #print 'ob_mat_color, ob_material=', ob_mat_color, ob_material #-------------- + + data = ob.getData() + data_materials = ob.getMaterials() + if data_materials: + data_material = data_materials[0] + data_mat_color = data_material.rgbCol + else: data_mat_color, data_material = None, None + #print 'data_mat_color, data_material=', data_mat_color, data_material #-------------- + + entitylayer = ENTITYLAYER_DEF + c = entitylayer_from_list[GUI_A['entitylayer_from'].val] + #["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 = data.name + entitylayer = validDXFr12name(PREFIX+entitylayer) + if entitylayer=="": entitylayer = "BF_0" + + entitycolor = ENTITYCOLOR_DEF + c = entitycolor_from_list[GUI_A['entitycolor_from'].val] + if c=="default_COLOR": + entitycolor = LAYERCOLOR_DEF + elif c=="BYLAYER": + entitycolor = BYLAYER + elif c=="BYBLOCK": + entitycolor = BYBLOCK + elif c=="obj.layer" and ob_layer_nr: + entitycolor = ob_layer_nr + elif c=="obj.color" and ob.color: + entitycolor = col2DXF(ob.color) + elif c=="obj.material" and ob_mat_color: + entitycolor = col2DXF(ob_mat_color) + elif c=="obj.data.material" and data_mat_color: + entitycolor = col2DXF(data_mat_color) + #if entitycolor!=None: layercolor = entitycolor + + entityltype = ENTITYLTYPE_DEF + c = entityltype_from_list[GUI_A['entityltype_from'].val] + if c=="default_LTYPE": + entityltype = LAYERLTYPE_DEF + elif c=="BYLAYER": + entityltype = BYLAYER + elif c=="BYBLOCK": + entityltype = BYBLOCK + elif c: + entityltype = c + + return entitylayer,entitycolor,entityltype + + #----------------------------------------------------- def do_export(export_list, filepath): + global PERSPECTIVE Window.WaitCursor(1) - t = sys.time() + t = Blender.sys.time() #init Drawing --------------------- - d=Drawing() + d=DXF.Drawing() #add Tables ----------------- - #d.blocks.append(b) #table blocks - d.styles.append(Style()) #table styles - d.views.append(View('Normal')) #table view - d.views.append(ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem + #d.blocks.append(b) #table blocks + #goes automatic: d.styles.append(DXF.Style()) #table styles + d.views.append(DXF.View('Normal')) #table view + d.views.append(DXF.ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem #add Entities -------------------- - something_ready = False - #ViewVector = Mathutils.Vector(Window.GetViewVector()) - #print 'deb: ViewVector=', ViewVector #------------------ - mw0 = Window.GetViewMatrix() - #mw0 = Window.GetPerspMatrix() #TODO: how get it working? - mw = mw0.copy() - if FLATTEN: - m0 = Mathutils.Matrix() - m0[2][2]=0.0 - mw *= m0 #flatten ViewMatrix + something_ready = 0 + sce = Scene.GetCurrent() - if APPLY_MODIFIERS: - tmp_me = Mesh.New('tmp') - else: - tmp_me = None + mw = Mathutils.Matrix( [1.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 1.0]) + if PROJECTION: + if CAMERA