Armature symmetry [solved - at least for me]

Scripting in Blender with Python, and working on the API

Moderators: jesterKing, stiv

Post Reply
damir
Posts: 0
Joined: Tue Feb 21, 2006 7:50 pm

Armature symmetry [solved - at least for me]

Post by damir »

I don't get it... Why bone and editbone roll isn't of the same type?
I wish to create a mirrored clone of a bone and I don't know how to set roll value correctly...

Edit:

Now I think that there is a bug in armature accesing with python. Let say that I have one armature (I use interactive console to do this):

Code: Select all


Arm = Armature.Get()

#qick access to one bone roll in that armature

roll = Arm.values()[0].bones.values()[0].roll

print roll

#I have only one test bone at center 3d window so roll is this
#('ARMATURESPACE':0.0,'BONESPACE':0,0)

#Now make that armature editable

Arm.values()[0].makeEditable()

#And get again roll of that bone

roll = Arm.values()[0].bones.values()[0].roll

print roll
#and here is a bug, I get this value:
#9.7028405954464057e-317

#if I set roll value to let say 10.0

Arm.values()[0].bones.values()[0].roll = 10.0

roll = Arm.values()[0].bones.values()[0].roll

print roll
#I get this
#-3.5827390665034156e+261


Now, If this is not a bug, how can I calculate those values from bone roll or matrix? And, btw, I'm not a programmer and I learn blender for a month now, and I use blender 2.41, build 2006-01-23 22:29:28.
So sorry on my ignorance.

Cheers!

Damir
Last edited by damir on Mon Mar 27, 2006 9:00 am, edited 2 times in total.

damir
Posts: 0
Joined: Tue Feb 21, 2006 7:50 pm

Post by damir »

Wow, thanks for so many replies and suggestions.
But it's not a problem any more, I have found a solution.
Cheers!

an-toni
Posts: 0
Joined: Wed Mar 17, 2004 5:20 pm

Post by an-toni »

would you care to post the solution?

it seems that Joseph / ascotan, who wrote the new PyArmature for 2.4 series, is busy somewhere else nowadays .. havent heard of him for a while, but he has been fixing bugs that have been found during the past months, and of course other ppl in py team can fix things too if something new was found now by you.

~Toni

Roja
Posts: 0
Joined: Tue May 04, 2004 4:36 pm

Post by Roja »

Is this perhaps the same bug discussed about here?:

http://www.blender3d.org/forum/viewtopi ... c11c48ba8c

damir
Posts: 0
Joined: Tue Feb 21, 2006 7:50 pm

Post by damir »


Well, I'm not a python programmer but I have managed to get that "Armature Symmetry" script work for me.
I had to rewrite most of the code but hey, life is a bitch :)
Unfortunatley, they have not yet included API for bone constrains, or I can't find it, so you must do some hady work even after this script.
I Hope that this will work for you.

So here is the code:

Code: Select all

#!BPY
######################################################

"""
Name: 'Armature Symmetry 241'
Blender: 241
Group: 'Animation'
Tooltip: 'Make an armature symetrical'
"""

######################################################
#
#------------------------------------------------------
# 'Armature Symmetry 241' v 0.1 by Damir Prebeg
# for Blender 2.41
#------------------------------------------------------
# Based on ' Armature Symmetry' from Jonas Petersen
# (code of his version is included below)
#------------------------------------------------------
# Notes:
#
#   I'm not a python programer. In fact, I'm not programer at all.
#   So if this script is not working for you, shame on her!
#   (But please tell me if it's not workig anyhow :) )
#   And I have maked code to work only on ONE armature at time
#   'cause I don't see a point why it should work on multiple armatures :)
#   Well, that's all. Enjoy!
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
# 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 as Armature
from Blender.Mathutils import *


#Centering vars.
CENTER_SUFFIX = '.001'
#DO SOME CENTERING (0 = off, 1 = on)
CENTER_MODE = 0

#Sufix for refference bones
REF_SUFFIX = '.r'

#Sufix for mirrored bones
OPP_SUFFIX = '.l'

#Mirror axis ( 0 = X, 1 = Y, 2 = Z)
AXIS = 0
	
def splitName(bone):
	name = bone.name
	base = name[0:len(name)-ref_suffix_len]
	rsuff = name[-ref_suffix_len:len(name)]
	csuff = name[-center_suffix_len:len(name)]
	return name, base, rsuff, csuff

