SOLVED Volume Builder Index returning None

Hello all,

I have been trying to create an automation script to help with a rather repetitive task involving volume builders. However, I am quite stuck in regards with how to change the mode of the objects in the Volume Builder.

Another issue I am having is in regards to the VolumeBuilder python page:

I cannot seem to get any of these functions to work. I am trying to change the mix mode. I have tried a few functions and they keep returning none. I suspect that I may not fully understand how to call indexes properly (I am just treating them as an integer at the moment where 0 is the first child and so on)

An example of a little debugging where I have 4 objects as a child of the VolumeBuilder (Which is active after being created, so I just assign it then (Which is probably super lazy of me) )

volBuilder = doc.GetActiveObject()
DEBUG = volBuilder.GetInputObject(1)
    print("DEBUG = "+str(DEBUG))

The resulting print:

DEBUG = None

Also, I was wondering if accessing the Objects attribute possible with Python? i.e. creating folders, arranging (Without pulling the object out and then inserting it again)

All the best,

Hayden.

Hi,

Based on our examples on github, i've create that script that will do some operation on the MeshBuilder:

Note that, to change the "mix mode" you must use the right fonction for the right volume type:

  • SDF -> SetBoolMode
  • Fog -> SetMixMode
  • vector -> SetMixVectorMode
    Note that the flags are different for each function.

Adding folder is possible with sending a message but after that you can't rename it or add a child to this folder.

import c4d
from c4d import gui
# Welcome to the world of Python


# Script state in the menu or the command palette
# Return True or c4d.CMD_ENABLED to enable, False or 0 to disable
# Alternatively return c4d.CMD_ENABLED|c4d.CMD_VALUE to enable and check/mark
#def state():
#    return True

# Main function
def main():
# Creates volume builder object
    volumeBuilder = c4d.BaseObject(c4d.Ovolumebuilder)
    if volumeBuilder is None:
        raise Exception('Could not create Volume Builder object')

    # Inserts volume builder into the active document
    doc.InsertObject(volumeBuilder, None, None)
    doc.SetActiveObject(volumeBuilder)

    # Creates a cube object
    cube = c4d.BaseObject(c4d.Ocube)
    if cube is None:
        raise Exception('Could not create cube object')
    
    capsule = c4d.BaseObject(c4d.Ocapsule)
    capsule.SetRelPos(c4d.Vector(0,100,0))

    # Inserts cube into the active document
    capsule.InsertUnder(volumeBuilder)
    cube.InsertUnder(volumeBuilder)
    
    

    # Adds cube object to the volume builder
    ret = volumeBuilder.AddSceneObject(cube)
    if not ret:
        raise Exception('Could not add scene object')
    ret = volumeBuilder.AddSceneObject(capsule)
    if not ret:
        raise Exception('Could not add scene object')

    # Retrieves cube's volume builder settings container
    settings = volumeBuilder.GetSettingsContainerForObject(capsule)
    if settings is None:
        raise Exception('Could not access settings')

    # Configures cube's settings
    settings[c4d.ID_VOLUMEBUILDER_TAG_USEPOINTS] = True
    settings[c4d.ID_VOLUMEBUILDER_TAG_MESHRADIUS] = 10.0

    volumeBuilder.SetBoolMode(0, c4d.BOOLTYPE_DIFF)
    
    inputCount = volumeBuilder.GetInputObjectCount()
    if inputCount == 0:
        raise RuntimeError("There is no input object for this volume builder.")

    # Iterates over all objects used in the volume builder
    for i in range(inputCount):
        # Retrieves the object
        inputObject = volumeBuilder.GetInputObject(i)
        if inputObject is None: continue

        # Prints the names and if it's a child of something else in the volume builder
        name = inputObject.GetName()
        print(name, i)

        if volumeBuilder.InputObjectIsChild(i):
            print("child object")

    # Pushes an update event to Cinema 4D
    c4d.EventAdd()

# Execute main()
if __name__=='__main__':
    main()

Hi,

Based on our examples on github, i've create that script that will do some operation on the MeshBuilder:

Note that, to change the "mix mode" you must use the right fonction for the right volume type:

  • SDF -> SetBoolMode
  • Fog -> SetMixMode
  • vector -> SetMixVectorMode
    Note that the flags are different for each function.

Adding folder is possible with sending a message but after that you can't rename it or add a child to this folder.

import c4d
from c4d import gui
# Welcome to the world of Python


# Script state in the menu or the command palette
# Return True or c4d.CMD_ENABLED to enable, False or 0 to disable
# Alternatively return c4d.CMD_ENABLED|c4d.CMD_VALUE to enable and check/mark
#def state():
#    return True

# Main function
def main():
# Creates volume builder object
    volumeBuilder = c4d.BaseObject(c4d.Ovolumebuilder)
    if volumeBuilder is None:
        raise Exception('Could not create Volume Builder object')

    # Inserts volume builder into the active document
    doc.InsertObject(volumeBuilder, None, None)
    doc.SetActiveObject(volumeBuilder)

    # Creates a cube object
    cube = c4d.BaseObject(c4d.Ocube)
    if cube is None:
        raise Exception('Could not create cube object')
    
    capsule = c4d.BaseObject(c4d.Ocapsule)
    capsule.SetRelPos(c4d.Vector(0,100,0))

    # Inserts cube into the active document
    capsule.InsertUnder(volumeBuilder)
    cube.InsertUnder(volumeBuilder)
    
    

    # Adds cube object to the volume builder
    ret = volumeBuilder.AddSceneObject(cube)
    if not ret:
        raise Exception('Could not add scene object')
    ret = volumeBuilder.AddSceneObject(capsule)
    if not ret:
        raise Exception('Could not add scene object')

    # Retrieves cube's volume builder settings container
    settings = volumeBuilder.GetSettingsContainerForObject(capsule)
    if settings is None:
        raise Exception('Could not access settings')

    # Configures cube's settings
    settings[c4d.ID_VOLUMEBUILDER_TAG_USEPOINTS] = True
    settings[c4d.ID_VOLUMEBUILDER_TAG_MESHRADIUS] = 10.0

    volumeBuilder.SetBoolMode(0, c4d.BOOLTYPE_DIFF)
    
    inputCount = volumeBuilder.GetInputObjectCount()
    if inputCount == 0:
        raise RuntimeError("There is no input object for this volume builder.")

    # Iterates over all objects used in the volume builder
    for i in range(inputCount):
        # Retrieves the object
        inputObject = volumeBuilder.GetInputObject(i)
        if inputObject is None: continue

        # Prints the names and if it's a child of something else in the volume builder
        name = inputObject.GetName()
        print(name, i)

        if volumeBuilder.InputObjectIsChild(i):
            print("child object")

    # Pushes an update event to Cinema 4D
    c4d.EventAdd()

# Execute main()
if __name__=='__main__':
    main()

@m_magalhaes Thank you so much for putting this togeather. It really helped me in working out where I was going wrong!

Thank you,

Hayden.

Hello @falcon,

without further questions or replies, we will consider this topic as solved by Monday, the 30th and flag it accordingly.

Thank you for your understanding,
Ferdinand