Example #1
0
static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node)
{
	bNodeSocket *input = node->inputs.first;
	bNodeSocket *output = node->outputs.first;
	bNodeLink *link;
	int type = SOCK_FLOAT;
	
	/* XXX it would be a little bit more efficient to restrict actual updates
	 * to rerout nodes connected to an updated node, but there's no reliable flag
	 * to indicate updated nodes (node->update is not set on linking).
	 */
	
	node->done = 1;
	
	/* recursive update */
	for (link = ntree->links.first; link; link = link->next) {
		bNode *fromnode = link->fromnode;
		bNode *tonode = link->tonode;
		if (!tonode || !fromnode)
			continue;
		if (nodeLinkIsHidden(link))
			continue;
		
		if (tonode == node && fromnode->type == NODE_REROUTE && !fromnode->done)
			node_reroute_inherit_type_recursive(ntree, fromnode);
		
		if (fromnode == node && tonode->type == NODE_REROUTE && !tonode->done)
			node_reroute_inherit_type_recursive(ntree, tonode);
	}
	
	/* determine socket type from unambiguous input/output connection if possible */
	if (input->limit == 1 && input->link)
		type = input->link->fromsock->type;
	else if (output->limit == 1 && output->link)
		type = output->link->tosock->type;
	
	/* arbitrary, could also test output->type, both are the same */
	if (input->type != type) {
		PointerRNA input_ptr, output_ptr;
		/* same type for input/output */
		RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, input, &input_ptr);
		RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, output, &output_ptr);
		
		RNA_enum_set(&input_ptr, "type", type);
		RNA_enum_set(&output_ptr, "type", type);
	}
}
Example #2
0
/* Global update function for Reroute node types.
 * This depends on connected nodes, so must be done as a tree-wide update.
 */
void ntree_update_reroute_nodes(bNodeTree *ntree)
{
	bNode *node;
	
	/* clear tags */
	for (node = ntree->nodes.first; node; node = node->next)
		node->done = 0;
	
	for (node = ntree->nodes.first; node; node = node->next)
		if (node->type == NODE_REROUTE && !node->done)
			node_reroute_inherit_type_recursive(ntree, node, REFINE_FORWARD | REFINE_BACKWARD);
}
Example #3
0
static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node, int flag)
{
	bNodeSocket *input = node->inputs.first;
	bNodeSocket *output = node->outputs.first;
	bNodeLink *link;
	int type = SOCK_FLOAT;
	const char *type_idname = nodeStaticSocketType(type, PROP_NONE);
	
	/* XXX it would be a little bit more efficient to restrict actual updates
	 * to rerout nodes connected to an updated node, but there's no reliable flag
	 * to indicate updated nodes (node->update is not set on linking).
	 */
	
	node->done = 1;
	
	/* recursive update */
	for (link = ntree->links.first; link; link = link->next) {
		bNode *fromnode = link->fromnode;
		bNode *tonode = link->tonode;
		if (!tonode || !fromnode)
			continue;
		if (nodeLinkIsHidden(link))
			continue;
		
		if (flag & REFINE_FORWARD) {
			if (tonode == node && fromnode->type == NODE_REROUTE && !fromnode->done)
				node_reroute_inherit_type_recursive(ntree, fromnode, REFINE_FORWARD);
		}
		if (flag & REFINE_BACKWARD) {
			if (fromnode == node && tonode->type == NODE_REROUTE && !tonode->done)
				node_reroute_inherit_type_recursive(ntree, tonode, REFINE_BACKWARD);
		}
	}
	
	/* determine socket type from unambiguous input/output connection if possible */
	if (input->limit == 1 && input->link) {
		type = input->link->fromsock->type;
		type_idname = nodeStaticSocketType(type, PROP_NONE);
	}
	else if (output->limit == 1 && output->link) {
		type = output->link->tosock->type;
		type_idname = nodeStaticSocketType(type, PROP_NONE);
	}
	
	if (input->type != type) {
		bNodeSocket *ninput = nodeAddSocket(ntree, node, SOCK_IN, type_idname, "input", "Input");
		for (link = ntree->links.first; link; link = link->next) {
			if (link->tosock == input) {
				link->tosock = ninput;
				ninput->link = link;
			}
		}
		nodeRemoveSocket(ntree, node, input);
	}
	
	if (output->type != type) {
		bNodeSocket *noutput = nodeAddSocket(ntree, node, SOCK_OUT, type_idname, "output", "Output");
		for (link = ntree->links.first; link; link = link->next) {
			if (link->fromsock == output) {
				link->fromsock = noutput;
			}
		}
		nodeRemoveSocket(ntree, node, output);
	}
	
	nodeUpdateInternalLinks(ntree, node);
}