Page 1 of 2 12 LastLast
Results 1 to 15 of 26

Thread: Code Snippets (aka: "How to...")

  1. #1
    Red Mage Celshader's Avatar
    Join Date
    Feb 2003
    Location
    Burbank, California
    Posts
    1,817

    Code Snippets (aka: "How to...")

    If it helps anyone, feel free to use these functions in your Python scripts...

    Code:
    ## the following returns a string containing
    ## the filepath to the content directory.
    
    def getContentDir():
        return lwsdk.LWDirInfoFunc('Content')
    Code:
    ## Given a string ("p") containing a file path to an image, the following
    ## attempts to load that image into the Image Editor. It then
    ## returns the name of that image and the image ID.
    
    def loadImage(p):
        IM = lwsdk.LWImageList()
        id = IM.load(p)
        name = IM.name(id)
        return name, id
    Code:
    ## this returns the FPS of the scene.
    
    def getFPS():
        info = lwsdk.LWSceneInfo()
        return info.framesPerSecond
    Code:
    ## these return the Preview Start and Preview End frames.
    
    def getPreviewStart():
        info = lwsdk.LWInterfaceInfo()
        return info.previewStart
    
    def getPreviewEnd():
        info = lwsdk.LWInterfaceInfo()
        return info.previewEnd
    Jen's 3D -- LightWave stuff.
    Jen's 2D -- my comic book.

    Python is my smashing board. LightWave is my S.M.A.K.

  2. #2
    Member
    Join Date
    Oct 2003
    Location
    Orlando, FL
    Posts
    4,146
    Thanks, Jen!

  3. #3
    Red Mage Celshader's Avatar
    Join Date
    Feb 2003
    Location
    Burbank, California
    Posts
    1,817

    Smile

    Quote Originally Posted by Dexter2999 View Post
    Thanks, Jen!


    Here's another set of functions that go together:

    Code:
    ## returns the item ID of a pyObj.
    
    def getObjID(pyObj):
        return lwsdk.itemid_to_str(pyObj)
    
    
    
    ## returns a list of pyObj representing the selected items in the scene.
    
    def getSelectedItems():
        interface_info = lwsdk.LWInterfaceInfo()
        return interface_info.selected_items()
    
    
    
    ## given a list of pyObjs, this function returns a list of IDs. It relies
    ## on the "getObjID" function above.
    
    def getIDs(pyObjs):
        li = []
        for pyObj in pyObjs:
            id = getObjID(pyObj)
            li.append(id)
        return li
    
    
           
    ## This function relies on three of the above functions to return
    ## a list of selected item IDs. It needs "getObjID", "getIDs" and
    ## "getSelectedItems"
     
    def getSelectedItemsIDs():    
        selected_items = getSelectedItems()
        objIDs = getIDs(selected_items)
        return objIDs
    
    
    
    ## This function returns the pyObj representing the current item.
    ## It relies on the "getSelectedItems" function, which is defined above.
    
    def getCurrentItem():
        return getSelectedItems()[0]
    
    
    
    ## This function returns the ID of the current item and relies on three
    ## of the above functions: "getCurrentItem", "getSelectedItems"
    ## and "getObjID"
    
    def getCurrentItemID():
        obj = getCurrentItem()
        return getObjID(obj)
    Jen's 3D -- LightWave stuff.
    Jen's 2D -- my comic book.

    Python is my smashing board. LightWave is my S.M.A.K.

  4. #4
    Red Mage Celshader's Avatar
    Join Date
    Feb 2003
    Location
    Burbank, California
    Posts
    1,817
    I prefer iterating over lists and dictionaries instead of while loops in Python, so these functions return dictionaries of specific item types in Layout:

    Code:
    ## returns a dictionary of objects. The keys contain the
    ## ID numbers, while the items contain the pyObjs themselves.
    
    def getObjects():
        d = {}
        info = lwsdk.LWItemInfo()
        item = info.first(lwsdk.LWI_OBJECT, None)
        while(item):
            id = getObjID(item)
            d[id] = {}
            d[id] = item
            item = info.next(item)
        return d
    Code:
    ## returns a dictionary of cameras. The keys contain the
    ## ID numbers, while the items contain the pyObjs themselves.
    
    def getCameras():
        d = {}
        info = lwsdk.LWItemInfo()
        item = info.first(lwsdk.LWI_CAMERA, None)
        while(item):
            id = getObjID(item)
            d[id] = {}
            d[id] = item
            item = info.next(item)
        return d
    Code:
    ## returns a dictionary of lights. The keys contain the
    ## ID numbers, while the items contain the pyObjs themselves.
    
    def getLights():
        d = {}
        info = lwsdk.LWItemInfo()
        item = info.first(lwsdk.LWI_LIGHT, None)
        while(item):
            id = getObjID(item)
            d[id] = {}
            d[id] = item
            item = info.next(item)
        return d
    Jen's 3D -- LightWave stuff.
    Jen's 2D -- my comic book.

    Python is my smashing board. LightWave is my S.M.A.K.

  5. #5
    Kamehameha Chameleon BigHache's Avatar
    Join Date
    Sep 2006
    Location
    Future Past Life
    Posts
    1,899
    Good stuff! Thank you!

  6. #6
    automator of tasks xchrisx's Avatar
    Join Date
    Jul 2003
    Location
    Nevada
    Posts
    593
    Blog Entries
    6
    Just started to get into python coding for LW and this stuff helps a bunch. Thanks Jen.
    My Lscript Collection | LinkedIn
    3D Generalist IGT

  7. #7
    Red Mage Celshader's Avatar
    Join Date
    Feb 2003
    Location
    Burbank, California
    Posts
    1,817

    Cool. I think I found a redundant line of code...

    Glad to help. Glancing at my code for getObjects/getCameras/getLights reveals a line that should probably be deleted.

    This:

    Code:
            d[id] = {}
            d[id] = item
    ...means the exact same thing as this:


    Code:
            d[id] = item
    There's no point in assigning an empty dictionary to a dictionary entry if I'm just going to replace it with a pyObj in the next line. It must have been a leftover from an earlier draft of the code.
    Jen's 3D -- LightWave stuff.
    Jen's 2D -- my comic book.

    Python is my smashing board. LightWave is my S.M.A.K.

  8. #8
    Red Mage Celshader's Avatar
    Join Date
    Feb 2003
    Location
    Burbank, California
    Posts
    1,817
    Two more "get directory" functions:

    Code:
    ## configs directory
    
    def getConfigsDir():
        return lwsdk.LWDirInfoFunc('Settings')
    
    
    
    ## temporary path directory
    
    def getTempDir():
        return lwsdk.LWDirInfoFunc('Temp')
    Jen's 3D -- LightWave stuff.
    Jen's 2D -- my comic book.

    Python is my smashing board. LightWave is my S.M.A.K.

  9. #9
    Red Mage Celshader's Avatar
    Join Date
    Feb 2003
    Location
    Burbank, California
    Posts
    1,817
    Typing in:

    Code:
    help(lwsdk)
    ...in PCore Console reveals a huge chunk of information which can be saved to a text file using "Save Log." This information includes these variables:

    Code:
        LWFTYPE_ANIMATION = 'Animations'
        LWFTYPE_CONTENT = 'Content'
        LWFTYPE_DYNAMICS = 'Dynamics'
        LWFTYPE_ENVELOPE = 'Envelopes'
        LWFTYPE_IMAGE = 'Images'
        LWFTYPE_INSTALL = 'Install'
        LWFTYPE_LIGHTS = 'Lights'
        LWFTYPE_MOTION = 'Motions'
        LWFTYPE_NODES = 'Nodes'
        LWFTYPE_OBJECT = 'Objects'
        LWFTYPE_PLUGIN = 'Plug-ins'
        LWFTYPE_PREVIEW = 'Previews'
        LWFTYPE_PSFONT = 'PSFonts'
        LWFTYPE_RADIOSITY = 'Radiosity'
        LWFTYPE_RIGS = 'Rigs'
        LWFTYPE_SCENE = 'Scenes'
        LWFTYPE_SETTING = 'Settings'
        LWFTYPE_SOUNDS = 'Sounds'
        LWFTYPE_SURFACE = 'Surfaces'
        LWFTYPE_VERTCACHE = 'VertCache'
    It looks like these variables and their values are what artists would use to get the directory paths they want using lwsdk.LWDirInfoFunc(). I've written code snippets above for getting the content directory, configs directory and temp path. Using the above information, here's a code snippet for getting the location of LWSN.exe:

    Code:
    import lwsdk
    import os
    
    def getLWSN():
        return os.path.join( lwsdk.LWDirInfoFunc('Install'), "lwsn.exe" )
    An alternative that uses the variable name for the same information:

    Code:
    import lwsdk
    import os
    
    def getLWSN():
        return os.path.join( lwsdk.LWDirInfoFunc(LWFTYPE_INSTALL), "lwsn.exe" )
    Jen's 3D -- LightWave stuff.
    Jen's 2D -- my comic book.

    Python is my smashing board. LightWave is my S.M.A.K.

  10. #10
    Newbie Member skarloc's Avatar
    Join Date
    Apr 2008
    Location
    France
    Posts
    50
    Thanks awfully for these - they helped me (along with the LWPy videos on YouTube) to do 2 scripts. My first excursion into LW Scripting (and Python) and getting my head around (a) the Python syntax and (b) the LW data model was an interesting challenge.

    For those interested, the 2 scripts are similar; one aligns the positions of objects in Layout with the last object selected (like the "Align" options, except it does all 3 at the same time, avoiding that annoying problem of the selection being inverted, meaning you have to reselect the items each time you want to align them). The other one does the same, but also sets the rotation to be the same as the last object (a kind of one-frame parenting).

    If anyone wants them (even for study for your own scripts), leave me a message.

    P.S. I hope these functions didn't existe elsewhere...

    [Edit] Thanks also to GregMalick, for his channel code which put me on the right track for getting the current position. Thanks also to those who I haven't mentioned as well.
    Last edited by skarloc; 07-19-2012 at 10:02 AM.

  11. #11
    Red Mage Celshader's Avatar
    Join Date
    Feb 2003
    Location
    Burbank, California
    Posts
    1,817

    How to get SaveRGB status (thanks, Bob Hood!!!!!!)

    Glad to help, skarloc!

    Here's another code snippet that a professional kindly handed me today:

    Code:
    ## is SaveRGB turned on?
    
    def getSaveRGB():
    	return (lwsdk.LWSceneInfo().renderOpts & lwsdk.LWROPT_SAVERGB) != 0
    This status used the LWROPT_SAVERGB flag to reveal the status of SaveRGB. Typing in help(lwsdk) on the PCore Console reveals these other render flags:

    Code:
        LWROPT_BLURBACKGROUND = 1048576
        LWROPT_CACHERADIOSITY = 67108864
        LWROPT_CAUSTICS = 65536
        LWROPT_CAUSTICSCACHE = 536870912
        LWROPT_DEPTHOFFIELD = 64
        LWROPT_DIRECTIONALRAYS = 16777216
        LWROPT_ENHANCEDAA = 512
        LWROPT_EVENFIELDS = 16
        LWROPT_EYECAMERA = 1073741824
        LWROPT_FIELDS = 8
        LWROPT_INTERPOLATED = 524288
        LWROPT_LIMITDYNAMICRANGE = 33554432
        LWROPT_LIMITEDREGION = 128
        LWROPT_MOTIONBLUR = 32
        LWROPT_OCCLUSION = 131072
        LWROPT_PARTICLEBLUR = 256
        LWROPT_RADIOSITY = 32768
        LWROPT_REFLECTTRACE = 2
        LWROPT_REFRACTTRACE = 4
        LWROPT_RENDERLINES = 262144
        LWROPT_RTTRANSPARENCIES = 16384
        LWROPT_SAVEALPHA = 4096
        LWROPT_SAVEANIM = 1024
        LWROPT_SAVERGB = 2048
        LWROPT_SHADOWTRACE = 1
        LWROPT_UNPREMULTIPLIEDALPHA = -2147483648
        LWROPT_USEAMBIENT = 8388608
        LWROPT_USEBEHINDTEST = 268435456
        LWROPT_USEGRADIENTS = 134217728
        LWROPT_USETRANSPARENCY = 2097152
        LWROPT_VOLUMETRICRADIOSITY = 4194304
        LWROPT_ZBUFFERAA = 8192
    This is only for querying the status of render options and not setting them. Setting the status of render options involves stock LightWave SDK Commands. In a Generic script, I would do this within the Generic class to turn on SaveRGB:

    Code:
    class Example(lwsdk.IGeneric):
        def __init__(self, context):                        
            super(Example, self).__init__()
            
        def process(self, ga):
            ## make sure SaveRGB is turned on.
            ga.evaluate(ga.data, "SaveRGB 1")
    "SaveRGB 1" is an example of a Command. A fantastic resource for Commands is LScript Commander in Layout. Launch LScript Commander and start poking around Layout. Half of the things you do will pop up in LScript Commander as proper LightWave SDK Commands.

    For example, turning on SaveRGB would show up in LScript Commander as "SaveRGB 1" -- and that's what you would use to turn on SaveRGB in your Python script. That's also how the instruction would appear in the text of the *.lws file -- which seems more and more to be a collection of LightWave SDK Commands.
    Last edited by Celshader; 07-19-2012 at 09:09 PM.
    Jen's 3D -- LightWave stuff.
    Jen's 2D -- my comic book.

    Python is my smashing board. LightWave is my S.M.A.K.

  12. #12
    Red Mage Celshader's Avatar
    Join Date
    Feb 2003
    Location
    Burbank, California
    Posts
    1,817

    Lightbulb A cross-platform approach to getLWSN()

    A Mac user informed me that the LWSN program is just called "lwsn" on the Mac instead of "lwsn.exe." With that in mind, here's a cross-platform approach to getting the path to LWSN:

    Code:
    import lwsdk
    import os
    import platform
    
    def getLWSN():
        test = platform.platform()
        if test.startswith("Windows"):
            lwsn = "lwsn.exe"
        else:
            lwsn = "lwsn"
        return os.path.join( lwsdk.LWDirInfoFunc(LWFTYPE_INSTALL), lwsn )
    Jen's 3D -- LightWave stuff.
    Jen's 2D -- my comic book.

    Python is my smashing board. LightWave is my S.M.A.K.

  13. #13
    Newbie Member skarloc's Avatar
    Join Date
    Apr 2008
    Location
    France
    Posts
    50
    Here are a few lines of code I use to ensure that Parent In Place is correct :

    1) Before the process function :

    Code:
        def setPIP(self, state):
            if (self._cur_pip != state):
                lwsdk.command("ParentInPlace")
                self._cur_pip = state
    At the start of the process function :
    Code:
            init_pip = ((lwsdk.LWInterfaceInfo().generalFlags & lwsdk.LWGENF_PARENTINPLACE) == lwsdk.LWGENF_PARENTINPLACE)
            self._cur_pip = init_pip
    When I need to set the PIP :
    Code:
                self.setPIP(False)
                self.setPIP(True)
    On quitting the process function :
    Code:
            self.setPIP(init_pip)
    That way, I don't need to keep track of what the PIP is (with what I'm doing, I need to change it often).

  14. #14
    Red Mage Celshader's Avatar
    Join Date
    Feb 2003
    Location
    Burbank, California
    Posts
    1,817

    Thanks, skarloc!!!!

    skarloc, thank you so much for that last post. Until you wrote that, I did not know one could execute commands just by writing:

    Code:
    lwsdk.command(<COMMAND>)
    This is a lot less cumbersome than the ga.evaluate(ga.data, <COMMAND>) method I was using in my scripts.

    Jen's 3D -- LightWave stuff.
    Jen's 2D -- my comic book.

    Python is my smashing board. LightWave is my S.M.A.K.

  15. #15
    Newbie Member skarloc's Avatar
    Join Date
    Apr 2008
    Location
    France
    Posts
    50

    Smile

    No problem - To be honest, I've never used that method (but I've seen it written - and you're right, it's a bit cumbersome).

    Speaking of reducing cumbersonness, I've done a large number of wrappers for the functions so as to make the code more readable and homogeneous. For example :

    Code:
                lwsdk.command("Position %f %f %f" % (fb_x, fb_y, fb_z))
                lwsdk.command("Rotation %f %f %f" % (fb_h, fb_p, fb_b))
                if not autokey_is_on:
                    lwsdk.command("CreateKey %f" % current_time)
    I've replaced with :
    Code:
                self.setPositionAndRotation(fb_x,fb_y,fb_z,fb_h,fb_p,fb_b,current_time)
    where setPositionAndRotation is defined :

    Code:
        def setPositionAndRotation(self, x, y, z, h, p, b, cur_time):
            lwsdk.command("Position %f %f %f" % (x, y, z))
            lwsdk.command("Rotation %f %f %f" % (h, p, b))
            if not self._autokey_on:
                lwsdk.command("CreateKey %f" % cur_time)
    This means (obviously) that in my main body, I've got 1 line of code and not 4. Also, I'm not worried about forgetting the autokey bit.

    FYO, in order to read the position and rotation of a given object at a given time (which may or not be a frame) :

    Code:
        def getPositionAndRotation(self, object, cur_time):
            # Note : this returns degrees - hence the "* 57.2957795"
            groupID = lwsdk.LWItemInfo().chanGroup( object )
            chanID = lwsdk.LWChannelInfo().nextChannel(groupID, None)
            (x,y,z,h,p,b) = (0.0,0.0,0.0,0.0,0.0,0.0)
            while chanID:
                channelName = lwsdk.LWChannelInfo().channelName(chanID)
                if channelName == "Position.X":
                    x = lwsdk.LWChannelInfo().channelEvaluate(chanID, cur_time)
                elif channelName == "Position.Y":
                    y = lwsdk.LWChannelInfo().channelEvaluate(chanID, cur_time)
                elif channelName == "Position.Z":
                    z = lwsdk.LWChannelInfo().channelEvaluate(chanID, cur_time)
                elif channelName == "Rotation.H":
                    h = lwsdk.LWChannelInfo().channelEvaluate(chanID, cur_time) * 57.2957795
                elif channelName == "Rotation.P":
                    p = lwsdk.LWChannelInfo().channelEvaluate(chanID, cur_time) * 57.2957795
                elif channelName == "Rotation.B":
                    b = lwsdk.LWChannelInfo().channelEvaluate(chanID, cur_time) * 57.2957795
                # else - we don't care !
                chanID = lwsdk.LWChannelInfo().nextChannel(groupID, chanID)
            return (x,y,z,h,p,b)
    And to use it :

    Code:
            (fb_x,fb_y,fb_z,fb_h,fb_p,fb_b) = self.getPositionAndRotation(temp_obj,startTime)
    Last edited by skarloc; 07-20-2012 at 05:54 PM. Reason: Because I'm worth it.

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •