Fri, Nov 8, 9:48 AM 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: Useful Code Snippets


  • 1
  • 2
structure ( ) posted Thu, 27 June 2019 at 4:56 PM · edited Thu, 07 November 2024 at 8:37 AM
Forum Coordinator

So I think with the advent of a new dawn for poser, this forum could use a sticky thread where snakeheads can supply snippets of poser python code that others may find useful, or indeed, be able to improve upon. Let me start the ball Rolling - the following is a complete library that I have built / collected over the years ( there are more to follow ) Some of the code was written by others, edited by myself and is now here - for the use of all of you fellow coders should you choose to.


# -*- coding: UTF8 -*-
# Dialog Library

import os
import wx
import wx.lib.imagebrowser as imagebrowser


class dialogs:
    def choose(self, title="", prompt="", OptionList=[], parent=None):
        # prepare the dialog
        dialog = wx.SingleChoiceDialog(parent, prompt, title, OptionList)
        # ensure the list is not empty
        if not OptionList == []:
            # check the dialog response
            return dialog.GetStringSelection() if dialog.ShowModal() == wx.ID_OK else None

    def choosemulti(self, title="", prompt="", OptionList=[], parent=None):
        # prepare the dialog
        dialog = wx.MultiChoiceDialog(parent, prompt, title, OptionList)
        # check the dialog response
        if dialog.ShowModal() == wx.ID_OK:
            # get the selections indices
            selections = dialog.GetSelections()
            # get the selections strings
            strings = [OptionList[x] for x in selections]
            dialog.Destroy()
            return (selections, strings)
        else:
            return (False, False)

    def colordialog(self, event=None):
        dialog = wx.ColourDialog(None)
        dialog.GetColourData().SetChooseFull(True)
        return dialog.GetColourData() if dialog.ShowModal() == wx.ID_OK else False

    def getfile(self, start="", filemustexist=True, parent=None):
        styles = [(wx.FD_OPEN | wx.FD_FILE_MUST_EXIST), (wx.FD_OPEN)]
        style = styles[0] if filemustexist else styles[1]
        types = "Camera         (*.cm2 , *.cmz)|*.cm2; *.cmz|"                                     \
            "Figure         (*.cr2 , *.crz)|*.cr2; *.crz|"                                    \
            "Expression     (*.fc2 , *.fcz)|*.fc2; *.fcz|"                                    \
            "Hand           (*.hd2 , *.hdz)|*.hd2; *.hdz|"                                    \
            "Hair           (*.hr2 , *.hrz)|*.hr2; *.hrz|"                                    \
            "Light          (*.lt2 , *.ltz)|*.lt2; *.ltz|"                                    \
            "Material       (*.mt5 , *.mtz , *.mc6 , *.mcz)|*.mt5; *.mtz; *.mc6; *.mcz|"      \
            "Object         (*.obj , *.obz)|*.obj; *.obz|"                                    \
            "Pose           (*.pz2 , *.p2z)|*.pz2; *.p2z|"                                    \
            "Prop           (*.pp2 , *.ppz)|*.pp2; *.ppz|"                                    \
            "Python Script  (*.py , *.pyc , *.pyd)|*.py; *.pyc; *.pyd|"                       \
            "Scene          (*.pz3 , *.pzz)|*.pz3; *.pzz|"                                    \
            "all files        (*.*)|*.*|"                                             # File Types

        # prepare dialog
        dialog = wx.FileDialog(parent, "Select a File",
                               start, "", types, style)
        # test dialog response
        return dialog.GetPath() if dialog.ShowModal() == wx.ID_OK else False

    def getfolder(self, start="", newdirbutton=True, parent=None):
        styles = [(wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON),
                  (wx.DD_DEFAULT_STYLE)]
        style = styles[0] if newdirbutton else styles[1]
        # prepare dialog
        dialog = wx.DirDialog(None, 'Select a Folder ', start, style)
        # test dialog response
        return dialog.GetPath() if dialog.ShowModal() == wx.ID_OK else False

    def get_desktop_path(self, event=None):
        import re
        # create variable
        D_paths = list()
        try:
            fs = open(os.sep.join((os.path.expanduser("~"),
                      ".config", "user-dirs.dirs")), 'r')
            data = fs.read()
            fs.close()
        except:
            data = ""

        D_paths = re.findall(r'XDG_DESKTOP_DIR="([^"]*)', data)

        if len(D_paths) == 1:
            D_path = D_paths[0]
            D_path = re.sub(r'$HOME', os.path.expanduser("~"), D_path)
        else:
            D_path = os.sep.join((os.path.expanduser("~"), 'Desktop'))

        return D_path if os.path.isdir(D_path) else None

    def getfont(self, f):
        fontdialog = wx.FontDialog(self, wx.FontData())

        if fontdialog.ShowModal() == wx.ID_OK:
            data = fontdialog.GetFontData()
            font = data.GetChosenFont()
            # self.text.SetFont(font)
            fontdialog.Destroy()
            return font
        fontdialog.Destroy()

    def getnumberentry(self, alertmessage, prompt, caption, value, min, max, pos=wx.DefaultPosition):
        NE_dialog = wx.NumberEntryDialog(
            None, alertmessage, prompt, caption, value, min, max, pos)
        return NE_dialog.GetValue() if NE_dialog.ShowModal() == wx.ID_OK else False

    def gettextentry(self, title="", message="", parent=None):
        TE_dialog = wx.TextEntryDialog(
            parent, message, title, "", style=wx.OK)                 # none=parent
        TE_dialog.SetValue("")
        return TE_dialog.GetValue() if TE_dialog.ShowModal() == wx.ID_OK else False

    def imageviewer(self, parent=None):
        dialog = imagebrowser.ImageDialog(parent)
        if dialog.ShowModal() == wx.ID_OK:
            print("You Selected File: ")+dialog.GetFile()

    def okcancel(self, title="", alertmessage="", okonly=False, parent=None):
        styles = [(wx.OK | wx.ICON_INFORMATION | wx.STAY_ON_TOP),
                  (wx.OK | wx.CANCEL | wx.ICON_INFORMATION | wx.STAY_ON_TOP)]
        style = styles[0] if okonly else styles[1]
        ok_dialog = wx.MessageDialog(parent, alertmessage, title, style)
        return True if ok_dialog.ShowModal() == wx.ID_OK else False

    def showalert(self, title="", alertmessage="", icon=0, Btype=0, bType=0, parent=None):
        icons = {
            0:  wx.ICON_ERROR,
            1:  wx.ICON_EXCLAMATION,
            2:  wx.ICON_HAND,
            3:  wx.ICON_QUESTION,
            4:  wx.ICON_INFORMATION,
            5:  wx.ICON_NONE
        }                                                                             # set up icons

        buttonType = {
            0:  wx.OK,
            # Must be combined with either OK or YES_NO
            1:  wx.CANCEL,
            2:  wx.YES_NO,
            3:  wx.HELP,
            # Can only be used with YES_NO
            4:  wx.NO_DEFAULT,
            # This style is currently not supported (and ignored) in wxOSX.
            5:  wx.CANCEL_DEFAULT,
            # Can only be used with YES_NO
            6:  wx.YES_DEFAULT,
            7:  wx.OK_DEFAULT
        }                                                                     # set up buttons

        behaviourType = {
            0:  wx.STAY_ON_TOP,
            1:  wx.CENTRE
        }                                                                     # set up behaviour

        # select icon to display
        icon = icons[icon]
        # select buttons to display
        atype = buttonType[Btype]
        # select behaviour
        btype = behaviourType[bType]

        wx.MessageDialog(parent, alertmessage, title, style=atype |
                         icon | btype).ShowModal()  # Show alert message

    def yesno(self, title="", message="", parent=None):
        style = (wx.YES | wx.NO)
        # prepare dialog
        YN_dialog = wx.MessageDialog(parent, message, title, style)
        # test dialog response
        return True if YN_dialog.ShowModal() == wx.ID_YES else False

    def onBusy(self,  message):
        busyDialog = wx.BusyInfo(message)
        busyDialog = None

