Fri, Sep 20, 8:31 AM CDT

Renderosity Forums / Poser Technical



Welcome to the Poser Technical Forum

Forum Moderators: Staff

Poser Technical F.A.Q (Last Updated: 2024 Sep 17 7:30 pm)

Welcome to the Poser Technical Forum.

Where computer nerds can Pull out their slide rules and not get laughed at. Pocket protectors are not required. ;-)

This is the place you come to ask questions and share new ideas about using the internal file structure of Poser to push the program past it's normal limits.

New users are encouraged to read the FAQ sections here and on the Poser forum before asking questions.



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



Subject: Pocket Protector required on this one...


_dodger ( ) posted Thu, 19 December 2002 at 2:49 PM · edited Fri, 20 September 2024 at 8:31 AM

Okay, I have become very sick of manually cleaning up my files, props, etc. Especially because I have a lot of them before I learned cleaner ways to do things. So I came up with this thing that seems to work pretty well. Really, there is no forum right for this. It's closest to going in Poser Python Scripting. But it's not Python. It's Perl. If you have Perl (or if you go get Perl from www.cpan.org), this little perlscript will do two cool things: 1) it will extract prop objects and seperate them out. 2) it will clean up your texture pathing. A note on 1: it will extract out your prop object, but it will put it right there in the same directory you're in. However, the script as-is will reference the object from :Runtime:Geometries:autoConvert so you will have to drop the OBJ in the right place yourself. Feel free to modify it, of course. Hell, it's a Perlscript. In the spirit of Perl, feel free to modify it beyond all belief and hack it up to make it set your automatic coffeemaker, if you please. What it does: from the command line, this script will take a filename as an argument and extract any prop object customGeom from it and create a file for each prop found with customGeom named .obj. This is the internal name, not the human-friendly Name name. It will strip out the customGeom data and replace it with a reference to the object file under :Runtime:Geometries:autoConvert but you will have to move the prop there yourself. It will also fix any "C:Program FilesMetaCreationsRuntimeTexturesyaddayaddapropsyaddayadda.jpg" type texture path references and trim them down to the bare necessities, i.e. the above would become :yaddayaddaprops:yaddayadda.jpg - it adds quotes only for paths with spaces but you can change this easily enough. The resulting px2 file will be spit out to the screen unless you redirect it into a file. For instance, I set this up for me to use on Linux (though it should work the same in a DOS window). Simply do something like this: dodger@gc% ./fileCleaner.pl poserSillyProp.pp2 > poserCleanProp.pp2 I am not too familiar with MacPerl but if you are using MacPerl already, you know how to translate this to the MacPerl shell, I'm sure. The shebang line (the first line that starts with hash-bang (#!) should be changed to point to your Perl executable if what I have there isn't it, i.e. #!/usr/local/bin/perl5 or #!C:perlbinperl.exe or whatever. However, unless you are running cygwin on a PC, this won't really matter because on a PC you probably have to say something like: C:> perl fileCleaner.pl poserSillyProp.pp2 > poserCleanProp.pp2 I think. I never use Perl on the PC, though, even though I have it installed in three places L commence script


#!/usr/bin/perl
use strict;
my $debug = 0;
my $geomMode = 0;
my $readMode = 0;
my $propName;
my $indent;
my $obj;
my $px2;
while (<>) {
    if ($debug) {
        my $next = <STDIN>;
        exit if $next =~ /qn/i;
    }
    chomp;
    s/^(s+)//; # strip leading whitespace
    $indent = $1;
    if (/^prop (S+)/) {
        $propName = $1; # prop name definition
        $propName =~ s/:d+//; # trim figureID
        $px2 .= "$indent$_n";
    }
    elsif (/^geomCustom/) {
        $geomMode = 1; # start customGeom block
        $obj = "# generated by Dodger's autoConvert poserfile cleanern";
    }
    elsif ($geomMode) { # in customGeom block
        if ($_ eq '{') { # start reading customGeom data
            $readMode = 1;
        }
        elsif ($_ eq '}') { # end geomCustom block
            $readMode = 0;
            $geomMode = 0;
            $px2 .= <<"EOF"; # add external OBJ reference
${indent}storageOffset 0 0.3487 0
${indent}objFileGeom 0 0 :Runtime:Geometries:autoConvert:$propName.obj
${indent}}
EOF
            # write the OBJect file
            open OBJ, ">$propName.obj";
            print OBJ $obj;
            close OBJ;
        }
        if ($readMode) {
            if (/^(v )|(vt )|(usemtl )|(g )|(f )|(vn )|(mtllib )/) {
                # proper Wavefront OBJ info
                $obj .= "$_n";
            }
            else {
                # not proper OBJ info -- keep but comment it out
                $obj .= "# $_n";
            }
        }
    }
    elsif (/^(texture|bump|reflection|transparency)Map (.*)$/) {
        # this is a map identifier
        my $mapType = $1;
        my $mapLoc = $2;
        if ($mapLoc =~ /Runtime/) { # don't affect if map not in Runtime
            $mapLoc =~ s/"//g; # strip quotes
            $mapLoc =~ s/C:.*Runtime/:Runtime/i; # remove absolute path
            $mapLoc =~ s//:/g; # replace  with :
            $mapLoc =~ s/:Runtime:Textures//i; # strip :Runtime:Textures
            $mapLoc = qq|"$mapLoc"| if $mapLoc =~ /s/; # quote if spaces
        }
        $px2 .= "$indent${mapType}Map $mapLocn";
    }
    else {
        # leave as-is unless blank
        $px2 .= "$indent$_n" if $_;
        # add whitespace if an end of block
        $px2 .= "n" if $_ eq '}';
    }
}

print $px2;


_dodger ( ) posted Thu, 19 December 2002 at 3:31 PM

Don't use it on CR2 files. It's not set up to deal with them, although it would tak very little work (in that place it looks for theprop name, change it so instead of if (/^prop (S+)/) { it says, instead, if (/^(prop|actor) (S+)/) { and it should work for figures, too. Though I'm not guarantying it and it's not tested to. The reason for this is that the form of the script as I posted it only looks for prop lines to name props from. This means that if an actor has custom geometry, it will overwrite the last prop .obj name found with the actor's geometry, and munge things up. It wasn't, however, something I was trying to deal with when I wrote it and so I didn't code for it. But that little mod I mentioned in the prior paragraph changes it to look for actor names too. However, that still won't fix it for a multi-figure grouping with custom geometry on all figures, because most body part names will be the same. Anyway, who told you to do that? You want to do something so silly, you hack the script yourself B^) It should work fine in the form posted on a CR2 or PZ3 that doesn't have any custom geometry except props, however, and since pz2 files don't have custom geometry at all, it shoudn't matter with them and should work fine as is just to clean up the texture paths.


AristaProductionLab ( ) posted Sat, 21 December 2002 at 2:25 AM

Hmm?? Cool Pearl reminds me of Stella & Adda? A.should you view the print files from the custom geom for possible variable/i.e.ect... calls that my have not been know{dictionaried} by the programmer?? B. This would then open a new command string that would handle this described custom geom?wouldn't it?? good luck in the future.. Question; what is the combination ratio/file size# of lines between Python & Pearl???Like if you wrote identical programs.But,one was in Python & the other in Pearl.. Hey! I would forget my kids if they didn't think that I was a tree?


_dodger ( ) posted Sat, 21 December 2002 at 4:03 AM

Attached Link: More than you ever wanted to know about Perl, plus dodger's modules!

Note: it's perl, not pearl. A pearl is an encapsulated mullusc irritant. Perl is 'Practical Extraction and Report Language'. Or perhaps 'Pathologically Eclectic Rubbish Lister'. It's up for debate, but both are good things, especially when you have to list pathologically eclectic rubbish, like the contents of a PZ3 file. Or feed it into a relational database. In Oregon. Or spit it back out as something different. Perl's originally derived from a combined permutation/combination of sed, awk, csh, and c. It's evolved into an entirely different camel since then, though B^) Honestly, I couldn't tell you, because I don't know Python much at all. As far as specifically for Poser goes, well, I'm planning on writing a module called Object::Poser one of these days and if it works well, putting it up for free on CPAN. This, in python:
    while 1:
            buf =index.html fp.read(blocksize)
            if not buf: break
            conn.send(buf)

would be this, in perl: while (1) { $buf = $fp->read($blocksize); last if not $buf; $conn->send($buf); }

But Perl lets you have more leeway in how you say things. For instance, you can also say: while (1) { $buf = $fp->read($blocksize) or last; $conn->send($buf); }

Which I find a lot more readable, and it does exactly the same thing. So at least in this example I found, you can go one line less, or 25% down. And it looks a lot more like natiral language to me. Oh, yeah, and in Perl curly braces are an absolute necessity, but indentation is merly highly recommended. I've seen entire programs written on one line, though, and they worked. Well, mostly. The reason I saw them is because it was my job to debug them. Which is why I highly recommend proper indentation in Perl anyway.


_dodger ( ) posted Sat, 21 December 2002 at 4:04 AM

Attached Link: fileCleaner.pl

Oh, forgot to mention: here's the finalised cleaner (see link)


_dodger ( ) posted Sat, 21 December 2002 at 4:07 AM

Attached Link: doall.pl

And this is the other little script that runs the whole thing on an entire directory as a batch (link attached) With the two of these in combination, I was able to clean up EVERY prop file in my library in about a minute. While I was in Renderosity (and if I didn't do it in two seperate scripts it would have been about ten seconds, I think).


_dodger ( ) posted Sat, 21 December 2002 at 4:32 AM

Oh, yeah--- Once I write that Model::Poser module I was talking about (I goofed on the name the first time), the above script will be OO, and thus as easy as:

#!/usr/bin/perl
use Model::Poser;

my $file = shift;
my $model = Model::Poser->open($file);
$model->SetRootPath(undef);
for my $actor ($model->Actors, $model->Props) {
    if ($actor->HasCustomGeom) {
        $actor->ExtractGeomToObject(-path => ':Runtime:Geometries:autoConvert',
                                    -nameFrom => [qw(actor model)]);
    }
}
$model->CleanAllPaths(-root => ':Runtime:Textures');


AristaProductionLab ( ) posted Sun, 22 December 2002 at 11:43 PM

WOW! Thanks for all of your hard work and Poser Sweat...This is fantastic...However,I think that there could be a web site out there that has developed a GUI program that could possibly include similar functions/batch jobs &/or processing.But I don't think that is this handy for the user...I'll look up the link!!! Would you be interested in writing/authoring a Python script to use in the material room?Is that material room damb hot or what!cheers Miracle.


_dodger ( ) posted Mon, 23 December 2002 at 4:39 AM

I don't write Python, sorry. Nor does the version of Poser that I have have anything called a 'room'. I won't upgrade to Poser 5, and I don't bother with PPP. On the GUI program -- I'm sure there are a number of programs out there, but IMO that's not as nice as having modules for your language of choice. GUIs are nice sometimes, but sometimes I really think that the command line makes things easier, and programming even easier. For a simple example, expressed in Windows terms -- if you're usingthe Windows Explorer GUI and, say, want to delete all files with the stirng '_old' in their name, you have to select each of them manually. You can't sort by reverse of name to drag-select them, and the normal Windows GUI won't let you stick a * in the address bar to limit those shown (the file-open variant will). You have to at least ctrl-click each in turn. Then you either drag to the rubbish bin or at least press 'Delete', after which you are prompted with a dialogue that asks if you really want to do this, which I think is kind of dumb becuase you're not really deleting anyting anyway -- if you made a mistake, you can easily recover from it. Then you have to switch over to the recycle bin itself and select 'Empty Recycle Bin' before it's (sort of) really gone. In DOS, you just type 'del _old' and the job is done. GUIs are really rather overrated, and only useful for some things. Well, maybe the AUI will be perfected soon and GUIs will become application-specific and otherwise a part of history.


AristaProductionLab ( ) posted Tue, 24 December 2002 at 11:31 PM

I was going to say that I thought that it could be done by a command line from dos using the delete *._old. but,that isn't very automated..??...I use the windows operating system..you can do batch jobs in windows xp..Thanks for the feedback..


_dodger ( ) posted Tue, 24 December 2002 at 11:50 PM

Yup, I'm just waiting for AUIs. Audio User Interfaces. I still read old science fiction, and as far as I'm concerned the old sci-fi authors had the right idea. I want to be able to wake up in the morning and say 'Do I have any new mail?' Then the computer says, 'Yes Dodger. 77% appears to be spam. There's one message from your sister. DAZ has released Victoria 8.0. You have fifty-seven e-bot messages from Renderosity. I like e-bot. She's nice. She should put some clothes on, though. There's one message in Korean I'm uncertain about -- am I to apply the "all Korean mail is spam" rule?'


_dodger ( ) posted Tue, 24 December 2002 at 11:56 PM

Oh, back on the perl thing... the file read/conn send can even be shortened to this:

$conn->send($buf) while $buf = $fp->read($blocksize);

But some people complain about Englishised Perl like that because it's too easy to read. They expect bassackwards computer Yodaspeak.


MarianneR ( ) posted Sat, 28 December 2002 at 11:34 AM

fileCleaner.pl works fine on Mac OSX, when I had chmod'ed it I didn't even have to type "perl" first. It doesn't like names with spaces though, they have to be between "". The other one, doall.pl writes the obj-files, but no new pp2's. I don't speak perl so I can't figure out why.


MarianneR ( ) posted Sat, 28 December 2002 at 11:42 AM

And then of course there is the problem with the shrugging guy ... no thumbnails for Poser to show. They'll have to be copied some other way.


_dodger ( ) posted Sat, 28 December 2002 at 7:50 PM

MacOSX is souped-up BSD UNIX. Try a '' before the space, as in: My Prop.pp2 doall.pl requires there to be a pp2 subdirectory there to avoid renaming them or overwriting them. so before running it, do:

<b>%</b>mkdir pp2


MarianneR ( ) posted Sat, 28 December 2002 at 8:11 PM

Thanks! Worked perfectly.


_dodger ( ) posted Sat, 28 December 2002 at 8:19 PM

No worries!


_dodger ( ) posted Sat, 28 December 2002 at 8:53 PM

Oh! I should list known issues (or issue (singular), really): Material maps that refer to locations that are not inside Runtime will not be affected usually However, if it looks like it's inside Runtime then the script will be fooled (because it doesn't know what's a real Runtime and what's not) and, as a result, may goof up things if you unzip a texture pack to somewhere besides Runtime, for instance, and just use a texture from the unzipped Runtime that's not a real Runtime. If that makes sense. Umm, in other words: "C:Program FilesCuriousLabsRuntimeTexturestextue.jpg" and "C:Progra~1Metacr~1Poser4~1RuntimeTexturestexture.jpg" will be fine and will both become :texture.jpg Which minimises the path, too. As will references to "D:downloadsTexturestexture.jpg" (though it will leave it like this) But if you for some reason have a prop referencing something like: "D:downloadsposerinstallsPropRuntimeTexturestexture.jpg" will get turned into: D::downloads:poserinstalls:Prop:texture.jpg Which is kinda weird. But it's not really common that you reference an install temp directory from an installed prop, texture, or whatever. I only did because I accidentally deleted a texture and pointed it back at the install directory which was kinda bad form anyway


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.