Forum: Poser 12


Subject: Moving the pivot point for a door

Eronik opened this issue on Jun 07, 2021 ยท 28 posts


adp001 posted Wed, 09 June 2021 at 8:32 PM

I had a different idea. Changing (changing) the objects vertices instead of just doing a Poser scale. With the following script this is as simple as the standard way.

The following script creates a new parameter inside the currently selected prop/actor. This prop contains the height of the prop measured in centimeters. If you dial it, the prop will scale (or if you type in a value in cm).

Note: Poser scale dials are not affected! The geometry changes, not the dials. The prop/actor is flagged as changed, so Poser can take actions accordingly.

And now the fun part:

from __future__ import print_function  # Python 3 print function in Python 2

import sys
import numpy as NP

def actor_has_geom(ac):
    return isinstance(ac, poser.ActorType) 
           and hasattr(ac, "Geometry") 
           and geom_ok(ac.Geometry())

def get_props_height_pnu(actor):
    if isinstance(actor, poser.ActorType) and actor_has_geom(actor):
        geom = actor.Geometry()
        verts = NP.array([[v.X(), v.Y(), v.Z()] for v in geom.Vertices()])
        return NP.max(verts[:, Y]) - NP.min(verts[:, Y])


def get_props_height_cm(actor):
    return get_props_height_pnu(actor) / 0.0038145


def change_props_size(actor, scale):
    if isinstance(actor, poser.ActorType) and actor_has_geom(actor):
        geom = actor.Geometry()
        for pv in geom.Vertices():
            pv.SetX(pv.X() * scale)
            pv.SetY(pv.Y() * scale)
            pv.SetZ(pv.Z() * scale)
        actor.MarkGeomChanged()

__lastsizes = dict()  # storage to remember scales

def dynamic_height_prop(actor):
    global __lastsizes

    def cb_func(parm, value):
        ac = parm.Actor()
        iname = ac.InternalName()
        old = __lastsizes[iname]
        if old != value:
            scale = 1.0 / old * value
            change_props_size(ac, scale)
            __lastsizes[iname] = value
        return value

    if isinstance(actor, poser.ActorType) and actor_has_geom(actor):
        parmname = "Dyn Height cm"
        parm = actor.Parameter(parmname)
        if parm is None:
            parm = actor.CreateValueParameter(parmname)
        last_value = __lastsizes[actor.InternalName()] = get_props_height_cm(actor)
        parm.SetValue(last_value)
        poser.Scene().DrawAll()
        parm.SetUpdateCallback(cb_func)


if __name__ == "__main__":
    dynamic_height_prop(poser.Scene().CurrentActor())
    print("Activated.")