Locked Out


FVerbaas ( ) posted Thu, 25 July 2019 at 2:31 PM
Forum Coordinator

Also do not forget the examples that come with Poser. They could do with more documentation but are a great reference.


FVerbaas ( ) posted Tue, 30 July 2019 at 9:44 AM
Forum Coordinator

A simple function to copy matrerial collections between figures and props. if the target (a prop or a figure) has a material defined with a name that also appears in the materials list of the source, that material definition (shader) in the target will be overwritten by the material of the source.

def copyMaterialDefinitions(source, target):
    srcmats = source.Materials()
    tgtmats = target.Materials()
    for srcmat in srcmats:
        matnam = srcmat.Name()
        srcmat.SaveMaterialSet(matnam)
        try:
            target.Material(matnam).LoadMaterialSet(matnam)
        except:
            pass


structure ( ) posted Sun, 01 September 2019 at 8:35 AM
Forum Coordinator

Nice routine! thanks

Locked Out


FVerbaas ( ) posted Mon, 06 January 2020 at 12:04 PM · edited Mon, 06 January 2020 at 12:05 PM
Forum Coordinator

I tried some of the dialogs class yesterday because I needed some of the functions. I assume the site formatting has ironed some things away here and there:

  • the definition of 'types' in GetFile triggers a complilation error and indentaiton error.
  • in 'get_desktop_path', 're' is not defined in
D_paths = re.findall(r'XDG_DESKTOP_DIR="([^"]*)', data)


structure ( ) posted Mon, 06 January 2020 at 12:07 PM · edited Tue, 07 January 2020 at 9:27 PM
Forum Coordinator

FVerbaas posted at 6:07PM Mon, 06 January 2020 - #4375651

I tried some of the dialogs class yesterday because I needed some of the functions. I assume the site formatting has ironed some things away here and there:

  • the definition of 'types' in GetFile triggers a complilation error and indentaiton error.
  • in 'get_desktop_path', 're' is not defined in
D_paths = re.findall(r'XDG_DESKTOP_DIR="([^"]*)', data)

add

Import re

Locked Out


structure ( ) posted Mon, 06 January 2020 at 4:21 PM
Forum Coordinator

the backslashes were not showing ( I forget about that in this forum ) so I have added a double backslash to enable them to be visible

Locked Out


structure ( ) posted Tue, 07 January 2020 at 9:42 PM · edited Thu, 04 November 2021 at 5:10 AM
Forum Coordinator

A dictionary of poser Figures by geometry:


# -*- coding: UTF8 -*-
# ©2001 - 2018 structure