def GetArmature():
	obj = Blender.Object.GetSelected()
	if len(obj) < 1:
		Blender.Draw.PupMenu("Mirror bones:%t|Select one Armature first")
		return False
	elif len(obj) > 1:
		Blender.Draw.PupMenu("Mirror bones:%t|Select ONLY one Armature")
		return False
	elif obj[0].getType() != "Armature":
		Blender.Draw.PupMenu("Mirror bones:%t|Selected object is not an Armature")
		return False
	else: return obj[0].getData()

def GetMirrVect(vect, axis):
  v = Vector(vect)
  v[axis]*=-1
  return v	

def GetCentVect(vect, axis):
  v = Vector(vect)
  v[axis]=0.0
  return v	

def CenterBone(bone):
	head = Vector(bone.head)
	tail = Vector(bone.tail)
		
	bone.head = GetCentVect(head,AXIS)
	bone.tail = GetCentVect(tail,AXIS)
	bone.roll = 0

def CreateMirrorBone(RefBone):
	#Get bone data
	head = RefBone.head['ARMATURESPACE']
	tail = RefBone.tail['ARMATURESPACE']
	roll = RefBone.roll['ARMATURESPACE']
	
	eb = Armature.Editbone()
	eb.head = GetMirrVect(head,AXIS)
	eb.tail = GetMirrVect(tail,AXIS)
	eb.roll = roll*-1
	
	return eb

ref_suffix_len = len(REF_SUFFIX);
center_suffix_len = len(CENTER_SUFFIX);
	
AData = GetArmature()

if AData:	
	bones = AData.bones.values()
	boneHash={}

#1. PASS - CREATE MIRRORED BONES AND INSERT THEM TO ARMATURE

	AData.makeEditable()
	
	for bone in bones:
		boneHash[bone.name]=bone
	
	for bone in bones:
		name, base, rsuff, csuff = splitName(bone)		
		if (rsuff == REF_SUFFIX):
			oppname = base + OPP_SUFFIX
			if not boneHash.has_key(oppname):
				AData.bones[oppname]=CreateMirrorBone(bone)

	AData.update()

#2. PASS - NOW LET'S DO SOME PARENTING AND CENTERING

	AData.makeEditable()
	
	bones = AData.bones.values()
	boneHash={}
	
	for bone in bones:
		boneHash[bone.name]=bone
	
	for bone in bones:
		name, base, rsuff, csuff = splitName(bone)
		
		#PARENTING			
		if (rsuff == REF_SUFFIX):
			oppname = base + OPP_SUFFIX
			refname = base + REF_SUFFIX
			parent = bone.parent
			if parent:
				pname, pbase, prsuff, pcsuff = splitName(parent)
				if prsuff == REF_SUFFIX:
					poppname = pbase + OPP_SUFFIX
					if boneHash.has_key(poppname):
						AData.bones[oppname].parent=boneHash[poppname]
						AData.bones[oppname].options = AData.bones[refname].options
				else:
					AData.bones[oppname].parent = parent
					AData.bones[oppname].options = AData.bones[refname].options
		
		#CENTERING
		if (csuff == CENTER_SUFFIX) and (CENTER_MODE == 1):
			CenterBone(AData.bones[name])
					
	AData.update()

Blender.Window.Redraw()

