Forum: Poser Python Scripting


Subject: Storing information in the scene

vholf opened this issue on Aug 14, 2011 ยท 9 posts


adp001 posted Tue, 16 August 2011 at 12:15 PM

It is possible to store a string in a dial, too.

Maybe a little bit wired, but it works.

<pre style="margin:0;padding:0;font-family:'courier new', courier;">

------------------------------------------------------------------------ 
# Make sure the actor used has at least len(string)/3 vertices.

import poser

TEXTDIAL_HIDDEN = False # set to True to hide text-dials

class TextDial(object):
    def __init__(self, actor, dialname, sc=poser.Scene()):
        if not isinstance(actor, (poser.ActorType, poser.ParmType)):
            raise AttributeError, "Parameter 'actor' must be a Poser Actor"

        self.name = dialname
        self.actor = actor.InternalName()
        p = actor.Parameter(dialname) or self.createDial()
        if p:
            p.SetMorphTargetDelta(0, 0, 0, 0)
            self.parm = p.InternalName()
            if TEXTDIAL_HIDDEN:
                p.SetHidden(1)

    def createDial(self, sc=poser.Scene()):
        ac = sc.ActorByInternalName(self.actor)
        assert ac
        try: parm = ac.SpawnTarget(self.name)
        except:
            # dialname can not be created or exists but is
            # not a TargetGeom as required.
            raise Exception, "Ups!"

        return parm


    def setText(self, text, sc=poser.Scene()):
        ac = sc.ActorByInternalName(self.actor)
        assert ac
        assert isinstance(text, str)

        dial = ac.Parameter(self.name) or self.createDial()
        assert dial

        geom = ac.Geometry()
        vcnt = geom.NumVertices()

        if (vcnt * 3) < len(text):
            raise ValueError, "String '%s' is longer than NumVertices()*3 (%s)" % (text, vcnt * 3)

        for entry in range(vcnt):
            c = []
            for i in range(3):
                pos = entry * 3 + i
                if pos >= len(text):
                    c.append(0)
                else:
                    c.append(ord(text[pos]))

            dial.SetMorphTargetDelta(entry, *c)
            if c[-1] == 0 : break


    def getText(self, sc=poser.Scene()):
        ac = sc.ActorByInternalName(self.actor)
        assert ac

        dial = ac.Parameter(self.name) or self.createDial()
        assert dial

        geom = ac.Geometry()
        vcnt = geom.NumVertices()

        c = []
        for entry in range(vcnt):
            c.extend(map(int, dial.MorphTargetDelta(entry)))
            if c[-1] == 0: break

        return "".join(map(chr, c[:c.index(0)]))


if __name__ == "__main__":

    print "Setting morph-dial 'demo' to a string."

    # create class for a dial via TextDial( actor,  dialname)
    demo = TextDial(poser.Scene().CurrentActor(), "demo")

    # set string via setText()
    demo.setText("This is a string stored in a Poser-Morphdial")

    print "nATTENTION: DON'T USE THIS DIAL AS USUAL! YOUR ACTOR/FIGURE MAY EXPLODE"

    # read back via getText()
    print "nReading back results in: '%s'" % demo.getText()

    print "nIf you save the scene, the string is saved like any other morph."