def FigureTypes():
return {
'!!!!TEO_PUR' : 'Teo Pur' ,
'!!!Kali_And_Kelm' : 'Kali_Kelm' ,
'!!AyanaDoll' : 'AyanaDoll' ,
'!!Eepo_Kobee' : 'EEpo' ,
'!Chip' : 'Cookie-Chip' ,
'3duSkye' : '!skye' ,
'3DrmLO_LO' : 'Little One' ,
'3DUDennis' : '3DUDennis' ,
'3duGramps' : '3duGramps' ,
'3duSadie' : 'Sadie' ,
'3duSam' : '3DUSam' ,
'AfrElephant' : 'Mammoth / African Elephant' ,
'Alexa21' : 'Alexa' ,
'Allosaurus' : 'Allosaurus' ,
'Alyson2_HR' : 'Alyson' ,
'AMSilver' : 'AlphaMan' ,
'Anceata_Semil' : 'Anceata-Semil' ,
'Andrea' : 'Andy' ,
'Andrewsarchus' : 'Andrewsarchus' ,
'Andy' : 'Andy' ,
'Andy2' : 'Andy' ,
'Angela' : 'Angela' ,
'Antonia-1.2' : 'Antonia' ,
'Antonia-1.2WM' : 'Antonia' ,
'ApolloMaximus2005' : 'Apollo' ,
'AucasaurusDR' : 'Aucasaurus' ,
'BabyLuna' : 'BabyLuna' ,
'Barney' : 'Barney' ,
'Barney2' : 'Barney' ,
'Ben' : 'Ben' ,
'BenP7' : 'Ben' ,
'Bertha' : 'Bertha' ,
'Bertha2' : 'Bertha' ,
'Betaboy' : 'BetaBoy' ,
'blAiko3' : 'Aiko 3' ,
'blBear' : 'Bear' ,
'blBizMan' : 'Biz Man' ,
'blBizWom' : 'Biz Woman' ,
'blDavid' : 'David 3' ,
'blDavidGEN' : 'David 3 Genitals' ,
'blDemon' : 'DAZ Demon' ,
'blFREAK' : 'Freak 3' ,
'blGhost' : 'Ghost' ,
'blGirl' : 'The Girl' ,
'blGirl_v3UV' : 'The Girl' ,
'blHiro' : 'Hiro 3' ,
'blHiro_Dv' : 'Hiro 3' ,
'blKid' : 'DeeDee / Sammy' ,
'blMilBaby' : 'Millennium Baby' ,
'blMilBaby_2' : 'Chubblies / Millennium Baby 3' ,
'blMilBigCat' : 'Millennium Big Cat' ,
'blMilCat' : 'Millennium Cat' ,
'blMilDog' : 'Millennium Dog' ,
'blMilDragon' : 'Millennium Dragon' ,
'blMilDragon2' : 'Millennium Dragon' ,
'blMilFoal' : 'Millennium Foal' ,
'blMilGirl' : 'Millennium Girl' ,
'blMilGirlPS' : 'Pre-School Boy / Girl' ,
'blMilGirlPT' : 'Pre-Teen Boy / Girl' ,
'blMilHorse' : 'Millennium Horse' ,
'blMilKid_k4b' : 'Kids 4' ,
'blMilMan' : 'Frank / Orc' ,
'blMilMan_m3' : 'Michael 3' ,
'blMilMan_m3GEN' : 'Michael 3 Genitals' ,
'blMilMan_m4b' : 'Michael 4' ,
'blMilMan_m4GEN' : 'Generation 4 Genitals' ,
'blMilPup' : 'Millennium Puppy' ,
'blMilWomLoNG' : 'Millennium Woman Low Res No Genitals' ,
'blMilWom_v3' : 'Victoria 3' ,
'blMilWom_v4' : 'Victoria4' ,
'blMilWom_v4b' : 'Victoria4' ,
'blMilWom_V4_V3b' : 'Victoria4 to Victoria 3' ,
'blPSBoy' : 'Matt' ,
'blPSBoyPS' : 'Matt' ,
'blPSGirl' : 'Maddie' ,
'blPSGirlPS' : 'Maddie' ,
'blPython' : 'Python' ,
'blSkeleton_m3' : 'Michael 3 Skeleton' ,
'blSkeleton_m4' : 'Michael 4 Skeleton' ,
'blSkeleton_v3' : 'Victoria 3 Skeleton' ,
'blSkeleton_v4' : 'Victoria4 Skeleton' ,
'blSnowman' : 'Snowman' ,
'blStephanie' : 'Stephanie' ,
'blStephaniePetite' : 'Stephanie Petite' ,
'blSubDragon' : 'SubDragon' ,
'blTriceratops' : 'Triceratops' ,
'blTroll' : 'Troll' ,
'blVickiP4' : 'Vicki Poser 4' ,
'blVittorio' : 'Vittorio' ,
'blWalter' : 'Walter' ,
'blWolf' : 'Zygote Wolf' ,
'blWyvern' : 'Wyvern' ,
'blYTBoy' : 'Luke' ,
'blYTGirl' : 'Laura' ,
'blYTGirlPT' : 'Laura Pre-Teen / Luke Pre-Teen' ,
'BrachiosaurusDR' : 'Brachiosaurus' ,
'BrachiosaurusDRnospikes' : 'Brachiosaurus' ,
'Butterfly' : 'Butterfly' ,
'Campestergum' : 'Campestergum' ,
'Cloud' : 'Butterfly Cloud' ,
'Creech' : 'Creech' ,
'Dawn' : 'Dawn' ,
'DI-D-O-Burden' : 'Dragon of Burden' ,
'Diego' : 'Diego' ,
'Dinohyus' : 'Dinohyus' ,
'DI_Biguana' : 'Biguana' ,
'DocPitterbill' : 'Doc Pitterbill' ,
'Dragon' : 'Dragon' ,
'DragonFlySID' : 'SID Dragonfly' ,
'DragonSkeleton' : 'Dragon Skeleton' ,
'Drossel' : 'Drossel2' ,
'DRSnDragon' : 'Snake Dragon' ,
'Dusk' : 'Dusk' ,
'Dylan' : 'CubedBabies' ,
'EasternDragon' : 'Eastern Dragon' ,
'Edgar' : 'Edgar' ,
'Edgar2' : 'Edgar' ,
'EiniosaurusDR' : 'Einiosaurus' ,
'FemaleMusculature' : 'Female Muscules' ,
'Fon' : 'Fon' ,
'Freddie' : 'Freddie' ,
'gallicu-2' : 'Gallimimus' ,
'GammaGirl' : 'GammaGirl' ,
'GenitalsG2' : 'G2 Genitals' ,
'Ginger' : 'Ginger' ,
'Ginger2' : 'Ginger' ,
'Glyptodon' : 'Glyptodon' ,
'GodfreyFinal_V07' : 'Godfrey' ,
'Goblin' : 'Goblin 2' ,
'Gosha' : 'Gosha' ,
'Gramps' : 'Gramps' ,
'Gramps2' : 'Gramps' ,
'GreyAlien2-5' : 'GreyAlien' ,
'Haru' : 'Haru' ,
'Hatchling' : 'Hatchling' ,
'Hein' : 'Hein' ,
'HummingBird' : 'HummingBird' ,
'Hydra' : 'Hydra' ,
'Ichiro2' : 'Ichiro' ,
'Ictiosaur' : 'Ictiosaur' ,
'Indricotherium' : 'Indricotherium' ,
'Izumi' : 'Izumi' ,
'James' : 'James' ,
'JamesCasual' : 'James' ,
'JamesG2' : 'James' ,
'JamesHiRes' : 'James' ,
'JamesLoRes' : 'James' ,
'JamesLoRes' : 'James' ,
'Jenny' : 'CubedBabies' ,
'Jessi' : 'Jessi' ,
'JessiCasual' : 'Jessi' ,
'JessiG2' : 'Jessi' ,
'JessiHires' : 'Jessi' ,
'JessiHiRes' : 'Jessi' ,
'JessiLores' : 'Jessi' ,
'Kate' : 'Kate' ,
'KateP7' : 'Kate' ,
'Kelvin' : 'Kelvin' ,
'KelvinG2' : 'Kelvin' ,
'KentrosaurusDR' : 'Kentrosaurus' ,
'Kiki' : 'Kiki' ,
'Kit' : 'LittleFox' ,
'Koji' : 'James' ,
'KojiG2' : 'Koji' ,
'kon' : 'Kon' ,
'Koshini2' : 'Koshini' ,
'Krystal' : 'Krystal' ,
'LaFemme1' : 'La Femme' ,
'L\'Homme1' : 'L\'Homme' ,
'LaRoo2' : 'LaRoo' ,
'LLF-Cookie' : 'Cookie-Chip' ,
'LLF-Star_Base3' : 'Star' ,
'Loik' : 'Loik' ,
'Lusitana' : 'Lusitana' ,
'Macrauchenia' : 'Macrauchenia' ,
'Majestic Dragon' : 'Majestic Dragon' ,
'MaleMusculature' : 'Male Muscles' ,
'Malik' : 'Malik' ,
'Mannequin' : 'mannequin' ,
'Marcus' : 'Marcus' ,
'Mavka' : 'Mavka' ,
'MDP_ANIME\\MDP-F202' : 'MDP Anime' ,
'Michelle' : 'Michelle' ,
'Mick' : 'Mick' ,
'Miki' : 'Miki' ,
'Miki2' : 'Miki' ,
'Miki3' : 'Miki' ,
'Miki4' : 'Miki' ,
'Minnie' : 'Minnie' ,
'Minnie2' : 'Minnie' ,
'MonolophosaurusDR' : 'Monolophosaurus' ,
'Natu2' : 'Natu' ,
'Natu3' : 'Natu' ,
'near_me' : 'Near Me' ,
'Nea_2_n2_4' : 'Nea 2' ,
'NogChick' : 'Noggins Chick' ,
'NogCockerel' : 'Noggins Cockerel' ,
'NogHen' : 'Noggins Hen' ,
'NogOwl' : 'Noggins Owl' ,
'NogOwl Perched' : 'Noggins Owl' ,
'nwsNetherGirl' : 'Phoebe' ,
'okcNadyaB' : 'Nadya' ,
'okcSenyaV1bW' : 'Senya' ,
'okcVini' : 'Vini' ,
'OliviaG2' : 'Olivia' ,
'P3DA_Goblin_HR' : 'Goblin' ,
'P3DA_Goblin_LR' : 'Goblin' ,
'P3DA_LoREZ_Crow' : 'P3DA Crow' ,
'P3DA_TrogGenital_HR' : 'Trog Genitals' ,
'P3DA_TrogGenital_LR' : 'Trog Genitals' ,
'P3DA_Trog_HR' : 'Trog' ,
'P3DA_Trog_LR' : 'Trog' ,
'P5CasualMan' : 'P5Casual' ,
'P5CasualWoman' : 'P5Casual' ,
'P5NudeBoy' : 'P5Nude' ,
'P5NudeGirl' : 'P5Nude' ,
'P5NudeMan' : 'P5Nude' ,
'P5NudeWoman' : 'P5Nude' ,
'P8Alyson' : 'Alyson' ,
'P8Alyson_Casual' : 'Alyson' ,
'P8Alyson_HR' : 'Alyson' ,
'P8Alyson_LR' : 'Alyson' ,
'P8Ryan' : 'Ryan' ,
'P8Ryan_Genitals_HR' : 'Ryan Genitals' ,
'P10Rex' : 'Rex' ,
'P10Rex1.1' : 'Rex' ,
'P10RexGenitals' : 'Rex Genitals' ,
'P10Roxie' : 'Roxie' ,
'P10Roxie1.1' : 'Roxie' ,
'PHFemale' : 'Project Human Female' ,
'PHMale' : 'Project Human Male' ,
'PolarBear' : 'Polar Bear' ,
'PosetteV3' : 'Posette' ,
'PPro_LR_Fem' : 'Poser Low Res Female' ,
'PPro_MR_Fem' : 'Poser Medium Res Female' ,
'PuntikKaalkopje' : 'Puntik' ,
'R-lina' : 'RLina' ,
'RIKI_A01' : 'Rikishi' ,
'RIKI_A01H' : 'Rikishi' ,
'Ryan2_HR' : 'Ryan' ,
'sbrm3' : 'Songbird Remix' ,
'sbrm3_g' : 'Songbird Remix' ,
'sbrm3_wf1' : 'Songbird Remix' ,
'sbrm3_wf4' : 'Songbird Remix' ,
'sbrm3_wf5' : 'Songbird Remix' ,
'sbrm3_wf7' : 'Songbird Remix' ,
'sbrm3_wf10' : 'Songbird Remix' ,
'sbrm_vulture' : 'Condor' ,
'SeaDragon' : 'Sea Dragon' ,
'Seq_orc' : 'Orc' ,
'serpent' : 'Serpent' ,
'SharkDR' : 'Shark' ,
'SimonG2' : 'Simon' ,
'Skywyrm' : 'Skywyrm' ,
'Slon' : 'Slon' ,
'Smilodon' : 'Smilodon' ,
'SpinosaurusDR' : 'Spinosaurus' ,
'Squeaker' : 'Squeaker' ,
'StorybookDragon' : 'Storybook Dragon' ,
'Suchomimus' : 'Suchomimus' ,
'SydneyG2' : 'Sydney' ,
'tawhak' : 'Tawhak' ,
'TeraiYuki2' : 'Terai Yuki 2' ,
'thanator gruppe3' : 'Thanator' ,
'Trex' : 'T-Rex' ,
'Troll' : 'Ragbesh' ,
'udadultd' : 'Adult Dragon' ,
'udhatchlingd' : 'Hatchling Dragon' ,
'Vila' : 'Vila' ,
'waterelemental2' : 'Water Elemental' ,
'Wolf' : 'Wolf' ,
'WoollyMammoth' : 'Wooly Mammoth' ,
'WWSal' : '3DWW' ,
'Yweeb' : 'Yweeb' ,
'Zot' : 'Zot' ,
'Zuniceratops' : 'Zuniceratops' ,
}

