Simple Organisational Structure Generation Script
-
I'm trying to create a simple script that creates a simple organisation structure using nulls. It's 99% of the way there but there is a minor detail that is evading me. You will also have to excuse the coding, this is my first foray into coding in Python so it is not the most elegant coding I'm sure.
When I set up the initial folder structure manually I set the 'Icon Color' of the Null object to 'Display Color'. In the documentation it seems I can only set it as None or Custom (ID_BASELIST_ICON_COLORIZE_MODE_NONE or ID_BASELIST_ICON_COLORIZE_MODE_CUSTOM). Obviously I could set it to a custom colour to match the layer colour but I would prefer it to be linked. Is this an option? Is there a value I can use to implement this?
from typing import Optional import c4d from pprint import pprint doc: c4d.documents.BaseDocument # The active document op: Optional[c4d.BaseObject] # The active object, None if unselected def CreateLayer(name, data): newLayer = c4d.documents.LayerObject() newLayer.SetName(name) newLayer.SetLayerData(doc,data) newLayer.InsertUnder(doc.GetLayerObjectRoot()) return newLayer def CreateFolder(name, icon, layer): newFolder = c4d.BaseObject(c4d.Onull) newFolder[c4d.ID_BASELIST_NAME] = name newFolder[c4d.ID_BASELIST_ICON_FILE] = icon newFolder[c4d.ID_BASEOBJECT_USECOLOR] = c4d.ID_BASEOBJECT_USECOLOR_LAYER newFolder[c4d.ID_BASELIST_ICON_COLORIZE_MODE] = c4d.ID_BASELIST_ICON_COLORIZE_MODE_NONE newFolder.SetLayerObject(layer) doc.InsertObject(newFolder) c4d.EventAdd() return newFolder def main() -> None: layerArchive = CreateLayer("ARCHIVE", { 'solo':False, 'view':False, 'render':False, 'manager':True, 'locked':False, 'animation':False, 'generators':False, 'deformers':False, 'expressions':False, 'xref':False, 'color':c4d.Vector(128/255,128/255,128/255), }) folderArchive = CreateFolder("ARCHIVE", "1052837", layerArchive) folderSpacer = CreateFolder("- - - - - - - - - - - - - - - - - - - -", "1031728", layerArchive) layerCameras = CreateLayer("CAMERAS", { 'solo':False, 'view':False, 'render':True, 'manager':True, 'locked':False, 'animation':True, 'generators':True, 'deformers':True, 'expressions':True, 'xref':True, 'color':c4d.Vector(255/255,87/255,34/255), }) folderCameras = CreateFolder("CAMERAS", "1052837", layerCameras) layerLights = CreateLayer("LIGHTS", { 'solo':False, 'view':False, 'render':True, 'manager':True, 'locked':False, 'animation':True, 'generators':True, 'deformers':True, 'expressions':True, 'xref':True, 'color':c4d.Vector(255/255,193/255,7/255), }) folderLights = CreateFolder("LIGHTS", "1052837", layerLights) layerGeo = CreateLayer("GEO", { 'solo':False, 'view':True, 'render':True, 'manager':True, 'locked':False, 'animation':True, 'generators':True, 'deformers':True, 'expressions':True, 'xref':True, 'color':c4d.Vector(33/255,150/255,243/255), }) folderGeo = CreateFolder("GEO", "1052837", layerGeo) layerGenerators = CreateLayer("GENERATORS", { 'solo':False, 'view':True, 'render':True, 'manager':True, 'locked':False, 'animation':True, 'generators':True, 'deformers':True, 'expressions':True, 'xref':True, 'color':c4d.Vector(139/255,195/255,74/255), }) folderGenerators = CreateFolder("GENERATORS", "1052837", layerGenerators) if __name__ == '__main__': main()
-
Seems like a bug. Or a feature? Not sure lol.
Anyway, it seems like you need to trigger colorize first then change it.def CreateFolder(name, icon, layer): newFolder = c4d.BaseObject(c4d.Onull) newFolder[c4d.ID_BASELIST_NAME] = name newFolder[c4d.ID_BASELIST_ICON_FILE] = icon newFolder[c4d.ID_BASEOBJECT_USECOLOR] = c4d.ID_BASEOBJECT_USECOLOR_LAYER newFolder[c4d.ID_BASELIST_ICON_COLORIZE_MODE] = 2 newFolder[c4d.ID_BASELIST_ICON_COLORIZE_MODE] = 2 newFolder.SetLayerObject(layer) doc.InsertObject(newFolder) c4d.EventAdd() return newFolder
Yep one of the lines is repeated. If you only retain one line, it wouldn't work. haha. Not sure why.
Result:
-
Thanks for the fix, at least it works how I want now. I did manage to find the value I wanted was 2 by printing it to the console but didn't think to put the line twice so it didn't seem to work. Hopefully someone may be able to explain why it is necessary to add the line twice?
-
Hi,
By default, the icon color has two modes, node or custom. Other mode can be added programmatically, that is the case of objects and lights for example. Lights do not have display color; the color parameter will be used instead.
That is why you must send a message to the object before defining the "third" value of the icon color. This message will initialise the internal data. There is no symbol defined for this "third" value. It is just ID_BASELIST_ICON_COLORIZE_MODE_CUSTOM + 1 (so 2)
newFolder.Message(c4d.MSG_GETCUSTOMICON_SETTINGS, dict()) newFolder[c4d.ID_BASELIST_ICON_COLORIZE_MODE] = 2
@bentraje solution also works and i do not see where or when it could fail but the message looks safer to me.
Thanks a lot @bentraje for sharing your knowledge on the forum it is really appreciated.Cheers,
Manuel -
Thanks @Manuel , that is useful to know... how can be marked as 'Solved'?
-
you can have a look at our forum guidelines we have a section that explains how to mark your thread as a question. Then you can select a post as the answer or mark the thread solved.
I forgot, welcome to the forum, i did not saw it was your first post.
Cheers,
Manuel