Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2006-04-21 13:41:58 +0400
committerCampbell Barton <ideasman42@gmail.com>2006-04-21 13:41:58 +0400
commit63868046f4cd50b775074ace5c94084d3f01f8eb (patch)
tree686aca610bcdd8950613366250f79b7c31c1beab
parent237030a6cae49597843c67b3b6211e7573873b20 (diff)
boneweight copy-
fixed the "No X Crossing option "Made 0-x verts snap to eachother. Added mesh_mirror_tool This is a tool that makes verts mirror, so that you can use xmirror in editmode and weight painting. Have imported a heap of models that are made mirrored but are slightly out of being in the range that blender uses to be mirrored. So this means I can make a models verts snap to its mirrored locations. Options are Limit, Mode l>R, R>L or Middle, Normal Weigting, only mirror Same edge user count may add support for mirroring vert weights later.
-rwxr-xr-xrelease/scripts/mesh_boneweight_copy.py6
-rw-r--r--release/scripts/mesh_mirror_tool.py146
2 files changed, 149 insertions, 3 deletions
diff --git a/release/scripts/mesh_boneweight_copy.py b/release/scripts/mesh_boneweight_copy.py
index c432ff98d3a..dd49cb32b2e 100755
--- a/release/scripts/mesh_boneweight_copy.py
+++ b/release/scripts/mesh_boneweight_copy.py
@@ -9,7 +9,7 @@ Tooltip: 'Copy Bone Weights from 1 weighted mesh, to other unweighted meshes.'
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
@@ -72,7 +72,7 @@ def copy_bone_influences(_from, _to, PREF_SEL_ONLY, PREF_NO_XCROSS):
useup= False
else:
i,v= vecs[upidx]
- if (not PREF_NO_XCROSS) or ((v.x >0 and seek_vec_x >0) or (v.x <0 and seek_vec_x <0)): # enfoce xcrossing
+ 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
@@ -90,7 +90,7 @@ def copy_bone_influences(_from, _to, PREF_SEL_ONLY, PREF_NO_XCROSS):
uselo= False
else:
i,v= vecs[loidx]
- if (not PREF_NO_XCROSS) or ((v.x >0 and seek_vec_x >0) or (v.x <0 and seek_vec_x <0)): # enfoce xcrossing
+ 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
diff --git a/release/scripts/mesh_mirror_tool.py b/release/scripts/mesh_mirror_tool.py
new file mode 100644
index 00000000000..b86e429f10c
--- /dev/null
+++ b/release/scripts/mesh_mirror_tool.py
@@ -0,0 +1,146 @@
+#!BPY
+"""
+Name: 'Mirror Snap Verts'
+Blender: 241
+Group: 'Object'
+Tooltip: 'Move verts so they snap to their mirrored locations.'
+"""
+
+from Blender import Draw, Window, Scene, Mesh, Mathutils, sys
+import BPyMesh
+
+
+def mesh_mirror(me, PREF_MAX_DIST, PREF_MODE, PREF_NOR_WEIGHT, PREF_SEL_ONLY, PREF_EDGE_USERS):
+ '''
+ PREF_MAX_DIST, Maximum distance to test snapping verts.
+ PREF_MODE, 0:middle, 1: Left. 2:Right.
+ PREF_NOR_WEIGHT, use normal angle difference to weight distances.
+ PREF_SEL_ONLY, only snap the selection
+ PREF_EDGE_USERS, match only verts with the same number of edge users.
+ '''
+
+ is_editmode = Window.EditMode() # Exit Editmode.
+ if is_editmode: Window.EditMode(0)
+ Window.WaitCursor(1)
+ Mesh.Mode(Mesh.SelectModes['VERTEX'])
+
+ # Operate on all verts
+ if not PREF_SEL_ONLY:
+ for v in me.verts:
+ v.sel=1
+
+ if PREF_EDGE_USERS:
+ edge_users= [0]*len(me.verts)
+ for ed in me.edges:
+ edge_users[ed.v1.index]+=1
+ edge_users[ed.v2.index]+=1
+
+
+ neg_vts = [v for v in me.verts if v.sel and v.co.x > 0.000001]
+ pos_vts = [v for v in me.verts if v.sel and v.co.x < -0.000001]
+
+ mirror_pos= True
+ mirror_weights=True
+
+
+ groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
+
+ mirror_pairs= []
+ # allign the negative with the positive.
+ flipvec= Mathutils.Vector()
+ len_neg_vts= float(len(neg_vts))
+ for i1, nv in enumerate(neg_vts):
+ nv_co= nv.co
+ for i2, pv in enumerate(pos_vts):
+ # Enforce edge users.
+ if not PREF_EDGE_USERS or edge_users[i1]==edge_users[i2]:
+ flipvec[:]= pv.co
+ flipvec.x= -flipvec.x
+ l= (nv_co-flipvec).length
+
+ # Record a match.
+ if l<=PREF_MAX_DIST:
+
+ # We can adjust the length by the normal, now we know the length is under the limit.
+ if PREF_NOR_WEIGHT>0:
+ # Get the normal and flipm reuse flipvec
+ flipvec[:]= pv.no
+ flipvec.x= -flipvec.x
+ try:
+ ang= Mathutils.AngleBetweenVecs(nv.no, flipvec)/180.0
+ except: # on rare occasions angle between vecs will fail.- zero length vec.
+ ang= 0
+
+ l=l*(1+(ang*PREF_NOR_WEIGHT))
+
+ mirror_pairs.append((l, nv, pv))
+
+ # Update every 20 loops
+ if i1 % 10 == 0:
+ Window.DrawProgressBar(0.8 * (i1/len_neg_vts), 'Mirror verts %i of %i' % (i1, len_neg_vts))
+
+
+ Window.DrawProgressBar(0.9, 'Mirror verts: Updating locations')
+ # Now we have a list of the pairs we might use, lets find the best and do them first.
+ # de-selecting as we go. so we can makke sure not to mess it up.
+ mirror_pairs.sort(lambda a,b: cmp(a[0], b[0]))
+
+ for dist, v1,v2 in mirror_pairs: # dist, neg, pos
+ if v1.sel and v2.sel:
+ if PREF_MODE==0: # Middle
+ flipvec[:]= v2.co # positive
+ flipvec.x= -flipvec.x # negatve
+ v2.co[:]= v1.co[:]= (flipvec+v1.co)*0.5 # midway
+ v2.co.x= -v2.co.x
+ elif PREF_MODE==2: # Left
+ v2.co[:]= v1.co
+ v2.co.x= -v2.co.x
+ elif PREF_MODE==1: # Right
+ v1.co[:]= v2.co
+ v1.co.x= -v1.co.x
+ v1.sel= 0
+ v2.sel= 0
+
+ me.update()
+
+ if is_editmode: Window.EditMode(1)
+ Window.WaitCursor(0)
+ Window.DrawProgressBar(1.0, '')
+ Window.RedrawAll()
+
+def main():
+ try:
+ scn = Scene.GetCurrent()
+ ob= scn.getActiveObject()
+ me= ob.getData(mesh=1)
+ except:
+ Draw.PupMenu('Error, select a mesh as your active object')
+
+ PREF_MAX_DIST= Draw.Create(0.2)
+ PREF_MODE= Draw.Create(0)
+ PREF_NOR_WEIGHT= Draw.Create(0.0)
+ PREF_SEL_ONLY= Draw.Create(1)
+ PREF_EDGE_USERS= Draw.Create(0)
+
+ pup_block = [\
+ ('MaxDist:', PREF_MAX_DIST, 0.0, 1.0, 'Generate interpolated verts so closer vert weights can be copied.'),\
+ ('Mode:', PREF_MODE, 0, 2, 'New Location (0:AverageL/R, 1:Left>Right 2:Right>Left)'),\
+ ('NorWeight:', PREF_NOR_WEIGHT, 0.0, 1.0, 'Generate interpolated verts so closer vert weights can be copied.'),\
+ ('Sel Only', PREF_SEL_ONLY, 'Only mirror selected verts. Else try and mirror all'),\
+ ('Edge Users', PREF_EDGE_USERS, 'Only match up verts that have the same number of edge users.'),\
+ ]
+
+ if not Draw.PupBlock("Mirror mesh tool", pup_block):
+ return
+
+ PREF_MAX_DIST= PREF_MAX_DIST.val
+ PREF_MODE= PREF_MODE.val
+ PREF_NOR_WEIGHT= PREF_NOR_WEIGHT.val
+ PREF_SEL_ONLY= PREF_SEL_ONLY.val
+ PREF_EDGE_USERS= PREF_EDGE_USERS.val
+ t= sys.time()
+ mesh_mirror(me, PREF_MAX_DIST, PREF_MODE, PREF_NOR_WEIGHT, PREF_SEL_ONLY, PREF_EDGE_USERS)
+ print 'Mirror done in %.6f sec.' % (sys.time()-t)
+
+if __name__ == '__main__':
+ main() \ No newline at end of file