I'm having issues wrapping my head around how to change an FBX Importer preference via Python. Any help would be appreciated, below explains my approach and what I was able to figure out so far. Please note that I am fairly new to the C4D Python API.
The specific goal is to change c4d.FBXIMPORT_NORMALS of the FBX Import.
First I need to figure out what the plugin ID is. I used the below approach to do. Please let me know if there is a better way to do this -
for p in c4d.plugins.FilterPluginList(c4d.PLUGINTYPE_ANY,True):
print (p.GetID(), " = ", p.GetName())
The above output gives me -
1026370 = FBX (*.fbx)
1026369 = FBX (*.fbx)
1026370 = FBX (*.fbx) Export
1026369 = FBX (*.fbx) Import
1026371 = FBXExportReferenceTag
The FBX Import Plugin Id is 1026369 . I now can return the BasePlugin object and SHOULD be able to set the parameter from here -
plug = c4d.plugins.FindPlugin(1026369, c4d.PLUGINTYPE_SCENELOADER)
>>> <c4d.plugins.BasePlugin object called FBX (*.fbx) with ID 15 at 2429143389120>
plug[c4d.FBXIMPORT_NORMALS] = c4d.FBXIMPORT_NORMALS_NORMALTAGS
I run the above without any changes to the Preferences/FBX Import UI. Following the same concept for the "Units" plugin I get the expected results when modifying it's parm Units[c4d.PREF_UNITS_AUTOCONVERT] = False
Units[c4d.PREF_UNITS_AUTOCONVERT] = False
Am I doing something incorrectly? Is this access via Python just not supported? Any help would be great. Thank you.
Hi @clayton_krause sorry for the late reply, There is actually two ways, one by accessing the global preference, but that will change the default import settings for every FBX importation. I would recommend to no change the preference as this could confuse user and instead use the second way that you tried to achieve (at least I think) by accessing the SceneLoader and only change the setting for the current Cinema 4D session.
To do so you need to retrieve the SceneLoader and then send the message MSG_RETRIEVEPRIVATEDATA to retrieve a dictionary containing a BaseList2D holding the settings used for the loading:
# Retrieves a path to load the imported file
selectedFile = c4d.storage.LoadDialog(title="Import a FBX File", type=c4d.FILESELECTTYPE_ANYTHING, force_suffix="fbx")
if not selectedFile:
plug = c4d.plugins.FindPlugin(c4d.FORMAT_FBX_IMPORT, c4d.PLUGINTYPE_SCENELOADER)
if plug is None:
raise RuntimeError("Failed to retrieve the FBX importer.")
data = dict()
if not plug.Message(c4d.MSG_RETRIEVEPRIVATEDATA, data):
raise RuntimeError("Failed to retrieve private data.")
# BaseList2D object stored in "imexporter" key hold the settings
fbxImport = data.get("imexporter", None)
if fbxImport is None:
raise RuntimeError("Failed to retrieve BaseList2D settings holder.")
# Defines the settings
fbxImport[c4d.FBXIMPORT_NORMALS] = c4d.FBXIMPORT_NORMALS_NORMALTAGS
# Imports without dialogs
if not c4d.documents.MergeDocument(doc, selectedFile, c4d.SCENEFILTER_OBJECTS | c4d.SCENEFILTER_MATERIALS, None):
raise RuntimeError("Failed to load the document.")
# Pushes an update event to Cinema 4D
if __name__ == '__main__':
@m_adam - Now I'm sorry for my late reply! I appreciate you writing this up for me and I think it's a really good reference. This question has been answered then!
Another quick question which sort of relates (I can create a new thread if admins want) - Do you have any recommendation for up-to-date C4D Python API training? I'm coming from writing Python in Houdini and Maya, but Cinema 4D seems to have a more unique setup with how to interface with their API.
Any training recommendations would be appreciated. Teach a man to fish and... something something fish.