Create empty object of type PyCObject



  • On 02/05/2018 at 05:17, xxxxxxxx wrote:

    Hi
    How do i create an empty object of type PyCObject?

    Im trying to iterate over Substance channels as its shown in c++. But i need an empty PyCObject for the first time c4d.modules.substance.GetSubstanceOutput is executed in the while loop:

      
    import c4d   
    try:   
        import redshift   
    except:   
        pass   
      
      
    def main() :   
        doc = c4d.documents.GetActiveDocument()   
        assets = c4d.modules.substance.GetSubstances(doc, 1)   
      
        if len(assets) == 0:   
            print 'Select a Substance in the Substance asset manager'   
            return   
           
        subGraph = c4d.modules.substance.GetSubstanceGraph(assets[0])   
      
        channels = {}   
        model = ['Base Color','Roughness','Metallic','Height','Normal','Ambient Occlusion']   
           
        lastOutput = PyCObject...   
        output = PyCObject...   
           
        while True:   
            output = c4d.modules.substance.GetSubstanceOutput(assets[0], subGraph[0], False, lastOutput)   
            lastOutput = output   
              
            if output[3] in model:   
                channels[output[3]] = output        
              
            if output[0] == None:   
                break   
      
        print channels   
           
    if __name__=='__main__':   
        main()   
    

    Any help appreciated.

    -b



  • On 02/05/2018 at 11:42, xxxxxxxx wrote:

    The documentation seems to indicate that passing 'None' for the prevObject attribute will get the first output.

    So:

    lastOuput = None
    

    Should do it in theory. You also shouldn't need to initiate 'output' before the loop.

    Also, it looks like the line:

    lastOutput = output
    

    Is setting lastOutput to a tuple when the GetSubstanceOutput() method is expecting a PyCObject.  I suspect this may need to be:

    lastOutput = output[0]
    


  • On 03/05/2018 at 00:52, xxxxxxxx wrote:

    Thanks. Setting lastOutput to None outside the loop gives this error:

    TypeError: argument 4 must be PyCObject, not tuple
    

    Output is outside the loop only because its like this in the c++ docs :) Thanks.

    -b



  • On 03/05/2018 at 01:43, xxxxxxxx wrote:

    That error probably occurs on the second time through the loop if you didn't change this line:

    lastOutput = output
    

    to:

    lastOutput = output[0]
    

    The return from GetSubstanceOutput() is a tuple and you want to set lastOutput to the first element of the tuple (the PyCObject).

    You will need to initialize lastOutput outside of the loop but I'd remove output from outside of the loop.  There's really no reason for it to be there.  It receives a value immediately after entering the loop.



  • On 03/05/2018 at 01:55, xxxxxxxx wrote:

    Ah! Now i understand. Thanks alot.

    -b



  • On 03/05/2018 at 02:06, xxxxxxxx wrote:

    Alternatively, you might consider storing the elements of the returned tuple in separate variables which makes things a little easier to read at a glance:

      
    ...
      
        lastOutput = None
      
        while True:
            output, uid, type, name, bmp = c4d.modules.substance.GetSubstanceOutput(assets[0], subGraph[0], False, lastOutput)
      
            lastOutput = output
      
            if name in model:
                channels[name] = (output, uid, type, name, bmp) #Or whatever combination of data you're interested in
      
            if output == None:
                break
      
    ...
    

    And if you wanted a reason to use output outside of the loop you could do this:

    lastOutput = None
    output = True
      
    while output:
            output, uid, type, name, bmp = c4d.modules.substance.GetSubstanceOutput(assets[0], subGraph[0], False, lastOutput)
      
            lastOutput = output
      
            if name in model:
                channels[name] = (output, uid, type, name, bmp) #Or whatever combination of data you're interested in
    

    But it's basically the same as keeping your break statement and removing output from outside the loop.



  • On 03/05/2018 at 02:28, xxxxxxxx wrote:

    Thats a nice alternative. Thanks.

    -b



  • On 03/05/2018 at 10:12, xxxxxxxx wrote:

    Hi,

    darby's explanation is correct.
    In our Python examples we also have a few scripts demonstrating the Substance API. Especially the substance_iterateGraphInputOutput comes pretty close to your application.



  • On 04/05/2018 at 00:33, xxxxxxxx wrote:

    Oh, those examples will come in handy. Thanks!
    I guess its time to clone that repo and start watching it for changes :)

    -b



  • On 04/05/2018 at 00:40, xxxxxxxx wrote:

    Alternatively these examples are also included in the Python SDK documentation archive, downloadable here. Usually we mention example changes in the changelog as well.



  • On 04/05/2018 at 00:55, xxxxxxxx wrote:

    Thanks!

    -b


Log in to reply