a short script to get the figure type.
import poser, os
figure=poser.Scene().CurrentFigure()
print(FigureTypes(os.path.splitext(os.path.basename(geomName))[0]))

Locked Out


structure ( ) posted Sun, 05 April 2020 at 11:11 PM · edited Thu, 04 November 2021 at 5:12 AM
Forum Coordinator

replacing all backslashes in a list of paths


def replaceBackslashinList( Thislist, bs, fs ):
    return list(map(lambda x: x.replace( bs, fs), Thislist) )

myList = replaceBackslashinList(myList, "\\", "/")

Locked Out


structure ( ) posted Fri, 10 April 2020 at 7:04 PM · edited Mon, 25 October 2021 at 7:27 AM
Forum Coordinator

Copy to Clipboard

import wx
def copytoclipboard( item  = None ):
    clipboard = wx.TheClipboard
    if not clipboard.IsOpened():
        clipboard.Open()
        data = wx.TextDataObject()
        data.SetText( item )
        clipboard.SetData(data)
    clipboard.Close()

without wx :

from subprocess import check_call
class clipboard:
    def copy2clip(self, txt):
        cmd='echo '+txt.strip()+'|clip'
        return check_call(cmd, shell=True)

Locked Out


adp001 ( ) posted Thu, 14 May 2020 at 9:36 AM

Simple method to save some typing while dealing with dicts:

class MyDict(dict):
    def __getattr__(self, item):
        if not item.startswith("_"):
            return self.get(item)
        return super(self.__class__, self).__getattribute__(item)

Instead of MyDict["keyword"]you can simplly write MyDict.keyword.




adp001 ( ) posted Thu, 14 May 2020 at 9:41 AM · edited Thu, 14 May 2020 at 9:43 AM

Above dict replacement delivers None for not existent elements. If you want original behaviour, use this a bit slower class:

class MyDict(dict):
    def __getattr__(self, item):
        if not item.startswith("_") and item in self:
            return self.get(item)
        return super(self.__class__, self).__getattribute__(item)




adp001 ( ) posted Sat, 16 May 2020 at 8:41 AM

I often use the following little function if I have to script something with Poser meshes. I do that outside of Poser, because I often need a debugger to follow what the script is doing step by step in critical parts.

With Poser-Python:

import numpy as NP

try:
    import poser

    INSIDEPOSER = True
except ImportError:
    # "POSER_FAKE" is a Python lib to allow your editor to know about Poser
    # for scripting outsite of Poser (code completition, type checking, highlighting).
    # Author: adp001
    # Direct download: http://adp.spdns.org/FakePoserLib3.zip
    import POSER_FAKE as poser

    INSIDEPOSER = False

# Pickle is used to save|load the complete geometry instead of a slow obj loader.
try:
    import cPickle as pickle
except ImportError:
    import pickle


# Returns python list (assume given poly is tri or quad):
f_forcequad = lambda _poly: list(_poly) if len(_poly) == QUAD else list(_poly) + [_poly[-1]]

VERSION = float(poser.Version()) if poser.Version()[0].isdigit() else 11
NP_PRECISION = NP.float32 if int(VERSION) <= 11 else NP.float

def save_figure(fig, filename):
    """
        Saves verts, tverts, polys (4 vertices as float), polysets (4 indices crossreferencing verts),
        tpolys (2 vertices as float), tpolysets (2 indices creossreferencing tverts), material names
        and a material indexlist for cross-reference.
        All collected arrays from current figure are pickled into a file.

        :param fig: Poser figure
        :param filename: Path and filename
        :type fig: poser.FigureType
        :type filename: basestring
    """
    if INSIDEPOSER:
        # Get unimesh of current figure (unmorphed, unposed)
        poser_geom = fig.UnimeshInfo()[0]
        assert isinstance(poser_geom, poser.GeomType)
        geom = MyGeom(
                verts=NP.array([[v.X(), v.Y(), v.Z()] for v in poser_geom.Vertices()], NP_PRECISION),
                tverts=NP.array([[v.U(), v.V()] for v in poser_geom.TexVertices()], NP_PRECISION),
                polys=NP.array([f_forcequad([[v.X(), v.Y(), v.Z()] for v in p.Vertices()])
                                for p in poser_geom.Polygons()], NP_PRECISION),
                polysets=NP.array([f_forcequad(poser_geom.Sets[p.Start():p.Start() + p.NumVertices()])
                                   for p in poser_geom.Polygons()], NP.int32),
                tpolys=NP.array([f_forcequad([[v.U(), v.V()]
                                              for v in p.TexVertices()]) for p in poser_geom.TexPolygons()],
                                NP_PRECISION),
                tpolysets=NP.array([f_forcequad(poser_geom.Sets[p.Start():p.Start() + p.NumVertices()])
                                    for p in poser_geom.TexPolygons()], NP.int32),
                matindex=NP.array([p.MaterialIndex() for p in poser_geom.Polygons()], NP.int32),
                matnames=[m.Name() for m in poser_geom.Materials()]
        )
        p = poser.TexPolygonType()

        with open(filename, "wb") as fh:
            pickle.dump(geom, fh, pickle.HIGHEST_PROTOCOL)

        return geom
    return None

This saves all those collected data in a file (pickled).




adp001 ( ) posted Sat, 16 May 2020 at 8:45 AM

Class "MyGeom" is actually a dict. But in my case it is what I mentioned before:

class MyGeom(dict):
    def __getattr__(self, item):
        if not item.startswith("_") and item in self:
            return self.get(item)
        return super(self.__class__, self).__getattribute__(item)




adp001 ( ) posted Sat, 16 May 2020 at 8:50 AM

