diff --git a/release/scripts/mesh_boneweight_copy.py b/release/scripts/mesh_boneweight_copy.py index e82769a3e04..c08f2b9c892 100755 --- a/release/scripts/mesh_boneweight_copy.py +++ b/release/scripts/mesh_boneweight_copy.py @@ -5,6 +5,10 @@ Blender: 241 Group: 'Object' Tooltip: 'Copy Bone Weights from 1 weighted mesh, to other unweighted meshes.' """ +# 37.314122 sec +# 8.9 sec sec + + import Blender from Blender import Armature, Object, Mathutils, Window, Mesh Vector= Mathutils.Vector @@ -14,26 +18,88 @@ def copy_bone_influences(_from, _to): ob_to, me_to, world_verts_to, dummy= _to del dummy - def getSnapIdx(vec, vecs): + def getSnapIdx(seek_vec, vecs): ''' Returns the closest vec to snap_points ''' - close_dist= 1<<30 - close_idx= None - x,y,z= tuple(vec) - for i, v in enumerate(vecs): - # quick length cmp before a full length comparison. - if\ - abs(x-v[0]) < close_dist and\ - abs(y-v[1]) < close_dist and\ - abs(z-v[2]) < close_dist: - l= (v-vec).length - if l 3: + half= _range/2 + z= vecs[upidx-half][1].z + if z > seek_vec_z: + upidx= upidx-half + elif z < seek_vec_z: + loidx= loidx+half + + _range=upidx-loidx + + from_vec_idx= loidx + + # Seek the rest of the way. should only need to seek 2 or 3 items at the most. + 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 + + uselo=useup= True # This means we can keep seeking up/down. + + # 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 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: + # 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