Example #1
0
void node_group_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp)
{
	node->id = (ID*)ntemp->ngroup;
	
	/* NB: group socket input/output roles are inverted internally!
	 * Group "inputs" work as outputs in links and vice versa.
	 */
	if (ntemp->ngroup) {
		bNodeSocket *gsock;
		for (gsock=ntemp->ngroup->inputs.first; gsock; gsock=gsock->next)
			node_group_add_extern_socket(ntree, &node->inputs, SOCK_IN, gsock);
		for (gsock=ntemp->ngroup->outputs.first; gsock; gsock=gsock->next)
			node_group_add_extern_socket(ntree, &node->outputs, SOCK_OUT, gsock);
	}
}
Example #2
0
static bNodeSocket *group_verify_socket(bNodeTree *ntree, ListBase *lb, int in_out, bNodeSocket *gsock)
{
	bNodeSocket *sock;
	
	/* group sockets tagged as internal are not exposed ever */
	if (gsock->flag & SOCK_INTERNAL)
		return NULL;
	
	for (sock= lb->first; sock; sock= sock->next) {
		if (sock->own_index==gsock->own_index)
				break;
	}
	if (sock) {
		sock->groupsock = gsock;
		
		BLI_strncpy(sock->name, gsock->name, sizeof(sock->name));
		if (gsock->type != sock->type)
			nodeSocketSetType(sock, gsock->type);
		
		/* XXX hack: group socket input/output roles are inverted internally,
		 * need to change the limit value when making actual node sockets from them.
		 */
		sock->limit = (in_out==SOCK_IN ? 1 : 0xFFF);
		
		BLI_remlink(lb, sock);
		
		return sock;
	}
	else {
		return node_group_add_extern_socket(ntree, NULL, in_out, gsock);
	}
}
Example #3
0
void node_forloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp)
{
    /* bNodeSocket *sock; */ /* UNUSED */

    node->id = (ID*)ntemp->ngroup;

    /* sock = */ nodeAddInputFloat(ntree, node, "Iterations", PROP_UNSIGNED, 1, 0, 10000);

    /* NB: group socket input/output roles are inverted internally!
     * Group "inputs" work as outputs in links and vice versa.
     */
    if (ntemp->ngroup) {
        bNodeSocket *gsock;
        for (gsock=ntemp->ngroup->inputs.first; gsock; gsock=gsock->next)
            node_group_add_extern_socket(ntree, &node->inputs, SOCK_IN, gsock);
        for (gsock=ntemp->ngroup->outputs.first; gsock; gsock=gsock->next)
            node_group_add_extern_socket(ntree, &node->outputs, SOCK_OUT, gsock);
    }
}
Example #4
0
void node_forloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp)
{
	bNodeSocket *sock;
	
	node->id = (ID*)ntemp->ngroup;
	
	sock = nodeAddSocket(ntree, node, SOCK_IN, "Iterations", SOCK_FLOAT);
	node_socket_set_default_value_float(sock->default_value, PROP_UNSIGNED, 1, 0, 10000);
	
	/* NB: group socket input/output roles are inverted internally!
	 * Group "inputs" work as outputs in links and vice versa.
	 */
	if (ntemp->ngroup) {
		bNodeSocket *gsock;
		for (gsock=ntemp->ngroup->inputs.first; gsock; gsock=gsock->next)
			node_group_add_extern_socket(ntree, &node->inputs, SOCK_IN, gsock);
		for (gsock=ntemp->ngroup->outputs.first; gsock; gsock=gsock->next)
			node_group_add_extern_socket(ntree, &node->outputs, SOCK_OUT, gsock);
	}
}
Example #5
0
bNode *node_group_make_from_selected(bNodeTree *ntree)
{
    bNodeLink *link, *linkn;
    bNode *node, *gnode, *nextn;
    bNodeTree *ngroup;
    bNodeSocket *gsock;
    ListBase anim_basepaths = {NULL, NULL};
    float min[2], max[2];
    int totnode=0;
    bNodeTemplate ntemp;

    INIT_MINMAX2(min, max);

    /* is there something to group? also do some clearing */
    for(node= ntree->nodes.first; node; node= node->next) {
        if(node->flag & NODE_SELECT) {
            /* no groups in groups */
            if(node->type==NODE_GROUP)
                return NULL;
            DO_MINMAX2( (&node->locx), min, max);
            totnode++;
        }
        node->done= 0;
    }
    if(totnode==0) return NULL;

    /* check if all connections are OK, no unselected node has both
    	inputs and outputs to a selection */
    for(link= ntree->links.first; link; link= link->next) {
        if(link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT)
            link->tonode->done |= 1;
        if(link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT)
            link->fromnode->done |= 2;
    }

    for(node= ntree->nodes.first; node; node= node->next) {
        if((node->flag & NODE_SELECT)==0)
            if(node->done==3)
                break;
    }
    if(node)
        return NULL;

    /* OK! new nodetree */
    ngroup= ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP);

    /* move nodes over */
    for(node= ntree->nodes.first; node; node= nextn) {
        nextn= node->next;
        if(node->flag & NODE_SELECT) {
            /* keep track of this node's RNA "base" path (the part of the pat identifying the node)
             * if the old nodetree has animation data which potentially covers this node
             */
            if (ntree->adt) {
                PointerRNA ptr;
                char *path;

                RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
                path = RNA_path_from_ID_to_struct(&ptr);

                if (path)
                    BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
            }

            /* change node-collection membership */
            BLI_remlink(&ntree->nodes, node);
            BLI_addtail(&ngroup->nodes, node);

            node->locx-= 0.5f*(min[0]+max[0]);
            node->locy-= 0.5f*(min[1]+max[1]);
        }
    }

    /* move animation data over */
    if (ntree->adt) {
        LinkData *ld, *ldn=NULL;

        BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths);

        /* paths + their wrappers need to be freed */
        for (ld = anim_basepaths.first; ld; ld = ldn) {
            ldn = ld->next;

            MEM_freeN(ld->data);
            BLI_freelinkN(&anim_basepaths, ld);
        }
    }

    /* make group node */
    ntemp.type = NODE_GROUP;
    ntemp.ngroup = ngroup;
    gnode= nodeAddNode(ntree, &ntemp);
    gnode->locx= 0.5f*(min[0]+max[0]);
    gnode->locy= 0.5f*(min[1]+max[1]);

    /* relink external sockets */
    for(link= ntree->links.first; link; link= linkn) {
        linkn= link->next;

        if(link->fromnode && link->tonode && (link->fromnode->flag & link->tonode->flag & NODE_SELECT)) {
            BLI_remlink(&ntree->links, link);
            BLI_addtail(&ngroup->links, link);
        }
        else if(link->tonode && (link->tonode->flag & NODE_SELECT)) {
            gsock = node_group_expose_socket(ngroup, link->tosock, SOCK_IN);
            link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock);
            link->tosock = node_group_add_extern_socket(ntree, &gnode->inputs, SOCK_IN, gsock);
            link->tonode = gnode;
        }
        else if(link->fromnode && (link->fromnode->flag & NODE_SELECT)) {
            /* search for existing group node socket */
            for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next)
                if (gsock->link && gsock->link->fromsock==link->fromsock)
                    break;
            if (!gsock) {
                gsock = node_group_expose_socket(ngroup, link->fromsock, SOCK_OUT);
                gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock);
                link->fromsock = node_group_add_extern_socket(ntree, &gnode->outputs, SOCK_OUT, gsock);
            }
            else
                link->fromsock = node_group_find_output(gnode, gsock);
            link->fromnode = gnode;
        }
    }

    ngroup->update |= NTREE_UPDATE;
    ntreeUpdateTree(ngroup);
    ntree->update |= NTREE_UPDATE_NODES|NTREE_UPDATE_LINKS;
    ntreeUpdateTree(ntree);

    return gnode;
}