|
| 1 | +#coding: utf-8 |
| 2 | +"""Demonstrates creating new node materials and adding graphs to them. |
| 3 | +
|
| 4 | +See the `create_redshift_nodematerial` and `create_standard_nodematerial` examples in this directory |
| 5 | +for also populating a graph with nodes and connecting them. |
| 6 | +
|
| 7 | +Topics: |
| 8 | + * Creating node materials. |
| 9 | + * Adding and removing graphs to them. |
| 10 | +""" |
| 11 | +__author__ = "Ferdinand Hoppe" |
| 12 | +__copyright__ = "Copyright (C) 2023 MAXON Computer GmbH" |
| 13 | +__date__ = "01/09/2023" |
| 14 | +__license__ = "Apache-2.0 License" |
| 15 | +__version__ = "2024.0.0" |
| 16 | + |
| 17 | +import c4d |
| 18 | +import maxon |
| 19 | + |
| 20 | +doc: c4d.documents.BaseDocument # The active document. |
| 21 | + |
| 22 | +def main(): |
| 23 | + """ |
| 24 | + """ |
| 25 | + # Node materials are instances of the classic API material type #BaseMaterial. The node data |
| 26 | + # is attached to them as a #NodeMaterial. We can retrieve a #NodeMaterial instance for each |
| 27 | + # #BaseMaterial instance, whether or not this material actually is a node material or not. |
| 28 | + |
| 29 | + # Instantiate a classic API material. |
| 30 | + material: c4d.BaseMaterial = c4d.BaseMaterial(c4d.Mmaterial) |
| 31 | + if not material: |
| 32 | + raise MemoryError(f"{material = }") |
| 33 | + doc.InsertMaterial(material) |
| 34 | + |
| 35 | + # Get the node material for it and add a graph for the currently active material space to it. |
| 36 | + nodeMaterial: c4d.NodeMaterial = material.GetNodeMaterialReference() |
| 37 | + graph: maxon.GraphModelInterface = nodeMaterial.CreateDefaultGraph(c4d.GetActiveNodeSpaceId()) |
| 38 | + if graph.IsNullValue(): |
| 39 | + raise RuntimeError("Could not add graph to material.") |
| 40 | + |
| 41 | + # The method #CreateDefaultGraph we used above does not create an empty graph, but the setup |
| 42 | + # the respective node space considers to be its default setup. For Redshift this is for example |
| 43 | + # an RS Standard Material node connected to an Output end node. |
| 44 | + print ("Nodes in CreateDefaultGraph setup:") |
| 45 | + for node in graph.GetRoot().GetInnerNodes(mask=maxon.NODE_KIND.NODE, includeThis=False): |
| 46 | + print (f"{node}") |
| 47 | + |
| 48 | + # Remove the graph we just created. |
| 49 | + nodeMaterial.RemoveGraph(c4d.GetActiveNodeSpaceId()) |
| 50 | + |
| 51 | + # We can also create an empty graph which contains no nodes at all with. |
| 52 | + graph: maxon.GraphModelInterface = nodeMaterial.CreateEmptyGraph(c4d.GetActiveNodeSpaceId()) |
| 53 | + if graph.IsNullValue(): |
| 54 | + raise RuntimeError("Could not add graph to material.") |
| 55 | + |
| 56 | + print ("Nodes in CreateEmptyGraph setup:") |
| 57 | + for node in graph.GetRoot().GetInnerNodes(mask=maxon.NODE_KIND.NODE, includeThis=False): |
| 58 | + print (f"{node}") |
| 59 | + |
| 60 | + # Remove the graph again. |
| 61 | + nodeMaterial.RemoveGraph(c4d.GetActiveNodeSpaceId()) |
| 62 | + |
| 63 | + # Finally, we should be aware that node material can hold graphs for multiple node spaces and |
| 64 | + # therefore can be used with multiple render engines. To do this, we can simply add multiple |
| 65 | + # graphs for specific nodes spaces. |
| 66 | + |
| 67 | + # Add a default graph for both the Redshift and Standard material node space, check the "Basic" |
| 68 | + # tab of the material, it will list a graph for both spaces. When you switch between render |
| 69 | + # engines, the material will have its own graph for each engine. To support 3rd party render |
| 70 | + # engines, you must ask their vendor for their node space ID. |
| 71 | + nodeMaterial.CreateDefaultGraph("com.redshift3d.redshift4c4d.class.nodespace") |
| 72 | + nodeMaterial.CreateDefaultGraph("net.maxon.nodespace.standard") |
| 73 | + |
| 74 | + |
| 75 | +if __name__ == "__main__": |
| 76 | + main() |
0 commit comments