예제 #1
0
static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op))
{
	SpaceNode *snode = CTX_wm_space_node(C);
	bNodeLink *link;
	bNode *node;
	
	for (node = snode->edittree->nodes.first; node; node = node->next)
		node->flag &= ~NODE_TEST;

	for (link = snode->edittree->links.first; link; link = link->next) {
		if (nodeLinkIsHidden(link))
			continue;
		if (link->fromnode && link->tonode && (link->tonode->flag & NODE_SELECT))
			link->fromnode->flag |= NODE_TEST;
	}
	
	for (node = snode->edittree->nodes.first; node; node = node->next) {
		if (node->flag & NODE_TEST)
			nodeSetSelected(node, true);
	}
	
	ED_node_sort(snode->edittree);
	
	WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
	return OPERATOR_FINISHED;
}
예제 #2
0
static void node_group_output_update(bNodeTree *ntree, bNode *node)
{
	bNodeSocket *extsock = node->inputs.last;
	bNodeLink *link, *linknext, *exposelink;
	/* Adding a tree socket and verifying will remove the extension socket!
	 * This list caches the existing links to the extension socket
	 * so they can be recreated after verification.
	 */
	ListBase tmplinks;
	
	/* find links to the extension socket and store them */
	BLI_listbase_clear(&tmplinks);
	for (link = ntree->links.first; link; link = linknext) {
		linknext = link->next;
		if (nodeLinkIsHidden(link))
			continue;
		
		if (link->tosock == extsock) {
			bNodeLink *tlink = MEM_callocN(sizeof(bNodeLink), "temporary link");
			*tlink = *link;
			BLI_addtail(&tmplinks, tlink);
			
			nodeRemLink(ntree, link);
		}
	}
	
	/* find valid link to expose */
	exposelink = NULL;
	for (link = tmplinks.first; link; link = link->next) {
		/* XXX Multiple sockets can be connected to the extension socket at once,
		 * in that case the arbitrary first link determines name and type.
		 * This could be improved by choosing the "best" type among all links,
		 * whatever that means.
		 */
		if (link->fromsock->type != SOCK_CUSTOM) {
			exposelink = link;
			break;
		}
	}
	
	if (exposelink) {
		bNodeSocket *gsock, *newsock;
		
		/* XXX what if connecting virtual to virtual socket?? */
		gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->fromnode, exposelink->fromsock);
		
		node_group_output_verify(ntree, node, (ID *)ntree);
		newsock = node_group_output_find_socket(node, gsock->identifier);
		
		/* redirect links to the extension socket */
		for (link = tmplinks.first; link; link = link->next) {
			nodeAddLink(ntree, link->fromnode, link->fromsock, node, newsock);
		}
	}
	
	BLI_freelistN(&tmplinks);
}
예제 #3
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);
	}
}
예제 #4
0
파일: node_util.c 프로젝트: pawkoz/dyplom
void node_update_internal_links_default(bNodeTree *ntree, bNode *node)
{
	bNodeLink *link;
	bNodeSocket *output, *input;
	
	/* sanity check */
	if (!ntree)
		return;
	
	/* use link pointer as a tag for handled sockets (for outputs is unused anyway) */
	for (output = node->outputs.first; output; output = output->next)
		output->link = NULL;
	
	for (link = ntree->links.first; link; link = link->next) {
		if (nodeLinkIsHidden(link))
			continue;
		
		output = link->fromsock;
		if (link->fromnode != node || output->link)
			continue;
		if (nodeSocketIsHidden(output) || output->flag & SOCK_NO_INTERNAL_LINK)
			continue;
		output->link = link; /* not really used, just for tagging handled sockets */
		
		/* look for suitable input */
		input = select_internal_link_input(node, output);
		
		if (input) {
			bNodeLink *ilink = MEM_callocN(sizeof(bNodeLink), "internal node link");
			ilink->fromnode = node;
			ilink->fromsock = input;
			ilink->tonode = node;
			ilink->tosock = output;
			/* internal link is always valid */
			ilink->flag |= NODE_LINK_VALID;
			BLI_addtail(&node->internal_links, ilink);
		}
	}
	
	/* clean up */
	for (output = node->outputs.first; output; output = output->next)
		output->link = NULL;
}
예제 #5
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);
}