Results 1 to 10 of 10

Thread: Python script as Channel Modifier: how often/when evaluated?

  1. #1
    Axes grinder- Dongle #99
    Join Date
    Jul 2003
    Location
    Seattle
    Posts
    14,726

    Python script as Channel Modifier: how often/when evaluated?

    When a python script is a CHANNEL MODIFIER, how often and when is it evaluated?
    They only call it 'class warfare' when we fight back.
    Praise to Buddha! #resist
    Chard's Credo-"Documentation is PART of the Interface"
    Film the cops. Always FILM THE COPS. Use this app.

  2. #2
    Axes grinder- Dongle #99
    Join Date
    Jul 2003
    Location
    Seattle
    Posts
    14,726

    Question Baffling: number of times a script is evaluated

    In an effort to determine this beyond the documentation's "evaluated at every timestep" (paraphrase), I inserted a :
    Code:
    		lwsdk.LWPCoreConsole().show()
    		print(time.time())
    into Bob Hood's noisy_channel.py in the section that defines the evaluate function. (I also imported the Time library.) Originally I just printed "evaluated" out, but thought a timestamp might be handy.

    I applied the altered script to the X channel of a null in an otherwise new Scene, with a total of 3 items (null, Cam, Light). The interesting outcome is:
    1. When first added to the channel, the console window immediately fills up, to, I believe, its max lines capacity.
    2. if you hit CLEAR LOG, and then frame forward, it adds 14 lines of output to the console.


    In a previous scene with MORE items, the script only added TEN lines of output to the console. iow, FEWER lines of output with more items. And 14 seems a curious quantity.

    Soooooo..... no clue as to why these two things occur that way.

    (For convenience I include the code below: )
    Code:
    #! /usr/bin/env python
    # -*- Mode: Python -*-
    # -*- coding: ascii -*-
    
    """
    This is a LightWave Channel Filter plug-in based on the LWSDK sample.
    """
    
    import sys
    import lwsdk
    import time
    
    __author__     = "Bob Hood+JEC"
    __date__       = "Sep 28, 2015"
    __copyright__  = "Copyright (C) 2011 NewTek, Inc."
    __version__    = "0.1"
    __maintainer__ = "jec"
    __email__      = "[email protected]"
    __status__     = "Example"
    __lwver__      = "11"
    
    RESOURCE = '\04(k:"%s" c:LWPy)'
    
    class noisy_channel(lwsdk.IChannel):
        def __init__(self, context):
            super(noisy_channel, self).__init__()
    
            self._channelid = context
    
            self._offset = 0.0
            self._speed = 1.0
            self._scale = 1.0
            self._phase = 0.0
    
        # LWInterfaceFuncs ------------------------------------
        def inter_ui(self):
            ui = lwsdk.LWPanels()
            panel = ui.create(RESOURCE % 'Noisy Channel')
            panel.setw(150)
    
            offset_control = panel.float_ctl(RESOURCE % 'Offset')
            offset_control.set_float(self._offset)
    
            speed_control = panel.float_ctl(RESOURCE % 'Speed')
            speed_control.set_float(self._speed)
    
            scale_control = panel.float_ctl(RESOURCE % 'Scale')
            scale_control.set_float(self._scale)
    
            phase_control = panel.float_ctl(RESOURCE % 'Phase')
            phase_control.set_float(self._phase)
    
            self._controls = [offset_control, speed_control, scale_control, phase_control]
            panel.align_controls_vertical(self._controls)
            #panel.size_to_layout(5, 5)
    
            if panel.open(lwsdk.PANF_BLOCKING | lwsdk.PANF_CANCEL):
                self._offset = offset_control.get_float()
                self._speed = speed_control.get_float()
                self._scale = scale_control.get_float()
                self._phase = phase_control.get_float()
    
            ui.destroy(panel)
    
            return lwsdk.AFUNC_OK
    
        # LWChannel -------------------------------------------
        def flags(self):
            return 0
    
        def evaluate(self, ca):
    		t = ca.time * self._speed
    
    		V = lwsdk.Vector()
    		V.x = 10 * t
    		V.y = self._phase
    		V.z = 20
    
    		# LWTextureFuncs is a complex mess, and is not completely exported for
    		# Python usage.  Only simple function calls and data members can be
    		# accessed successfully. at this time.
    
    		val = lwsdk.LWTextureFuncs().noise(V)
    		val *= self._scale
    		val += self._offset
    		val += ca.value
    
    		ca.setChannel(ca.chan, val)
    
    		lwsdk.LWPCoreConsole().show()
    		print(time.time())
    	
    
    
    
    
        # LWInstanceFuncs -------------------------------------
        def inst_load(self, state):
            result, value = state.lwload_fp(1)
            self._offset = value
    
            result, value = state.lwload_fp(1)
            self._speed = value
    
            result, value = state.lwload_fp(1)
            self._scale = value
    
            result, value = state.lwload_fp(1)
            self._phase = value
    
            return None     # LWError
    
        def inst_save(self, state):
            state.lwsave_fp(self._offset)
            state.lwsave_fp(self._speed)
            state.lwsave_fp(self._scale)
            state.lwsave_fp(self._phase)
    
            return None     # LWError
    
        def inst_copy(self, source):
            self._offset = source._offset
            self._speed = source._speed
            self._scale = source._scale
            self._phase = source._phase
    
            return None     # LWError
    
        def inst_descln(self):
            return "%s (%s: %.2f %s %2f)" % (RESOURCE % 'Noisy Channel', RESOURCE % 'Scale', self._scale, RESOURCE % 'Speed', self._speed)
    
        # LWItemFuncs  ----------------------------------------
        def item_changeID(self, itemid_list):
            # we have no dependency on any item ids, so we pass
            pass
    
    ServerTagInfo = [
                        ( "Python Noisy Channel-JEC", lwsdk.SRVTAG_USERNAME | lwsdk.LANGID_USENGLISH ),
                        ( "Noisy Channel-JEC", lwsdk.SRVTAG_BUTTONNAME | lwsdk.LANGID_USENGLISH ),
                    ]
    
    ServerRecord = { lwsdk.ChannelFactory("LW_PyNoisyChannel-JEC", noisy_channel) : ServerTagInfo }
    They only call it 'class warfare' when we fight back.
    Praise to Buddha! #resist
    Chard's Credo-"Documentation is PART of the Interface"
    Film the cops. Always FILM THE COPS. Use this app.

  3. #3
    Axes grinder- Dongle #99
    Join Date
    Jul 2003
    Location
    Seattle
    Posts
    14,726
    Here's a screengrab after two frames of a render. In THIS case (not just jogging the timeline), the Channel Modifier seems to get called twice per frame.

    Click image for larger version. 

