create_nodematerial.py from Github not working
-
Hi,
Whenever I run create_nodematerial.py from Github in R25, it gives me an error of :
Traceback (most recent call last): File "C:\Program Files\Maxon Cinema 4D R25\resource\modules\python\libs\python39\maxon\data.py", line 75, in __getattribute__ return Data_GetMember(self, name, o) AttributeError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "scriptmanager", line 111, in <module> File "scriptmanager", line 90, in main File "scriptmanager", line 56, in CreateMaterialForNodeSpace File "C:\Program Files\Maxon Cinema 4D R25\resource\modules\python\libs\python39\maxon\data.py", line 77, in __getattribute__ return object.__getattribute__(self, name) AttributeError: 'UnknownDataType' object has no attribute 'GetGraph'
-
Hmm. Okay. I guess there is a change in API in R25 and R26.
Used the R25 code and it now works (under the GitHub releases)Why does this simple create material task needed a change code anyway?
Checked also the changes and the changes are trivial.maxon.frameworks.graph.NODE_KIND.ALL_MASK
tomaxon.NODE_KIND.ALL_MASK
So trivial. So I guess we need a lot of this if else statement for a script/plug in to work for R25 and R26/R27 at the same time?
-
Hi @bentraje sorry nodes examples were adapted to 26 but nothing mention it's 26+ only this is going to be fixed today. I would advice you to download the R25 python SDK which contain examples for the R25 version
here
[URL-REMOVED].Regarding your issue, as mentioned in the S26.0 Python Changelog frameworks are now by default imported so you don't need anymore to explicitly address the type from its framework but you can directly address it from the maxon module. Nevertheless any existent code (pre R25) where you need to import frameworks keep working.
So to make it works in R25 you need to import the relevant frameworks at the beginning and then use the correct type, instead ofmaxon.NODE_KIND.ALL_MASK
usemaxon.frameworks.graph.NODE_KIND.ALL_MASK
.
So the next code will work from R24 up to 2023.0.0:""" Copyright: MAXON Computer GmbH Author: Manuel Magalhaes Description: Creates a NodeMaterial for the current node space and for Redshift node space. NodeMaterials inherit from BaseMaterial. To be able to use the functions that are in the NodeMaterial class, the BaseMaterial must be cast to a NodeMaterial. This is done with the function GetNodeMaterialReference. To add a graph to an existing node space, one must use the function AddGraph. If one wants to have access to an already added node graph, one must retrieve the nimbus reference which does store the graph. Once one has retrieved the graph, one can access the root that contains all the nodes. Class/method highlighted: - GetNodeMaterialReference - AddGraph - GetActiveNodeSpaceId - GetChildren - GetNimbusRef """ import c4d import maxon import maxon.frameworks.nodespace import maxon.frameworks.nodes # Define a function that will create the node material for the passed # nodespace Id and return the root of the created Graph def CreateMaterialForNodeSpace(nodespaceId): # Create a baseMaterial first mat = c4d.BaseMaterial(c4d.Mmaterial) if mat is None: raise ValueError("Cannot create a BaseMaterial.") # Retrieve the reference of the material as a node material. nodeMaterial = mat.GetNodeMaterialReference() if nodeMaterial is None: raise ValueError("Cannot retrieve nodeMaterial reference.") # Add a graph for the space Id addedGraph = nodeMaterial.AddGraph(nodespaceId) if addedGraph is None: raise ValueError("Cannot add a GraphNode for this NodeSpace.") # Retrieve the Nimbus reference for a specific NodeSpace nimbusRef = mat.GetNimbusRef(nodespaceId) if nimbusRef is None: raise ValueError( "Cannot retrieve the nimbus reference for that NodeSpace.") # Retrieve the graph corresponding to that NodeSpace. graph = nimbusRef.GetGraph() if graph is None: raise ValueError("Cannot retrieve the graph of this nimbus NodeSpace.") # Retrieve the root of the graph root = graph.GetRoot() # Insert the material in the document doc.InsertMaterial(mat) return root # Define a function that will recursively print all the child of the root node. def PrintChildren(node): if node is None: return None # Print the current Node print(node) # Call GetChildren on this node with the delegate function node.GetChildren(PrintChildren, maxon.frameworks.graph.NODE_KIND.ALL_MASK) # Important that the delegate return True or False return True def main(): # Retrieve the current node space Id nodespaceId = c4d.GetActiveNodeSpaceId() # Create the material and retrieve the root of the graph root = CreateMaterialForNodeSpace(nodespaceId) # Start the recursive process on the first node PrintChildren(root) # Do the same with the Redshift node space. The Redshift plugin is not # installed by default, so we call the function in an exception handling # context. redShiftNodeSpPaceId = maxon.Id( 'com.redshift3d.redshift4c4d.class.nodespace') try: root = CreateMaterialForNodeSpace(redShiftNodeSpPaceId) PrintChildren(root) except: print(f"The node space with id {redShiftNodeSpPaceId} does not exist") # Pushes an update event to Cinema 4D c4d.EventAdd() if __name__ == "__main__": main()
Cheers,
Maxime.
[URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
-
Gotcha. Thansk for confirmation.
Looking forward for the update. -
Hi @bentraje I think there was a small misscommunication what was fixed on Github was the fact that the file does not contain the information of which Cinema 4D version they are working. We are not going to adapt our GitHub script to make it work for R25.
If you want code that is going to work for R25, the only solution is to download the python SDK for R25.Cheers,
Maxime.