diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-04-20 19:06:46 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-04-20 19:06:46 +0400 |
commit | 874c29cea8e6f9bc411fccf2d6f4cb07e94328d0 (patch) | |
tree | 5971e577cf7c02e05a1e37b5ad058c71a6744877 /release/scripts | |
parent | 7555bfa793a2b0fc187c6211c56986f35b2d7b09 (diff) | |
parent | c5bc4e4fb1a33eda8c31f2ea02e91f32f74c8fa5 (diff) |
2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r19323:HEAD
Notes:
* blenderbuttons and ICON_SNAP_PEEL_OBJECT were not merged.
Diffstat (limited to 'release/scripts')
-rw-r--r-- | release/scripts/3ds_import.py | 5 | ||||
-rw-r--r-- | release/scripts/bevel_center.py | 2 | ||||
-rw-r--r-- | release/scripts/bpymodules/dxfLibrary.py | 59 | ||||
-rw-r--r-- | release/scripts/export_dxf.py | 195 | ||||
-rw-r--r-- | release/scripts/image_auto_layout.py | 13 | ||||
-rw-r--r-- | release/scripts/import_dxf.py | 245 | ||||
-rw-r--r-- | release/scripts/import_obj.py | 2 | ||||
-rw-r--r--[-rwxr-xr-x] | release/scripts/import_web3d.py | 7 | ||||
-rw-r--r-- | release/scripts/mesh_poly_reduce_grid.py | 351 | ||||
-rw-r--r-- | release/scripts/scripttemplate_camera_object.py (renamed from release/scripts/scripttemplate_camer_object.py) | 0 | ||||
-rw-r--r-- | release/scripts/uvcalc_smart_project.py | 2 |
11 files changed, 733 insertions, 148 deletions
diff --git a/release/scripts/3ds_import.py b/release/scripts/3ds_import.py index 028b9633606..1963d2e7433 100644 --- a/release/scripts/3ds_import.py +++ b/release/scripts/3ds_import.py @@ -844,11 +844,13 @@ def load_3ds(filename, PREF_UI= True): # IMPORT_AS_INSTANCE= Blender.Draw.Create(0) IMPORT_CONSTRAIN_BOUNDS= Blender.Draw.Create(10.0) IMAGE_SEARCH= Blender.Draw.Create(1) + APPLY_MATRIX= Blender.Draw.Create(0) # Get USER Options pup_block= [\ ('Size Constraint:', IMPORT_CONSTRAIN_BOUNDS, 0.0, 1000.0, 'Scale the model by 10 until it reacehs the size constraint. Zero Disables.'),\ ('Image Search', IMAGE_SEARCH, 'Search subdirs for any assosiated images (Warning, may be slow)'),\ + ('Transform Fix', APPLY_MATRIX, 'Workaround for object transformations importing incorrectly'),\ #('Group Instance', IMPORT_AS_INSTANCE, 'Import objects into a new scene and group, creating an instance in the current scene.'),\ ] @@ -861,6 +863,7 @@ def load_3ds(filename, PREF_UI= True): IMPORT_CONSTRAIN_BOUNDS= IMPORT_CONSTRAIN_BOUNDS.val # IMPORT_AS_INSTANCE= IMPORT_AS_INSTANCE.val IMAGE_SEARCH = IMAGE_SEARCH.val + APPLY_MATRIX = APPLY_MATRIX.val if IMPORT_CONSTRAIN_BOUNDS: BOUNDS_3DS[:]= [1<<30, 1<<30, 1<<30, -1<<30, -1<<30, -1<<30] @@ -887,6 +890,8 @@ def load_3ds(filename, PREF_UI= True): if ob.type=='Mesh': me= ob.getData(mesh=1) me.verts.delete([me.verts[0],]) + if not APPLY_MATRIX: + me.transform(ob.matrixWorld.copy().invert()) # Done DUMMYVERT """ diff --git a/release/scripts/bevel_center.py b/release/scripts/bevel_center.py index 063c6380483..637ed08127f 100644 --- a/release/scripts/bevel_center.py +++ b/release/scripts/bevel_center.py @@ -1,5 +1,5 @@ #!BPY -# coding: utf-8 +# -*- coding: utf-8 -*- """ Registration info for Blender menus Name: 'Bevel Center' Blender: 243 diff --git a/release/scripts/bpymodules/dxfLibrary.py b/release/scripts/bpymodules/dxfLibrary.py index 96caa50cc41..5390be084ee 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.28beta - 2008.12.13" +__version__ = "v1.29beta - 2008.12.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,11 @@ IDEAs: - TODO: -- add support for SPLINEs +- add support for SPLINEs, (bad idea, cause DXF r14 object :( History +v1.29 - 2008.12.28 by Yorik +- modif POLYLINE to support bulge segments v1.28 - 2008.12.13 by Steeve/BlenderArtists - bugfix for EXTMIN/EXTMAX to suit Cycas-CAD v1.27 - 2008.10.07 by migius @@ -297,41 +299,60 @@ class Line(_Entity): #----------------------------------------------- class PolyLine(_Entity): def __init__(self,points,org_point=[0,0,0],flag=0,width=None,**common): + #width = number, or width = list [width_start=None, width_end=None] + #for 2d-polyline: points = [ [x, y, z, width_start=None, width_end=None, bulge=0 or None], ...] + #for 3d-polyline: points = [ [x, y, z], ...] + #for polyface: points = [points_list, faces_list] _Entity.__init__(self,**common) self.points=points self.org_point=org_point self.flag=flag - if self.flag==64: + if self.flag & POLYFACE_MESH: + self.polyface=True self.points=points[0] self.faces=points[1] self.p_count=len(self.points) self.f_count=len(self.faces) - self.width=width + elif not self.flag & POLYLINE_3D: + self.polyline2d = True + if width: + if type(width)!='list': + width=[width,width] + self.width=width def __str__(self): result= ' 0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.flag) #print 'deb: self._common()', self._common() #---------- result+=' 66\n1\n' result+='%s\n' %_point(self.org_point) - if self.flag==64: + if self.polyface: result+=' 71\n%s\n' %self.p_count result+=' 72\n%s\n' %self.f_count + elif self.polyline2d: + if self.width: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1]) for point in self.points: result+=' 0\nVERTEX\n' result+=' 8\n%s\n' %self.layer - result+='%s\n' %_point(point) - if self.flag==64: result+=' 70\n192\n' - if self.width: result+=' 40\n%s\n 41\n%s\n' %(self.width,self.width) - if self.flag==64: - for face in self.faces: - result+=' 0\nVERTEX\n' - result+=' 8\n%s\n' %self.layer - result+='%s\n' %_point(self.org_point) - result+=' 70\n128\n' - result+=' 71\n%s\n' %face[0] - result+=' 72\n%s\n' %face[1] - result+=' 73\n%s\n' %face[2] - if len(face)==4: result+=' 74\n%s\n' %face[3] + result+='%s\n' %_point(point[0:2]) + if self.polyface: + result+=' 70\n192\n' + elif self.polyline2d: + if len(point)>4: + width1, width2 = point[3], point[4] + if width1!=None: result+=' 40\n%s\n' %width1 + if width2!=None: result+=' 41\n%s\n' %width2 + if len(point)==6: + bulge = point[5] + if bulge: result+=' 42\n%s\n' %bulge + for face in self.faces: + result+=' 0\nVERTEX\n' + result+=' 8\n%s\n' %self.layer + result+='%s\n' %_point(self.org_point) + result+=' 70\n128\n' + result+=' 71\n%s\n' %face[0] + result+=' 72\n%s\n' %face[1] + result+=' 73\n%s\n' %face[2] + if len(face)==4: result+=' 74\n%s\n' %face[3] result+=' 0\nSEQEND\n' result+=' 8\n%s\n' %self.layer return result @@ -711,5 +732,5 @@ def test(): if __name__=='__main__': if not copy: Draw.PupMenu('Error%t|This script requires a full python install') - main() + else: main()
\ No newline at end of file diff --git a/release/scripts/export_dxf.py b/release/scripts/export_dxf.py index 061e29b81c7..99c6acaceab 100644 --- a/release/scripts/export_dxf.py +++ b/release/scripts/export_dxf.py @@ -1,14 +1,14 @@ #!BPY """ - Name: 'Autodesk DXF (.dxf)' + Name: 'Autodesk (.dxf .dwg)' Blender: 247 Group: 'Export' - Tooltip: 'Export geometry to DXF-r12 (Drawing eXchange Format).' + Tooltip: 'Export geometry to Autocad DXF/DWG-r12 (Drawing eXchange Format).' """ -__version__ = "v1.27beta - 2008.10.07" -__author__ = "Remigiusz Fiedler (AKA migius)" +__version__ = "v1.29 - 2009.04.11" +__author__ = "Remigiusz Fiedler (AKA migius), Alexandros Sigalas (AKA alxarch), Stani Michiels" __license__ = "GPL" __url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" __bpydoc__ ="""The script exports Blender geometry to DXF format r12 version. @@ -25,8 +25,9 @@ url: %s IDEAs: - correct normals for POLYLINE-POLYFACE via proper point-order - HPGL output for 2d and flattened 3d content - + 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 @@ -36,6 +37,11 @@ TODO: - write drawing extends for automatic view positioning in CAD History +v1.29 - 2009.04.11 by migius +- added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter +v1.28 - 2009.02.05 by alxarch +- added option to apply modifiers on exported meshes +- added option to also export duplicates (from dupliverts etc) v1.27 - 2008.10.07 by migius - exclude Stani's DXF-Library to extern module v1.26 - 2008.10.05 by migius @@ -86,14 +92,95 @@ ______________________________________________________________ import Blender -from Blender import Mathutils, Window, Scene, sys, Draw +from Blender import Mathutils, Window, Scene, sys, Draw, Mesh import BPyMessages +import os +import subprocess + +#print os.sys.platform +#print dir(os.sys.version) #import dxfLibrary #reload(dxfLibrary) 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 + + + +#----------------------------------------------------- +def dupTest(object): + """ + Checks objects for duplicates enabled (any type) + object: Blender Object. + Returns: Boolean - True if object has any kind of duplicates enabled. + """ + if (object.enableDupFrames or \ + object.enableDupGroup or \ + object.enableDupVerts): + return True + else: + return False + +def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False): + """ + Return a list of real objects and duplicates and optionally their matrices + oblist: List of Blender Objects + MATRICES: Boolean - Check to also get the objects matrices default=False + HACK: Boolean - See note default=False + Returns: List of objects or + List of tuples of the form:(ob,matrix) if MATRICES is set to True + NOTE: There is an ugly hack here that excludes all objects whose name + starts with "dpl_" to exclude objects that are parented to a duplicating + object, User must name objects properly if hack is used. + """ + + result = [] + for ob in oblist: + if dupTest(ob): + dup_obs=ob.DupObjects + if len(dup_obs): + for dup_ob, dup_mx in dup_obs: + if MATRICES: + result.append((dup_ob,dup_mx)) + else: + result.append(dup_ob) + else: + if HACK: + if ob.getName()[0:4] != "dpl_": + if MATRICES: + mx = ob.mat + result.append((ob,mx)) + else: + result.append(ob) + else: + if MATRICES: + mx = ob.mat + result.append((ob,mx)) + else: + result.append(ob) + return result + #----------------------------------------------------- def hidden_status(faces, mx_n): #print 'HIDDEN_MODE: caution! not full implemented yet' @@ -146,9 +233,13 @@ def flatten(points, mw): return points #----------------------------------------------------- -def exportMesh(ob, mx, mx_n): +def exportMesh(ob, mx, mx_n,me=None): entities = [] - me = ob.getData(mesh=1) + global APPLY_MODIFIERS + if me is None: + me = ob.getData(mesh=1) + else: + me.getFromObject(ob) #me.transform(mx) # above is eventualy faster, but bad, cause # directly transforms origin geometry and write back rounding errors @@ -209,7 +300,7 @@ def exportMesh(ob, mx, mx_n): points = [ me_verts[key].co[:3] for key in e] dxfLINE = Line(points) entities.append(dxfLINE) - + else: for e in me.edges: #print 'deb: edge=', e #--------- @@ -257,7 +348,7 @@ def exportCurve(ob, mx): return entities #----------------------------------------------------- -def do_export(sel_group, filepath): +def do_export(export_list, filepath): Window.WaitCursor(1) t = sys.time() @@ -281,22 +372,27 @@ def do_export(sel_group, filepath): m0[2][2]=0.0 mw *= m0 #flatten ViewMatrix - for ob in sel_group: + if APPLY_MODIFIERS: + tmp_me = Mesh.New('tmp') + else: + tmp_me = None + + for ob,mx in export_list: entities = [] - mx = ob.matrix.copy() + #mx = ob.matrix.copy() mb = mx.copy() #print 'deb: mb =\n', mb #--------- #print 'deb: mw0 =\n', mw0 #--------- mx_n = mx.rotationPart() * mw0.rotationPart() #trans-matrix for normal_vectors if SCALE_FACTOR!=1.0: mx *= SCALE_FACTOR if FLATTEN: mx *= mw - + #mx_inv = mx.copy().invert() #print 'deb: mx =\n', mx #--------- #print 'deb: mx_inv=\n', mx_inv #--------- if (ob.type == 'Mesh'): - entities = exportMesh(ob, mx, mx_n) + entities = exportMesh(ob, mx, mx_n,tmp_me) elif (ob.type == 'Curve'): entities = exportCurve(ob, mx) @@ -305,11 +401,30 @@ def do_export(sel_group, filepath): something_ready = True if something_ready: - d.saveas(filepath) - Window.WaitCursor(0) - #Draw.PupMenu('DXF Exporter: job finished') - print 'exported to %s' % filepath - print 'finished in %.2f seconds' % (sys.time()-t) + if not OUTPUT_DWG: + print 'exporting to %s' % filepath + d.saveas(filepath) + Window.WaitCursor(0) + #Draw.PupMenu('DXF Exporter: job finished') + print ' finished in %.2f seconds. -----DONE-----' % (sys.time()-t) + else: + if not extCONV_OK: + Draw.PupMenu(extCONV_TEXT) + Window.WaitCursor(False) + else: + print 'temp. exporting to %s' % filepath + d.saveas(filepath) + #Draw.PupMenu('DXF Exporter: job finished') + #print 'exported to %s' % filepath + #print 'finished in %.2f seconds' % (sys.time()-t) + filedwg = filepath[:-3]+'dwg' + print 'exporting to %s' % filedwg + os.system('%s %s -acad13 -dwg' %(extCONV_PATH,filepath)) + #os.chdir(cwd) + os.remove(filepath) + Window.WaitCursor(0) + print ' finished in %.2f seconds. -----DONE-----' % (sys.time()-t) + else: Window.WaitCursor(0) print "Abort: selected objects dont mach choosen export option, nothing exported!" @@ -323,8 +438,9 @@ POLYFACES = 1 FLATTEN = 0 HIDDEN_MODE = False #filter out hidden lines SCALE_FACTOR = 1.0 #optional, can be done later in CAD too - - +APPLY_MODIFIERS = True +INCLUDE_DUPLIS = False +OUTPUT_DWG = False #optional save to DWG with extern converter #----------------------------------------------------- def dxf_export_ui(filepath): @@ -334,9 +450,12 @@ def dxf_export_ui(filepath): POLYFACES,\ FLATTEN,\ HIDDEN_MODE,\ - SCALE_FACTOR + SCALE_FACTOR,\ + APPLY_MODIFIERS,\ + OUTPUT_DWG,\ + INCLUDE_DUPLIS - print '\n\nDXF-Export %s -----------------------' %__version__ + print '\n\nDXF-Export %s -----------START-----------' %__version__ #filepath = 'blend_test.dxf' # Dont overwrite if not BPyMessages.Warning_SaveOver(filepath): @@ -352,19 +471,26 @@ def dxf_export_ui(filepath): PREF_FLATTEN= Draw.Create(FLATTEN) PREF_HIDDEN_MODE= Draw.Create(HIDDEN_MODE) PREF_SCALE_FACTOR= Draw.Create(SCALE_FACTOR) + PREF_APPLY_MODIFIERS= Draw.Create(APPLY_MODIFIERS) + PREF_INCLUDE_DUPLIS= Draw.Create(INCLUDE_DUPLIS) PREF_HELP= Draw.Create(0) + PREF_DWG= Draw.Create(OUTPUT_DWG) block = [\ ("only selected", PREF_ONLYSELECTED, "export only selected geometry"),\ + ("Apply Modifiers", PREF_APPLY_MODIFIERS, "Apply modifier stack to mesh objects before export"),\ + ("Include Duplis", PREF_INCLUDE_DUPLIS, "Export also Duplicates (dupliverts, dupliframes etc)"),\ ("global Scale:", PREF_SCALE_FACTOR, 0.001, 1000, "set global Scale factor for exporting geometry"),\ - ("only faces", PREF_ONLYFACES, "from mesh-objects export only faces, otherwise only edges"),\ - ("write POLYFACE", PREF_POLYFACES, "export mesh to POLYFACE, otherwise to 3DFACEs"),\ - ("write POLYLINEs", PREF_POLYLINES, "export curve to POLYLINE, otherwise to LINEs"),\ + (''),\ + ("export to 3DFaces", PREF_ONLYFACES, "from mesh-objects export only faces, otherwise only edges"),\ + ("mesh to POLYFACE", PREF_POLYFACES, "export mesh to POLYFACE, otherwise to 3DFACEs"),\ + ("curves to POLYLINEs", PREF_POLYLINES, "export curve to POLYLINE, otherwise to LINEs"),\ ("3D-View to Flat", PREF_FLATTEN, "flatten geometry according current 3d-View"),\ ("Hidden Mode", PREF_HIDDEN_MODE, "filter out hidden lines"),\ - #(''),\ ("online Help", PREF_HELP, "calls DXF-Exporter Manual Page on Wiki.Blender.org"),\ + (''),\ + ("DXF->DWG", PREF_DWG, "writes DWG with extern converter"),\ ] - + if not Draw.PupBlock("DXF-Exporter %s" %__version__[:10], block): return if PREF_HELP.val!=0: @@ -372,7 +498,7 @@ def dxf_export_ui(filepath): import webbrowser webbrowser.open('http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf') except: - Draw.PupMenu('DXF Exporter: %t|no connection to manual-page on Blender-Wiki! try:|\ + Draw.PupMenu('DXF Exporter: %t|no connection to manual-page on Blender-Wiki! try:|\ http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf') return @@ -383,12 +509,14 @@ http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf') FLATTEN = PREF_FLATTEN.val HIDDEN_MODE = PREF_HIDDEN_MODE.val SCALE_FACTOR = PREF_SCALE_FACTOR.val - + OUTPUT_DWG = PREF_DWG.val + sce = Scene.GetCurrent() if ONLYSELECTED: sel_group = sce.objects.selected else: sel_group = sce.objects + export_list = getObjectsAndDuplis(sel_group,MATRICES=True) - if sel_group: do_export(sel_group, filepath) + if export_list: do_export(export_list, filepath) else: print "Abort: selection was empty, no object to export!" Draw.PupMenu('DXF Exporter: nothing exported!|empty selection!') @@ -401,7 +529,4 @@ if __name__=='__main__': #main() if not copy: Draw.PupMenu('Error%t|This script requires a full python install') - Window.FileSelector(dxf_export_ui, 'EXPORT DXF', sys.makename(ext='.dxf')) - - -
\ No newline at end of file + else: Window.FileSelector(dxf_export_ui, 'EXPORT DXF', sys.makename(ext='.dxf'))
\ No newline at end of file diff --git a/release/scripts/image_auto_layout.py b/release/scripts/image_auto_layout.py index c6f97a25434..d19ba1da662 100644 --- a/release/scripts/image_auto_layout.py +++ b/release/scripts/image_auto_layout.py @@ -9,7 +9,7 @@ Tooltip: 'Pack all texture images into 1 image and remap faces.' __author__ = "Campbell Barton" __url__ = ("blender", "blenderartists.org") -__version__ = "1.1 2007/02/15" +__version__ = "1.1a 2009/04/01" __bpydoc__ = """\ This script makes a new image from the used areas of all the images mapped to the selected mesh objects. @@ -273,9 +273,12 @@ def consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PR # New Mesh and Object render_mat= B.Material.New() - render_mat.mode |= B.Material.Modes.SHADELESS - render_mat.mode |= B.Material.Modes.TEXFACE - render_mat.mode |= B.Material.Modes.ZTRANSP + render_mat.mode |= \ + B.Material.Modes.SHADELESS | \ + B.Material.Modes.TEXFACE | \ + B.Material.Modes.TEXFACE_ALPHA | \ + B.Material.Modes.ZTRANSP + render_mat.setAlpha(0.0) render_me= B.Mesh.New() @@ -420,7 +423,7 @@ def main(): PREF_IMAGE_PATH= PREF_IMAGE_PATH.val PREF_IMAGE_SIZE= PREF_IMAGE_SIZE.val - PREF_IMAGE_MARGIN= PREF_IMAGE_MARGIN.val + PREF_IMAGE_MARGIN= float(PREF_IMAGE_MARGIN.val) # important this is a float otherwise division wont work properly PREF_KEEP_ASPECT= PREF_KEEP_ASPECT.val PREF_ALL_SEL_OBS= PREF_ALL_SEL_OBS.val diff --git a/release/scripts/import_dxf.py b/release/scripts/import_dxf.py index c3203891c60..ceb4dd56722 100644 --- a/release/scripts/import_dxf.py +++ b/release/scripts/import_dxf.py @@ -1,20 +1,21 @@ #!BPY """ -Name: 'Autodesk DXF (.dxf)' +Name: 'Autodesk DXF (.dxf .dwg)' Blender: 246 Group: 'Import' -Tooltip: 'Import for DXF geometry data (Drawing eXchange Format).' +Tooltip: 'Import for DWG/DXF geometry data.' """ __author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)' -__version__ = '1.12 - 2009.03.14 by migius' +__version__ = '1.12 - 2009.04.11 by migius' __url__ = ["http://blenderartists.org/forum/showthread.php?t=84319", "http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"] __email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"] __bpydoc__ = """\ -This script imports objects from DXF (2d/3d) into Blender. +This script imports objects from DWG/DXF (2d/3d) into Blender. This script imports 2d and 3d geometery from DXF files. +It supports DWG format too, with help of an external converter. Supported DXF format versions: from (r2.5) r12 up to r2008. Enhanced features are: - configurable object filtering and geometry manipulation, @@ -111,6 +112,8 @@ History: -- support ortho mode for VIEWs and VPORTs as cameras + v1.12 - 2009.04.11 by migius + d4 added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter v1.12 - 2009.03.14 by migius d3 removed all set()functions (problem with osx/python<2.4 reported by Blinkozo) d3 code-cleaning @@ -305,7 +308,8 @@ History: # -------------------------------------------------------------------------- import Blender -from Blender import * +from Blender import Mathutils, BezTriple, Draw, Registry, sys,\ +Text3d, Window, Mesh, Material, Group #from Blender.Mathutils import Vector, Matrix #import bpy #not used yet #import BPyMessages @@ -314,7 +318,7 @@ from dxfReader import readDXF #from dxfReader import get_name, get_layer from dxfReader import Object as dxfObject from dxfColorMap import color_map -from math import * +from math import log10, sqrt, radians, degrees, atan, cos, sin # osx-patch by Blinkozo #todo: avoid additional modules, prefer Blender-build-in test routines @@ -325,9 +329,10 @@ from math import * #ver = '%s.%s' % version_info[0:2] # end osx-patch -try: - import os - if os.name != 'mac': +import subprocess +import os +if os.name != 'mac': + try: import psyco psyco.log(Blender.Get('tempdir')+"/blender.log-psyco") #psyco.log() @@ -335,14 +340,13 @@ try: psyco.profile(0.05, memory=100) psyco.profile(0.2) #print 'psyco imported' -except ImportError: - print 'psyco not imported' - pass + except ImportError: + print 'psyco not imported' #try: Curve.orderU print '\n\n\n' -print 'DXF-Importer v%s *** start ***' %(__version__) #--------------------- +print 'DXF/DWG-Importer v%s *** start ***' %(__version__) #--------------------- SCENE = None WORLDX = Mathutils.Vector((1,0,0)) @@ -386,6 +390,29 @@ FREE = BezTriple.HandleTypes.FREE VECT = BezTriple.HandleTypes.VECT ALIGN = BezTriple.HandleTypes.ALIGN +UI_MODE = True #activates UI-popup-print, if not multiple files imported + + +#-------- 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-Importer cant find external DWG-converter (%s) in 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 = 'The external DWG-converter (%s) needs Wine installed on your system.|\ +More details in online Help.' %extCONV +#print 'extCONV_PATH = ', extCONV_PATH + + class View: #----------------------------------------------------------------- """Class for objects representing dxf VIEWs. @@ -754,7 +781,7 @@ class Solid: #----------------------------------------------------------------- if settings.var['vGroup_on'] and not M_OBJ: # each MeshSide becomes vertexGroup for easier material assignment --------------------- - replace = Blender.Mesh.AssignModes.ADD #or .AssignModes.ADD/REPLACE + replace = Mesh.AssignModes.ADD #or .AssignModes.ADD/REPLACE if vg_left: me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace) if vg_right:me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace) if vg_top: me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace) @@ -899,7 +926,7 @@ class Line: #----------------------------------------------------------------- ob.link(me) # link mesh to that object vG_name = 'color_%s' %self.color_index if edges: faces = edges - replace = Blender.Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD + replace = Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD try: me.assignVertsToGroup(vG_name, faces[0], 1.0, replace) #print 'deb: existed vGroup:', vG_name #--------------------- @@ -1792,7 +1819,7 @@ class Polyline: #-------------------------------------------------------------- # which may be linked to more than one object. if settings.var['vGroup_on'] and not M_OBJ: # each MeshSide becomes vertexGroup for easier material assignment --------------------- - replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD + replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD vg_left, vg_right, vg_top, vg_bottom = [], [], [], [] for v in f_left: vg_left.extend(v) for v in f_right: vg_right.extend(v) @@ -2640,7 +2667,7 @@ class Circle: #---------------------------------------------------------------- # each MeshSide becomes vertexGroup for easier material assignment --------------------- if settings.var['vGroup_on'] and not M_OBJ: # each MeshSide becomes vertexGroup for easier material assignment --------------------- - replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD + replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD vg_band, vg_top, vg_bottom = [], [], [] for v in f_band: vg_band.extend(v) me.addVertGroup('side.band') ; me.assignVertsToGroup('side.band', vg_band, 1.0, replace) @@ -2820,7 +2847,7 @@ class Arc: #----------------------------------------------------------------- # each MeshSide becomes vertexGroup for easier material assignment --------------------- if settings.var['vGroup_on'] and not M_OBJ: # each MeshSide becomes vertexGroup for easier material assignment --------------------- - replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD + replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD vg_left, vg_right, vg_top, vg_bottom = [], [], [], [] for v in f_left: vg_left.extend(v) for v in f_right: vg_right.extend(v) @@ -3364,7 +3391,7 @@ class Ellipse: #--------------------------------------------------------------- me.faces[i].smooth = True if settings.var['vGroup_on'] and not M_OBJ: # each MeshSide becomes vertexGroup for easier material assignment --------------------- - replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD + replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD vg_left, vg_right, vg_top, vg_bottom = [], [], [], [] for v in f_left: vg_left.extend(v) for v in f_right: vg_right.extend(v) @@ -3517,7 +3544,7 @@ class Face: #----------------------------------------------------------------- ob.link(me) # link mesh to that object vG_name = 'color_%s' %self.color_index if edges: faces = edges - replace = Blender.Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD + replace = Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD try: me.assignVertsToGroup(vG_name, faces[0], 1.0, replace) #print 'deb: existed vGroup:', vG_name #--------------------- @@ -4022,10 +4049,8 @@ class Settings: #-------------------------------------------------------------- """Wraps the built-in print command in a optimization check. """ if self.var['optimization'] <= self.MID: - if newline: - print text - else: - print text, + if newline: print text + else: print text, def redraw(self): @@ -4067,9 +4092,9 @@ def analyzeDXF(dxfFile): #--------------------------------------- """ Window.WaitCursor(True) # Let the user know we are thinking print 'reading DXF file: %s.' % dxfFile - time1 = Blender.sys.time() #time marker1 + time1 = sys.time() #time marker1 drawing = readDXF(dxfFile, objectify) - print 'finish reading in %.4f sec.' % (Blender.sys.time()-time1) + print 'finish reading in %.4f sec.' % (sys.time()-time1) # First sort out all the section_items sections = dict([(item.name, item) for item in drawing.data]) @@ -4282,10 +4307,45 @@ def main(dxfFile): #---------------#############################----------- if dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile): Window.WaitCursor(True) # Let the user know we are thinking print 'reading file: %s.' % dxfFile - time1 = Blender.sys.time() #time marker1 + time1 = sys.time() #time marker1 drawing = readDXF(dxfFile, objectify) - print 'reading finished in %.4f sec.' % (Blender.sys.time()-time1) + print 'reading finished in %.4f sec.' % (sys.time()-time1) Window.WaitCursor(False) + elif dxfFile.lower().endswith('.dwg') and sys.exists(dxfFile): + if not extCONV_OK: + Draw.PupMenu(extCONV_TEXT) + Window.WaitCursor(False) + if editmode: Window.EditMode(1) # and put things back how we fond them + return None + else: + Window.WaitCursor(True) # Let the user know we are thinking + #todo: issue: in DConvertCon.exe the output filename is fixed to dwg_name.dxf + + if 0: # works only for Windows + dwgTemp = 'temp_01.dwg' + dxfTemp = 'temp_01.dxf' + os.system('copy %s %s' %(dxfFile,dwgTemp)) + else: + dwgTemp = dxfFile + dxfTemp = dxfFile[:-3]+'dxf' + #print 'temp. converting: %s\n to: %s' %(dxfFile, dxfTemp) + #os.system('%s %s -acad11 -dxf' %(extCONV_PATH, dxfFile)) + os.system('%s %s -dxf' %(extCONV_PATH, dwgTemp)) + #os.system('%s %s -dxf' %(extCONV_PATH, dxfFile_temp)) + if sys.exists(dxfTemp): + print 'reading file: %s.' % dxfTemp + time1 = sys.time() #time marker1 + drawing = readDXF(dxfTemp, objectify) + #os.remove(dwgTemp) + os.remove(dxfTemp) # clean up + print 'reading finished in %.4f sec.' % (sys.time()-time1) + Window.WaitCursor(False) + else: + if UI_MODE: Draw.PupMenu('DWG importer: nothing imported!%t|No valid DXF-representation found!') + print 'DWG importer: nothing imported. No valid DXF-representation found.' + Window.WaitCursor(False) + if editmode: Window.EditMode(1) # and put things back how we fond them + return None else: if UI_MODE: Draw.PupMenu('DXF importer: Alert!%t| no valid DXF-file selected!') print "DXF importer: Alert! - no valid DXF-file selected." @@ -4295,7 +4355,7 @@ def main(dxfFile): #---------------#############################----------- # Draw all the know entity types in the current scene oblist = [] # a list of all created AND linked objects for final f_globalScale - time2 = Blender.sys.time() #time marker2 + time2 = sys.time() #time marker2 Window.WaitCursor(True) # Let the user know we are thinking settings.write("\n\nDrawing entities...") @@ -4322,7 +4382,7 @@ def main(dxfFile): #---------------#############################----------- #SCENE.objects.selected = SCENE.objects #select all objects in current scene Blender.Redraw() - time_text = Blender.sys.time() - time2 + time_text = sys.time() - time2 Window.WaitCursor(False) if settings.var['paper_space_on']: space = 'from paper space' else: space = 'from model space' @@ -4571,7 +4631,7 @@ def drawer(_type, entities, settings, block_def): #---------------------------- activObjectLayer = '' activObjectName = '' - message = "Drawing dxf\'%ss\'..." %_type + message = "Drawing dxf \'%ss\'..." %_type cur_COUNTER += len_temp - len(entities) settings.write(message, False) settings.progress(cur_COUNTER, message) @@ -5078,7 +5138,7 @@ def drawCurveArc(self): #---- only for ELLIPSE -------------------------------- # GUI STUFF -----#################################################----------------- -from Blender.BGL import * +from Blender.BGL import glColor3f, glRecti, glClear, glRasterPos2d EVENT_NONE = 1 EVENT_START = 2 @@ -5577,7 +5637,7 @@ def draw_UI(): #--------------------------------------------------------------- y += 30 colorbox(x, y+20, x+menu_w+menu_margin*2, menu_margin) - Draw.Label("DXF-Importer v" + __version__, but0c, y, menu_w, 20) + Draw.Label("DXF/DWG-Importer v" + __version__, but0c, y, menu_w, 20) if config_UI.val: b0, b0_ = but0c, but_0c + butt_margin @@ -5853,9 +5913,9 @@ def draw_UI(): #--------------------------------------------------------------- #y -= 10 Draw.BeginAlign() - Draw.PushButton('DXFfile >', EVENT_CHOOSE_DXF, but0c, y, but_0c, 20, 'Select DXF-file from project directory') - dxfFileName = Draw.String(' :', EVENT_NONE, but1c, y, but_1c+but_2c+but_3c-20, 20, dxfFileName.val, FILENAME_MAX, "type the name of DXF-file or type *.dxf for multi-import") - Draw.PushButton('*.*', EVENT_DXF_DIR, but3c+but_3c-20, y, 20, 20, 'import all dxf files from this directory') + Draw.PushButton('DXFfile >', EVENT_CHOOSE_DXF, but0c, y, but_0c, 20, 'Select DXF/DWG-file for import') + dxfFileName = Draw.String(' :', EVENT_NONE, but1c, y, but_1c+but_2c+but_3c-20, 20, dxfFileName.val, FILENAME_MAX, "type the name of DXF/DWG-file or type *.dxf/*.dwg for multiple files") + Draw.PushButton('*.*', EVENT_DXF_DIR, but3c+but_3c-20, y, 20, 20, 'set filter for import all files from this directory') Draw.EndAlign() y -= 30 @@ -5902,8 +5962,9 @@ def colorbox(x,y,xright,bottom): def dxf_callback(input_filename): global dxfFileName - dxfFileName.val=input_filename -# dirname == Blender.sys.dirname(Blender.Get('filename')) + if input_filename.lower()[-3:] in ('dwg','dxf'): + dxfFileName.val=input_filename +# dirname == sys.dirname(Blender.Get('filename')) # update_RegistryKey('DirName', dirname) # update_RegistryKey('dxfFileName', input_filename) @@ -5913,17 +5974,17 @@ def ini_callback(input_filename): def event(evt, val): if evt in (Draw.QKEY, Draw.ESCKEY) and not val: - Blender.Draw.Exit() + Draw.Exit() def bevent(evt): # global EVENT_NONE,EVENT_LOAD_DXF,EVENT_LOAD_INI,EVENT_SAVE_INI,EVENT_EXIT global config_UI, user_preset - global GUI_A + global GUI_A, UI_MODE ######### Manages GUI events if (evt==EVENT_EXIT): - Blender.Draw.Exit() - print 'DXF-Importer *** exit ***' #--------------------- + Draw.Exit() + print 'DXF/DWG-Importer *** exit ***' #--------------------- elif (evt==EVENT_CHOOSE_INI): Window.FileSelector(ini_callback, "INI-file Selection", '*.ini') elif (evt==EVENT_REDRAW): @@ -5980,13 +6041,14 @@ http://wiki.blender.org/index.php?title=Scripts/Manual/Import/DXF-3D') Draw.Redraw() elif (evt==EVENT_DXF_DIR): dxfFile = dxfFileName.val + dxfFileExt = '*'+dxfFile.lower()[-4:] #can be .dxf or .dwg dxfPathName = '' if '/' in dxfFile: dxfPathName = '/'.join(dxfFile.split('/')[:-1]) + '/' elif '\\' in dxfFile: dxfPathName = '\\'.join(dxfFile.split('\\')[:-1]) + '\\' - dxfFileName.val = dxfPathName + '*.dxf' -# dirname == Blender.sys.dirname(Blender.Get('filename')) + dxfFileName.val = dxfPathName + dxfFileExt +# dirname == sys.dirname(Blender.Get('filename')) # update_RegistryKey('DirName', dirname) # update_RegistryKey('dxfFileName', dxfFileName.val) GUI_A['newScene_on'].val = 1 @@ -5994,45 +6056,55 @@ http://wiki.blender.org/index.php?title=Scripts/Manual/Import/DXF-3D') elif (evt==EVENT_CHOOSE_DXF): filename = '' # '*.dxf' if dxfFileName.val: filename = dxfFileName.val - Window.FileSelector(dxf_callback, "DXF-file Selection", filename) + Window.FileSelector(dxf_callback, "DXF/DWG-file Selection", filename) elif (evt==EVENT_START): dxfFile = dxfFileName.val #print 'deb: dxfFile file: ', dxfFile #---------------------- if E_M: dxfFileName.val, dxfFile = e_mode(dxfFile) #evaluation mode update_RegistryKey('dxfFileName', dxfFileName.val) if dxfFile.lower().endswith('*.dxf'): - if Draw.PupMenu('DXF importer: OK?|will import all DXF-files from:|%s' % dxfFile) == 1: - global UI_MODE + if Draw.PupMenu('DXF importer will import all DXF-files from:|%s|OK?' % dxfFile) != -1: UI_MODE = False - multi_import(dxfFile[:-5]) # cut last 5 characters '*.dxf' + multi_import(dxfFile) + UI_MODE = True Draw.Redraw() - #Draw.Exit() - else: + + elif dxfFile.lower().endswith('*.dwg'): + if not extCONV_OK: Draw.PupMenu(extCONV_TEXT) + elif Draw.PupMenu('DWG importer will import all DWG-files from:|%s|OK?' % dxfFile) != -1: + #elif Draw.PupMenu('DWG importer will import all DWG-files from:|%s|Caution! overwrites existing DXF-files!| OK?' % dxfFile) != -1: + UI_MODE = False + multi_import(dxfFile) + UI_MODE = True Draw.Redraw() - elif dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile): - print '\nStandard Mode: active' - if GUI_A['newScene_on'].val: - _dxf_file = dxfFile.split('/')[-1].split('\\')[-1] - _dxf_file = _dxf_file[:-4] # cut last char:'.dxf' - _dxf_file = _dxf_file[:MAX_NAMELENGTH] #? [-MAX_NAMELENGTH:]) - global SCENE - SCENE = Blender.Scene.New(_dxf_file) - SCENE.makeCurrent() - Blender.Redraw() - #or so? Blender.Scene.makeCurrent(_dxf_file) - #sce = bpy.data.scenes.new(_dxf_file) - #bpy.data.scenes.active = sce + + elif sys.exists(dxfFile) and dxfFile.lower()[-4:] in ('.dxf','.dwg'): + if dxfFile.lower().endswith('.dwg') and (not extCONV_OK): + Draw.PupMenu(extCONV_TEXT) else: - SCENE = Blender.Scene.GetCurrent() - SCENE.objects.selected = [] # deselect all - main(dxfFile) - #SCENE.objects.selected = SCENE.objects - #Window.RedrawAll() - #Blender.Redraw() - #Draw.Redraw() + #print '\nStandard Mode: active' + if GUI_A['newScene_on'].val: + _dxf_file = dxfFile.split('/')[-1].split('\\')[-1] + _dxf_file = _dxf_file[:-4] # cut last char:'.dxf' + _dxf_file = _dxf_file[:MAX_NAMELENGTH] #? [-MAX_NAMELENGTH:]) + global SCENE + SCENE = Blender.Scene.New(_dxf_file) + SCENE.makeCurrent() + Blender.Redraw() + #or so? Blender.Scene.makeCurrent(_dxf_file) + #sce = bpy.data.scenes.new(_dxf_file) + #bpy.data.scenes.active = sce + else: + SCENE = Blender.Scene.GetCurrent() + SCENE.objects.selected = [] # deselect all + main(dxfFile) + #SCENE.objects.selected = SCENE.objects + #Window.RedrawAll() + #Blender.Redraw() + #Draw.Redraw() else: - Draw.PupMenu('DXF importer: Alert!%t|no valid DXF-file selected!') - print "DXF importer: error, no valid DXF-file selected! try again" + Draw.PupMenu('DXF importer: nothing imported!%t|no valid DXF-file selected!') + print "DXF importer: nothing imported, no valid DXF-file selected! try again" Draw.Redraw() @@ -6043,20 +6115,25 @@ def multi_import(DIR): """ global SCENE - batchTIME = Blender.sys.time() + batchTIME = sys.time() #if #DIR == "": DIR = os.path.curdir - if DIR == "": DIR = Blender.sys.dirname(Blender.Get('filename')) - print 'Multifiles Import from %s' %DIR + if DIR == "": + DIR = sys.dirname(Blender.Get('filename')) + EXT = '.dxf' + else: + EXT = DIR[-4:] # get last 4 characters '.dxf' + DIR = DIR[:-5] # cut last 5 characters '*.dxf' + print 'importing multiple %s files from %s' %(EXT,DIR) files = \ - [sys.join(DIR, f) for f in os.listdir(DIR) if f.lower().endswith('.dxf')] + [sys.join(DIR, f) for f in os.listdir(DIR) if f.lower().endswith(EXT)] if not files: - print '...None DXF-files found. Abort!' + print '...None %s-files found. Abort!' %EXT return i = 0 for dxfFile in files: i += 1 - print '\nDXF-file', i, 'of', len(files) #,'\nImporting', dxfFile + print '\n%s-file' %EXT, i, 'of', len(files) #,'\nImporting', dxfFile if GUI_A['newScene_on'].val: _dxf_file = dxfFile.split('/')[-1].split('\\')[-1] _dxf_file = _dxf_file[:-4] # cut last char:'.dxf' @@ -6072,13 +6149,11 @@ def multi_import(DIR): main(dxfFile) #Blender.Redraw() - print 'TOTAL TIME: %.6f' % (Blender.sys.time() - batchTIME) + print 'TOTAL TIME: %.6f' % (sys.time() - batchTIME) print '\a\r', # beep when done + Draw.PupMenu('DXF importer: Done!|finished in %.4f sec.' % (sys.time() - batchTIME)) - -UI_MODE = True - if __name__ == "__main__": UI_MODE = True # recall last used DXF-file and INI-file names @@ -6086,7 +6161,7 @@ if __name__ == "__main__": #print 'deb:start dxffilename:', dxffilename #---------------- if dxffilename: dxfFileName.val = dxffilename else: - dirname = Blender.sys.dirname(Blender.Get('filename')) + dirname = sys.dirname(Blender.Get('filename')) #print 'deb:start dirname:', dirname #---------------- dxfFileName.val = sys.join(dirname, '') inifilename = check_RegistryKey('iniFileName') @@ -6099,7 +6174,7 @@ if __name__ == "__main__": if 1: # DEBUG ONLY UI_MODE = False - TIME= Blender.sys.time() + TIME= sys.time() #DIR = '/dxf_r12_testfiles/' DIR = '/metavr/' import os @@ -6128,5 +6203,5 @@ if 1: dxfFileName.val = _dxf main(_dxf) - print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME) + print 'TOTAL TIME: %.6f' % (sys.time() - TIME) """
\ No newline at end of file diff --git a/release/scripts/import_obj.py b/release/scripts/import_obj.py index 42cdac4dc35..493354601a6 100644 --- a/release/scripts/import_obj.py +++ b/release/scripts/import_obj.py @@ -537,6 +537,7 @@ def get_float_func(filepath): ''' file= open(filepath, 'rU') for line in file: #.xreadlines(): + line = line.lstrip() if line.startswith('v'): # vn vt v if ',' in line: return lambda f: float(f.replace(',', '.')) @@ -590,6 +591,7 @@ def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS time_sub= sys.time() file= open(filepath, 'rU') for line in file: #.xreadlines(): + line = line.lstrip() # rare cases there is white space at the start of the line if line.startswith('v '): line_split= line.split() diff --git a/release/scripts/import_web3d.py b/release/scripts/import_web3d.py index 87a259cbe56..fc3b5262376 100755..100644 --- a/release/scripts/import_web3d.py +++ b/release/scripts/import_web3d.py @@ -1332,7 +1332,9 @@ class x3dNode(vrmlNode): # Other funcs operate from vrml, but this means we can wrap XML fields, still use nice utility funcs # getFieldAsArray getFieldAsBool etc - def getFieldName(self, field): + def getFieldName(self, field, ancestry, AS_CHILD=False): + # ancestry and AS_CHILD are ignored, only used for VRML now + self_real = self.getRealNode() # incase we're an instance field_xml = self.x3dNode.getAttributeNode(field) if field_xml: @@ -1564,7 +1566,8 @@ def importMesh_IndexedFaceSet(geom, bpyima, ancestry): vcolor_spot = None # spot color when we dont have an array of colors if vcolor: # float to char - ifs_vcol = [[int(c*256) for c in col] for col in vcolor.getFieldAsArray('color', 3, ancestry)] + ifs_vcol = [(0,0,0)] # EEKADOODLE - vertex start at 1 + ifs_vcol.extend([[int(c*256) for c in col] for col in vcolor.getFieldAsArray('color', 3, ancestry)]) ifs_color_index = geom.getFieldAsArray('colorIndex', 0, ancestry) if not ifs_vcol: diff --git a/release/scripts/mesh_poly_reduce_grid.py b/release/scripts/mesh_poly_reduce_grid.py new file mode 100644 index 00000000000..3741a47723a --- /dev/null +++ b/release/scripts/mesh_poly_reduce_grid.py @@ -0,0 +1,351 @@ +#!BPY +""" +Name: 'Poly Reduce Selection (Unsubsurf)' +Blender: 245 +Group: 'Mesh' +Tooltip: 'pradictable mesh simplifaction maintaining face loops' +""" + +from Blender import Scene, Mesh, Window, sys +import BPyMessages +import bpy + +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Script copyright (C) Campbell J Barton +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + + +def my_mesh_util(me): + me_verts = me.verts + + vert_faces = [ [] for v in me_verts] + vert_faces_corner = [ [] for v in me_verts] + + + # Ignore topology where there are not 2 faces connected to an edge. + edge_count = {} + for f in me.faces: + for edkey in f.edge_keys: + try: + edge_count[edkey] += 1 + except: + edge_count[edkey] = 1 + + for edkey, count in edge_count.iteritems(): + + # Ignore verts that connect to edges with more then 2 faces. + if count != 2: + vert_faces[edkey[0]] = None + vert_faces[edkey[1]] = None + # Done + + + + def faces_set_verts(face_ls): + unique_verts = set() + for f in face_ls: + for v in f: + unique_verts.add(v.index) + return unique_verts + + for f in me.faces: + for corner, v in enumerate(f): + i = v.index + if vert_faces[i] != None: + vert_faces[i].append(f) + vert_faces_corner[i].append( corner ) + + grid_data_ls = [] + + for vi, face_ls in enumerate(vert_faces): + if face_ls != None: + if len(face_ls) == 4: + if face_ls[0].sel and face_ls[1].sel and face_ls[2].sel and face_ls[3].sel: + # Support triangles also + unique_vert_count = len(faces_set_verts(face_ls)) + quads = 0 + for f in face_ls: + if len(f) ==4: + quads += 1 + if unique_vert_count==5+quads: # yay we have a grid + grid_data_ls.append( (vi, face_ls) ) + + elif len(face_ls) == 3: + if face_ls[0].sel and face_ls[1].sel and face_ls[2].sel: + unique_vert_count = len(faces_set_verts(face_ls)) + if unique_vert_count==4: # yay we have 3 triangles to make into a bigger triangle + grid_data_ls.append( (vi, face_ls) ) + + + + # Now sort out which grid faces to use + + + # This list will be used for items we can convert, vertex is key, faces are values + grid_data_dict = {} + + if not grid_data_ls: + print "doing nothing" + return + + # quick lookup for the opposing corner of a qiad + quad_diag_mapping = 2,3,0,1 + + verts_used = [0] * len(me_verts) # 0 == untouched, 1==should touch, 2==touched + verts_used[grid_data_ls[0][0]] = 1 # start touching 1! + + # From the corner vert, get the 2 edges that are not the corner or its opposing vert, this edge will make a new face + quad_edge_mapping = (1,3), (2,0), (1,3), (0,2) # hi-low, low-hi order is intended + tri_edge_mapping = (1,2), (0,2), (0,1) + + done_somthing = True + while done_somthing: + done_somthing = False + grid_data_ls_index = -1 + + for vi, face_ls in grid_data_ls: + grid_data_ls_index += 1 + if len(face_ls) == 3: + grid_data_dict[vi] = face_ls + grid_data_ls.pop( grid_data_ls_index ) + break + elif len(face_ls) == 4: + # print vi + if verts_used[vi] == 1: + verts_used[vi] = 2 # dont look at this again. + done_somthing = True + + grid_data_dict[vi] = face_ls + + # Tag all faces verts as used + + for i, f in enumerate(face_ls): + # i == face index on vert, needed to recall which corner were on. + v_corner = vert_faces_corner[vi][i] + fv =f.v + + if len(f) == 4: + v_other = quad_diag_mapping[v_corner] + # get the 2 other corners + corner1, corner2 = quad_edge_mapping[v_corner] + if verts_used[fv[v_other].index] == 0: + verts_used[fv[v_other].index] = 1 # TAG for touching! + else: + corner1, corner2 = tri_edge_mapping[v_corner] + + verts_used[fv[corner1].index] = 2 # Dont use these, they are + verts_used[fv[corner2].index] = 2 + + + # remove this since we have used it. + grid_data_ls.pop( grid_data_ls_index ) + + break + + if done_somthing == False: + # See if there are any that have not even been tagged, (probably on a different island), then tag them. + + for vi, face_ls in grid_data_ls: + if verts_used[vi] == 0: + verts_used[vi] = 1 + done_somthing = True + break + + + # Now we have all the areas we will fill, calculate corner triangles we need to fill in. + new_faces = [] + quad_del_vt_map = (1,2,3), (0,2,3), (0,1,3), (0,1,2) + for vi, face_ls in grid_data_dict.iteritems(): + for i, f in enumerate(face_ls): + if len(f) == 4: + # i == face index on vert, needed to recall which corner were on. + v_corner = vert_faces_corner[vi][i] + v_other = quad_diag_mapping[v_corner] + fv =f.v + + #print verts_used[fv[v_other].index] + #if verts_used[fv[v_other].index] != 2: # DOSNT WORK ALWAYS + + if 1: # THIS IS LAzY - some of these faces will be removed after adding. + # Ok we are removing half of this face, add the other half + + # This is probably slower + # new_faces.append( [fv[ii].index for ii in (0,1,2,3) if ii != v_corner ] ) + + # do this instead + new_faces.append( (fv[quad_del_vt_map[v_corner][0]], fv[quad_del_vt_map[v_corner][1]], fv[quad_del_vt_map[v_corner][2]]) ) + + del grid_data_ls + + + # me.sel = 0 + def faceCombine4(vi, face_ls): + edges = [] + + for i, f in enumerate(face_ls): + fv = f.v + v_corner = vert_faces_corner[vi][i] + if len(f)==4: ed = quad_edge_mapping[v_corner] + else: ed = tri_edge_mapping[v_corner] + + edges.append( [fv[ed[0]].index, fv[ed[1]].index] ) + + # get the face from the edges + face = edges.pop() + while len(face) != 4: + # print len(edges), edges, face + for ed_idx, ed in enumerate(edges): + if face[-1] == ed[0] and (ed[1] != face[0]): + face.append(ed[1]) + elif face[-1] == ed[1] and (ed[0] != face[0]): + face.append(ed[0]) + else: + continue + + edges.pop(ed_idx) # we used the edge alredy + break + + return face + + for vi, face_ls in grid_data_dict.iteritems(): + if len(face_ls) == 4: + new_faces.append( faceCombine4(vi, face_ls) ) + #pass + if len(face_ls) == 3: # 3 triangles + face = list(faces_set_verts(face_ls)) + face.remove(vi) + new_faces.append( face ) + + + # Now remove verts surounded by 3 triangles + + + + # print new_edges + # me.faces.extend(new_faces, ignoreDups=True) + + ''' + faces_remove = [] + for vi, face_ls in grid_data_dict.iteritems(): + faces_remove.extend(face_ls) + ''' + + orig_facelen = len(me.faces) + + orig_faces = list(me.faces) + me.faces.extend(new_faces, ignoreDups=True) + new_faces = list(me.faces)[len(orig_faces):] + + + + + + if me.faceUV: + uvnames = me.getUVLayerNames() + act_uvlay = me.activeUVLayer + + vert_faces_uvs = [] + vert_faces_images = [] + + + act_uvlay = me.activeUVLayer + + for uvlay in uvnames: + me.activeUVLayer = uvlay + vert_faces_uvs[:] = [None] * len(me.verts) + vert_faces_images[:] = vert_faces_uvs[:] + + for i,f in enumerate(orig_faces): + img = f.image + fv = f.v + uv = f.uv + mat = f.mat + for i,v in enumerate(fv): + vi = v.index + vert_faces_uvs[vi] = uv[i] # no nice averaging + vert_faces_images[vi] = img + + + # Now copy UVs across + for f in new_faces: + fi = [v.index for v in f.v] + f.image = vert_faces_images[fi[0]] + uv = f.uv + for i,vi in enumerate(fi): + uv[i][:] = vert_faces_uvs[vi] + + if len(me.materials) > 1: + vert_faces_mats = [None] * len(me.verts) + for i,f in enumerate(orig_faces): + mat = f.mat + for i,v in enumerate(f.v): + vi = v.index + vert_faces_mats[vi] = mat + + # Now copy UVs across + for f in new_faces: + print vert_faces_mats[f.v[0].index] + f.mat = vert_faces_mats[f.v[0].index] + + + me.verts.delete(grid_data_dict.keys()) + + # me.faces.delete(1, faces_remove) + + if me.faceUV: + me.activeUVLayer = act_uvlay + + me.calcNormals() + +def main(): + + # Gets the current scene, there can be many scenes in 1 blend file. + sce = bpy.data.scenes.active + + # Get the active object, there can only ever be 1 + # and the active object is always the editmode object. + ob_act = sce.objects.active + + if not ob_act or ob_act.type != 'Mesh': + BPyMessages.Error_NoMeshActive() + return + + is_editmode = Window.EditMode() + if is_editmode: Window.EditMode(0) + + Window.WaitCursor(1) + me = ob_act.getData(mesh=1) # old NMesh api is default + t = sys.time() + + # Run the mesh editing function + my_mesh_util(me) + + # Restore editmode if it was enabled + if is_editmode: Window.EditMode(1) + + # Timing the script is a good way to be aware on any speed hits when scripting + print 'My Script finished in %.2f seconds' % (sys.time()-t) + Window.WaitCursor(0) + + +# This lets you can import the script without running it +if __name__ == '__main__': + main() + diff --git a/release/scripts/scripttemplate_camer_object.py b/release/scripts/scripttemplate_camera_object.py index cacc35ed1a5..cacc35ed1a5 100644 --- a/release/scripts/scripttemplate_camer_object.py +++ b/release/scripts/scripttemplate_camera_object.py diff --git a/release/scripts/uvcalc_smart_project.py b/release/scripts/uvcalc_smart_project.py index d622e1a2af8..55d6ebfaa6f 100644 --- a/release/scripts/uvcalc_smart_project.py +++ b/release/scripts/uvcalc_smart_project.py @@ -870,7 +870,7 @@ def main(): 'UV Layout',\ ('Share Tex Space', USER_SHARE_SPACE, 'Objects Share texture space, map all objects into 1 uvmap.'),\ ('Stretch to bounds', USER_STRETCH_ASPECT, 'Stretch the final output to texture bounds.'),\ - ('Island Margin:', USER_ISLAND_MARGIN, 0.0, 0.25, 'Margin to reduce bleed from adjacent islands.'),\ + ('Island Margin:', USER_ISLAND_MARGIN, 0.0, 0.5, 'Margin to reduce bleed from adjacent islands.'),\ 'Fill in empty areas',\ ('Fill Holes', USER_FILL_HOLES, 'Fill in empty areas reduced texture waistage (slow).'),\ ('Fill Quality:', USER_FILL_HOLES_QUALITY, 1, 100, 'Depends on fill holes, how tightly to fill UV holes, (higher is slower)'),\ |