Wed, Oct 2, 9:39 PM CDT

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: Script that fixes vertex order - testers welcome


odf ( ) posted Mon, 06 December 2021 at 9:33 PM · edited Tue, 10 September 2024 at 8:41 PM

Okay, it seems I've got some working code for fixing vertex orders in morph targets. Typical example: I export a character's head from Poser, spend a few hours reshaping it in Blender, and then realize I haven't checked "keep vertex order" when importing. Now with my script, I can still apply the morph by reconstructing the correct order, even if the mesh shape has changed drastically so that simple distance-based methods don't work.

If anyone is keen on trying it out, the code can be found at https://github.com/odf/pydeltamesh. Look for tags v0.9.0 and v0.9.0_py27 for the Python-3-only version (with type annotations) and the backported one that works in both Python 2 and Python 3, respectively. If you're unfamiliar with git or the github interface, let me know and I'll post some instructions.

There's a stand-alone script "applyMorph" that takes two OBJ files and produces a new OBJ file as output, and there's the core "match" module that can be used by other scripts, for example a fancy Python-based Poser morph loader. I haven't tested it with Poser yet (and probably won't any time soon), so if there are any problems, let me know. SciPy is used at one point, which I think may not be available in Poser versions before 12? If that's a problem, let me know and I'll come up with a workaround. Other than that, only Numpy is required. For a usage example, just check applyMorph.py.

At the moment the mesh must be a manifold. Adding support for non-manifold meshes (e.g. certain kinds of garment) will be my next mission.

-- I'm not mad at you, just Westphalian.


FVerbaas ( ) posted Tue, 07 December 2021 at 4:02 AM
Forum Coordinator

Thanks I will try this later this week.  

Indeed SciPy is in Poser12 only.


FVerbaas ( ) posted Tue, 07 December 2021 at 4:23 PM · edited Tue, 07 December 2021 at 4:24 PM
Forum Coordinator

Just found out myfavorite vertex order mangler (Marvelous Designer loading an existing .obj as a garment) has bettered its ways and now returns objects with verts in the order it received them.  May take a tad longer and a little more pushing before I can try the script.


odf ( ) posted Tue, 07 December 2021 at 5:10 PM · edited Tue, 07 December 2021 at 5:12 PM

FVerbaas posted at 4:23 PM Tue, 7 December 2021 - #4431434

Just found out myfavorite vertex order mangler (Marvelous Designer loading an existing .obj as a garment) has bettered its ways and now returns objects with verts in the order it received them.  May take a tad longer and a little more pushing before I can try the script.

That sounds so familiar. 😄

By the way, I forgot to mention that the script does not only fix mangled vertex orders, but can also deal with missing or extra connected components (or loose parts in Blender parlance). Imagine the following scenario:

I export Antonia's head and eyes separately from Poser, then import both into Blender and make the eyes un-selectable so that I can see them while morphing the face but not accidentally deform them. The extra eyebrow geometry bothers me so I delete it. Oops, should have hidden it instead, but now I've already started morphing. Also, I forget to check "selected only" when I export.

Now I have an output mesh with the brows missing but the eyes added to the head. When I try to load that as a morph target, Poser is so confused it can't even. But my applyMorph script happily transfers vertex positions between the matching parts and ignores the rest.

-- I'm not mad at you, just Westphalian.


odf ( ) posted Wed, 08 December 2021 at 1:03 AM

I think I've now figured out how to properly implement the part that I had left to SciPy. Interestingly, it kind of looks as if the algorithm is in the high school curriculum here in Australia, because I found dozens of YouTube videos that explain all the easy steps in great detail but don't say a word about how to actually do the one interesting step in practice*. 😄

* From reading the original papers and fast-forwarding to modern terminology, it turns out to be the max-flow min-cut principle applied to maximal bipartite matchings, which I guess may not be in the high school curriculum.

-- I'm not mad at you, just Westphalian.


FVerbaas ( ) posted Wed, 08 December 2021 at 4:09 AM
Forum Coordinator
odf posted at 1:03 AM Wed, 8 December 2021 - #4431448

....Interestingly, it kind of looks as if the algorithm is in the high school curriculum here in Australia, because I found dozens of YouTube videos that explain all the easy steps in great detail but don't say a word about how to actually do the one interesting step in practice*. :smile:

So familiar. They probably copied and had no idea where the crux was. Same here.


FVerbaas ( ) posted Wed, 08 December 2021 at 4:26 AM
Forum Coordinator

odf posted at 5:10 PM Tue, 7 December 2021 - #4431436


That sounds so familiar. :smile:

By the way, I forgot to mention that the script does not only fix mangled vertex orders, but can also deal with missing or extra connected components (or loose parts in Blender parlance). ....


This begins to get very interesting. 

