Sun, Nov 3, 4:50 PM CST

Renderosity Forums / Poser Python Scripting



Welcome to the Poser Python Scripting Forum

Forum Moderators: Staff

Poser Python Scripting F.A.Q (Last Updated: 2024 Sep 18 2:50 am)

We now have a ProPack Section in the Poser FreeStuff.
Check out the new Poser Python Wish List thread. If you have an idea for a script, jot it down and maybe someone can write it. If you're looking to write a script, check out this thread for useful suggestions.

Also, check out the official Python site for interpreters, sample code, applications, cool links and debuggers. This is THE central site for Python.

You can now attach text files to your posts to pass around scripts. Just attach the script as a txt file like you would a jpg or gif. Since the forum will use a random name for the file in the link, you should give instructions on what the file name should be and where to install it. Its a good idea to usually put that info right in the script file as well.

Checkout the Renderosity MarketPlace - Your source for digital art content!



Subject: Using a Python script to move geometry vertexes


Anthony Appleyard ( ) posted Wed, 12 July 2017 at 11:13 AM · edited Thu, 31 October 2024 at 10:27 PM

I have written a Python script which looks a figure's Geometry(). OK.

It (in two nested loops) contains this line

x=v.X(); y=v.Y(); z=v.Z()

which looks at the vertex v's coordinates (which are later printed out). OK.

So I changed it to:

    x=v.X(); y=v.Y(); z=v.Z(); v.SetY(y+1.0)

which, as obeyed many times in the loop iterations, would have moved a big area of the model's vertexes upwards by about 8 feet 4 inches. But nothing changed on render or when I exported the geometry to an .obj file. Please what must I do to make those changes show on display or render or when I export a geometry .obj file?


PhilC ( ) posted Wed, 12 July 2017 at 10:15 PM

How have you defined v ?


Anthony Appleyard ( ) posted Wed, 12 July 2017 at 11:28 PM · edited Wed, 12 July 2017 at 11:36 PM

The relevant Python operations in this script are as follows.

The idea struck me: hereinunder, am I working on the original values of the vertexes that Poser's renderer works from? Or am I working on a copy and leaving the originals alone?

d=scn.Figure("duck")

unim=d.UnimeshInfo(); dgeom=unim[0]; acts=unim[1]; vinfo=unim[2]

vertices=dgeom.Vertices(); nverts=len(vertices)
polys=dgeom.Polygons(); npolys=len(polys);    
vsets=dgeom.Sets(); nvsets=len(vsets);    

for i in range(0,npolys):
    p=polys[i]
    imat=p.MaterialIndex()
    nv=p.NumVertices()
    st=p.Start()
    for j in range(st,st+nv):
        k=vsets[j]

        v=vertices[k]
        x=v.X(); y=v.Y(); z=v.Z()
        v.SetY(y+1.0)


Anthony Appleyard ( ) posted Wed, 12 July 2017 at 11:43 PM · edited Wed, 12 July 2017 at 11:50 PM

P.S. I have tried inserting the line


        vertices[k]=v

next after the last line shown above, and calling the script, and still no change shows on rendering.

Should I be working on the separate geometries of each actor of the figure, and not on the geometry of the figure as assembled by calling d.UnimeshInfo()? Or what?


PhilC ( ) posted Wed, 12 July 2017 at 11:59 PM

Something appears to not be working any more. Your script looks to be correct. I ran UnimeshDemo.py on the P4 nude male in Poser 2014 and whereas a vertex in his thigh got displaced in previous versions it is no longer apparent now.

I do not know if it is due to various Poser updates or Windows updates but I've found that a number of scripts that worked fine for years now no longer do so.


Anthony Appleyard ( ) posted Thu, 13 July 2017 at 4:11 AM

I have Poser 11.0.6.33735

I have Windows 10 Home, version 1703, OS Build 15063.483


PhilC ( ) posted Thu, 13 July 2017 at 5:30 AM

What do you get when you run UnimeshDemo.py ? Do you see the spike?


Anthony Appleyard ( ) posted Thu, 13 July 2017 at 6:16 AM

How can I download UnimeshDemo.py ? The Poser Python manual says "Click the GeomMods button and look for UnimeshDemo sample script"; but where is the GeomMods button?


