diff options
Diffstat (limited to 'release/scripts/mesh_boneweight_copy.py')
-rw-r--r-- | release/scripts/mesh_boneweight_copy.py | 287 |
1 files changed, 0 insertions, 287 deletions
diff --git a/release/scripts/mesh_boneweight_copy.py b/release/scripts/mesh_boneweight_copy.py deleted file mode 100644 index d2a477fbc0b..00000000000 --- a/release/scripts/mesh_boneweight_copy.py +++ /dev/null @@ -1,287 +0,0 @@ -#!BPY -""" -Name: 'Bone Weight Copy' -Blender: 245 -Group: 'Object' -Tooltip: 'Copy Bone Weights from 1 mesh, to all other selected meshes.' -""" - -__author__ = "Campbell Barton aka ideasman42" -__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"] -__version__ = "0.1" -__bpydoc__ = """\ - -Bone Weight Copy - -This script is used to copy bone weights from 1 mesh with weights (the source mesh) to many (the target meshes). -Weights are copied from 1 mesh to another based on how close they are together. - -For normal operation, select 1 source mesh with vertex weights and any number of unweighted meshes that overlap the source mesh. -Then run this script using default options and check the new weigh. - - -A differnt way to use this script is to update the weights an an alredy weighted mesh. -this is done using the "Copy to Selected" option enabled and works a bit differently, -With the target mesh, select the verts you want to update. -since all meshes have weights we cant just use the weighted mesh as the source, -so the Active Object is used for the source mesh. -Run the script and the selected verts on all non active meshes will be updated. -""" - -# ***** 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 ***** -# -------------------------------------------------------------------------- - -import Blender -from Blender import Armature, Object, Mathutils, Window, Mesh -Vector= Mathutils.Vector -SMALL_NUM= 0.000001 -def copy_bone_influences(_from, _to, PREF_SEL_ONLY, PREF_NO_XCROSS): - ob_from, me_from, world_verts_from, from_groups= _from - ob_to, me_to, world_verts_to, dummy= _to - del dummy - - def getSnapIdx(seek_vec, vecs): - ''' - Returns the closest vec to snap_points - ''' - - # First seek the closest Z axis vert idx/v - seek_vec_x,seek_vec_y,seek_vec_z= seek_vec - - from_vec_idx= 0 - - len_vecs= len(vecs) - - upidx= len_vecs-1 - loidx= 0 - - while from_vec_idx < len_vecs and vecs[from_vec_idx][1].z < seek_vec_z: - from_vec_idx+=1 - - # Clamp if we overstepped. - if from_vec_idx >= len_vecs: - from_vec_idx-=1 - - close_dist= (vecs[from_vec_idx][1]-seek_vec).length - close_idx= vecs[from_vec_idx][0] - - upidx= from_vec_idx+1 - loidx= from_vec_idx-1 - - # Set uselo/useup. This means we can keep seeking up/down. - if upidx >= len_vecs: useup= False - else: useup= True - - if loidx < 0: uselo= False - else: uselo= True - - # Seek up/down to find the closest v to seek vec. - while uselo or useup: - if useup: - if upidx >= len_vecs: - useup= False - else: - i,v= vecs[upidx] - if (not PREF_NO_XCROSS) or ((v.x >= -SMALL_NUM and seek_vec_x >= -SMALL_NUM) or (v.x <= SMALL_NUM and seek_vec_x <= SMALL_NUM)): # enfoce xcrossing - if v.z-seek_vec_z > close_dist: - # the verticle distance is greater then the best distance sofar. we can stop looking up. - useup= False - elif abs(seek_vec_y-v.y) < close_dist and abs(seek_vec_x-v.x) < close_dist: - # This is in the limit measure it. - l= (seek_vec-v).length - if l<close_dist: - close_dist= l - close_idx= i - upidx+=1 - - if uselo: - - if loidx == 0: - uselo= False - else: - i,v= vecs[loidx] - if (not PREF_NO_XCROSS) or ((v.x >= -SMALL_NUM and seek_vec_x >= -SMALL_NUM) or (v.x <= SMALL_NUM and seek_vec_x <= SMALL_NUM)): # enfoce xcrossing - if seek_vec_z-v.z > close_dist: - # the verticle distance is greater then the best distance sofar. we can stop looking up. - uselo= False - elif abs(seek_vec_y-v.y) < close_dist and abs(seek_vec_x-v.x) < close_dist: - # This is in the limit measure it. - l= (seek_vec-v).length - if l<close_dist: - close_dist= l - close_idx= i - loidx-=1 - - return close_idx - - - to_groups= me_to.getVertGroupNames() # if not PREF_SEL_ONLY will always be [] - from_groups= me_from.getVertGroupNames() - - if PREF_SEL_ONLY: # remove selected verts from all groups. - vsel= [v.index for v in me_to.verts if v.sel] - for group in to_groups: - me_to.removeVertsFromGroup(group, vsel) - else: # Add all groups. - for group in from_groups: - me_to.addVertGroup(group) - - add_ = Mesh.AssignModes.ADD - - for i, co in enumerate(world_verts_to): - if (not PREF_SEL_ONLY) or (PREF_SEL_ONLY and me_to.verts[i].sel): - - Window.DrawProgressBar(0.99 * (i/float(len(world_verts_to))), 'Copy "%s" -> "%s" ' % (ob_from.name, ob_to.name)) - - from_idx= getSnapIdx(co, world_verts_from) - from_infs= me_from.getVertexInfluences(from_idx) - - for group, weight in from_infs: - - # Add where needed. - if PREF_SEL_ONLY and group not in to_groups: - me_to.addVertGroup(group) - to_groups.append(group) - - me_to.assignVertsToGroup(group, [i], weight, add_) - - me_to.update() - -# ZSORT return (i/co) tuples, used for fast seeking of the snapvert. -def worldspace_verts_idx(me, ob): - mat= ob.matrixWorld - verts_zsort= [ (i, v.co*mat) for i, v in enumerate(me.verts) ] - - # Sorts along the Z Axis so we can optimize the getsnap. - try: verts_zsort.sort(key = lambda a: a[1].z) - except: verts_zsort.sort(lambda a,b: cmp(a[1].z, b[1].z,)) - - return verts_zsort - - -def worldspace_verts(me, ob): - mat= ob.matrixWorld - return [ v.co*mat for v in me.verts ] - -def subdivMesh(me, subdivs): - oldmode = Mesh.Mode() - Mesh.Mode(Mesh.SelectModes['FACE']) - me.sel= 1 - for i in xrange(subdivs): - me.subdivide(0) - Mesh.Mode(oldmode) - - -def main(): - print '\nStarting BoneWeight Copy...' - scn= Blender.Scene.GetCurrent() - contextSel= Object.GetSelected() - if not contextSel: - Blender.Draw.PupMenu('Error%t|2 or more mesh objects need to be selected.|aborting.') - return - - PREF_QUALITY= Blender.Draw.Create(0) - PREF_NO_XCROSS= Blender.Draw.Create(0) - PREF_SEL_ONLY= Blender.Draw.Create(0) - - pup_block = [\ - ('Quality:', PREF_QUALITY, 0, 4, 'Generate interpolated verts for a higher quality result.'),\ - ('No X Crossing', PREF_NO_XCROSS, 'Do not snap across the zero X axis'),\ - '',\ - '"Update Selected" copies',\ - 'active object weights to',\ - 'selected verts on the other',\ - 'selected mesh objects.',\ - ('Update Selected', PREF_SEL_ONLY, 'Only copy new weights to selected verts on the target mesh. (use active object as source)'),\ - ] - - - if not Blender.Draw.PupBlock("Copy Weights for %i Meshs" % len(contextSel), pup_block): - return - - PREF_SEL_ONLY= PREF_SEL_ONLY.val - PREF_NO_XCROSS= PREF_NO_XCROSS.val - quality= PREF_QUALITY.val - - act_ob= scn.objects.active - if PREF_SEL_ONLY and act_ob==None: - Blender.Draw.PupMenu('Error%t|When dealing with 2 or more meshes with vgroups|There must be an active object|to be used as a source|aborting.') - return - - sel=[] - from_data= None - - for ob in contextSel: - if ob.type=='Mesh': - me= ob.getData(mesh=1) - groups= me.getVertGroupNames() - - # If this is the only mesh with a group OR if its one of many, but its active. - if groups and ((ob==act_ob and PREF_SEL_ONLY) or (not PREF_SEL_ONLY)): - if from_data: - Blender.Draw.PupMenu('More then 1 mesh has vertex weights, only select 1 mesh with weights. aborting.') - return - else: - # This uses worldspace_verts_idx which gets (idx,co) pairs, then zsorts. - if quality: - for _ob in contextSel: - _ob.sel=0 - ob.sel=1 - Object.Duplicate(mesh=1) - ob= scn.objects.active - me= ob.getData(mesh=1) - # groups will be the same - print '\tGenerating higher %ix quality weights.' % quality - subdivMesh(me, quality) - scn.unlink(ob) - from_data= (ob, me, worldspace_verts_idx(me, ob), groups) - - else: - data= (ob, me, worldspace_verts(me, ob), groups) - sel.append(data) - - if not from_data: - Blender.Draw.PupMenu('Error%t|No mesh with vertex groups found.') - return - - if not sel: - Blender.Draw.PupMenu('Error%t|Select 2 or more mesh objects, aborting.') - if quality: from_data[1].verts= None - return - - t= Blender.sys.time() - Window.WaitCursor(1) - - # Now do the copy. - print '\tCopying from "%s" to %i other mesh(es).' % (from_data[0].name, len(sel)) - for data in sel: - copy_bone_influences(from_data, data, PREF_SEL_ONLY, PREF_NO_XCROSS) - - # We cant unlink the mesh, but at least remove its data. - if quality: - from_data[1].verts= None - - print 'Copy Complete in %.6f sec' % (Blender.sys.time()-t) - Window.DrawProgressBar(1.0, '') - Window.WaitCursor(0) - -if __name__ == '__main__': - main()
\ No newline at end of file |