updated pyconstraint template from nathan (cessen) which exposed some

bugs with pyconstraints, also added a missing decref from python (wasnt freeing the return value from the settings 
button).
This commit is contained in:
Campbell Barton 2007-10-15 15:28:09 +00:00
parent 15ad8e7e66
commit e9c2aa691e
2 changed files with 88 additions and 87 deletions

@ -3,106 +3,106 @@
Name: 'Script Constraint'
Blender: 245
Group: 'ScriptTemplate'
Tooltip: 'Add a new text for custom constraints'
Tooltip: 'Add a new script for custom constraints'
"""
from Blender import Window
import bpy
script_data = \
'''#BPYCONSTRAINT
""" <------- Start removable description section ----------->
PyConstraints are text buffers that start with #BPYCONSTRAINT.
They must define a doConstraint function. The doConstraint
function is called with the matrix of the parent object/posebone
as the first argument, the matrix of the target object/posebone as
the second, and an ID property that's attached to the current constraint
instance. The function then must return a 4x4 Mathutils.Matrix() object.
They must also define a getSettings function. The getSettings
function is called with the ID property that's attached to the current constraint
instance. It should create a pupblock using the Blender.Draw module to
get/set the relevant values of the ID properties.
When a constraint needs to have a Target Object/Bone, the USE_TARGET line
below must be present. Also, if any special matrix creation needs to be performed
for the target, a doTarget function must also be defined.
Optionally, a doDriver function may be defined. This function is used
to get and/or modify settings of the owner and target, and as such, should
be used with caution. Under no circumstances, should you modify the transforms
of either the owner or the target in this function, as they will either have
no effect, or will result in other things not being updated correctly. Therefore,
it should be used sparringly.
<------- End removable description section -----------> """
# Add a licence here if you wish to re-distribute, we recommend the GPL
# uncomment the following line if Target access is wanted
"""
USE_TARGET = True
"""
"""#BPYCONSTRAINT
'''
PyConstraint template, access this in the "add constraint" scripts submenu.
Add docstring here
'''
import Blender
from Blender import Draw
from Blender import Mathutils
from math import *
import math
# this function is called to evaluate the constraint
# inputmatrix: (Matrix) copy of owner's worldspace matrix
# targetmatrix: (Matrix) copy of target's worldspace matrix (where applicable)
# idproperty: (IDProperties) wrapped data referring to this
# constraint instance's idproperties
def doConstraint(inputmatrix, targetmatrix, idproperty):
# must return a 4x4 matrix (owner's new matrix)
return inputmatrix;
USE_TARGET = True
# this function draws a pupblock that lets the user set
# the values of custom settings the constraint defines
# idprop: (IDProperties) wrapped data referring to this
# constraint instance's idproperties
# You MUST use a pupblock. There are errors if you try to use the UIBlock ones.
def getSettings(idproperty):
pass;
# this optional function performs special actions that only require
# access to the target data - calculation of special information
# targetobject: (Object) wrapped data referring to the target object
# subtarget: (String/PoseChannel)
# - If the target is a PoseChannel in an armature, then this
# is a wrapped copy of that PoseChannel.
# - Otherwise, this field will either be an empty string or the
# name of the vertex group
# targetmatrix: (Matrix) matrix that will be used as the target matrix
# idprop: (IDProperties) wrapped data referring to this
# constraint instance's idproperties
"""
def doTarget (targetobject, subtarget, targetmatix, idproperty):
# return a 4x4 matrix (which acts as the matrix of the target)
return targetmatrix;
"""
# This optional function is used to modify/get values on the owner and the
# target for creating certain setups. It should be used sparingly
# ownerobject: (Object) wrapped data referring to the owning object
# subowner: (PoseChannel) wrapped data referring to the PoseChannel that
# owns the constraint (where applicable)
# target: (Object) wrapped data referring to the target
# subtarget: (String/PoseChannel)
# - If the target is a PoseChannel in an armature, then this
# is a wrapped copy of that PoseChannel.
# - Otherwise, this field will either be an empty string or the
# name of the vertex group
"""
def doDriver (ownerobject, subowner, targetobject, subtarget, idproperty):
pass;
"""
'''
This function is called to evaluate the constraint
obmatrix: (Matrix) copy of owner's worldspace matrix
targetmatrix: (Matrix) copy of target's worldspace matrix (where applicable)
idprop: (IDProperties) wrapped data referring to this
constraint instance's idproperties
'''
def doConstraint(obmatrix, targetmatrix, idprop):
# Separate out the tranformation components for easy access.
obloc = obmatrix.translationPart() # Translation
obrot = obmatrix.toEuler() # Rotation
obsca = obmatrix.scalePart() # Scale
# Define user-settable parameters.\
# Must also be defined in getSettings().
if not idprop.has_key('user_toggle'): idprop['user_toggle'] = 1
if not idprop.has_key('user_slider'): idprop['user_slider'] = 1.0
# Do stuff here, changing obloc, obrot, and obsca.
# Convert back into a matrix for loc, scale, rotation,
mtxloc = Mathutils.TranslationMatrix( obloc )
mtxrot = obrot.toMatrix().resize4x4()
mtxsca = Mathutils.Matrix([obsca[0],0,0,0], [0,obsca[1],0,0], [0,0,obsca[2],0], [0,0,0,1])
# Recombine the separate elements into a transform matrix.
outputmatrix = mtxsca * mtxrot * mtxloc
# Return the new matrix.
return outputmatrix
'''
This function manipulates the target matrix prior to sending it to doConstraint()
target_object: wrapped data, representing the target object
subtarget_bone: wrapped data, representing the subtarget pose-bone (where applicable)
target_matrix: (Matrix) the transformation matrix of the target
id_properties_of_constraint: (IDProperties) wrapped idproperties
'''
def doTarget(target_object, subtarget_bone, target_matrix, id_properties_of_constraint):
return target_matrix
'''
This function draws a pupblock that lets the user set
the values of custom settings the constraint defines.
This function is called when the user presses the settings button.
idprop: (IDProperties) wrapped data referring to this
constraint instance's idproperties
'''
def getSettings(idprop):
# Define user-settable parameters.
# Must also be defined in getSettings().
if not idprop.has_key('user_toggle'): idprop['user_toggle'] = 1
if not idprop.has_key('user_slider'): idprop['user_slider'] = 1.0
# create temporary vars for interface
utoggle = Draw.Create(idprop['user_toggle'])
uslider = Draw.Create(idprop['user_slider'])
# define and draw pupblock
block = []
block.append("Buttons: ")
block.append(("Toggle", utoggle, "This is a toggle button."))
block.append("More buttons: ")
block.append(("Slider", uslider, 0.0000001, 1000.0, "This is a number field."))
retval = Draw.PupBlock("Constraint Template", block)
# update id-property values after user changes settings
if (retval):
idprop['user_toggle']= utoggle.val
idprop['user_slider']= uslider.val
"""
new_text = bpy.data.texts.new('pyconstraint_template.py')
new_text.write(script_data)

@ -1627,6 +1627,7 @@ void BPY_pyconstraint_settings(void *arg1, void *arg2)
/* free temp objects */
Py_XDECREF( idprop );
Py_DECREF( retval );
return;
}
}