From 1021949c3a5c5b427b83f2623388b935f0c9a00e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Feb 2007 18:34:31 +0000 Subject: [PATCH] removing this script- has been added back with correct spelling. --- release/scripts/armature_symetry.py | 325 ---------------------------- 1 file changed, 325 deletions(-) delete mode 100644 release/scripts/armature_symetry.py diff --git a/release/scripts/armature_symetry.py b/release/scripts/armature_symetry.py deleted file mode 100644 index 1e4484d0efc..00000000000 --- a/release/scripts/armature_symetry.py +++ /dev/null @@ -1,325 +0,0 @@ -#!BPY - -""" -Name: 'Armature Symmetry' -Blender: 242 -Group: 'Animation' -Tooltip: 'Make an Armature symetrical' -""" - -__author__ = "Campbell Barton" -__url__ = ("blender", "blenderartist") -__version__ = "1.0 2006-7-26" - -__doc__ = """\ -This script creates perfectly symmetrical armatures, -based on the best fit when comparing the mirrored locations of 2 bones. -Hidden bones are ignored, and optionally only operate on selected bones. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton 2006 -# -# 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 Scene -Vector= Blender.Mathutils.Vector - - -def VecXFlip(vec): - ''' - Return a copy of this vector x flipped. - ''' - x,y,z= vec - return Vector(-x,y,z) - -def editbone_mirror_diff(editbone1, editbone2): - ''' - X Mirror bone compare - return a float representing the difference between the 2 bones - the smaller the better the match - ''' - h1= editbone1.head - h2= editbone2.head - - t1= editbone1.tail - t2= editbone2.tail - - # Mirror bone2's location - h2= VecXFlip(h2) - t2= VecXFlip(t2) - - #return (h1-h2).length + (t1-t2).length # returns the length only - - # For this function its easier to return the bones also - return ((h1-h2).length + (t1-t2).length)/2, editbone1, editbone2 - -def editbone_mirror_merge(editbone1, editbone2, PREF_MODE_L2R, PREF_MODE_R2L): - ''' - Merge these 2 bones to their mirrored locations - ''' - h1= editbone1.head - h2= editbone2.head - - t1= editbone1.tail - t2= editbone2.tail - - if PREF_MODE_L2R and PREF_MODE_R2L: - # Median, flip bone2's locations and average, then apply to editbone1, flip and apply to editbone2 - h2_f= VecXFlip(h2) - t2_f= VecXFlip(t2) - - h_med= (h1+h2_f)*0.5 # middle between t1 and flipped t2 - t_med= (t1+t2_f)*0.5 # middle between h1 and flipped h2 - - # Apply the median to editbone1 - editbone1.head= h_med - editbone1.tail= t_med - - # Flip in place for editbone2 - h_med.x= -h_med.x - t_med.x= -t_med.x - - # Apply the median to editbone2 - editbone2.head= h_med - editbone2.tail= t_med - - # Average the roll, this might need some logical work, but looks good for now. - r1= editbone1.roll - r2= -editbone2.roll - # print 'rolls are', r1,r2 - r_med= (r1+r2)/2 - # print 'new roll is', r_med - editbone1.roll= r_med - editbone2.roll= -r_med # mirror roll - - else: # Copy from 1 side to another - - # Crafty function we can use so L>R and R>L can use the same code - def IS_XMIRROR_SOURCE(xval): - '''Source means is this the value we want to copy from''' - - if PREF_MODE_L2R: - if xval<0: return True - else: return False - else: # PREF_MODE_R2L - if xval<0: return False - else: return True - - if IS_XMIRROR_SOURCE( h1.x ):# head bone 1s negative, so copy it to h2 - editbone2.head= VecXFlip(h1) - else: - ''' - assume h2.x<0 - not a big deal if were wrong, - its unlikely to ever happen because the bones would both be on the same side. - ''' - - # head bone 2s negative, so copy it to h1 - editbone1.head= VecXFlip(h2) - - # Same as above for tail - if IS_XMIRROR_SOURCE(t1.x): - editbone2.tail= VecXFlip(t1) - else: - editbone1.tail= VecXFlip(t2) - - # Copy roll from 1 bone to another, use the head's location to decide which side it's on. - if IS_XMIRROR_SOURCE(editbone1.head): - editbone2.roll= -editbone1.roll - else: - editbone1.roll= -editbone2.roll - - -def armature_symetry(\ - arm_ob,\ - PREF_MAX_DIST,\ - PREF_XMID_SNAP,\ - PREF_XZERO_THRESH,\ - PREF_MODE_L2R,\ - PREF_MODE_R2L,\ - PREF_SEL_ONLY): - - ''' - Main function that does all the work, - return the number of - ''' - arm_data= arm_ob.data - arm_data.makeEditable() - - # Get the bones - bones= [] - HIDDEN_EDIT= Blender.Armature.HIDDEN_EDIT - BONE_SELECTED= Blender.Armature.BONE_SELECTED - - if PREF_SEL_ONLY: - for eb in arm_data.bones.values(): - options= eb.options - if HIDDEN_EDIT not in options and BONE_SELECTED in options: - bones.append(eb) - else: - # All non hidden bones - for eb in arm_data.bones.values(): - options= eb.options - if HIDDEN_EDIT not in options: - bones.append(eb) - - del HIDDEN_EDIT # remove temp variables - del BONE_SELECTED - - # Store the numder of bones we have modified for a message - tot_editbones= len(bones) - tot_editbones_modified= 0 - - if PREF_XMID_SNAP: - # Remove bones that are in the middle (X Zero) - # reverse loop so we can remove items in the list. - for eb_idx in xrange(len(bones)-1, -1, -1): - edit_bone= bones[eb_idx] - if abs(edit_bone.head.x) + abs(edit_bone.tail.x) <= PREF_XZERO_THRESH/2: - - # This is a center bone, clamp and remove from the bone list so we dont use again. - if edit_bone.tail.x or edit_bone.head.x: - tot_editbones_modified += 1 - - edit_bone.tail.x= edit_bone.head.x= 0 - del bones[eb_idx] - - - - - bone_comparisons= [] - - # Compare every bone with every other bone, shouldn't be too slow. - # These 2 "for" loops only compare once - for eb_idx_a in xrange(len(bones)-1, -1, -1): - edit_bone_a= bones[eb_idx_a] - for eb_idx_b in xrange(eb_idx_a-1, -1, -1): - edit_bone_b= bones[eb_idx_b] - # Error float the first value from editbone_mirror_diff() so we can sort the resulting list. - bone_comparisons.append(editbone_mirror_diff(edit_bone_a, edit_bone_b)) - - - bone_comparisons.sort() # best matches first - - # Make a dict() of bone names that have been used so we dont mirror more then once - bone_mirrored= {} - - for error, editbone1, editbone2 in bone_comparisons: - # print 'Trying to merge at error %.3f' % error - if error > PREF_MAX_DIST: - # print 'breaking, max error limit reached PREF_MAX_DIST: %.3f' % PREF_MAX_DIST - break - - if not bone_mirrored.has_key(editbone1.name) and not bone_mirrored.has_key(editbone2.name): - # Were not used, execute the mirror - editbone_mirror_merge(editbone1, editbone2, PREF_MODE_L2R, PREF_MODE_R2L) - # print 'Merging bones' - - # Add ourselves so we aren't touched again - bone_mirrored[editbone1.name] = None # dummy value, would use sets in python 2.4 - bone_mirrored[editbone2.name] = None - - # If both options are enabled, then we have changed 2 bones - tot_editbones_modified+= PREF_MODE_L2R + PREF_MODE_R2L - - arm_data.update() # get out of armature editmode - return tot_editbones, tot_editbones_modified - - -def main(): - ''' - User interface function that gets the options and calls armature_symetry() - ''' - - scn= Scene.GetCurrent() - arm_ob= scn.objects.active - - if not arm_ob or arm_ob.type!='Armature': - Blender.Draw.PupMenu('No Armature object selected.') - return - - # Cant be in editmode for armature.makeEditable() - is_editmode= Blender.Window.EditMode() - if is_editmode: Blender.Window.EditMode(0) - Draw= Blender.Draw - - # Defaults for the user input - PREF_XMID_SNAP= Draw.Create(1) - PREF_MAX_DIST= Draw.Create(0.4) - PREF_XZERO_THRESH= Draw.Create(0.02) - - PREF_MODE_L2R= Draw.Create(1) - PREF_MODE_R2L= Draw.Create(0) - PREF_SEL_ONLY= Draw.Create(1) - - pup_block = [\ - 'Left (-), Right (+)',\ - ('Left > Right', PREF_MODE_L2R, 'Copy from the Left to Right of the mesh. Enable Both for a mid loc.'),\ - ('Right > Left', PREF_MODE_R2L, 'Copy from the Right to Left of the mesh. Enable Both for a mid loc.'),\ - '',\ - ('MaxDist:', PREF_MAX_DIST, 0.0, 4.0, 'Maximum difference in mirror bones to match up pairs.'),\ - ('XZero limit:', PREF_XZERO_THRESH, 0.0, 2.0, 'Tolerance for locking bones into the middle (X/zero).'),\ - ('XMidSnap Bones', PREF_XMID_SNAP, 'Snap middle verts to X Zero (uses XZero limit)'),\ - ('Selected Only', PREF_SEL_ONLY, 'Only xmirror selected bones.'),\ - ] - - # Popup, exit if the user doesn't click OK - if not Draw.PupBlock("X Mirror mesh tool", pup_block): - return - - # Replace the variables with their button values. - PREF_XMID_SNAP= PREF_XMID_SNAP.val - PREF_MAX_DIST= PREF_MAX_DIST.val - PREF_MODE_L2R= PREF_MODE_L2R.val - PREF_MODE_R2L= PREF_MODE_R2L.val - PREF_XZERO_THRESH= PREF_XZERO_THRESH.val - PREF_SEL_ONLY= PREF_SEL_ONLY.val - - # If both are off assume mid-point and enable both - if not PREF_MODE_R2L and not PREF_MODE_L2R: - PREF_MODE_R2L= PREF_MODE_L2R= True - - - tot_editbones, tot_editbones_modified = armature_symetry(\ - arm_ob,\ - PREF_MAX_DIST,\ - PREF_XMID_SNAP,\ - PREF_XZERO_THRESH,\ - PREF_MODE_L2R,\ - PREF_MODE_R2L,\ - PREF_SEL_ONLY) - - if is_editmode: Blender.Window.EditMode(1) - - # Redraw all views before popup - Blender.Window.RedrawAll() - - # Print results - if PREF_SEL_ONLY: - msg= 'moved %i bones of %i selected' % (tot_editbones_modified, tot_editbones) - else: - msg= 'moved %i bones of %i visible' % (tot_editbones_modified, tot_editbones) - - - Blender.Draw.PupMenu(msg) - -# Check for __main__ so this function can be imported by other scripts without running the script. -if __name__=='__main__': - main()