Name:	cm.jpg 
Views:	119 
Size:	54.2 KB 
ID:	130015
    They only call it 'class warfare' when we fight back.
    Praise to Buddha! #resist
    Chard's Credo-"Documentation is PART of the Interface"
    Film the cops. Always FILM THE COPS. Use this app.

  4. #4
    That's interesting, I wonder why it does it twice.

  5. #5
    Axes grinder- Dongle #99
    Join Date
    Jul 2003
    Location
    Seattle
    Posts
    14,726
    Twice seems quite restrained, contrasted with the 1000 or so when you activate the script.

    Or the 14 when you frame forward once.
    They only call it 'class warfare' when we fight back.
    Praise to Buddha! #resist
    Chard's Credo-"Documentation is PART of the Interface"
    Film the cops. Always FILM THE COPS. Use this app.

  6. #6
    Maybe there are multiple event calls happening?
    My opinions and comments do not represent those of my employer.
    www.ernestpchan.com
    www.zazzle.com/gopuggo

  7. #7
    Axes grinder- Dongle #99
    Join Date
    Jul 2003
    Location
    Seattle
    Posts
    14,726
    Quote Originally Posted by ernpchan View Post
    Maybe there are multiple event calls happening?
    do you mean "added by the user" or "in the natural course of updating the frame"?

    I was adding this to a New Scene, so there were no other plugins/scripts running.
    They only call it 'class warfare' when we fight back.
    Praise to Buddha! #resist
    Chard's Credo-"Documentation is PART of the Interface"
    Film the cops. Always FILM THE COPS. Use this app.

  8. #8
    Quote Originally Posted by jeric_synergy View Post
    do you mean "added by the user" or "in the natural course of updating the frame"?
    My guess would be during updating of the frame but this is all just a guess by me. We're seeing multiple print statement for each scrub. But I'm just speculating. I don't know enough about that stuff so don't look to me for any valuable information.
    My opinions and comments do not represent those of my employer.
    www.ernestpchan.com
    www.zazzle.com/gopuggo

  9. #9
    Axes grinder- Dongle #99
    Join Date
    Jul 2003
    Location
    Seattle
    Posts
    14,726
    It's just so odd that it's so MANY times, but then only twice during the render.

    And the "fill the console buffer" number of times when you first add it. >|^P Boooooooo!
    They only call it 'class warfare' when we fight back.
    Praise to Buddha! #resist
    Chard's Credo-"Documentation is PART of the Interface"
    Film the cops. Always FILM THE COPS. Use this app.

  10. #10
    I suspect that the initial burst is to fill in the graph editor display.

Tags for this Thread

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
  •