Node port Vector2 value is not recognized by Python
-
I'm writing a script that gathers the node information of a Redshift material and spits out a JSON file that can be read by other 3D programs with Redshift installed. It's working great for most values, but attributes of type Vector2d64 trip Python up. When it comes to attributes like "scale" and "offset" on a texture node, GetDefaultValue() from the graph module returns UnknownDataType(net.maxon.parametrictype.vec<2,float64>) and I can't figure out a way to get around it. I did manage to get MaxonConvert() to return the X value of these ports, but no luck on the Y value so far.
This script from the PluginCafe Github demonstrates what I mean. If you unhide the "scale" port on a texture node and select it, the script returns the UnknownDataType for the portValue variable. Any help grabbing those values would be hugely appreciated.
import c4d import maxon def main(): # Get active material mat = doc.GetActiveMaterial() if mat is None: raise ValueError("There is no selected BaseMaterial") # Retrieve the reference of the material as a node Material. nodeMaterial = mat.GetNodeMaterialReference() if nodeMaterial is None: raise ValueError("can't retrieve nodeMaterial reference") # Retrieve the current node space Id nodespaceId = c4d.GetActiveNodeSpaceId() # Retrieve the graph corresponding to that nodeSpace. graph = nodeMaterial.GetGraph(nodespaceId) if graph is None: raise ValueError("can't retrieve the graph of this nimbus ref") def GetName(node): """ Retrieve the displayed name of a node. Args: node: (maxon.GraphNode): The node to retrieve the name from. Returns: Optional[str]: The node name, or None if the Node name can't be retrieved. """ if node is None: return None nodeName = node.GetValue(maxon.NODE.BASE.NAME) if nodeName is None: nodeName = node.GetValue(maxon.EffectiveName) if nodeName is None: nodeName = str(node) return nodeName def RetrieveInformationOfPort(port): """ Retrieve the name of the port, it's value, it's parent name, the name of the true node holding the port and if the port is connected the input port name, it is connected. This function is used as a callback parameter of GraphHelper.GetSelectedPorts. Args: port: (maxon.GraphNode): The output port, to query for information. Returns: bool: **True** if the iteration over ports should continue, otherwise **False** """ if port is None: return True # Get the port's name portName = GetName(port) # Get the parent's name of the port, could be another port, a port # list or a node. directParent = port.GetParent() directParentName = GetName(directParent) # Try to find the last port to be an ancestor of the selected node. # Input or output list are not considered as ancestor. ancestorName = None # If the directParent is a port list, we will never find the last # ancestor port kind = (directParent.GetKind() & maxon.NODE_KIND.PORTLIST_MASK) if kind != directParent.GetKind(): # we must start from the parent, otherwise, the port itself will # be returned. (see mask below) ancestor = directParent.GetParent() # We get the ancestor that is the kind of port. ancestor = ancestor.GetAncestor(maxon.NODE_KIND.PORT_MASK) ancestorName = GetName(ancestor) # We retrieve the node where this port belong to by retrieving the # ancestor with a mask of node kind set to NODE. trueNode = port.GetAncestor(maxon.NODE_KIND.NODE) trueNodeName = GetName(trueNode) # To retrieve and set the value of a port, Set/GetDefaultValue must # be used. portValue = port.GetDefaultValue() # Print the information we gathered. msg = (f"{portName}\nThis port has the value {portValue}.\nThe direct " f"parent is {directParentName}.\nThe ancestor port is " f"{ancestorName}.\nThe port is in the node {trueNodeName}.") print(msg) return True # Print information of the selected ports. maxon.GraphModelHelper.GetSelectedNodes(graph, maxon.NODE_KIND.PORT_MASK, RetrieveInformationOfPort) # Pushes an update event to Cinema 4D c4d.EventAdd() if __name__ == "__main__": main()
-
Hi,
not all maxon datatype are available in python. 2d vector (or vec2) is one of them. Of course, c4d is not able to convert it. with the default values, c4d is converting the data to a float and that is why you only retrieve the first value X.
You can select all the nodes and use the copy command; this will export to clipboard the selected nodes as a json formatted text. Unfortunately, only the modified values will be exported, not the default ones. That should still work for other dcc using redshift if the default values are the same.
Cheers,
Manuel -
Thank you for the answer Manuel