[Bf-python] Fwd: Pyconstraint patch

joe joeedh at gmail.com
Fri May 18 21:15:26 CEST 2007


[sent this twice, as the first one I sent to
bf-python at projects.blender.org, and I thing that's the wrong address]

Patch link:

http://joeedh.googlepages.com/pyconstraint.patch

This patch implements python-defined constraints.

Pyconstraints are python text buffers that begin with #BPYCONSTRAINT.
No loading of
external pyconstraints is supported (deliberately), the idea being
that forcing people to
include the constraints in the .blend is the best way to avoid
compatibility issues.

Pyconstraints must define 2 functions: doConstraint(inmatrix,
targetmatrix, idproperty) and
doDraw(x, y, idproperty).

For doConstraint, inmatrix is the owning object/posebone's world-space
matrix, and
targetmatrix is the world-space matrix of the target object/posebone.
doConstraint must
 return a 4x4 Mathutils.Matrix() object, representing the new matrix
of the owning
object/posebone (in world space).  Note that inmatrix and targetmatrix
are copies, so
modifying them won't affect anything.

doDraw is used to define the UI of the constraint.  At the moment this
UI is placed in a
popup block, due to limitations of the interface code.  doDraw works
exactly the same way
 as if it were called with Draw.UIBlock(doDraw) (except that doDraw is
passed the x and y
coordinates to start at), and has the same rules/limitations.

Note that pyconstraints are handled in much the same way as normal
script with UIs; e.g.,
 their global namespace dictionary is kept alive unless an error happens.

Several issues with scoping in the Draw module came up while I was
working on this,
which I solved.  The most annoying one is no local copy of button
tooltips were made (in
 violation of the python design guidelines, btw) which meant if you
didn't use a global string
 variable for a tooltip, you could get garbarge or even a crash.  Also
not putting the result of
 Draw.String() in a global variable would cause garbage or a crash.

This issue turns out to be part of a bigger problem, where blender's
UI would internally hold
 references to python objects without somehow increasing their
reference count.  To solve
this, I modified the Draw.c code where each script area and each
pyconstraint instance
internally cache Button objects in a python list.  This solves the
problem of having to place
 each button in a global variable, and also allowed solving the
tooltip problem by copying
the tooltip from the python string to a 256-long char array in Button
(using strncpy of
course).

This allows for the following code form for pyconstraints:

def doDraw(x, y, idprop):
  def callback(id, val):
    if id == 0:
      print val
      idprop['bleh'] = val
  if idprop.has_key('bleh')==0: idprop['bleh'] = ""
  Draw.String("Bleh:", 0, x, y, 100, 22, idprop['bleh'], 32, "tooltip")

. . .which as you can see is very clear and compact.

One other small change I did was to extend Campbell's UIBlock code
changes to also work with pyconstraints (which only required adding
one small function, Set_UIBlock(), to Draw.c).

Due to time limitations and prior commitments with bmesh, I will not
have any more time till after summer for large changes to this patch.
If approved and committed, I can do maintenance work on it, fix bugs,
etc, but spending days rewriting it just because someone objects to
part of the design is definitely out. :)

Joe

!DSPAM:49,464dffb636371184790343!





More information about the Bf-python mailing list