Beispiel #1
0
void node_group_link(bNodeTree *ntree, bNodeSocket *sock, int in_out)
{
	node_group_expose_socket(ntree, sock, in_out);
}
Beispiel #2
0
static void loop_sync(bNodeTree *ntree, int sync_in_out)
{
	bNodeSocket *sock, *sync, *nsync, *mirror;
	ListBase *sync_lb;
	
	if (sync_in_out==SOCK_IN) {
		sock = ntree->outputs.first;
		
		sync = ntree->inputs.first;
		sync_lb = &ntree->inputs;
	}
	else {
		sock = ntree->inputs.first;
		
		sync = ntree->outputs.first;
		sync_lb = &ntree->outputs;
	}
	
	/* NB: the sock->storage pointer is used here directly to store the own_index int
	 * out the mirrored socket counterpart!
	 */
	
	while (sock) {
		/* skip static and internal sockets on the sync side (preserves socket order!) */
		while (sync && ((sync->flag & SOCK_INTERNAL) || !(sync->flag & SOCK_DYNAMIC)))
			sync = sync->next;
		
		if (sync && !(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC)) {
			if (sock->storage==NULL) {
				/* if mirror index is 0, the sockets is newly added and a new mirror must be created. */
				mirror = node_group_expose_socket(ntree, sock, sync_in_out);
				/* store the mirror index */
				sock->storage = SET_INT_IN_POINTER(mirror->own_index);
				mirror->storage = SET_INT_IN_POINTER(sock->own_index);
				/* move mirror to the right place */
				BLI_remlink(sync_lb, mirror);
				if (sync)
					BLI_insertlinkbefore(sync_lb, sync, mirror);
				else
					BLI_addtail(sync_lb, mirror);
			}
			else {
				/* look up the mirror socket */
				for (mirror=sync; mirror; mirror=mirror->next)
					if (mirror->own_index == GET_INT_FROM_POINTER(sock->storage))
						break;
				/* make sure the name is the same (only for identification by user, no deeper meaning) */
				BLI_strncpy(mirror->name, sock->name, sizeof(mirror->name));
				/* fix the socket order if necessary */
				if (mirror != sync) {
					BLI_remlink(sync_lb, mirror);
					BLI_insertlinkbefore(sync_lb, sync, mirror);
				}
				else
					sync = sync->next;
			}
		}
		
		sock = sock->next;
	}
	
	/* remaining sockets in sync_lb are leftovers from deleted sockets, remove them */
	while (sync) {
		nsync = sync->next;
		if (!(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC))
			node_group_remove_socket(ntree, sync, sync_in_out);
		sync = nsync;
	}
}
Beispiel #3
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;
}