I think I will make a small  test rig that can swap vertex numbers in  a mesh. Let's say let original vertex numbers 3 and 8 change place. That is a simple process that can be applied a number of times with different vertex numbers. Such would yield a consistent mangled result with controlled degree of difference from the original. From there, jitter along the normal can provide a morph  target and of course additions and deletions can be applied.

 


odf ( ) posted Thu, 09 December 2021 at 2:21 AM

Little heads-up: I've now written some replacement code for the one SciPy function I'm using in the script, which honestly was a lot of fun (yes, I like algorithms, sue me 😄). If you're curious, google "assignment problem."

It's only really needed for fairly extreme cases, like when you have a creature with lots of teeth that all have the same topology, then do a radical change in the head shape and need to come up with a reasonable guess of which tooth went where.

I've written some randomized tests for it, so I am quite confident that it works correctly. If all goes well, I'll make the change to the main script tomorrow and add new version tags v0.9.1 and v0.9.1_py27. Version v0.9.1_py27 should theoretically work with all Poser version from whenever the switch from Numeric to numpy was made.

-- I'm not mad at you, just Westphalian.


odf ( ) posted Thu, 09 December 2021 at 6:47 PM · edited Thu, 09 December 2021 at 6:50 PM

Here's a quick test and demo of what the tie breaking does. I made five copies of a (slightly beveled) cube in Blender, then moved the leftmost copy all the way to the right and also rotated all the cubes around. The image on the top left shows the initial state, the one on the bottom right the final state.

The top right shows what happens if I load the original export from Blender as a morph target and dial it to 0.5. The bottom left shows the corrected morph target, also at 0.5. The strategy here is to minimize the sum of squared distances travelled by the individual vertices.

JXpkvGsWhx7Q96nWR1ogviUI3JYO5wzWhA9RITbI.jpg

-- I'm not mad at you, just Westphalian.


odf ( ) posted Thu, 09 December 2021 at 7:48 PM

PS: The new SciPy-free versions 0.9.1 and 0.9.1_py27 are now tagged on github.

-- I'm not mad at you, just Westphalian.


odf ( ) posted Fri, 10 December 2021 at 4:12 PM · edited Fri, 10 December 2021 at 4:15 PM

I think I'll try putting the type annotations into comments next, so I can have just one version that works with both Python 2 and Python 3, but still can run mypy on it to check the types.

Also, I'm thinking about putting all the code into one big file. Not my preference, but that way it's easier for folks who just want to use it as a script from outside Poser. That would mean though that when it's used from inside Poser, there's a bit of extra code (270 lines, at the moment) that's being loaded in but never used.

In the JavaScript world, I'd keep the files separate for development and run a precompile thingie that bunches them all together into one for deployment, but I'm not sure such a beast exists for Python.

Thoughts?

-- I'm not mad at you, just Westphalian.


odf ( ) posted Fri, 10 December 2021 at 7:13 PM

Woah, mind blown! I googled a bit and it turns out python can execute a regular zip file if it contains a __main__.py on the top level.

So, no point in smashing all the code into one source file! Just zip it up instead. 😄

-- I'm not mad at you, just Westphalian.


odf ( ) posted Sun, 12 December 2021 at 1:00 AM

@FVerbaas: It seems I've got the non-manifold version working, as well. Do you happen to have any clothes - or could point me to any free ones - that I could test this on?

-- I'm not mad at you, just Westphalian.


odf ( ) posted Mon, 13 December 2021 at 6:26 PM · edited Mon, 13 December 2021 at 6:30 PM

*taps micro* Is this thing on? 😄

I've found some old conforming clothes and props that have non-manifold parts according to my script, but in the ones I checked so far I haven't been able to find the offending edges easily. Not great for testing if they are so hidden. I've also discovered another problem with clothes, which is that there can be parts with ridiculous numbers of topological symmetries. This can easily happen if one uses deformed tubes, UV spheres or, worst of all, tori for parts of garments. I have to take a closer look to identify the offending parts and see if I can think of any solution. The script still works in those cases, but it takes ages.

Anyway, I also remembered that Apollo's eyes aren't manifolds, which should make them a great test/demo case. They're also, as it turns out, completely asymmetric, which was confusing because at first I thought my script not reporting any symmetries was due to a bug. Anyway, here's a morph for Apollo's left eye done in Blender, again without checking any of the "keep vertex order" boxes. Unmorphed eye at the top, raw Blender export fed into Poser in the middle, fixed at the bottom.

vJYjus67iCUH9EfuV98oH8tmP66sAhr9OGfOEvki.png

I think I'll probably have to mull over the algorithm a bit more and try to build meshes that break it, because I'm not a hundred percent convinced yet that it can really handle any non-manifold meshes I throw at it. Anyway, the new code is in the "non-manifold" branch of the Github repo if you'd like to give it a whirl.

-- I'm not mad at you, just Westphalian.


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.