Anthony Appleyard ( ) posted Thu, 13 July 2017 at 6:45 AM · edited Thu, 13 July 2017 at 6:59 AM

I have raised this bug at https://mantis.smithmicro.com/view.php?id=39448

I found UnimeshDemo by directory search; it is in Poser11's Runtime/Python/poserScripts/GeomMods

I just now tried UnimeshDemo on my man in boilersuit, and its statement "scene.CreatePropFromGeom(unigeom, "figureProp") " created a prop called figureProp which is a complete duplicate of his geometry, in the default pose with a rotates = 0, and with all the same materials, but the prop's materials are all textured smooth blue and not as in my character.

One vertex in his left thigh was moved.


Anthony Appleyard ( ) posted Thu, 13 July 2017 at 7:02 AM

One vertex in his left thigh was moved, in the character, but not the corresponding vertex in the prop.


Anthony Appleyard ( ) posted Thu, 13 July 2017 at 7:34 AM · edited Thu, 13 July 2017 at 7:36 AM

In my test model, some of the runs of the script print out the vertex coordinates. Some of those printouts show that the vertex values are being changed; but my Poser is ignoring them and working from another copy of the vertexes somewhere in its system, or when displaying or rendering is working straight from the character's geometry file.


Anthony Appleyard ( ) posted Thu, 13 July 2017 at 7:59 AM · edited Thu, 13 July 2017 at 8:11 AM

I tried UnimeshDemo on the Poser 4 Nude Man, and no vertex was moved either in the man character nor in the prop made from his unimesh geometry.

After that test run, Poser crashed when I tried to delete the Nude Man character, as if the UnimeshDemo had corrupted something in Poser's workings.

I tried UnimeshDemo on the Poser 4 businessman, and a vertex was moved in the man character, but not in the prop made from his unimesh geometry.

After that test run, Poser did not crash when I deleted the character and the prop.

I tried UnimeshDemo on the Poser 4 Nude Man again, and no vertex was moved either in the man character nor in the prop made from his unimesh geometry.

Afterwards, I deleted the character and the prop successfully.


Anthony Appleyard ( ) posted Thu, 13 July 2017 at 8:28 AM

I tested Unicodemesh on my man in boilersuit, as before, and then exported his mesh, and as exported his mesh had the displaced vertex.


Anthony Appleyard ( ) posted Thu, 13 July 2017 at 10:14 AM

I suspect that somewhere between the Unimesh that Python sees and the displayer / renderer / .OBJ file exporter, the geometry is going through an intermediate buffer, perhaps held in binary form to make it quicker for the displayer / renderer / .OBJ file exporter to read it. And that that buffer is not always being updated often enough from the form that Python sees and works on. If so, Poser needs a function or control to make it flush and update these buffers.


ironsoul ( ) posted Thu, 13 July 2017 at 5:21 PM · edited Thu, 13 July 2017 at 5:35 PM

Although marked as 2.7.1 for both pp2014 and pp11 the python interpreters have been compiled under different versions of MSC. If its possible to point p11 at an earlier version of 2.7.1 might be worth a test. I thought there was a way but maybe mistaken.



Anthony Appleyard ( ) posted Thu, 13 July 2017 at 11:49 PM

Thanks for your help.


adp001 ( ) posted Sat, 15 July 2017 at 1:35 AM

As far as I remember one have to inform Poser about the changed geometry via MarkGeomChanged().




Anthony Appleyard ( ) posted Sat, 15 July 2017 at 4:15 AM

I just now tried inserting

for i in range(0,nacts):
    acts[i].MarkGeomChanged()
    print "MarkGeomChanged",acts[i].Name()

after all the vertex changes, and still nothing changes on the screen, even after I render.


Anthony Appleyard ( ) posted Sat, 15 July 2017 at 5:35 AM · edited Sat, 15 July 2017 at 5:36 AM

Success at last!

I ran this new script, on my posable duck model, and the jointed parts flew to the side by varying amounts, as expected. The difference is that this time I worked on the .Geometry() of each actor in turn, not on the Unimesh geometry got via unim=d.UnimeshInfo(); dgeom=unim[0]; acts=unim[1]; vinfo=unim[2] . The bug seems to be in the Unimesh system. Is .MarkGeomChanged() intended to work on Unimesh geometry? When did the Unimesh system start to appear in Poser?