To load the data back if you are scripting outside of Poser:

try:
    import cPickle as pickle
except ImportError:
    import pickle

with open(filename, "rb") as fh:
    geom = pickle.load(fh)

(Make sure there is access to the class you saved the file with – maybe it's better to use plain dict in the Poser script part)

Now you can get from the dict what you need and ignore/discard the rest.




adp001 ( ) posted Sat, 16 May 2020 at 8:54 AM

I extraced the Poser part from a whole script and forgot to copy 2 declarations:

TRI, QUAD = 3, 4

Sorry for that.




adp001 ( ) posted Sat, 16 May 2020 at 9:03 AM

Something useful when dealing with Numpy:

try:
    # Try to make Numpy show numbers in this format:
    float_formatter = "{:.4f}".format
    NP.set_printoptions(formatter={'float_kind': float_formatter})
except TypeError as err:
    # Numpy to old. But "precision" should work.
    NP.set_printoptions(precision=4)




adp001 ( ) posted Sat, 16 May 2020 at 9:06 AM

Some "constants" I often use:

# Poser <= version 11 seems to work with 32-bit float precision (Numpy standard is 64-bit)
VERSION = float(poser.Version()) if poser.Version()[0].isdigit() else 11
NP_PRECISION = NP.float32 if int(VERSION) <= 11 else NP.float
NP_VERT_ZERO = NP.array((0, 0, 0), NP_PRECISION)

# Simplification to deal with some names used as indices
X, Y, Z = range(3)
A, B, C, D = range(4)
QUAD = 4
TRI = 3

(Because Poser does not know constants, I write them in Uppercase to remember)




adp001 ( ) posted Sat, 16 May 2020 at 9:13 AM · edited Sat, 16 May 2020 at 9:13 AM

Polys can have 3 or 4 vertices (TRI or QUAD). Numpy arrays must have a constant length. So it is common behaviour to set the 4th entry for a TRI equal to the third entry (isTri == (p[3] == p[4]) )




adp001 ( ) posted Sat, 16 May 2020 at 9:15 AM

And a real fast function to compute the distance between 2 verts:

def distance_e(v, u):
    # Distance with Numpy "einsum"
    # https://semantive.com/blog/high-performance-computation-in-python-numpy-2/
    z = v - u
    return NP.sqrt(NP.einsum('i,i->', z, z))




adp001 ( ) posted Sat, 16 May 2020 at 3:10 PM · edited Sat, 16 May 2020 at 3:12 PM

The function to save the figure is pretty slow, because a whole lot of function calls to Poser are needed when collecting the indices. Use the following and it is pretty fast:

        vsets = poser_geom.Sets()
        tsets = poser_geom.TexSets()
        geom = MyGeom(
                verts=NP.array([[v.X(), v.Y(), v.Z()] for v in poser_geom.Vertices()], NP_PRECISION),
                tverts=NP.array([[v.U(), v.V()] for v in poser_geom.TexVertices()], NP_PRECISION),
                polys=NP.array([f_forcequad([[v.X(), v.Y(), v.Z()] for v in p.Vertices()])
                                for p in poser_geom.Polygons()], NP_PRECISION),
                polysets=NP.array([f_forcequad(vsets[p.Start():p.Start() + p.NumVertices()])
                                   for p in poser_geom.Polygons()], NP.int32),
                tpolys=NP.array([f_forcequad([[v.U(), v.V()]
                                              for v in p.TexVertices()]) for p in poser_geom.TexPolygons()],
                                NP_PRECISION),
                tpolysets=NP.array([f_forcequad(tsets[p.Start():p.Start() + p.NumTexVertices()])
                                    for p in poser_geom.TexPolygons()], NP.int32),
                matindex=NP.array([p.MaterialIndex() for p in poser_geom.Polygons()], NP.int32),
                matnames=[m.Name() for m in poser_geom.Materials()]
        )




VedaDalsette ( ) posted Tue, 16 June 2020 at 9:29 AM
Online Now!

I''m no snakehead, and I'm not sure if this is even a good thing to do, but I'm always changing the shadow strength for lights, so I modified someone's script (can't remember whose). This script is useful to me, because, when there are a lot of lights, the displayed log tells me what I've changed already.

# Change Shadow Intensity of Selected Lights
#

import poser scene = poser.Scene() actor = scene.CurrentActor()

def doIt(): dialog = None dialog2 = None actor = scene.CurrentActor("GROUND") dialog = poser.DialogSimple.AskActor("Please select a light.") actor = scene.CurrentActor(dialog) if actor.IsLight(): print "n ",actor.Name() dialog2 = poser.DialogSimple.AskFloat("Type a value from 0 to 1.") if dialog2 == None: print "n Please type in a value from 0 to 1." doIt() else: if float(dialog2) < 0: print "n Please type in a value from 0 to 1." doIt() elif float(dialog2) > 1: print "n Please type in a value from 0 to 1." doIt() else: print "n You want ",dialog2," shadow intensity for ",actor.Name() actor.ParameterByCode(poser.kParmCodeDEPTHMAPSTRENGTH).SetValue(float(dialog2)) print "n Update done." scene.SelectActor(scene.Actor("GROUND")) another() else: print "n You didn't select a light." doIt()

def another(): message = "Select another light?" dialog = None dialog = poser.DialogSimple.YesNo(message) if dialog == 1: print "n Yes, another light." doIt() else: print "n No, no more lights." return

doIt()



W11,Intel i9-14900KF @ 3.20GHz, 64.0 GB RAM, 64-bit, GeForce GTX 4070 Ti SUPER, 16GB. 

Old lady hobbyist.

All visual art or fiction is "playing with dolls."


structure ( ) posted Sun, 19 July 2020 at 9:47 PM · edited Sun, 19 July 2020 at 10:01 PM
Forum Coordinator

Updated version of the above code

# -*- coding: utf-8 -*- 
# Change Shadow Intensity of Selected Lights

import poser
import wx
scene = poser.Scene()
title = "Shadow Intensity Editor"

def chooselights( title = "", prompt = "", OptionList = [], parent = None ):
    if OptionList == []: return False
    dialog = wx.MultiChoiceDialog( parent, prompt, title, OptionList )

    if dialog.ShowModal() == wx.ID_OK:
        selections = dialog.GetSelections()
        strings = [OptionList[x] for x in selections]
        if selections == []:
            selections = False
        return ( selections )

    else:
        return ( False )
    
    dialog.Destroy()

def gettextentry( title = "", message = "", parent = None ):

    TE_dialog = wx.TextEntryDialog( parent, message, title, "", style=wx.OK)
    TE_dialog.SetValue("")

    return TE_dialog.GetValue() if TE_dialog.ShowModal() == wx.ID_OK else False

def okcancel( title = "", alertmessage = "", okonly = False, parent = None ):

    if okonly:
        style = ( wx.OK|wx.ICON_INFORMATION|wx.STAY_ON_TOP )
    else:
        style = ( wx.OK|wx.CANCEL|wx.ICON_INFORMATION|wx.STAY_ON_TOP )      

    ok_dialog = wx.MessageDialog( parent, alertmessage, title, style )
    
    return True if ok_dialog.ShowModal() == wx.ID_OK else False

lights = []

for light in scene.Lights():
    lights.append( light.Name() )

lights = chooselights( title, "Please select which lights to edit.", lights )
if lights:
    try:
        value = float( gettextentry( title, "Please enter your value ( 0 - 1 )" ) )
    except:
        value = 0

    for light in lights:
        scene.Lights()[light].ParameterByCode( poser.kParmCodeDEPTHMAPSTRENGTH ).SetValue( value )

