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