import poser
import string
import os
import sys
import aasubrs

scn = poser.Scene()
acs=scn.Actors()
figs=scn.Figures()
d=scn.Figure("duck")
#d=scn.CurrentFigure()
acts=d.Actors()
print "figures:",
for fig in figs:
    print fig.Name(),",",
print
print"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
i=0
for a in acts:
    i+=1
    if a.IsBodyPart():
        print "working on",a.Name()
        g=a.Geometry()
        if g==None: continue
        vv=g.Vertices()
        nn=0
        for v in vv:
            x=v.X(); y=v.Y(); z=v.Z()
            v.SetX(x+i*.1); nn+=1
        a.MarkGeomChanged() 
        print "worked on",a.Name(),nn,"vertexes"
poser.ProcessCommand(1559)
scn.DrawAll();


adp001 ( ) posted Sat, 15 July 2017 at 6:16 AM

My understanding: UnimeshInfo delivers - info. A copy or something. Not a pointer to the actual geometry. If you want to use the geometry from UnimeshInfo, you have to use Actor.SetGeometry().




Anthony Appleyard ( ) posted Sat, 15 July 2017 at 7:29 AM

Uhh. Thanks. It would be useful if the Poser Python manual said explicitly that UnimeshInfo's output cannot be used to move or create or delete vertexes.


ironsoul ( ) posted Sat, 15 July 2017 at 10:41 AM · edited Sat, 15 July 2017 at 10:47 AM

Anthony Appleyard posted at 4:35PM Sat, 15 July 2017 - #4309888

Uhh. Thanks. It would be useful if the Poser Python manual said explicitly that UnimeshInfo's output cannot be used to move or create or delete vertexes.

We could derive our own classes to add the behaviour Anthony expacted in the initial post. My question is has someone already done this?



Anthony Appleyard ( ) posted Sat, 15 July 2017 at 11:42 AM · edited Sat, 15 July 2017 at 11:54 AM

Someone should write a way to write from Unimesh back into the actors' separate geometries.

My script is moving all vertexes which are in a particular volume-range and also in a particular material. Thus I had to look in the polygons, to find which material each was in, and then list all the vertexes of all those polygons. And from that list, to eliminate duplicates, to avoid handling the same vertex more than once. For each polygon vertex, the script must search through that actor's main list of vertexes, and over a big scene that may add up to a long time. In polygon p, it would be useful to have a function p.VertexLink(i), which returns a number k, where the i'th vertex of polygon p is the k'th vertex in the actor's main list of vertexes.Then I can create an index array q, where I can set q[k] = 0 or 1 according to whether vertex k has already been handled. I have experience in such matters: I have written in Visual C++ a mesh-editing program (which I have used to create many of my models), and in it, each corner of each polygon has merely a link pointing to a place in the main list of vertexes.

Is there a way to tell Poser to re-read all geometries from the files?


Anthony Appleyard ( ) posted Sat, 15 July 2017 at 4:28 PM · edited Sat, 15 July 2017 at 4:29 PM

My test job is duck_at_zero.pz3 . It gets all its geometry from an .obj file. My test script is called quack2.py . I ran duck_at_zero.pz3 and called quack2.py on it, and saved it to duck_at_zero_afterrun_00.pz3. And I found (using a utility called Listitem that I wrote some years ago in Visual C++) that in duck_at_zero_afterrun_00.pz3 , all the actors whose geometry had been changed, now had embedded geometry.


ironsoul ( ) posted Sun, 16 July 2017 at 12:18 PM

Anthony Appleyard posted at 5:51PM Sun, 16 July 2017 - #4309899

Someone should write a way to write from Unimesh back into the actors' separate geometries.