if you wish to edit each light individually, change the script to the following :


lights = []
for light in scene.Lights():
    lights.append( light.Name() )

lights = chooselights( title, "Please select which lights to edit.", lights )
if lights:
    for light in lights:
        try:
            value = float( gettextentry( title, "Please enter your value ( 0 - 1 )" ) )
        except:
            value = scene.Lights()[light].Value()
        scene.Lights()[light].ParameterByCode( poser.kParmCodeDEPTHMAPSTRENGTH ).SetValue( value )

Locked Out


structure ( ) posted Wed, 12 August 2020 at 8:28 AM · edited Wed, 12 August 2020 at 7:20 PM
Forum Coordinator

A simple lights class

class poserlights:
    def processlights( self, code = 0 ):
        if not isinstance( code, int):
            return

        lights = scene.Lights()
    
        if not code > 1:
            # LightsOnOff
            [light.SetLightOn(code) for light in lights]
        
        elif code == 2:
            # toggle lights
            [light.SetLightOn(not light.LightOn()) for light in lights]
    
        else:
            # Delete Lights
            [light.Delete() for light in lights]

        scene.DrawAll()

import poser
scene = poser.Scene()
l = poserlights()

# turn lights off
l.processlights(0)

# turn lights on
l.processlights(1)

# toggle lights
l.processlights(2)

# delete lights
l.processlights(3) (any number above 2)

Locked Out


structure ( ) posted Wed, 12 August 2020 at 7:16 PM · edited Mon, 25 October 2021 at 7:31 AM
Forum Coordinator

Dealing with figure IK

class IK:
    def SetIK( self, figure = None , status = 0 , parts = 2 ):
        # status    : 0 = off, 1 = on , 2 = toggle
        # setup parts dictionary (ikrange)
        ikrange =   {
                        0   :   (0,1),          # legs
                        1   :   (2,3),          # arms
                        2   :   (0,1,2,3),      # all
                        3   :   (0,None),       # left leg
                        4   :   (1,None),       # Right leg
                        5   :   (2,None),       # left arm
                        6   :   (3,None),       # right arm
                        7   :   (0,2),          # left leg + left arm
                        8   :   (1,3),          # right leg + right arm
                        9   :   (0,3),          # left leg + right arm
                        10  :   (1,2)           # right leg + left arm
                    }
        if figure:
            IkNames=figure.IkNames()
            if status==0 or status ==1:             # turn off / on
                [figure.SetIkStatus(ik,status) for ik in ikrange[parts] if not ik==None]
            elif status==2:                         # toggle
                [figure.SetIkStatus(ik,not figure.IkStatus(ik)) for ik in ikrange[parts] if not ik==None]
        else:
            return False

Locked Out


structure ( ) posted Wed, 12 August 2020 at 7:49 PM · edited Thu, 10 March 2022 at 8:06 AM
Forum Coordinator

Use a tuple as a dictionary key

theDict = { (0,1,2,3) : "This is a test" }
print(theDict[ tuple(range(0,4))])

which gives this output
This is a test

keys=theDict.keys()
test=(0,3)
for item in test:
    for key in keys:
        if item in key:
        print(theDict[tuple(key)])


which also gives this output
This is a test

Locked Out


structure ( ) posted Fri, 14 August 2020 at 12:35 PM · edited Thu, 10 March 2022 at 8:14 AM
Forum Coordinator

call a function using a string as a variable.

for i in range( 0, 5 ):
    FUNCTIONNAME = str( i )
    getattr(globals()['CLASSNAME'](), FUNCTIONNAME )( args )
example script


from __future__ import print_function
import inspect
functionlist = []

class stringclass:
    def stripstring( self, i ):
        i=str(i).split(",")[0]
        return i.translate(None, "()'")

class materialclass:
    def get_all_scene_materials( self, item = None ):
        print("You are in the {} function".format( item ) )
        return

    def get_item_materials( self, item = None ):
        print("You are in the {} function".format( item ) )
        return

for i in (inspect.getmembers(materialclass, predicate=inspect.ismethod ) ):
    i = stringclass().stripstring( i )
    functionlist.append( i )

for f in functionlist:
    getattr(globals()['materialclass'](), f )( f ) # the 2nd f can be any argument


output

You are in the get_all_scene_materials function

You are in the get_item_materials function

Locked Out


structure ( ) posted Sun, 23 August 2020 at 1:18 PM · edited Mon, 25 October 2021 at 1:03 PM
Forum Coordinator

create your UI with no stay_on_top style

use the following to make it stay on top - or cancel stay on top as you need

def set_style( self, event = None ):
    self.old_style = self.GetWindowStyle()

def stay_on_top( self, event=None ):
    self.SetWindowStyle(self.old_style | wx.STAY_ON_TOP)

def cancel_on_top( self, event = None ):
    self.SetWindowStyle(self.old_style)

Locked Out


structure ( ) posted Sat, 29 August 2020 at 2:34 PM · edited Thu, 10 March 2022 at 8:20 AM
Forum Coordinator
apply a material ( not a pose ) to an unparented prop

import os
import poser                                                # get poser
reset = False                                               # set reparent variable
scene = poser.Scene()                                       # define scene
actor = scene.CurrentActor()                                # get the actor

if len( actor.Materials() ) > 0:                            # make sure the actor has materials
    if actor.IsProp():                                      # is this actor a prop?
        if actor.Parent().Name() == "UNIVERSE":             # is this actor parented?
            actor.SetParent( scene.Actor("GROUND") )        # set actor parent
            reset = True                                    # inform script we need to reparent prop

    material = actor.Materials()[0]                         # get actors preview material
    material.LoadMaterialSet(
        os.path.join(poser.TempLocation(), "test.mt5" ))    # load material
    if reset:
        actor.SetParent( scene.Actor( "UNIVERSE") )         # if we need to reparent - do so

    scene.DrawAll()

Locked Out


structure ( ) posted Sun, 08 November 2020 at 10:23 AM · edited Mon, 25 October 2021 at 1:13 PM
Forum Coordinator
convert bytes to kb, mb. gb etc :

class conversions:
    def convert_bytes( self, size_bytes ):
        if size_bytes == 0:
            return "0B"
        size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
        i = int(math.floor(math.log(size_bytes, 1024)))
        p = math.pow(1024, i)
        s = round(size_bytes / p, 2)
        return "%s %s" % (s, size_name[i])

Locked Out


adp001 ( ) posted Sat, 05 December 2020 at 3:23 PM · edited Sat, 05 December 2020 at 3:24 PM

Or in short (and without the use of a library):

has_ext = lambda path: path.rfind(".") != -1

hasext("myown/directory/file")
# says: False
hasext("myown/directory/file.txt")
# says: True




adp001 ( ) posted Sat, 05 December 2020 at 3:57 PM

Or, to make a simplyfied version of what os.path.splitext() does (needs os imported because we need the path seperator):

hasext = lambda path: path[path.rfind(os.sep) if os.sep in path else 0:].rfind(".") != -1

P.s.: I love it fast and dirty ;)




adp001 ( ) posted Sat, 05 December 2020 at 4:37 PM · edited Sat, 05 December 2020 at 4:40 PM

In real life I assume no extension is more than 5 characters (not where it matters for my scripts). So I simply use:


if "." in path[-5:]...

or as a function:

hasext = lambda path: "." in path[-5:]

I assume this is the faster possible form and fine for 99.9% of cases a script has to handle files.




structure ( ) posted Tue, 08 December 2020 at 3:56 PM · edited Mon, 25 October 2021 at 6:39 AM
Forum Coordinator

