Forum: Poser Python Scripting


Subject: Useful Code Snippets

structure opened this issue on Jun 27, 2019 ยท 94 posts


adp001 posted Sat, 16 May 2020 at 8:41 AM

I often use the following little function if I have to script something with Poser meshes. I do that outside of Poser, because I often need a debugger to follow what the script is doing step by step in critical parts.

With Poser-Python:

import numpy as NP

try:
    import poser

    INSIDEPOSER = True
except ImportError:
    # "POSER_FAKE" is a Python lib to allow your editor to know about Poser
    # for scripting outsite of Poser (code completition, type checking, highlighting).
    # Author: adp001
    # Direct download: http://adp.spdns.org/FakePoserLib3.zip
    import POSER_FAKE as poser

    INSIDEPOSER = False

# Pickle is used to save|load the complete geometry instead of a slow obj loader.
try:
    import cPickle as pickle
except ImportError:
    import pickle


# Returns python list (assume given poly is tri or quad):
f_forcequad = lambda _poly: list(_poly) if len(_poly) == QUAD else list(_poly) + [_poly[-1]]

VERSION = float(poser.Version()) if poser.Version()[0].isdigit() else 11
NP_PRECISION = NP.float32 if int(VERSION) <= 11 else NP.float

def save_figure(fig, filename):
    """
        Saves verts, tverts, polys (4 vertices as float), polysets (4 indices crossreferencing verts),
        tpolys (2 vertices as float), tpolysets (2 indices creossreferencing tverts), material names
        and a material indexlist for cross-reference.
        All collected arrays from current figure are pickled into a file.

        :param fig: Poser figure
        :param filename: Path and filename
        :type fig: poser.FigureType
        :type filename: basestring
    """
    if INSIDEPOSER:
        # Get unimesh of current figure (unmorphed, unposed)
        poser_geom = fig.UnimeshInfo()[0]
        assert isinstance(poser_geom, poser.GeomType)
        geom = MyGeom(
                verts=NP.array([[v.X(), v.Y(), v.Z()] for v in poser_geom.Vertices()], NP_PRECISION),
                tverts=NP.array([[v.U(), v.V()] for v in poser_geom.TexVertices()], NP_PRECISION),
                polys=NP.array([f_forcequad([[v.X(), v.Y(), v.Z()] for v in p.Vertices()])
                                for p in poser_geom.Polygons()], NP_PRECISION),
                polysets=NP.array([f_forcequad(poser_geom.Sets[p.Start():p.Start() + p.NumVertices()])
                                   for p in poser_geom.Polygons()], NP.int32),
                tpolys=NP.array([f_forcequad([[v.U(), v.V()]
                                              for v in p.TexVertices()]) for p in poser_geom.TexPolygons()],
                                NP_PRECISION),
                tpolysets=NP.array([f_forcequad(poser_geom.Sets[p.Start():p.Start() + p.NumVertices()])
                                    for p in poser_geom.TexPolygons()], NP.int32),
                matindex=NP.array([p.MaterialIndex() for p in poser_geom.Polygons()], NP.int32),
                matnames=[m.Name() for m in poser_geom.Materials()]
        )
        p = poser.TexPolygonType()

        with open(filename, "wb") as fh:
            pickle.dump(geom, fh, pickle.HIGHEST_PROTOCOL)

        return geom
    return None

This saves all those collected data in a file (pickled).