DIY compound figures and the beginning of instancing...?



  • So I've been doing a lot of repetitive stuff lately, especially since I've been developing my comic figure a lot alongside PE.mesh5. I've been:

    • Replacing characters with the newly updated figure several times.
    • Making new scenes with the usual suspects (usual gang of comic characters)

    Now all this takes a long time, especially that last one. For example in a recent scene I did I had to load up six characters of the Erogirl figure, which each take about 20 seconds to half a minute to load, depending on how crazy the scene is. These are all the same base figure, so now for each of these characters I need to dial in their respective characters. That takes about a minute or two (scrolling, selection) and longer if its a busy scene. Then I need to look up their materials, load then up for each. Also about half a minute each (locating, loading). Then their hair, also about half a minute each. Then clothing... and I haven't even started with posing. Altogether I can sometimes be busy for 15 to 20 minutes just loading characters into a scene, not including crashes. 20 minutes might not seem like a lot, but when you have a load of other things to do, 20 minutes can be painful, especially if its not needed!

    Now there is such a thing as compound figures, but they're not cool for a few reasons:

    • unnecessary HD bloat (the PMDs get combined into a new one)
    • You're dependent on the version of the CR2 that you saved into the compound figure
    • for some reason it hasn't worked properly for me since I made mesh4.5 (morph mashing)?
    • And the materials might be outdated so you'll have to reload them anyway.

    I found a better solution. A CR2 per girl that accesses a python script that:

    • finds and loads the latest version of the figure
    • loads the pose that dials in the character that is specified
    • Loads her materials
    • loads her hair and if needed its materials
    • Renames her in the scene with the relevant name (as well as her hair)
    • Ends with a message "Such and such is loaded.".

    Man it works like a charm. I have loading 6 figures down to two minutes, all complete with mats, poses and hair. I also have wet versions of those characters, incl wet hair (when they go swimming). All I need to do is keep the references updated, and it will work nicely all the time.

    I also used PFE to filter out all the dials needed to make pose files to dial in the relevant girl (and all the others to zero). I could have also done that through python actually, but this works for now. The pose files are nice to have anyway. (I have to say, pose files made by poser are so full of useless information, we need a better way to control that somehow.)

    I'm going to now extend this to groups that I often have in one scene (including translations not to have them piled on top of each other); characters with a usual combination of clothing. This way I can avoid long loading times, avoid scrolling and searching, all my figures will be up to date, and avoid huge PMD files in my library.

    The code is something like this:

    scene = poser.Scene()	
    
    scene.LoadLibraryFigure(":Runtime:libraries:Character:Erogirl:Figures:Mesh4-5:NEW 
    MESH:!ErogirlMesh4_5Ap_89.crz")
    
    newFigure = scene.CurrentFigure()
    newFigure.Restore()
    
    scene.DrawAll()
    

    And then per girl:

    scene = poser.Scene()	
    girl = scene.CurrentFigure()
    girl.SetName("ANNABELLA")
    scene.LoadLibraryPose(":Runtime:libraries:Pose:Erogirl:Poses:Mesh45:Characters:Annabella.p2z")
    
    bodyactor = girl.Actor("Body")
    
    bodyactor.LoadMaterialCollection(":Runtime:libraries:Materials:Erogirl:Annabella:Annabella 3.mcz")
    
    scene.LoadLibraryFigure(":Runtime:libraries:Character:Erogirl:Hair:Upgraded hair:AmarsedaHair pem45a.crz")
    
    figureHair = scene.CurrentFigure()
    figureHair.SetName("ANNABELLA HAIR")
    figureHair.SetConformTarget(girl)
    
    poser.DialogSimple.MessageBox("Annabella loaded")
    
    scene.DrawAll()
    

    I would love to have a script that parses CR2 and python files for me, where I could just specify which figure needs loading, which material and which hair, what needs renaming and what extra clothing needs to be added.


    Replacing the CR2 code, in situ?

    But now the the first issue, replacing a figure is a tedious task. Just replacing it with Poser's replace function will sometimes result in missing keyframes, or doubled values. I need to copy all the keyframes as a backup, and if its a 400 page comic the copy action sometimes takes 5 minutes! I need to lock all conforming items because once I conform them to the new figure, they get re-scaled and re-interpreted, etc. Its a pain in the butt basically.

    Now I am wondering, because I've got this picture that the entire CR2 of the character is just loaded onto the stack in Poser (correct me if I am wrong, I might be showing off my staggering ignorance here), is there a way to just flat out replace/swap the actual CR2 code and PMD reference of the figure in the actual scene? This would save me having to reload the damn figure all the time.



  • I suppose I could just try swap out the CR2 in the actual pz3 scene file?



  • Hello
    Yes the figures can be swapped - how to do it with python I don't have a clue and like many just get shouted down on this forum. The Poser 11 library has the swap figure check mark which allows the figure, clothing and props to be swapped or not depending on which items you select - i don't know if this is visible to python as many options aren't.
    I know it is possible for items to be swapped using python as snarlygribbly created a script called propswap many moons ago which would swap a prop multiple times in the same co-ordinates, which could be turned on and off using a check box. This however does not function correctly with Poser 11 and disables (breaks) the add and replace figure check marks. The script is encrypted though so you would need to contact him to ask how he did it.



  • @erogenesis working on it. Redacted (for length) .cr2 file for loading a fully clothed and conformed character from a single library selection.

    {

    version
    {
    number 11
    build 33735
    }
    readScript ":Runtime:libraries:Character: GeoffIX: ReadScript:Lily Half_Objcts.cr2"
    readScript ":Runtime:libraries:!DAZ:GeoffIX:V4-Cameras_1_Objcts.pz2"
    readScript ":Runtime:libraries:Props: GeoffIX:Prop Hair:Hair Accessories_Objcts.pp2"
    readScript ":Runtime:libraries:Props: GeoffIX:Prop Clothing:Body Accessories_Objcts.pp2"
    readScript ":Runtime:libraries:Props: GeoffIX:Prop Clothing:Ladybug Clothing Accessories_Objcts.pp2"
    readScript ":Runtime:libraries:Character: GeoffIX:Conformed Hair:Persephone LPart Hair_Objcts.cr2"
    readScript ":Runtime:libraries:Character: GeoffIX:Conformed Clothing:Second Skin_Objcts.cr2"
    readScript ":Runtime:libraries:Props: GeoffIX:Prop Clothing:Body Accessories Ashi 3_Objcts.pp2"
    readScript ":Runtime:libraries:Props: GeoffIX:Prop Hair:Hair Accessories 3_Objcts.pp2"
    readScript ":Runtime:libraries:Character: GeoffIX:Conformed Hair:Wet Hair_Objcts.cr2"
    readScript ":Runtime:libraries:Character: GeoffIX:Conformed Clothing:V4Skeleton_Objcts.cr2"
    readScript ":Runtime:libraries:Props: GeoffIX:Prop Hair:Brain_V4_Objcts.pp2"
    readScript ":Runtime:libraries:Character: GeoffIX:Conformed Hair:Christine Hair 6_Objcts.cr2"
    ... more clothing figure object definitions
    readScript ":Runtime:libraries:character: GeoffIX:Conformed Clothing:V4 Mask_Objcts.cr2"
    readScript ":Runtime:libraries:character: GeoffIX:Conformed Clothing:V4YShirt_Objcts.cr2"
    readScript ":Runtime:libraries:character: GeoffIX:Conformed Clothing:V4 Business Tie_Objcts.cr2"
    readScript ":Runtime:libraries:Character: GeoffIX: ReadScript:Lily Half_Actrs.cr2"
    readScript ":Runtime:libraries:!DAZ:GeoffIX:V4-Cameras_1_Actrs.pz2"
    readScript ":Runtime:libraries:Props: GeoffIX:Prop Hair:Hair Accessories Blue Black_Actrs.pp2"
    readScript ":Runtime:libraries:Props: GeoffIX:Prop Clothing:Body Accessories_Actrs.pp2"
    readScript ":Runtime:libraries:Props: GeoffIX:Prop Clothing:Ladybug Clothing Accessories_Actrs.pp2"
    readScript ":Runtime:libraries:Character: GeoffIX: ReadScript:Marinette Dupain-Cheng Figure.cr2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Body Styles:Marinette.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Body Attributes:Unhide Tongue, Drool & Saliva.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Body Attributes:Unhide Tail.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Body Attributes:Show Tongue.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Body Attributes:Hide Drool & Saliva.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Body Attributes: Human.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Arms:Weight Mapped:Arms Attention Susann MF.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style: Selection:Alice & RJScalp.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Alice:Fringe Forehead Lower.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style: Selection:Christine & UpDo 2 + Fringe.pz2"
    ... more default hair style selection poses
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Selection:Marinette Ladybug (FWSel).pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Pleats:Pleats Close Fit Susann.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Footwear Fits:V4Booties Susann Attn WM FWP NG.pz2"
    readScript ":Runtime:libraries:Face:Hermione: Eyes Portrait.fc2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Arms:Orbit:Attention:Arms Relaxed.pz2"
    readScript ":Runtime:libraries:Character: GeoffIX: ReadScript:BodyCamera Lily Half Barefoot Off.cm2"
    readScript ":Runtime:libraries:Character: GeoffIX:Conformed Hair:Persephone LPart Hair Blue Black Figure.cr2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Persephone:Volume 2:Long Spread Front.pz2"
    readScript ":Runtime:libraries:Character: GeoffIX:Conformed Clothing:Second Skin Wet Droplets Level Dublin EBOU Sparse Ashi Figure.cr2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Second Skin:Skintight Droplets Wet.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Second Skin:Egg Head:Ashi, Daughter of Aku.pz2"
    readScript ":Runtime:libraries:Character: GeoffIX:Conformed Hair:Wet Hair Blue-Black Figure.cr2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Wet:Fit Selena.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Wet:Long 65%:Long Behind Shoulders.pz2"
    readScript ":Runtime:libraries:Character: GeoffIX:Conformed Clothing:V4Skeleton Brain Figure.cr2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Anatomy:V4 Skeleton: Increase Clavicle Back Limits.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Anatomy:V4 Skeleton: Increase Toe Bend Limits.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Anatomy:V4 Skeleton:Susann Default.pz2"
    readScript ":Runtime:libraries:Character: GeoffIX:Conformed Hair:Christine Hair 6 Blue Black Figure.cr2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Christine:6 Fit Hermione.pz2"
    ... more figure actor definitions and figure blocks
    readScript ":Runtime:libraries:character: GeoffIX:Conformed Clothing:V4 Mask Ladybug Figure.cr2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:V4Mask:Miraculous Ladybug.pz2"
    readScript ":Runtime:libraries:character: GeoffIX:Conformed Clothing:V4YShirt Ladybug Figure.cr2"
    readScript ":Runtime:libraries:character: GeoffIX:Conformed Clothing:V4 Business Tie Ladybug Figure.cr2"
    setGeomHandlerOffset 0 0.3487 0
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNewBaseFigure.py"
    runPythonScript ":Runtime:Python:poserScripts:ScriptsMenu:MyScripts:V4 Scripts:EnableGravity.py"
    runPythonScript ":Runtime:Python:poserScripts:ScriptsMenu:MyScripts:V4 Scripts:ReconformTails.py"
    runPythonScript ":Runtime:Python:poserScripts:ScriptsMenu:MyScripts:V4 Scripts:MagnifyScatterScale.py"
    readScript ":Runtime:libraries:Camera: AnimSets:+Ladybug All Clothing AnimSets.cm2"
    }



  • Here's a multi-figure pose file, also loadable from the library, which, when applied to the base figure, poses all of the conforming hair and clothing figures with poses matching the base figure. Requires a couple of strategic python scripts to manage figure selection in the scene as the individual clothing/hair poses are applied.

    {

    version
    {
    number 11
    build 33735
    }

    {
    // Figure poses interspersed with scripts.
    // Note: cannot place any comments at end of runPythonScript lines
    // Note: Poser has problems if files readScript any file with the same os.path.basename in another directory
    }
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SaveCurrentFigure.py" 
    // 'Marinette'(1)
    readScript ":Runtime:libraries:Pose: GeoffIX:Selena Gomez:Crouch & Squat:Ladybug Side Squat Left.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:TPreea:Side Squat Left.pz2"
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Pleats:Side Squat Left.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Pershair'(2)
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Persephone:Volume 2 Left Part:Long Spread Front.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Second Skin'(3)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Second Skin:Skintight Droplets Wet.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Wet Hair V4'(4)
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Wet:Long 65%:Long Behind Shoulders.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4 Skeleton'(5)
    readScript ":Runtime:libraries:Pose: GeoffIX:Anatomy:V4 Skeleton:Ladybug Side Squat Left.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Christine Hair'(6)
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Christine:6 Fit Hermione.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Twin Tails'(7)
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'BH-V4'(8)
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Boy:Widow's Peak.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Wet Hair SS'(9)
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4 4inc heel'(10)
    readScript ":Runtime:libraries:Pose: GeoffIX:Footwear Fits:RedSandals:RedSandals FitMegan Attention.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // '1fullfringe'(11)
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Cytherea:Fringe Height 0,10.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Brassiere'(12)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Hongyu:Marietta Bra Under One Pc Dress.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Pantie'(13)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Hongyu:Marietta Pantie Fit Susann.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'EZCasual'(14)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:EZCasual:Ladybug Side Squat Left.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4JeanZ'(15)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:V4JeanZ: Default.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Flexible Tail'(16)
    readScript ":Runtime:libraries:Pose: GeoffIX:Flexible Tail:Belle Default.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4 Cloak'(17)
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'B25BikiniPantiesUm'(18)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Bobbie25:B25 Bikini Panties:Ladybug Side Squat Left.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'B25BikiniTopUm'(19)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Bobbie25:B25 Bikini Top:New Fitting 2016:Ladybug New Fit Susann.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4Bodysuit'(20)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:V4Bodysuit:Ladybug Side Squat Left.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4TankTop'(21)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Little_Dragon:TankTop V4:TankTop Fit Elissa.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4TubeTop'(22)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Little_Dragon:TubeTop V4: Default (22).pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4SuperGloves'(23)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:V4Gloves:Ladybug Short Wrists Flush (23).pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Flexible Tongue'(24)
    readScript ":Runtime:libraries:Pose: GeoffIX:Flexible Tongue:Tongue Default.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Second Flexible Tail'(25)
    readScript ":Runtime:libraries:Pose: GeoffIX:Flexible Tail:Belle Droplets Default.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Drool 1'(26)
    readScript ":Runtime:libraries:Pose: GeoffIX:Drool: Default (26).pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4_Breasts'(27)
    readScript ":Runtime:libraries:Pose: GeoffIX:Anatomy:V4 Breast:Ladybug Side Squat Left.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4_Gut'(28)
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4_Thorax'(29)
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Second Flexible Tongue'(30)
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4Bootie'(31)
    readScript ":Runtime:libraries:Pose: GeoffIX:Footwear Fits:V4Booties:Ladybug Side Squat Left.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Dress'(32)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:BAT:One Piece Dress: Default (32).pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Kintaro Apron'(33)
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Bossy Boots'(34)
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'AmarsedaHair'(35)
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Amarseda:Behind Shoulders Loose.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Swimsuit'(36)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:V4Swimsuit:Fit Hermione.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4HoodedCloak'(37)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Hooded Cloak:Raven Cloak Open Hood Back.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'MariaHair V4'(38)
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Maria:V4:Behind Shoulders:Behind Shoulders 72.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'TDB Shoes'(39)
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'GwenithV4'(40)
    readScript ":Runtime:libraries:Pose: GeoffIX:Hair Style:Gwenith:Fit Hermione (40).pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4Cowl'(41)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Morphing Cowl:Miraculous Ladybug.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4BikerBoots'(42)
    readScript ":Runtime:libraries:Pose: GeoffIX:Footwear Fits:V4BikerBoots:V4BikerBoots Fit V4BodySuit (42).pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Down Jacket'(43)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Down Jacket: Default Closed.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'Caudal Vertebrae'(44)
    readScript ":Runtime:libraries:Pose: GeoffIX:Anatomy:Caudal Vertebrae: Default (44).pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4Mask'(45)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:V4Mask:Miraculous Ladybug (45).pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'YShirt'(46)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:V4YShirt:Ladybug Side Squat Left.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNextFigure.py"
    // 'V4 Business Tie'(47)
    readScript ":Runtime:libraries:Pose: GeoffIX:Clothing Fits:Business Tie:Side Squat Left.pz2"
    runPythonScript ":Runtime:libraries:character: GeoffIX: ReadScript:SelectNewBaseFigure.py"
    readScript ":Runtime:libraries:Camera:Hermione:Face:Side Squat Left 51mm f188.cm2"
    readScript ":Runtime:libraries:Camera:Hermione:Dolly1:Ladybug Side Squat 51mm f29.cm2"
    

    }



  • I have a mostly complete CR2 parser script which can load a directory full of poses or characters and even handles (at least reports problems without crashing or hanging Poser) unbalanced braces and recursive readScript references.

    There are some significant limitations though, due to missing functionality in the Python API. I haven't taught it to handle custom geometry, or directly read .obj files yet, because there's no point if I can't assign vertices to a material group from within python.



  • @adi said in DIY compound figures and the beginning of instancing...?:

    Hello
    Yes the figures can be swapped - how to do it with python I don't have a clue and like many just get shouted down on this forum. The Poser 11 library has the swap figure check mark which allows the figure, clothing and props to be swapped or not depending on which items you select - i don't know if this is visible to python as many options aren't.
    I know it is possible for items to be swapped using python as snarlygribbly created a script called propswap many moons ago which would swap a prop multiple times in the same co-ordinates, which could be turned on and off using a check box. This however does not function correctly with Poser 11 and disables (breaks) the add and replace figure check marks. The script is encrypted though so you would need to contact him to ask how he did it.

    Yeah I'll hook up with snarls and see what he has to tune me about it. I think if I can just find a way to swap out the CR2 in the actual PZ3 using PFE, then I'll be happy enough. I've seen all that really needs transferring is the keys info and the conforming info... I think...

    @anomalaus said in DIY compound figures and the beginning of instancing...?:

    Here's a multi-figure pose file, also loadable from the library, which, when applied to the base figure, poses all of the conforming hair and clothing figures with poses matching the base figure. Requires a couple of strategic python scripts to manage figure selection in the scene as the individual clothing/hair poses are applied.

    {

    version
    {
    number 11
    build 33735
    }

    lol you took it a step further!!!! I think I need to get more into python scripting because we can make our lives so much easier with all that!

    @anomalaus said in DIY compound figures and the beginning of instancing...?:

    I have a mostly complete CR2 parser script which can load a directory full of poses or characters and even handles (at least reports problems without crashing or hanging Poser) unbalanced braces and recursive readScript references.

    Is that your own creation?

    There are some significant limitations though, due to missing functionality in the Python API. I haven't taught it to handle custom geometry, or directly read .obj files yet, because there's no point if I can't assign vertices to a material group from within python.

    I've only been playing with this properly for a day or so, but I've already found some weird structure, like I need to load figure mats through an actor and not a figure, which is weird to me. Took me a while to figure that one out...



  • @erogenesis It is based on a minimal, public domain CR2 class reading framework which was only capable of identifying the bones in a figure and couldn't handle more than a single keyframe per channel. I've done major code refactoring on it, extracted the file handling to allow recursive readScript handling and correctly detect End Of File conditions and unbalanced braces (which took huge amounts of tedious logging and debugging when I found a file with a typo which would initially crash the script or just hang poser).

    Here's the blurb from the original parser:

    {

    v1.0 20141027 Initial version based on cr2_parser.py (c) Frederick Lee phaethon@linux.ucla.edu.

    cr2_parser, Poser file pseudo-parser; python module.

    Copyright (C) 2006 Frederick Lee phaethon@linux.ucla.edu

    This program is free software; you can redistribute it and/or modify

    it under the terms of the GNU General Public License as published by

    the Free Software Foundation; either version 2 of the License, or

    (at your option) any later version.

    This program is distributed in the hope that it will be useful,

    but WITHOUT ANY WARRANTY; without even the implied warranty of

    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License

    along with this program; if not, write to the Free Software

    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

    # Dumb parser version
    # Relies on the tendancy of cr2 files to put "{" and "}" on lines of their own.
    # Relies on newline appearing to be significant.
    # Collects entire contents of cr2 into "blocks", which are just classes for now.
    # Primary target: create armature skeleton

    # Information from http://home.carolina.rr.com/kattman/Tutorials.htm
    }



  • And my subsequent development history:

    v1.0 20151009 Based on LoadFolderPoses.py version 2.1

    # Parses Poser files and sets keyframes rather than using poser's own load routines
    # Allow loading of poses 'in place', i.e. without overriding the figure's BODY actor transforms.
    # This feature is a mirror of the standard Poser pose saving dialogue check box 'Body Transformations'

    v1.1 20151009 Allow loading of only actor transform parameters.

    # This feature is a mirror of the standard Poser pose saving dialogue check box 'Morph Channels'

    v1.2 20160112 Parse and ignore remainder of line following '//' comment marker at each readline() call.

    # Removed sys.path mods to find PoserPrefs and PoserUI modules now in PoserLib package in
    # Runtime/Python/addons folder.
    # Implement recursive 'readScript' sub-file support.
    # Import macpath module to handle splitting colon-delimited paths
    # Implement eof() method in file2 class to detect EOF condition, since the readline() already
    # strips the whitespace and newlines from the returned line which would otherwise indicate the
    # end of file condition when readline() == ''. (Blank lines return '\n', not '')
    # Prevent the creation of new instances of existing actor objects wiping out any previously read
    # dial settings.
    # 20160328 Handle version and comment blocks at any level within a readScript
    # Support actor object blocks
    # 20160329 Ensure that readline() parses and swallows readScript lines without returning them to caller.
    # 20160330 Enforce every file read being a brace-balanced poser file. Raise exception if breached.
    # Change raw readline processing from strip().split('//')[0] to split('//')[0].strip() to prevent
    # brace string equality comparisons failing when whitespace exists between brace and comment.
    # 20160331 Dial valueOperation parsing must happen in two phases: Source Parameter determination and
    # Subsequent Modifier determination. The first is initiated by a valueOp... keyword and the second
    # by any of the beginValueKeys, strength and deltaAddDelta keywords. Subsequent modifiers are set
    # for the most recent valop instance appended to the dial instance
    # 20160402 Fix camera prop keyword detection in cr2.load() (matched cameraProp, not camera).
    # Implement geomCustom in actor object load.
    # 20160407 Change file open mode from 'rt' to 'rU' for universal newline support.
    # Add P11 groupingObject to prop actor types
    # 20160425 Add afterBend keyword to dial parsing

    v1.3 20160806 Incorporate LoadFolderPoses.py v2.3 changes.

    # PoserPrefs & PoserUI modules now imported from PoserLib package in Runtime/Python/addons folder.
    # Add 'runPythonScript' support to allow context switch of current figure in multi-figure poses.
    # NOTE: 'runPythonScript' is only supported in cr2.Load(), rather than within fileobj.readline() as
    # 'readScript' is supported, to prevent context-switch of current figure while that figure is still
    # being read.
    # Added unbuffered logging to external file as traceLoad buffering causes massive slowdown and
    # produces no output at all until script terminates.
    # Added test for camera actors, which are not typically parented to figures, to apply_pose().
    # Implemented doc {} useCamera and renderDefaults {} newWinWidth, newWinHeight setting.
    # Must treat channelset dials the same way actors are. I.e. if a dial name already exists for an
    # actor, load the new settings for the named dial already in the OrderedDict. Previously was
    # always instantiating a new dial and then overwriting the one in the OrderedDict. WRONG CRETIN!!!
    # Act consistently on parsing actor and dial names to be used as OrderedDict keys. If the assigned
    # object.name property is allowed to contain spaces (e.g. actor.name = ' '.join(w[1:],) ), then the
    # dict key comparison must also use ' '.join(w[1:],), not just w[1] !!!! WRONG AGAIN CRETIN !!!!

    v1.4 20160814 Allow apply_pose() to operate on whichever actors are specified by the pose file, if they exist,

    # regardless of current figure or prop selection. This allows posing of unparented props.
    # The exception remaining that figure poses will not be applied unless their targetFigure or
    # figureResFile matches the selected figure.

    v1.5 20160902 Add customDialPalette support.

    v1.6 20160914 Fix apply_pose() parameters for multi-figure poses.

    v1.7 20170123 Clear pre-existing keyframes within the range currentFrame to currentFrame + x.clearFigureKeys - 1

    # for parameters set by multi-frame poses to avoid corruption of animations. Keyframes of parameters
    # which are not referenced by the applied pose will remain.

    v1.8 20170129 Add graphPalette support. NOTE: both customDialPalettes and graphPalettes can be parsed but not

    # created as the poser python methods to do so do not exist in version 11.0.5.32974.

    v1.9 20170418 Add customData support to actor class to support pre-labelling of poses when saving back to the

    # library on a per-frame basis. I.e. with a key which includes the frame number, e.g. 'PN#41'
    # Since version 11.0.6.33735 does not expose the customData key list, a separate key named 'Keys'
    # will be used to store a delimiter-separated list of all other keys for subsequent internal access.
    # Protect apply_pose() from modifying a figure of a different type as specified by targetFigure or
    # figureResFile if no figure is selected, which would bypass the comparison in the tryProp case
    # intended for unparented props, rather than figures.

    v1.10 20170425 Add a preference customLoad to act like traceLoad and prevent assignment of the loaded poses, but

    # actually assign the customData to figures and actors as found in the pose files. This allows
    # customData assigned in pose files to update a loaded scene without the appropriate customData for
    # saving back to the library.

    v1.11 20170618 Attempt to allow loading of .pz3 poser scene files to extract and apply saved poses.

    # Add figure context change precautions and pose application methods to end of figure load method.
    # Fix SameFigureType() method to avoid os.path.basename() failing when Mac style paths from files are
    # compared with unix paths. Requires import of subprocess module to call applescript.
    # Will prevent applying pose to hidden channels to protect joint parameters if loading scene pz3.
    # When applying pose, detect highest frame number to be set and prompt user if it exceeds scene size.
    # As multi-figure poses may change the figure selection and accumulated pose information must be
    # applied before doing so and then reset, the x.clearFigureKeys frameAdvance information must
    # preserve and accumulate the largest x.clearFigureKeys value from all of the figures posed, not just
    # the last one in the pose file being currently applied. Added x.mostFigureKeys as accumulator.
    # Loading a pz3 scene file typically does not include the clearFigureKeys keyword used in pose files.
    # Nor does movieInfo necessarily define the highest frame number referred to in channel keys, so we
    # must accumulate the maximum frame number from each dial read to avoid exceptions when calling
    # SetValueFrame() for keyframes beyond the end of the scene in apply_pose()
    # Add support for subdivDeltas of various levels in targetExtendedInfo blocks.
    # Changed deltaset instantiation to use OrderedDict() rather than pre-allocated list.
    # Poser seems to change dial screen names when saving to scene files e.g. yrot not yRotate, so
    # use dial OrderedDict key chan, rather than dial.name when accessing actor parameters in apply_pose.
    # Determined how to select the next figure referenced in a pz3 scene file to apply poses to:
    # PZ3 starts with a geometry loading section with scene actor geometry then figureResFile and actor
    # geometries for each figure, but no figure {} blocks, so no need to change selection until figure {}
    # block followed by figureResFile line. Apply poses at the end of the figure block (including any
    # accumulated scene actors belonging to no figure. Final apply_pose() call at end will finish.
    # Reset file2.readline.debuglimit to 0 from 30720000 as test pz3 file had 35640346 lines and was being
    # truncated before final figure poses and doc settings could be read and applied.
    # Create animSets read from file (test for existence and delete if found).

    v1.12 20170622 Protect SameFigureType() comparisons failing if compressed .obz extension is compared to .obj

    v1.13 20170628 Add sound support to movieInfo.

    # Add initial support for keyLayers.
    # Add initial support for talkDesigner.

    TODO Allow loading of any uncompressed Poser file type

    # Add support for addonData
    # Add support for walk designer keyLayer and includedLayers.
    ########################################################################################################################