adp001 posted at 3:55PM Tue, 08 December 2020 - #4406505

Or in short (and without the use of a library):

has_ext = lambda path: path.rfind(".") != -1

hasext("myown/directory/file")
# says: False
hasext("myown/directory/file.txt")
# says: True

this is awesome, I always forget about lambda, thanks.

Locked Out


adp001 ( ) posted Tue, 08 December 2020 at 8:21 PM

structure posted at 8:18PM Tue, 08 December 2020 - #4406737

this is awesome, I always forget about lambda, thanks.

Keep in mind that this version can give a false response if you have pathes with an "." in it. This is why I prefer "." in path[-5:].




structure ( ) posted Mon, 21 December 2020 at 6:37 AM · edited Mon, 25 October 2021 at 6:38 AM
Forum Coordinator

list the contents of a folder in date order - new to old or old to new ( dealers choice )

import platform
class file_times:
    def creation_date(self, path_to_file):
        """
        Try to get the date that a file was created, falling back to when it was
        last modified if that isn't possible.
        See http://stackoverflow.com/a/39501288/1709587 for explanation.
        """
        if platform.system() == 'Windows':
            timestamp = (os.path.getctime(path_to_file))
            return timestamp
        else:
            stat = os.stat(path_to_file)
            try:
                return stat.st_birthtime
            except AttributeError:
                # We're probably on Linux. No easy way to get creation dates here,
                # so we'll settle for when its content was last modified.
                return stat.st_mtime



Locked Out


structure ( ) posted Fri, 25 December 2020 at 9:13 AM · edited Wed, 18 May 2022 at 8:37 AM
Forum Coordinator

get Poser's install directory from the windows registry While this is actually mostly redundant
thanks to Poser's AppLocation() it does show how to access the registry to read keys / data.

import winreg as reg


class _REGISTRY:
    def _find_poser_win(self, version):
        poser = r"SOFTWARE\\Poser Software\\Poser\\Poser %d" % version
        with reg.OpenKey(reg.HKEY_LOCAL_MACHINE, poser) as key:
            if poser.endswith(str(version)) and key:
                return(reg.QueryValueEx(key, "InstallDir")[0])

# example code


installdirs = []
for version in (10, 11, 12):
    print(f"testing Poser {version}")
    try:
        installdir = _REGISTRY()._find_poser_win(version)
    except:
        installdir = "Not Installed"
    if not installdir in installdirs:
        installdirs.append(installdir)
    print(installdir)

Locked Out


structure ( ) posted Mon, 04 January 2021 at 8:58 AM · edited Mon, 25 October 2021 at 6:31 AM
Forum Coordinator

Check if a module exists before trying to import it.

from pkgutil import iter_modules


class basic_functions:
    def module_exists( self, module_name):
        return module_name in (name for loader, name, ispkg in iter_modules())

if basic_functions().module_exists( "poser" ):
    import poser
else:
    if basic_functions().module_exists( "POSER_FAKE"):
        import POSER_FAKE as poser

Locked Out


structure ( ) posted Mon, 25 October 2021 at 3:35 AM · edited Tue, 02 November 2021 at 5:42 AM
Forum Coordinator

store dictionary names in a list, and retrieve them as a printable string 

def varname(var):
    import inspect
    frame = inspect.currentframe()
    var_id = id(var)
    for name in frame.f_back.f_locals.keys():
        try:
            if id(eval(name)) == var_id:return(name)
        except:return var

cmra_data,char_data, face_data, hand_data = {}, {}, {}, {}
hair_data, lite_data, mtrl_data, pose_data = {}, {}, {}, {}
prop_data =  {}

alldicts = [cmra_data, char_data, face_data, hand_data,
            hair_data, lite_data, mtrl_data, pose_data,
            prop_data,]

count = 0
for dictionary in alldicts:
    print(f"Dictionary {count} Name : {varname(dictionary)}")
    count += 1

output : 
Dictionary 0 Name : cmra_data
Dictionary 1 Name : char_data
Dictionary 2 Name : face_data
Dictionary 3 Name : hand_data
Dictionary 4 Name : hair_data
Dictionary 5 Name : lite_data
Dictionary 6 Name : mtrl_data
Dictionary 7 Name : pose_data
Dictionary 8 Name : prop_data

This script allows you to store dictionary names as strings :
useful if you need to print the dictionary name for debugging
or just to let the user know which dictionary is being accessed.

** NOTE @ it does not work for :
    alldicts = [{} for _ in range(9)]
    since alldicts has no named dictionaries inside

For which; the output becomes :
Dictionary 0 Name : dictionary
Dictionary 1 Name : dictionary
Dictionary 2 Name : dictionary
Dictionary 3 Name : dictionary
Dictionary 4 Name : dictionary
Dictionary 5 Name : dictionary
Dictionary 6 Name : dictionary
Dictionary 7 Name : dictionary
Dictionary 8 Name : dictionary

Locked Out


structure ( ) posted Mon, 25 October 2021 at 6:24 AM · edited Tue, 26 October 2021 at 12:40 AM
Forum Coordinator

Find a word / phrase in any file without loading the file into memory; 

import mmap
import os


class Dialogs:
    def get_folder( self, start = "" ):
        style = wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON
        dialog = wx.DirDialog( None, 'Select a Folder ', start , style )
        return dialog.GetPath() if dialog.ShowModal() == wx.ID_OK else None

    def get_text( self, title = "", message = "" ):
        style = wx.ID_OK|wx.ID_CANCEL
        TE_dialog = wx.TextEntryDialog( None, message, title, "", style )
        TE_dialog.SetValue("")
        return TE_dialog.GetValue() if TE_dialog.ShowModal() == wx.ID_OK else None


class File_Ops:
    def find_in_files( self, root, listoffiles, thing_to_find ):
        found_in_files = False
        thing_to_find = bytes( thing_to_find, encoding = 'utf8' )
        for file in listoffiles:
            file = os.path.join(root, file)
            with open(file) as f:
                s = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
                if s.find( thing_to_find ) != -1:
                    print(f'{thing_to_find} found in {file}.')
                    found_in_files = True
                elif len(list_of_files) == 1 and s.find(thing_to_find) == -1:
                    print(f'{thing_to_find} not found in {file}.')
                else:
                    pass
        if not found_in_files:
            print(f'{thing_to_find} not found.')

title = "find in files"
root = Dialogs().get_folder()
list_of_files = os.listdir(root)
thing_to_find = Dialogs().Get_text(title, "Find What ?",  )
if root and list_of_files and thing_to_find:
    File_Ops().find_in_files(root, list_of_files, thing_to_find)

Locked Out


structure ( ) posted Tue, 26 October 2021 at 12:11 AM · edited Wed, 18 May 2022 at 9:01 AM
Forum Coordinator

get machine current ID and BIOS serial number

from subprocess import check_output
def get_details():
    current_machine_id = str(check_output('wmic csproduct get uuid'), 'utf-8').split('\n')[1].strip()
    current_machine_sn = str(check_output('wmic bios get serialnumber'), 'utf-8').split('\n')[1].strip()
    return current_machine_id, current_machine_sn

cid, csn = get_details()

Locked Out


structure ( ) posted Tue, 26 October 2021 at 2:24 AM · edited Thu, 28 October 2021 at 8:07 AM
Forum Coordinator

sort dictionary by value

from operator import itemgetter

