Dev:Source/Constraints

提供: wiki
移動先: 案内検索

Constraints API

Purpose

The Constraints API was started but development stalled out, so this page is intended as a place to work out the details which the users need.

Overall Details of Constraints

  • The following types of constraints are implemented: Null, Copy Location, Copy Rotation, Copy Size, Track To, Floor, Locked Track, Follow Path, Stretch To, IK Solver, Action
  • Objects and Poses can have constraints
  • Only Poses can have IK Solver and Action constraints
  • Constraints are applied in a particular order

For Armatures, Ton wrote a nice description of how armatures, poses and actions work together, which also describes constraints. Another page describes Actions and NLAs; actions now also work with some non-armature objects.

BPy Implementation Ideas

Some of the ideas here are borrowed from the Modifier API (added to the API in version 2.42). If you aren't familiar with it, see Cam's copy of the page

BPy_ConstraintSeq Type

Since an object or pose can have more than one constraint, we implement a sequence operator to access/manipulate the constraint stack. It basically defines

  • a PySequenceMethods structure for the index operator [],
  • a PyMethodDef structure for some instance methods, and
  • (optionally) a PyGetSetDef structure for any general attributes.

BPy_Constraint Type

The Constraint type allows access to the data for a particular constraint. Since there are many types of constraints, we probably don't want to implement PyTypes for each. As is done for BPy Objects, a read-only attribute type is defined for each BPy_Constraint instance which identifies the type of Constraint and also determines what type of data is wrapped by the BPy object. The type definition contains

  • a PyMappingMethods structure for the mapping operator [],
  • a PyMethodDef structure for some instance methods, and
  • a PyGetSetDef structure for any general attributes

As is the case for the BPy_Modifier type, the mapping operator [] is used to access the data particular to the Constraint type. For example, to access the "Offset" data for a Floor constraint:

from Blender import *

ob = Object.Get('Cube')
if len(ob.constraints) > 0:
  const = ob.constraints[0]
  if const.type == Constraint.Type.FLOOR:
    offs = const[Constraint.Settings.OFFSET]

Or to print all the constraints attached to each bone in a pose:

from Blender import *

ob = Object.Get('Armature')
pose = ob.getPose()
for bonename in pose.bones.keys():
  bone = pose.bones[bonename]
  for const in bone.constraints:
    print bone.name
    print '\t',const
Object vs Pose Constriants

Pose are unique in two ways:

  • they can also have the two constraint types IK Solver and Action
  • internally their data is stored within the object's pose data instead of the constraints

So they can't be referenced the same way; for an object, there is a sequence of constraints, but for a pose there is a sequence (of poses) of sequence of constraints