Hi, I’m currently working on a Python script in C4D that tries to read out some Corona object properties, in that case the ChaosScatter[c4d.CHAOS_SCATTER_DISTRIBUTE_ON_OBJECTS] list. I’m no pro at writing code, but with the help of ChatGPT I’ve created some nice little helper for basic C4D stuff, but mostly with built-in objects, Cloner and so on. Does anyone know how I could get the list and / or change the objects inside that list with code? Can’t read the data that ChaosScatter[c4d.CHAOS_SCATTER_DISTRIBUTE_ON_OBJECTS] would give me, I believe! (could be totally wrong how I’m trying to do it), but that [c4d…] doesn’t give me anything if I simply print it out? Is this some kind of packaged variable that I need to unpack? Iterating over it with a for loop isn’t possible and to that point I’ve no other clue Reading the values, and changing them would be the thing I need to achieve.
Hi, the data for the list is stored in a data type slightly different from normal C4D object list - this is because the list contains also additional values for each node (e.g. frequency for Distribute On list and some other values for Areas include/exclude lists). This data type is not directly available in Python, however you can still access it by using sub-ids when reading parameters from Python.
The details are explained in the file “ChaosScatter/res/description/guichaosincludelist.h” (it is written for C++, but the information is also usable for Python). The other IDs (e.g. column IDs) used here can be found in file “ochaosscatter.h”.
Here is an example that should work for Python since Scatter 7 (Corona 13):
# These IDs are taken from guichaosincludelist.h that can be found in the scatter plugin directory
# (unfortunately these are not automatically loaded by C4D into c4d.*)
CHAOS_INCLUDE_LIST_INEXCLUDE = 100
CHAOS_INCLUDE_LIST_DATA_OFFSET = 200
CHAOS_INCLUDE_LIST_DATA_STEP = 100
CHAOS_INCLUDE_LIST_DATA_TRANSLATE_INDEX_TO_ID = 199
def read_scatter_list(scatter, main_id):
"""
Reads list of all nodes added in one of scatter extended include lists
"""
document = scatter.GetDocument()
object_list = scatter[main_id, CHAOS_INCLUDE_LIST_INEXCLUDE]
result = (object_list.ObjectFromIndex(document, i) for i in range(object_list.GetObjectCount()))
return list(filter(bool, result))
def read_scatter_list_column(scatter, main_id, object, column_id):
"""
Reads additional value in specified column inside extended scatter include list for given object
"""
object_list = scatter[main_id, CHAOS_INCLUDE_LIST_INEXCLUDE]
node_index = object_list.GetObjectIndex(doc, object)
node_id = scatter[main_id, CHAOS_INCLUDE_LIST_DATA_TRANSLATE_INDEX_TO_ID, node_index]
if node_id < 0:
return None # object was not found in the scatter list
data_id = CHAOS_INCLUDE_LIST_DATA_OFFSET + node_id * CHAOS_INCLUDE_LIST_DATA_STEP + column_id
return scatter[main_id, data_id]
# This example prints names of all objects in "Distribute On" parameter for scatter called "Chaos Scatter" with their frequencies
scatter = doc.SearchObject("Chaos Scatter")
for object in read_scatter_list(scatter, c4d.CHAOS_SCATTER_DISTRIBUTE_ON_OBJECTS):
name = object.GetName()
frequency = read_scatter_list_column(scatter, c4d.CHAOS_SCATTER_DISTRIBUTE_ON_OBJECTS, object, c4d.CHAOS_SCATTER_DISTRIBUTE_ON_FACTOR)
print(f"{name}: {frequency}")
Writing the value for the extra columns can be done similarly to how reading is done in read_scatter_list_column.