Adding nodes to existing material won't auto arrange the node editor
-
Hi there, I'm adding nodes to an existing node material and I'm not being able to get a nice and organized result in the node editor, even after all connections are done.
However, if I create a material from scratch, then add the nodes and connect them the same way, the node editor finds an optimized way to organize the graph and the result is nice as expected.So, these are the 2 approaches and the result:
1- add and connect nodes within an existing material - the new nodes are overlapping each other
2- create the material and then add and connect the nodes within it - the new nodes are nicely organizedHow can I get a nice result with approach 1?
I used the example create_redshift_nodematerial_2024.py for the approach 2.
For the approach 1 I'm commenting the line:createRSMaterial()
import c4d import maxon doc: c4d.documents.BaseDocument # The active document. def createRSMaterial(): 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() doc.InsertMaterial(material) doc.SetActiveMaterial(material) c4d.EventAdd() def main(): # create a RS material createRSMaterial() # Get the material material = doc.GetActiveMaterial() # Check if the material exists and is a node material if not material or not material.IsInstanceOf(c4d.Mmaterial): return # Get the node material nodeMaterial = material.GetNodeMaterialReference() nodespaceId = c4d.GetActiveNodeSpaceId() rsNodeSpaceId = maxon.Id("com.redshift3d.redshift4c4d.class.nodespace") if nodespaceId != rsNodeSpaceId: return # Get the graph try: graph = nodeMaterial.GetGraph(nodespaceId) except: return # Set the asset IDs idTextureNode = maxon.Id("com.redshift3d.redshift4c4d.nodes.core.texturesampler") idColorCorrection = maxon.Id("com.redshift3d.redshift4c4d.nodes.core.rscolorcorrection") # Find all the texture nodes tex_nodes = [] maxon.GraphModelHelper.FindNodesByAssetId(graph, idTextureNode, True, tex_nodes) if not tex_nodes: return for node in tex_nodes: for out_port in node.GetOutputs().GetChildren(): for dest_port, wires in out_port.GetConnections(maxon.PORT_DIR.OUTPUT, None, maxon.Wires.All(), maxon.WIRE_MODE.ALL): with graph.BeginTransaction() as transaction: # Remove existing connection maxon.GraphModelHelper.RemoveConnection(out_port, dest_port) # Create node colorCorrectionNode = graph.AddChild(maxon.Id(), idColorCorrection) # Get the ports cc_inPort = colorCorrectionNode.GetInputs().FindChild("com.redshift3d.redshift4c4d.nodes.core.rscolorcorrection.input") cc_outPort = colorCorrectionNode.GetOutputs().FindChild("com.redshift3d.redshift4c4d.nodes.core.rscolorcorrection.outcolor") # Connect the nodes cc_outPort.Connect(dest_port, modes=maxon.WIRE_MODE.NORMAL, reverse=False) out_port.Connect(cc_inPort, modes=maxon.WIRE_MODE.NORMAL, reverse=False) transaction.Commit() doc.InsertMaterial(material) c4d.EventAdd() if __name__ == "__main__": main()
-
Hi @danielsian ,
As @m_adam said, this is the "auto-layouter" didn't work, if we add something to existed materials, the new node will set at the center of the graph editor, seems nothing we can do here, one bad solution is call the "Arrange All Nodes", but this will break the existed layout, hope it will be a better solution asap.Cheers~
DunHou -
-
Hi thanks a lot, this is most likely the same bug that @Dunhou reported but that I was never able to reproduce.
I will forward that to the responsible dev.Cheers,
Maxime. -
Thanks @m_adam !
-
Hey guys, how is it going with this BUG?
Is it gonna be fixed soon?
Thanks -
Hi sadly no news, except we kind of know the issue, sadly this issue is somehow by design and will require an architectural change.
While we still want to fix this issue, everything is about priority and this is not a urgent priority at the moment so I can't tell you when it will be fixed. But it's on our list.
Cheers,
Maxime.