Hi,
There are quite a few hoops to jump through, but this example should get you the idea.
import c4d
def get_port_descid(node, port):
"""Returns the DescID for a ``GvPort``.
If all our ports would be for static description elements, this would be
easy. It would be just ``port.GetSubID()``. Unfortunately we are dealing
with a lot of dynamic descriptions in the context of Xpresso, and at
least I am not aware of any builtin methods that would return the
``DescID`` of a ``GvPort`` in a more sane way.
This solution is especially lazy, a solution less prone to errors
would be to iterate over the description of the ``GvNode`` and see which
combination of ``m, s, u`` is in there.
Args:
node (``c4d.modules.graphview.GvNode``): The node of the port.
port (``c4d.modules.graphview.GvPort``): The port to get the DescID for.
Returns:
``tuple[int]`` or ``None``: The resolved DescID.
"""
# The fragments (DescLevels) of the DescID of the port. The problem is
# that all methods always return an integer-
m, s, u = port.GetMainID(), port.GetSubID(), port.GetUserID()
# Now we are just trying to access the node and see if it raises an
# (attribute) error. If so, we just try the next combination.
# There are no user data DescLevels below 1.
if u > 0:
try:
node[(m, s, u)]
# It is a user data DescID.
return (m, s, u)
except AttributeError as e:
pass
try:
node[(m, s)]
# It is a dynamic description DescID.
return (m, s)
except AttributeError as e:
pass
try:
node[s]
# It is a static description DescID.
return s
except AttributeError as e:
pass
return None
def main():
"""Entry point.
"""
# This example is for a Xpresso GraphView instance, since I do not
# have access to RedShift. I did use two constant nodes and a math
# node as an example scene.
if not op or not op.GetTag(c4d.Texpresso):
return
tag = op.GetTag(c4d.Texpresso)
master = tag.GetNodeMaster()
root = master.GetRoot()
if not root:
return
nodes = root.GetChildren()
if not nodes:
return
# I just took the first top-level node as the node to disconnect,
# which was one of the constant nodes connected to the math node.
out_node = nodes[0]
# Go over all output ports in our node to disconnect/remove.
for out_port in out_node.GetOutPorts():
# Get all input ports the current output port is connected to.
connected_ports = out_port.GetDestination()
# Severe all connections from our output port.
out_port.Remove()
# Let Cinema catch up.
c4d.EventAdd()
# This one of the nastier parts. We will have to unwind the
# DescID the output port has been build for. See the
# respective function for details.
out_did = get_port_descid(out_node, out_port)
# We couldn't resolve the DescID properly.
if out_did is None:
continue
# Now we are just going over all input ports, get the DescID
# they are pointing at and write the value from our output_node
# to the input_node with these two DescIDs.
for in_port in connected_ports:
in_node = in_port.GetNode()
in_did = (in_port.GetMainID(), in_port.GetSubID())
in_did = get_port_descid(in_node, in_port)
if in_did is not None:
in_node[in_did] = out_node[out_did]
if __name__=='__main__':
main()
Cheers,
zipit