From 983ffa63d7688013ee4bc7d2171cc1f33869303c Mon Sep 17 00:00:00 2001 From: Remigiusz Fiedler Date: Mon, 8 Jun 2009 01:29:58 +0000 Subject: [PATCH] DXF-Exporter script update v1.34 - 2009.06.08 - export Lamps and Cameras as POINTs - export passepartout for perspective projection - added option for export objects only from visible layers --- release/scripts/export_dxf.py | 325 +++++++++++++++++++++------------- 1 file changed, 199 insertions(+), 126 deletions(-) diff --git a/release/scripts/export_dxf.py b/release/scripts/export_dxf.py index 75cbd9d0014..b32962241cc 100644 --- a/release/scripts/export_dxf.py +++ b/release/scripts/export_dxf.py @@ -7,7 +7,7 @@ Tooltip: 'Export geometry to DXF/DWG-r12 (Drawing eXchange Format).' """ -__version__ = "1.34 - 2009.06.07" +__version__ = "1.34 - 2009.06.08" __author__ = "Remigiusz Fiedler (AKA migius)" __license__ = "GPL" __url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" @@ -17,7 +17,7 @@ Version %s Copyright %s License %s -extern dependances: dxfLibrary.py, (optionaly: DConvertCon.exe) +extern dependances: dxfLibrary.py, dxfColorMap.py (optionaly: DConvertCon.exe) CONTRIBUTORS: Remigiusz Fiedler (AKA migius) @@ -28,21 +28,27 @@ See the homepage for documentation. url: %s IDEAs: -- HPGL output, especially usefull for correct scaled printing of 2d drawings +- HPGL output, usefull for correct scaled printing of 2d drawings TODO: - export dupligroups and dupliverts as blocks (option for the user to decide) - optimize POLYFACE routine: remove double-vertices -- optimize POLYFACE routine: remove loose vertices -- stable support X,Y-rotated curves(to POLYLINEs): fix blender negative-matrix.invert() +- more stable support for X,Y-rotated curves(to POLYLINEs): fix blender negative-matrix.invert() - support hierarchies: groups, instances, parented structures -- write drawing extends for automatic view positioning in CAD +- support n/f-gons as POLYFACEs with invisible edges - mapping materials to DXF-styles -- wip: corrected text-objects in persp-projection -- wip: fix filter out objects from inactive(off) layers +- ProgressBar +- wip: write drawing extends for automatic view positioning in CAD +- wip: correct text-objects in persp-projection +- wip: translate Camera to VPORT/VIEW +- wip: translate current 3D-View to *ACTIVE-VPORT History -v1.34 - 2009.06.07 by migius +v1.34 - 2009.06.08 by migius +- export Lamps and Cameras as POINTs +- export passepartout for perspective projection +- added option for export objects only from visible layers +- optimized POLYFACE output: remove loose vertices in back-faces-mode - cleaning code - fix nasty bug in getExtrusion() - support text-objects, also in ortho/persp-projection @@ -58,7 +64,7 @@ v1.33 - 2009.05.25 by migius - 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 +- debug mode for curve-objects: output redirect to Blender - wip support 210-code(extrusion) calculation - default settings for 2D and 3D export v1.31 - 2009.05.18 by migius @@ -150,18 +156,20 @@ d2r = math.pi / 180.0 print '\n\n\n' print 'DXF-Exporter v%s *** start ***' %(__version__) #--------------------- -#DEBUG = True #activets debug mode +#DEBUG = True #activates debug mode #----globals------------------------------------------ ONLYSELECTED = 1 # 0/1 = False/True +ONLYVISIBLE = 1 # ignore objects on invisible layers POLYLINES = 1 # prefer POLYLINEs not LINEs POLYFACES = 1 # prefer POLYFACEs not 3DFACEs -PROJECTION = 0 # flatten output geometry to Z = 0.0 +PROJECTION = 0 # output geometry will be projected to XYplane with 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 +CAMERA = 1 # selected camera index +PERSPECTIVE = 0 # projection (camera) type: perspective, opposite to orthographic +CAMERAVIEW = 0 # use camera for projection, opposite is 3d-view APPLY_MODIFIERS = 1 INCLUDE_DUPLIS = 0 OUTPUT_DWG = 0 #optional save to DWG with extern converter @@ -170,13 +178,6 @@ 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 @@ -266,7 +267,7 @@ def updateCAMERA(): if currcam: currcam = currcam.getName() if currcam in CAMERAS: CAMERA = CAMERAS.index(currcam)+1 - GUI_A['camera_on'].val = CAMERA + GUI_A['camera_selected'].val = CAMERA #---------------------------------------------- def gotoCAMERA(): @@ -502,27 +503,23 @@ def exportMesh(ob, mx, mx_n, me=None, **common): else: me.getFromObject(ob) # me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state - # above is eventualy faster, but bad, cause - # invasive: directly transforms origin geometry and write back rounding errors - #we dont want to manipulate origin data + # above .transform method is faster, 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.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: - for p in allpoints: - p[0] += G_ORIGIN[0] - p[1] += G_ORIGIN[1] - p[2] += G_ORIGIN[2] + allpoints = toNewOrigin(allpoints) faces=[] edges=[] if me.faces and PROJECTION and HIDDEN_LINES: - if DEBUG: print 'deb:exportMesh HIDDEN_LINES mode' #--------- + #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: - if DEBUG: print 'deb:exportMesh STANDARD mode' #--------- + #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] @@ -553,23 +550,23 @@ def exportMesh(ob, mx, mx_n, me=None, **common): 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] - - 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,new_position,newverts=0,[],[] - for used_i,used in enumerate(verts_state): - if used: - newverts.append(allpoints[used_i]) - new_position.append(i) - i+=1 - allpoints = newverts - faces = [[new_position[v]+1 for v in f] for f in faces] - else: + if not (PROJECTION and HIDDEN_LINES): faces = [[v+1 for v in f] for f in faces] + else: + # for back-Faces-mode remove face-free verts + 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] dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag=64, **common) #print '\n deb: dxfPOLYFACE=',dxfPOLYFACE #------------- entities.append(dxfPOLYFACE) @@ -642,17 +639,26 @@ def curve_drawBlender(vertList, org_point=[0.0,0.0,0.0], closed=0, name="dxfCurv #return ob +#----------------------------------------------------- +def toNewOrigin(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 + + #----------------------------------------------------- def exportEmpty(ob, mx, mw, **common): """converts Empty-Object to desired projection and representation(DXF-Entity type) """ p = Mathutils.Vector(ob.loc) - #print 'deb: is it a vector?:', p #--------------- [p] = projected_co([p], mx) - if GUI_A['g_origin_on'].val: #TODO: scale and object orientation - p[0] += G_ORIGIN[0] - p[1] += G_ORIGIN[1] - p[2] += G_ORIGIN[2] + [p] = toNewOrigin([p]) entities = [] c = empty_as_list[GUI_A['empty_as'].val] @@ -661,6 +667,36 @@ def exportEmpty(ob, mx, mw, **common): entities.append(dxfPOINT) return entities +#----------------------------------------------------- +def exportCamera(ob, mx, mw, **common): + """converts Camera-Object to desired projection and representation(DXF-Entity type) + """ + p = Mathutils.Vector(ob.loc) + [p] = projected_co([p], mx) + [p] = toNewOrigin([p]) + + entities = [] + c = camera_as_list[GUI_A['camera_as'].val] + if c=="POINT": # export as POINT + dxfPOINT = DXF.Point(points=[p],**common) + entities.append(dxfPOINT) + return entities + +#----------------------------------------------------- +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] = toNewOrigin([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 + #----------------------------------------------------- def exportText(ob, mx, mw, **common): """converts Text-Object to desired projection and representation(DXF-Entity type) @@ -719,13 +755,10 @@ def exportText(ob, mx, mw, **common): #print 'deb: coef=', coef #-------------- #print 'deb: point=', point #-------------- - if GUI_A['g_origin_on'].val: #TODO: scale and object orientation - point[0] += G_ORIGIN[0] - point[1] += G_ORIGIN[1] - point[2] += G_ORIGIN[2] + [point] = toNewOrigin([point]) point2 = point - if 0: pass #DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene + #if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene common['extrusion']= Extrusion #common['elevation']= Elevation common['thickness']= Thickness @@ -870,11 +903,8 @@ def exportCurve(ob, mx, mw, **common): if cur.isCyclic(): closed = 1 else: closed = 0 - if GUI_A['g_origin_on'].val: #TODO: scale and object orientation - for p in points: - p[0] += G_ORIGIN[0] - p[1] += G_ORIGIN[1] - p[2] += G_ORIGIN[2] + points = toNewOrigin(points) + if DEBUG: curve_drawBlender(points,OCS_origin,closed) #deb: draw to scene common['extrusion']= Extrusion ##common['rotation']= ZRotation @@ -905,11 +935,8 @@ def exportCurve(ob, mx, mw, **common): points = projected_co(points, mx) if cur.isCyclic(): points.append(points[0]) #print 'deb: points', points #-------------- - if GUI_A['g_origin_on'].val: #TODO: scale and object orientation - for p in points: - p[0] += G_ORIGIN[0] - p[1] += G_ORIGIN[1] - p[2] += G_ORIGIN[2] + points = toNewOrigin(points) + if DEBUG: curve_drawBlender(points,WCS_loc,closed) #deb: draw to scene common['extrusion']= Extrusion common['elevation']= Elevation @@ -977,7 +1004,7 @@ def getClipBox(camera): scaleZ = 1.0/float(far - near) z3 = -float(near)/float(far - near) - matr = Mathutils.Matrix( [scaleX, 0.0, 0.0, x3], + matrix = 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]) @@ -1014,7 +1041,7 @@ def getClipBox(camera): #[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], + matrix = 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]) @@ -1028,7 +1055,7 @@ def getClipBox(camera): clip1_Z, clip2_Z] #print 'deb: clip_box=\n', clip_box #------------------ #drawClipBox(clip_box) - return clip_box, matr + return clip_box, matrix #----------------------------------------------------- @@ -1143,19 +1170,19 @@ def getCommons(ob): #----------------------------------------------------- def do_export(export_list, filepath): - global PERSPECTIVE + global PERSPECTIVE, CAMERAVIEW Window.WaitCursor(1) t = Blender.sys.time() - #init Drawing --------------------- + # init Drawing --------------------- d=DXF.Drawing() - #add Tables ----------------- + # add Tables ----------------- #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('BF_TOPVIEW',leftBottom=(-10,-6),rightTop=(10,6))) #idem + d.views.append(DXF.ViewByWindow('BF_TOPVIEW',leftBottom=(-100,-60),rightTop=(100,60))) #idem - #add Entities -------------------- + # add Entities -------------------- something_ready = 0 selected_len = len(export_list) sce = Scene.GetCurrent() @@ -1165,38 +1192,47 @@ def do_export(export_list, filepath): [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]) if PROJECTION: - if CAMERA', EVENT_setCAMERA, b0+b0_-20, y, 20, 20, 'switch to selected Camera - make it active') - GUI_A['hidden_lines_on'] = Draw.Toggle('Hide back-Faces', EVENT_NONE, b0, y-20, b0_, 20, GUI_A['hidden_lines_on'].val, "Filter out back-Faces on/off") - #GUI_A['shadows_on'] = Draw.Toggle('..Shadows', EVENT_REDRAW, b0, y-40, but_2c, 20, GUI_A['shadows_on'].val, "(*todo) Shadow tracing on/off") - #GUI_A['light_on'] = Draw.Menu(MenuLIGHT, EVENT_LIGHT, but3c, y-40, but_3c, 20, GUI_A['light_on'].val, '(*todo) Choose the light source(sun) to be rendered') + GUI_A['camera_selected'] = Draw.Menu(MenuCAMERA, EVENT_CAMERA, b0, y-20, b0_-20, 20, GUI_A['camera_selected'].val, 'Choose the camera to be rendered') + Draw.PushButton('>', EVENT_setCAMERA, b0+b0_-20, y-20, 20, 20, 'switch to selected Camera - make it active') + GUI_A['hidden_lines_on'] = Draw.Toggle('Remove backFaces', EVENT_NONE, b0, y-40, b0_, 20, GUI_A['hidden_lines_on'].val, "Filter out backFaces on/off") + #GUI_A['shadows_on'] = Draw.Toggle('..Shadows', EVENT_REDRAW, b0, y-60, but_2c, 20, GUI_A['shadows_on'].val, "(*todo) Shadow tracing on/off") + #GUI_A['light_on'] = Draw.Menu(MenuLIGHT, EVENT_LIGHT, but3c, y-60, but_3c, 20, GUI_A['light_on'].val, '(*todo) Choose the light source(sun) to be rendered') Draw.EndAlign() + y -= 20 + b0, b0_ = but0c, but_0c + butt_margin +but_1c + GUI_A['only_visible_on'] = Draw.Toggle('Visible only', EVENT_PRESETPLINE, b0, y, b0_, 20, GUI_A['only_visible_on'].val, "Export only from visible layers on/off") + #b0, b0_ = but2c, but_2c + butt_margin + but_3c + + y -= 20 + b0, b0_ = but0c, but_0c + butt_margin +but_1c + GUI_A['to_polyline_on'] = Draw.Toggle('POLYLINE-Mode', EVENT_PRESETPLINE, b0, y, b0_, 20, GUI_A['to_polyline_on'].val, "Export to POLYLINE/POLYFACEs, otherwise to LINEs/3DFACEs on/off") + #b0, b0_ = but2c, but_2c + butt_margin + but_3c + y -= 20 b0, b0_ = but0c, but_0c + butt_margin +but_1c GUI_A['apply_modifiers_on'] = Draw.Toggle('Apply Modifiers', EVENT_NONE, b0, y, b0_, 20, GUI_A['apply_modifiers_on'].val, "Apply modifier stack to mesh objects before export on/off") - b0, b0_ = but2c, but_2c + butt_margin + but_3c + #b0, b0_ = but2c, but_2c + butt_margin + but_3c y -= 20 b0, b0_ = but0c, but_0c + butt_margin +but_1c GUI_A['include_duplis_on'] = Draw.Toggle('Include Duplis', EVENT_NONE, b0, y, b0_, 20, GUI_A['include_duplis_on'].val, "Export Duplicates (dupliverts, dupliframes, dupligroups) on/off") - b0, b0_ = but2c, but_2c + butt_margin + but_3c + #b0, b0_ = but2c, but_2c + butt_margin + but_3c + - y -= 50 + y -= 30 Draw.PushButton('EXIT', EVENT_EXIT, but0c, y, but_0c+bm, 20, '' ) Draw.PushButton('HELP', EVENT_HELP, but1c, y, but_1c+bm, 20, 'goes to online-Manual on wiki.blender.org') GUI_A['optimization'] = Draw.Number('', EVENT_NONE, but2c, y, 40, 20, GUI_A['optimization'].val, 0, 3, "Optimization Level: 0=Debug/Draw-in, 1=Verbose, 2=ProgressBar, 3=SilentMode") @@ -2541,11 +2604,11 @@ def bevent(evt): resetDefaultConfig_3D() Draw.Redraw() elif evt in (EVENT_CAMERA,EVENT_LIGHT): - CAMERA = GUI_A['camera_on'].val + CAMERA = GUI_A['camera_selected'].val if CAMERA==len(CAMERAS)+1: doAllCameras = True else: - print 'deb: CAMERAS=',CAMERAS #---------------- + pass #print 'deb: CAMERAS=',CAMERAS #---------------- Draw.Redraw() elif (evt==EVENT_setCAMERA): if CAMERA