[Bf-taskforce25] PyConstraints V.2 - Proposal + Unresolved Issues

Nathan Vegdahl cessen at cessen.com
Sun Jul 26 22:20:53 CEST 2009


Dunno if this is the right time to bring this up, but I have been
thinking of some other ways that pyconstraints could be improved as
well:

1. The ability to specify what spaces (local, world, etc.) the
constraint can operate in.  This would let the writer of the
pyconstraint limit the constraint to the spaces where it makes sense,
reducing user confusion.  For example, my foot-roll constraint only
really makes sense in local space.

2. The ability to read the length of bones from inside the constraint.

3. The ability to do the constraining on the local transforms
themselves, rather than on a transform matrix.  For example: getting
the actual quat components of bones as input, and being able to output
directly to the quat components of the constrained bone.  This isn't
important for translation or scale, but using transform matrices to
pass and transform rotations is extremely lossy, and limits the
rigging schemes that can be developed (I've had to abandon potentially
useful schemes due to these limitations).

I suspect that #3 would be huge pain to do?  Because it implies
substantial changes in how Blender handles rotations in general.  And
there are also a lot of complexities it would add, especially in terms
of handling mixed rotation representations (quat vs euler vs etc.).
But if it's possible, it would be extremely useful, and would unlock a
lot of possibilities in rigging.

But even just #1 and #2 would be really nice.

--Nathan V


On Sun, Jul 26, 2009 at 5:38 AM, Joshua Leung<aligorith at gmail.com> wrote:
> Hi all,
>
> With the new style of coding py-extensions for Blender 2.5 coming in (with
> the new PyAPI), it's about time that we had a look at refreshing the way
> PyConstraints are coded.
>
> Firstly, an theoretical example of how a new PyConstraint could look like...
>
> class MyPyConstraint (bpy.types.pyconstraint):
>     __name__ = "Dummy Test";
>     __description__= "A silly constraint that makes use of and showcases
> several features that would need to be used.";
>     __num_targets__ = 1;
>
>     # evaluate the constraint for the given matrix and target matrices
>     def doConstraint (self, eval_matrix, target_matrices):
>          # get location parts
>          loc= eval_matrix.translationPart();
>          locT= target_matrices[0].translationPart();
>          # and other parts of matrix
>          obrot = obmatrix.toEuler()            # Rotation
>          obsca = obmatrix.scalePart()        # Scale
>
>          # snap to grid, then add target location on top + a custom factor
>          for i in xrange(3):
>             loc[i]= floor(loc[i]+0.5) + locT[i] + self.factor;
>
>          # Convert back into a matrix for loc, scale, rotation
>          mtxloc = Mathutils.TranslationMatrix(loc)
>          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 outputmatrix;
>
>     # manipulate matrix of target before giving it to the doConstraint()
> callback
>     doTarget(self, target_object, subtarget_bone, target_matrix):
>           return target_matrix;  # for this constraint, do nothing
>
>     # draw custom settings for constraint as part of constraints panel
>     def drawSettings (self, layout):
>           # add a single button for this custom factor
>           layout.itemR(self, "factor");
>
>
> -----------------------
>
> As can be seen, it takes into account several of the new PyAPI style issues:
> - subclassing RNA-defined base types   (bpy.types.pyconstraint)
> - layout engine is used to include the buttons defined in drawSettings() at
> the end of panel for instances of the constraint
> - name and num-targets can be defined in the way above, or by some other
> means (details to be confirmed)
> - custom properties can be directly accessed from the constraint instance
> like regular properties (due to RNA)
>
> However, I think it is important to still maintain a few other
> characteristics
> - constraint instances still must reference text buffers/datablocks instead
> of some magical global list that is maintained at startup... The main
> benefit here is that in productions where multiple versions of the
> constraints may be used, you don't need to register all the pyconstraints
> for every machine that you work on, leading to problems with version
> control...
> - keeping the text buffers, we can also easily edit the scripts and test
> without having to click on too many 'refresh' buttons
>
> The example above is incomplete in some ways though. Notably, there needs to
> be some way of checking for (and initialising) missing but required custom
> properties - probably a initSettings() call that checks if a setting exists
> already (creating a new prop if non-existant) that gets called at certain
> points? Getting this feature working is currently dependent on having
> bpy/RNA methods available for doing this (TODO #1)
> Also, the way of specifying the number of targets required indicated above
> may not work that well in practice?
>
> Technical issues
> - supposing that we compiled scripts containing such code, how would we go
> about executing the constraints that are defined in this way? How are
> changes such as number of targets going to cause changes?
>
>
> Anybody have any comments on the proposed PyConstraints 2? (More
> importantly, would be answers to the technical issues raised)
>
> Regards,
> Joshua
>
> _______________________________________________
> Bf-taskforce25 mailing list
> Bf-taskforce25 at blender.org
> http://lists.blender.org/mailman/listinfo/bf-taskforce25
>
>


More information about the Bf-taskforce25 mailing list