My script is moving all vertexes which are in a particular volume-range and also in a particular material. Thus I had to look in the polygons, to find which material each was in, and then list all the vertexes of all those polygons. And from that list, to eliminate duplicates, to avoid handling the same vertex more than once. For each polygon vertex, the script must search through that actor's main list of vertexes, and over a big scene that may add up to a long time. In polygon p, it would be useful to have a function p.VertexLink(i), which returns a number k, where the i'th vertex of polygon p is the k'th vertex in the actor's main list of vertexes.Then I can create an index array q, where I can set q[k] = 0 or 1 according to whether vertex k has already been handled. I have experience in such matters: I have written in Visual C++ a mesh-editing program (which I have used to create many of my models), and in it, each corner of each polygon has merely a link pointing to a place in the main list of vertexes.

The following code should build an associative array with the unimesh vert index as the key and returns the actor name(s) and relative vertex number(s). It should then be possible to go through each poly and link back to the actor to change the geom. I don't know if that's necessary as cycling through the actors seems to replace rather than add up changes.

import poser
scn = poser.Scene()
d = scn.CurrentFigure()

unim=d.UnimeshInfo(); dgeom=unim[0]; acts=unim[1]; vinfo=unim[2]

vertices=dgeom.Vertices(); nverts=len(vertices)
polys=dgeom.Polygons(); npolys=len(polys);    
vsets=dgeom.Sets(); nvsets=len(vsets);    

uniMap={}
actorIndex=0
for actor in acts:

  gm = actor.Geometry()

  if gm:
      vv = gm.Vertices()
      vIndx = 0
            
      for v in vv:
         uni_index = vinfo[actorIndex][vIndx]
               
         if not (uni_index in  uniMap):
            uniMap[uni_index] =[(actor.Name(),vIndx)]
         else:
            uniMap[uni_index].append((actor.Name(),vIndx))
          
         vIndx+=1
        
  actorIndex+=1
         
            
print "Test Code - use polyset 5000 on V4"
p=polys[5500]
st=p.Start()
print "Debug Group name ",p.Groups()[0]
print "Debug Materal name ",p.MaterialName()

for j in range(st,st+nv):
   k = vsets[j]

   if k in uniMap:
      print "Unimesh Index ",k
      for LocalMap in uniMap[k]:
          print "tActor name ",LocalMap[0]
          print "tLocal Vertex Index", LocalMap[1]

      print "debug name =", uniMap[k][0][0]
      dA = d.Actor(uniMap[k][0][0])
      dV = dA.Geometry().Vertex(uniMap[k][0][1])
      dV.SetX(dV.X()+0.1)
      dA.MarkGeomChanged()



Anthony Appleyard ( ) posted Sun, 16 July 2017 at 4:01 PM · edited Sun, 16 July 2017 at 4:15 PM

Thanks. Currently when I am working with the geometries of the actors:

    vv=geom.Vertices(); nv=len(vv)
.............
    pp=geom.Polygons()
    for p in pp:
        if p.MaterialIndex()!=fe: continue
        pvv=p.Vertices()
        npvv=len(pvv)
        for i in range(0,npvv):
            v=pvv[i]; k=-1; # Find which main-list vertex is this polygon vertex.
            for j in range(0,nv):
                if v==vv[j]: k=j; break;  # 555
            if k<0: print "polygon vertex is not in actor vertexes"; continue
            if vc[astart[g]+k]==0: continue # vertex not in range
            if vc[astart[g]+k]>1: continue # vertex already attended to
            x=v.X(); y=v.Y(); z=v.Z(); v.SetY(y-.01); vc[astart[g]+k]=2 # move the vertex & log it as moved
    a.MarkGeomChanged()

This works, but the search at the line with comment "555" is likely to take a long time in a big model, when repeated with every vertex in every polygon in the material "fe" . To make it a bit quicker, I tried this:

            for j in range(0,nv):
                if pvv[i] is vv[j]: k=j; break;  # 555

but it did not work. Poser must know somehow which polygon vertex is which vertex in the actor's main list of vertexes, but how can I quickly access that information?

When I wrote a mesh-editing program in Visual C++, in it a polygon vertex is merely a pointer to a member of the main list of vertexes.


Privacy Notice

This site uses cookies to deliver the best experience. Our own cookies make user accounts and other features possible. Third-party cookies are used to display relevant ads and to analyze how Renderosity is used. By using our site, you acknowledge that you have read and understood our Terms of Service, including our Cookie Policy and our Privacy Policy.