How to group nodes in a Scaffold using Python
-
Hi, I've been searching for examples on how to add nodes to a scaffold group in Python, but there is nothing available and the documentation is not helping too much as well....
This is what I was trying to do, creating a material based on the example from github and adding a scaffold and then trying to move some nodes into it. But of course it is not working as this is just an attempt from a trial and error.
Any help would be appreciated.Thanks
import c4d import maxon doc: c4d.documents.BaseDocument def main(): urlTexRust: maxon.Url = maxon.Url(r"asset:///file_edb3eb584c0d905c") urlTexSketch: maxon.Url = maxon.Url(r"asset:///file_3b194acc5a745a2c") # The node asset IDs idTextureNode: maxon.Id = maxon.Id("com.redshift3d.redshift4c4d.nodes.core.texturesampler") idMixNode: maxon.Id = maxon.Id("com.redshift3d.redshift4c4d.nodes.core.rscolormix") idRsStandardMaterial: maxon.Id = maxon.Id("com.redshift3d.redshift4c4d.nodes.core.standardmaterial") # Instantiate a material, get its node material and the graph for the RS material space. material: c4d.BaseMaterial = c4d.BaseMaterial(c4d.Mmaterial) if not material: raise MemoryError(f"{material = }") nodeMaterial: c4d.NodeMaterial = material.GetNodeMaterialReference() graph: maxon.GraphModelRef = nodeMaterial.CreateDefaultGraph( maxon.Id("com.redshift3d.redshift4c4d.class.nodespace")) if graph.IsNullValue(): raise RuntimeError("Could not add RS graph to material.") # Get the Standard Material node result: list[maxon.GraphNode] = [] maxon.GraphModelHelper.FindNodesByAssetId(graph, idRsStandardMaterial, True, result) if len(result) < 1: raise RuntimeError("Could not find RS Standard node in material.") standardNode: maxon.GraphNode = result[0] with graph.BeginTransaction() as transaction: # Add two texture nodes and a blend node to the graph. rustTexNode: maxon.GraphNode = graph.AddChild(maxon.Id(), idTextureNode) sketchTexNode: maxon.GraphNode = graph.AddChild(maxon.Id(), idTextureNode) mixNode: maxon.GraphNode = graph.AddChild(maxon.Id(), idMixNode) mixAmount: maxon.GraphNode = mixNode.GetInputs().FindChild( "com.redshift3d.redshift4c4d.nodes.core.rscolormix.mixamount") mixAmount.SetDefaultValue(0.5) # Get the ports and set the values pathRustPort: maxon.GraphNode = rustTexNode.GetInputs().FindChild( "com.redshift3d.redshift4c4d.nodes.core.texturesampler.tex0").FindChild("path") pathSketchPort: maxon.GraphNode = sketchTexNode.GetInputs().FindChild( "com.redshift3d.redshift4c4d.nodes.core.texturesampler.tex0").FindChild("path") pathRustPort.SetDefaultValue(urlTexRust) pathSketchPort.SetDefaultValue(urlTexSketch) # Get the color output ports of the two texture nodes and the color blend node. rustTexColorOutPort: maxon.GraphNode = rustTexNode.GetOutputs().FindChild( "com.redshift3d.redshift4c4d.nodes.core.texturesampler.outcolor") sketchTexColorOutPort: maxon.GraphNode = sketchTexNode.GetOutputs().FindChild( "com.redshift3d.redshift4c4d.nodes.core.texturesampler.outcolor") mixColorOutPort: maxon.GraphNode = mixNode.GetOutputs().FindChild( "com.redshift3d.redshift4c4d.nodes.core.rscolormix.outcolor") # Get the ports mixInput1Port: maxon.GraphNode = mixNode.GetInputs().FindChild( "com.redshift3d.redshift4c4d.nodes.core.rscolormix.input1") mixInput2Port: maxon.GraphNode = mixNode.GetInputs().FindChild( "com.redshift3d.redshift4c4d.nodes.core.rscolormix.input2") stdBaseColorInPort: maxon.GraphNode = standardNode.GetInputs().FindChild( "com.redshift3d.redshift4c4d.nodes.core.standardmaterial.base_color") # Connect the nodes rustTexColorOutPort.Connect(mixInput1Port, modes=maxon.WIRE_MODE.NORMAL, reverse=False) sketchTexColorOutPort.Connect(mixInput2Port, modes=maxon.WIRE_MODE.NORMAL, reverse=False) mixColorOutPort.Connect(stdBaseColorInPort, modes=maxon.WIRE_MODE.NORMAL, reverse=False) transaction.Commit() # Find all the texture nodes tex_nodes = [] maxon.GraphModelHelper.FindNodesByAssetId(graph, idTextureNode, True, tex_nodes) ################################ # my attempt of grouping the texture nodes in a Scaffold # with graph.BeginTransaction() as transaction: scaffold = graph.AddChild(maxon.Id(), maxon.Id("net.maxon.node.scaffold")) graph.MoveToGroup(scaffold, maxon.Id("idOfMyGroup"), tex_nodes) transaction.Commit() # ################################ doc.InsertMaterial(material) doc.SetActiveMaterial(material) c4d.EventAdd() if __name__ == "__main__": main()
-
Hi @danielsian you need to define the scaffold ID.
# Find all the texture nodes tex_nodes = [] maxon.GraphModelHelper.FindNodesByAssetId(graph, idTextureNode, True, tex_nodes) with graph.BeginTransaction() as transaction: scaffold = graph.AddChild(maxon.Id(), maxon.Id("net.maxon.node.scaffold")) for node in tex_nodes: node.SetValue("net.maxon.node.attribute.scaffoldid", scaffold.GetId()) transaction.Commit()
Cheers,
Maxime. -
Hey @m_adam ,
Thanks for your help. It works now.
However, I'm wondering how I would have known that I needed to set the scaffold ID to the node. The documentation doesn't seem to explicitly mention this step. I might be wrong, but for someone without strong knowledge of the API, I'd never thought that way. I would rather added the selected nodes to a group, as this is what a scaffol is. Does that make sense?
As a side note, after adding the nodes to the scaffold group, they appear messy, actually the nodes are nicely arranged inside the group, but the scaffold is overlapping other nodes. This is likely related to the bug we discussed here: https://developers.maxon.net/forum/post/73446. Am I right?
Cheers