##############################################################################
##ORIGINAL CODE###############################################################
##############################################################################
##!BPY
#
#"""
#Name: 'Armature Symmetry'
#Blender: 234
#Group: 'Object'
#Tooltip: 'Make an armature symetrical'
#"""
## --------------------------------------------------------------------------
## "Armature Symmetry" by Jonas Petersen
## Version 0.9 - 10th November 2004 - first public release
## --------------------------------------------------------------------------
##
## A script for creating perfectly symmetrical armatures.
##
## It is available in Object Mode via the menu item:
##
##   Object -> Scripts -> Armature Symmetry
##
## With default configuration it will:
##
##   - Look for bones that have the reference suffix (".L") and
##     adjust/create the according opposite bone (suffix ".R").
##
##   - Center align all bones that _don't_ have the suffix ".X"
##
## Find the latest version at: http://www.mindfloaters.de/blender/
##
## --------------------------------------------------------------------------
## (This is my local CVS, not the Blender CVS.)
## $Id: armature_symetry.py,v 1.1 2004/10/23 03:19:01 jonas Exp $
## --------------------------------------------------------------------------
## ***** BEGIN GPL LICENSE BLOCK *****
##
## Copyright (C) 2004: Jonas Petersen, jonas at mindfloaters dot de
##
## 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 *****
#
## --------------------------------------------------------------------------
## CONFIGURATION
## --------------------------------------------------------------------------
#
## Note: Theses values will later be editable via a gui interface
## within Blender.
#
## CENTER_SUFFIX is the suffix for bones that should (or shouldn't) get
## center aligned. The default is '.X'.
#CENTER_SUFFIX = '.X'
#
## CENTER_SUFFIX_MODE:
##
##   'include'  only bones with the CENTER_SUFFIX appended
##              get center aligned.
##
##   'exclude'  (default)
##              all bones except those with the CENTER_SUFFIX
##              appended get center aligned.
##
##
##   'off'      bones will not get center aligned at all.
##
#CENTER_SUFFIX_MODE = 'exclude'
#
## The suffix for the reference and opposite side of the
## armature. Bone positions of the opposite side will be overwritten by
## the mirrored values of the reference side.
## The default is REF_SUFFIX = '.L' and OPP_SUFFIX = '.R'.
#REF_SUFFIX = '.L'
#OPP_SUFFIX = '.R'
#
## MIRROR_AXIS defines the axis in which bones are mirrored/aligned.
## Values:
##   0 for X (default)
##   1 for Y
##   2 for Z
#MIRROR_AXIS = 0
#
## --------------------------------------------------------------------------
## END OF CONFIGURATION
## --------------------------------------------------------------------------
#
#import Blender
#
#def splitName(bone):
#	name = bone.getName()
#	base = name[0:len(name)-ref_suffix_len]
#	rsuff = name[-ref_suffix_len:len(name)]
#	csuff = name[-center_suffix_len:len(name)]
#	return name, base, rsuff, csuff
#
#ref_suffix_len = len(REF_SUFFIX);
#center_suffix_len = len(CENTER_SUFFIX);
#armature_selected = False
#
#obj_list = Blender.Object.GetSelected()
#for obj in obj_list:
#    if obj.getType() == "Armature":
#		armature_selected = True
#		arm = obj.getData()
#		bones = arm.getBones()
#		bonehash = {}
#
#		for bone in bones:
#			bonehash[bone.getName()] = bone
#
#		for bone in bones:
#			name, base, rsuff, csuff = splitName(bone)
#
#			# reference bone?
#			if (rsuff == REF_SUFFIX):
#				oppname = base + OPP_SUFFIX
#
#				# create opposite bone if necessary
#				if not bonehash.has_key(oppname):
#					bonehash[oppname]=Blender.Armature.Bone.New(oppname)
#					parent = bone.getParent()
#					if parent:
#						pname, pbase, prsuff, pcsuff = splitName(parent)
#						if prsuff == REF_SUFFIX:
#							poppname = pbase + OPP_SUFFIX
#							if bonehash.has_key(poppname):
#								bonehash[oppname].setParent(bonehash[poppname])
#						else:
#							bonehash[oppname].setParent(parent)
#					arm.addBone(bonehash[oppname])
#
#				# mirror bone coords
#
#				tail = bone.getTail()
#				tail[MIRROR_AXIS] *= -1;
#				bonehash[oppname].setTail(tail)
#
#				head = bone.getHead()
#				head[MIRROR_AXIS] *= -1;
#				bonehash[oppname].setHead(head)
#
#				roll = -bone.getRoll()
#				bonehash[oppname].setRoll(roll)
#
#				# Write access to ik flag not (yet?) supported in Blender (2.34)
#				#if bone.hasParent():
#				#	bonehash[oppname].setIK(not bone.getIK())
#
#			# center bone?
#			elif (rsuff != OPP_SUFFIX) and \
#			     (CENTER_SUFFIX_MODE != 'off') and \
#			     ((CENTER_SUFFIX_MODE == 'exclude' and csuff != CENTER_SUFFIX) or \
#			     (CENTER_SUFFIX_MODE == 'include' and csuff == CENTER_SUFFIX)):
#
#				# center bone coords
#
#				tail = bone.getTail()
#				tail[MIRROR_AXIS] = 0.0;
#				bone.setTail(tail)
#
#				head = bone.getHead()
#				head[MIRROR_AXIS] = 0.0;
#				bone.setHead(head)
#
#				# Setting set roll in python rotates all child bones.
#				# Not so if set via the Transform Properties in Blender.
#				# Bug?
#				bone.setRoll(0.0)
#
#if not armature_selected:
#	Blender.Draw.PupMenu("Armature Symmetry%t|Please select an Armature object!")
###############################################################################
##END OF ORIGINAL CODE#########################################################
###############################################################################

Cheers!

Post Reply