Forum: Poser 12


Subject: Moving the pivot point for a door

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


adp001 posted Tue, 08 June 2021 at 5:05 PM

Often the problem is that the geometry center of a prop is displaced (the center of the OBJ is not at coordinate (0, 0, 0)). You don't always notice this because the prop may have been moved to the center of the image with the dials.

This can lead to problems when processing such props further. Among other things, it can cause the prop to rotate around its parent in a strange way.

The following small Python script based on "NumThe script changes the vertices of a prop or actor, not just the poser coordinates.

If you start the script as is, the currently selected Poser Actor will be changed.py" remedies this. Here is the core:

    verts = NP.array([[v.X(), v.Y(), v.Z()] for v in geom.Vertices()])
    v_min = NP.array([NP.min(verts[:, X]), NP.min(verts[:, Y]), NP.min(verts[:, Z])])
    v_max = NP.array([NP.max(verts[:, X]), NP.max(verts[:, Y]), NP.max(verts[:, Z])])
    center = v_min + (v_max - v_min) / 2.0
    for pv, new_verts in zip(geom.Vertices(), verts - center):
        pv.SetX(new_verts[X])
        pv.SetY(new_verts[Y])
        pv.SetZ(new_verts[Z])

And here is a working script (save it under any filename ending with ".py"):

from __future__ import print_function  # Python 3 print function in Python 2
import poser
import numpy as NP

X, Y, Z = range(3)

def geom_ok(geom):
    return isinstance(geom, poser.GeomType) \
           and geom.NumVertices() > 0


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


def set_geom2center(actor):
    if isinstance(actor, poser.GeomType) and geom_ok(actor):
        geom = actor
    elif isinstance(actor, poser.ActorType) and actor_has_geom(actor):
        geom = actor.Geometry()
    else:
        raise AttributeError("Call this function with a Poser actor or geometry.")

    verts = NP.array([[v.X(), v.Y(), v.Z()] for v in geom.Vertices()])
    v_min = NP.array([NP.min(verts[:, X]), NP.min(verts[:, Y]), NP.min(verts[:, Z])])
    v_max = NP.array([NP.max(verts[:, X]), NP.max(verts[:, Y]), NP.max(verts[:, Z])])
    center = v_min + (v_max - v_min) / 2.0
    for pv, new_verts in zip(geom.Vertices(), verts - center):
        pv.SetX(new_verts[X])
        pv.SetY(new_verts[Y])
        pv.SetZ(new_verts[Z])


if __name__ == "__main__":
    set_geom2center(poser.Scene().CurrentActor())
    print("Done.")

The script changes the vertices of a prop or actor, not just the poser coordinates.

If you start the script as is, the currently selected Poser Actor will be changed.