def pTypes():
    return{ ('.pz3', '.pzz') : 'Scene',
            ('.pp2', '.ppz') : 'Prop',
            ('.cr2', '.crz') : 'Character',
            ('.pz2', '.p2z') : 'Pose',
            ('.hr2', '.hrz') : 'Hair',
            ('.fc2', '.fcz') : 'Expression',
            ('.hd2', '.hdz') : 'Hand',
            ('.lt2', '.ltz') : 'Light',
            ('.cm2', '.cmz') : 'Camera',
            ('.mt5', '.mz5') : 'Material',
            ('.mc6', '.mcz') : 'Material',
            ('.obj', '.obz') : 'Geometry',}

marklist= sorted(pTypes().items(), key=itemgetter(1))
pTypes=dict(marklist)
for item in pTypes:
    print(item, pTypes[item])


output:
('.cm2', '.cmz') Camera
('.cr2', '.crz') Character
('.fc2', '.fcz') Expression
('.obj', '.obz') Geometry
('.hr2', '.hrz') Hair
('.hd2', '.hdz') Hand
('.lt2', '.ltz') Light
('.mc6', '.mcz') Material
('.mt5', '.mz5') Material
('.pz2', '.p2z') Pose
('.pp2', '.ppz') Prop
('.pz3', '.pzz') Scene

Locked Out


structure ( ) posted Tue, 26 October 2021 at 2:11 PM · edited Tue, 26 October 2021 at 2:13 PM
Forum Coordinator

simple beep function

import sys

class OS_BEEP:
    def beep_macos(self, **kwargs):
        from AppKit import NSBeep
        NSBeep()
   
    def beep_windows(self, **kwargs):
        import winsound
        winsound.MessageBeep()

if sys.platform == "win32":
    OS_BEEP().beep_windows()
else:
    OS_BEEP().beep_macos()

Locked Out


structure ( ) posted Tue, 02 November 2021 at 12:27 PM · edited Tue, 02 November 2021 at 12:32 PM
Forum Coordinator
get libraries (outside of poser) : 

import os
import xml.etree.cElementTree as ElementTree

def PrefsLocation(version):
    if version > 10:
        return os.path.join(os.environ["APPDATA"], "poser", str(Version()))
    else:
        return os.path.join(os.environ["APPDATA"], "poser pro", str(Version()))

def get_libraries( xml_file ):
    try:
        tree = ElementTree.parse(xml_file)
    except Exception as inst:
        print( "Unexpected error opening %s: %s" % (xml_file, inst) )
        return None
   
    libraries = []
   
    if os.path.exists(xml_file):
        root=tree.getroot()
        for child in root:
            if child.tag=='ContentFolder':
                libraries.append(str(child.attrib['folder']))
   
    return libraries

def Version(): # edit to suit your needs
    # return 10
    return 12

def get_libraries( xml_file ):
    try:
        tree = ElementTree.parse(xml_file)
    except Exception as inst:
        print( "Unexpected error opening %s: %s" % (xml_file, inst) )
        return None
    libraries = []
   
    if os.path.exists(xml_file):
        root=tree.getroot()
        for child in root:
            if child.tag=='ContentFolder':
                libraries.append(str(child.attrib['folder']))
   
    return libraries

PrefsLocation = PrefsLocation(Version())
PrefsFile = "LibraryPrefs.xml"
xml_file = os.path.join(PrefsLocation, PrefsFile)
libraries = get_libraries( xml_file)

for library in libraries:
    print(library)

Locked Out


adp001 ( ) posted Tue, 02 November 2021 at 3:50 PM

A shorter and less complicated version:


import os
import re

def get_library_pathes():
    version = int(poser.Version().split(".")[0])
    fname = os.path.join(os.environ["APPDATA"],
                         "Poser" if version < 11 else "Poser Pro", str(version),
                         "LibraryPrefs.xml")
    re_libs = re.compile(r"<ContentFolder.*?folder=\"([^\"]+)\"")
    with open(fname, "r") as fh:
        for line in fh:
            res = re.search(re_libs, line)
            if res:
                yield res.group(1)


if __name__ == "__main__":
    for entry in get_library_pathes():
        print(entry)




adp001 ( ) posted Wed, 03 November 2021 at 2:31 AM · edited Wed, 03 November 2021 at 2:51 AM

Not so seldom we have situations in which an occurring error is tollerable. Typically we wrap such a situation in a try/except clause.

But this can also be done differently, if we use an appropriate class:


class objectdef __init__selfpass

def __enter__selfreturn self

def __exit__self, , , return True


Now we can write:


with ignore_error():
actor = poser.Scene().Actor("not existing actor")

without causing an error.

Note that the entire block after "ignore_error" is ignored in case of an error. Like the part that follows a "try".




adp001 ( ) posted Wed, 03 November 2021 at 2:44 AM

A slightly extended version prevents only allowed exceptions:


class ignore_error(object):
def __init__(self, *args):
self.tolerable = args

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
return exc_type in self.tolerable if len(self.tolerable) else True


with ignore_error(NameError, poser.error):
actor = poser.Scene().Actor("not existing actor")

(The construct is called "Context Manager", by the way).




adp001 ( ) posted Wed, 03 November 2021 at 2:49 AM

As you can see above, the editor still doesn't work properly. The indentations are completely off when they are displayed. When I bring the text back into the editor, it looks completely right again.

Here again inserted as standard text:


class ignore_error(object):
    def __init__(self, *args):
        self.tolerable = args

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        return exc_type in self.tolerable if len(self.tolerable) else True


with ignore_error(NameError, poser.error):
    actor = poser.Scene().Actor("not existing actor")






structure ( ) posted Wed, 03 November 2021 at 2:59 AM · edited Wed, 03 November 2021 at 3:05 AM
Forum Coordinator

adp001 posted at 3:50 PM Tue, 2 November 2021 - #4429791

A shorter and less complicated version:


import os
import re

def get_library_pathes():
    version = int(poser.Version().split(".")[0])
    fname = os.path.join(os.environ["APPDATA"],
                         "Poser" if version < 11 else "Poser Pro", str(version),
                         "LibraryPrefs.xml")
    re_libs = re.compile(r"<ContentFolder.*?folder=\"([^\"]+)\"")
    with open(fname, "r") as fh:
        for line in fh:
            res = re.search(re_libs, line)
            if res:
                yield res.group(1)


if __name__ == "__main__":
    for entry in get_library_pathes():
        print(entry)

this line : 
    version = int(poser.Version().split(".")[0]) can be better written thus     
version = int(float(poser.Version())) and requires that poser or perhaps POSER_FAKE be imported.
better to include a dummy version function 
def Version():
    return 12 also this construct : 
    fname = os.path.join(os.environ["APPDATA"],
                         "Poser" if version < 11 else "Poser Pro", str(version),
                         "LibraryPrefs.xml") 

does not appear to working - I have set version to 12 - but it keeps using poser pro as the folder name .

    poserversion =  "Poser" if Version() < 11 else "Poser Pro"
    print(poserversion, Version()<11, Version())

output :
Poser Pro False 12

 


Locked Out


structure ( ) posted Wed, 03 November 2021 at 3:02 AM
Forum Coordinator

adp001 posted at 2:49 AM Wed, 3 November 2021 - #4429830

As you can see above, the editor still doesn't work properly. The indentations are completely off when they are displayed. When I bring the text back into the editor, it looks completely right again.

Here again inserted as standard text:


class ignore_error(object):
    def __init__(self, *args):
        self.tolerable = args

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        return exc_type in self.tolerable if len(self.tolerable) else True


with ignore_error(NameError, poser.error):
    actor = poser.Scene().Actor("not existing actor")



looking forward to trying this out


Locked Out


adp001 ( ) posted Wed, 03 November 2021 at 3:09 AM
version = int(poser.Version().split(".")[0]) if globals().get("poser", False) else 12

Should do the trick.




  • 1
  • 2

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.