Useful Python Script



  • @anomalaus Oh, I'm blind... Overlooked the link.



  • @anomalaus Sorry, can't load anything from mega.nz with any of my browsers on no machine I have. This is what I get:
    0_1531062175656_Bildschirmfoto vom 2018-07-08 17-01-04.png



  • @adp Oh, that's frustrating. I've not seen that before. Do you have an ad blocker or something that's preventing javascript?

    I see this when I click the link (though I have a mega account so that may be relevant):
    0_1531063007359_Screen Shot 2018-07-09 at 1.15.04 am.png

    OK, try this Make2Manifold.py first time I've uploaded anything to ShareCG!



  • @anomalaus I disabled adblockers in firefox and chromium, tried with a very simple webbrowser (without any extensions), and tried with tablets/smartphones.
    But: I'm behind a firewall that blocks .ru and .cn IPs and rejects calls to/from IPs listed as malicious.
    I can ping mega.nz and get the first part from their index-page. But it seems they do load something from somewhere my firewall calls "malicious".

    Anyway, thanks for uploading to ShareCG. Now I'm off for a moment or two, looking at your script...



  • I think I'll go with a binary searched list to get a pseudo-sorted vertexlist.
    In a test I was able to compute and write an OBJ file with a vertexlist (no tex-vertices jet) and new constructed polygon-indices from Roxie (~30000 vertices) within rund about 2 seconds (but the polygons are not correctly constructed yet :)).

    Tested with an older laptop (SSD, 8 gig Memory, I5 processor), Poser Python, empty scene, just plain Roxie loaded.
    With a "busy" Poser scene and more vertices it may last a bit longer because of memory swapping. I'll test that later. First I have to look why I get a polygonset that looks like a pot full of spaghetti. :)



  • @adp assuming you don't have an out-by-one error in your vertex indexing (that happened to me all the time, in development, because the memory array indices are zero based, but the vertex references in the obj file are one based), make sure you haven't re-ordered any of the vertex references in the facets, because that could randomise the normals (reverse vertex order flips the normal, determined by curled Right Hand fingers match the vertex winding and RH thumb gives the normal direction).



  • @anomalaus No, it wasn't this well know "out-by-one" thing :)
    I simply didn't change the polygon-sets right. Now, if I export Roxie, I get:

    Export to: F:\Python\Morphs+Mags\OBJ-TRANSFER\Roxie.obj
    Time used to export: 1.927 seconds.
    Done.

    Aaaaand: I can load it perfectly well into my modeler. Without groups, without duplicate vertices!
    :) :) :) :) :) :) :) :) (and a lot more of this...)

    Ok, still no tex-vertices written, but for morphs this is not required.

    Next step is to import the changed model and create a FBM. But only for the actors with moved vertices.



  • @anomalaus said in Useful Python Script:

    @adp make sure you haven't re-ordered any of the vertex references in the facets, because that could randomise the normals (reverse vertex order flips the normal, determined by curled Right Hand fingers match the vertex winding and RH thumb gives the normal direction).

    I construct and write a complete different mesh. I have to, because I have to remove the doubled vertices on groups-boundaries. And I have to create a new set of polygons.

    I do not write normals, because my modeller constructs normals automatically. As far as I know, Poser ignores normales in an OBJ file.



  • @adp it is correct that Poser ignores the OBJ file, vn x y z normal lines, as it creates the normals based on the implicit winding of the facets (which could, theoretically contradict vertex normals), so in effect, poser uses facet normals, rather than vertex normals.

    The other thing to note is that poser IS perfectly capable of creating (and subsequently exporting without corruption) an internal geometry mesh from python scripts (without recourse to writing and reading obj files manually in python), as long as you don't use groups at all (the Python API does not yet support mesh group creation).

    Have you compared the vertex order you generate with that of the original obj file for the figure? Are you able to reconstruct that order so that external morphs you create can load on the original obj version of the figure?



  • @anomalaus Goal is, to remove double vertices and get a watertight mesh. No groups. So the new vertexorder is different and will be reconstructed on input.

    I mark Poly-groups with "o" or "usemtl". What to use depends on what the other app does with "o". By default C4D splits a mesh if an "o" is seen (adding vertices!). Others may not. Using materialzones for the posergroups makes it easier to morph in certain situations.

    This is useful only for creating morphs if ZBrush is not an option.



  • @adp I understand, but the original figure's obj file is presumably without any duplicated vertices. If you load that in with an OBJ reading python script and just ignore the group definition lines, while creating the mesh you've just read, you'll get a mesh whose vertices match the original order. If that process parallels parsing (and eliminating duplicated vertices) the already loaded figure, you could directly map vertex indices and acquire all of the figure's morphs onto the new, ungrouped geometry you've created.

    That was the secondary premise of the Make2Manifold script (apart from creating a second shell to enclose a volume) and would work on a figure too.



  • But the original file is not what I'm after.

    What I try to do is all about morphing.
    I want to be able to fix a posed and morphed figure. Or cloth on a figure. Importing both into the modeller, fix an issue and move it back to Poser.



  • @adp so your workflow is just for your own use and will never be distributed? I've been focused on mechanisms that can validly produce distributable morphs for third party figures. Once a scheme departs from the original geometry, no one else can make use of it. Am I wrong in thinking that once you've exported, modified, re-imported and applied externally created morphs to a figure with modified geometry in Poser, you can't make use of those morphs on another instance of the original figure. [Apologies if I'm slow to catch on. Chronic sleep debt is my life, sigh X-/ ]

    As a side note, while I was investigating a DSON bypass for Poser, by reading Genesis figure .duf & .dsf files directly, I noticed that DSON was making extensive use of CustomData in the Poser files it was creating. Following this, I came to the logical conclusion that that was the most appropriate mechanism for storing a per-actor vertex index translation table, to convert morph delta indices to (original, ungrouped, unduplicated) figure geometry vertex indices.

    When [hopelessly optimistic] Poser finally goes fully unimesh internally, these dramas will all seem like a particularly disturbing cheese dream, no doubt. ;-)



  • @adp since ShareCG rejected my original post due to reasons, I've re-uploaded it with an image attached to meet their current posting policy. Here's the link for anyone that comes across this thread and finds a dead link. Make2Manifold zip archive with instructions



  • @adp ColorCurvature's Pose Morph Loader has done this for years. It's an excellent piece of python programming that I used extensively.

    While it isn't available at a brokerage now, I have had several folks I'm helping contact him and he sold them the package privately.

    There's an email address on his page here.
    http://cgscripts.colorcurvature.com/



  • @Glitterati3D
    I want to have an open source script. Usable by anyone, hopefully to extend it further. Or use it for things I didn't think of.



  • @adp Ah, well, OK then. More power to you.



  • @adp I'm replying to this old thread as it's still relevant to the question I need to ask, and, more importantly, you mention in your original post that you were working on weightmaps and morphs while developing your script.

    It's come to my attention, having written my Make2Manifold script specifically to treat hair props, that there are a significant number of conforming hair figures out there that only have mesh vertices assigned to their neck actor group, and might therefore be amenable to the same treatment. Make2Manifold certainly works on figure actors, duplicating vertices (with the option of not cloning edge verts) and cloning the morph deltas for the new vertices. But I does absolutely nothing with the weight maps, at the moment. On my first perusal of the actor.JointVertexWeights() method, it's described as taking a single string parameter of 'x', 'y' or 'z' to define the axis whose weight map is to be returned. I can't see how this can return bulge maps. Any clues?

    I'm also mystified as to how to set new vertex weights. The actor.SetZoneVertexWeights() method specifies that it applies to magnet zones, not ordinary actors' joint weight mapping. I fail to see what the point of getting a list of vertex weights is if you can't modify them.



  • @anomalaus said in Useful Python Script:

    I'm also mystified as to how to set new vertex weights. The actor.SetZoneVertexWeights() method specifies that it applies to magnet zones, not ordinary actors' joint weight mapping. I fail to see what the point of getting a list of vertex weights is if you can't modify them.

    The only way I've found so far is to create a partial pose file with weightmap data as the only content. This method is amazingly fast if you want to provide an entire figure with weightmaps.

    For about a month (and probably the next few weeks) I'm not working on Poser / 3D because I have some interesting IOT stuff to do here (based on Arduino / ATTiny, RasPi-Zero and ESP8266 / ESP32).



  • @adp thanks, that's the streamlined way to do it in-scene, rather that write a whole figure out and re-load it. Though I'm still to figure out how to read back bulge weight maps (other than parse the library .CR2 file) I did determine that JointVertexWeights() and TwistVertexWeights() are the way to get the rest of the weight map data. I can't just copy it from another figure, since I've created a prop (to be merged back into a figure external to Poser) with cloned vertices that need weight mappings to be cloned.

    On second thought, once I've merged the newly manifold actor and it's morphs back into a new version of the original figure, I suppose there's no reason I can't repeat the process of copying the joint parameters from the weight mapped conforming parent, which is how the hair figure got weight mapped in the first place, copying joints from a weight mapped V4. Okay, that should sort that problem. Just a pity it's still not possible to have a Python script modify weight maps. (or even interrogate the bulge weight maps for actors within the scene).