Forum: Poser Python Scripting


Subject: Storing information in the scene

vholf opened this issue on Aug 14, 2011 · 9 posts


vholf posted Sun, 14 August 2011 at 12:16 AM

Hi all,

I've seen several python scripts which seem to store information within the scene, like the script settings, button states, etc.

How can this be achieved? where is the information actually stored? I've seen it in the form of props and such, maybe as parameters? I hope this is not a secret of the trade, as I've seen it so far only in comercial script.

Any pointers are welcome.


deastham posted Sun, 14 August 2011 at 12:26 AM Online Now!

It depends on what you're trying to do/store. I'm not sure you can store parameters in the objects themselves, but you can set values from or store values to another variable/array/etc. You can also directly set values for parameters.


vholf posted Sun, 14 August 2011 at 12:38 AM

Well, a long time ago I wrote a script to isolate a figure in the scene, an idea I got from watching a friend work in 3ds max, you hit isolate and all other figures and props are hidden, hit it again and they show back, useful for making quick adjustments.

I would like to store the figure state (if it's isolated or not), which figure it is, and a few other options and parameters. I'm storing it in text format right now, but is a clumsy solution, I know there are ways to save this parameters within the poser scene, I've seen it done, just have no clue of how :P


semidieu posted Sun, 14 August 2011 at 2:23 AM

To set:

parm = Actor.CreateValueParameter('THISFIGUREISHIDDEN')

 

To remove (--> search for the parameter which name is 'THISFIGUREISHIDDEN' and

Actor.RemoveValueParameter(parm)

 


deastham posted Sun, 14 August 2011 at 2:58 AM Online Now!

Awesome. Thank you semidieu! That is immensely helpful with my own project.


vholf posted Sun, 14 August 2011 at 3:09 PM

Thanks semidieu! that works wonderfuly. It's from you scripts I got the idea btw, AdvRenderSetting and AdvFigureManager :)

This works for numeric values quite well, but is it possible to also store text content somehow? (500 characters or more).


semidieu posted Mon, 15 August 2011 at 12:51 AM

When I need to store text, I'm using external text files...


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."



colorcurvature posted Fri, 23 September 2011 at 1:43 AM

For my enhanced ERC tool, I also do store ERC setup code in invisible morph targets. It is very nice because you can store it in the library as well.