Example #1
0
static void 
map_path(node_t * from, node_t * to, edge_t * orig, edge_t * ve, int type)
{
    int r;
    node_t *u, *v;
    edge_t *e;

    assert(ND_rank(from) < ND_rank(to));

    if ((agtail(ve) == from) && (aghead(ve) == to))
	return;

    if (ED_count(ve) > 1) {
	ED_to_virt(orig) = NULL;
	if (ND_rank(to) - ND_rank(from) == 1) {
	    if ((e = find_fast_edge(from, to)) && (ports_eq(orig, e))) {
		merge_oneway(orig, e);
		if ((ND_node_type(from) == NORMAL)
		    && (ND_node_type(to) == NORMAL))
		    other_edge(orig);
		return;
	    }
	}
	u = from;
	for (r = ND_rank(from); r < ND_rank(to); r++) {
	    if (r < ND_rank(to) - 1)
		v = clone_vn(agraphof(from), aghead(ve));
	    else
		v = to;
	    e = virtual_edge(u, v, orig);
	    ED_edge_type(e) = type;
	    u = v;
	    ED_count(ve)--;
	    ve = ND_out(aghead(ve)).list[0];
	}
    } else {
	if (ND_rank(to) - ND_rank(from) == 1) {
	    if ((ve = find_fast_edge(from, to)) && (ports_eq(orig, ve))) {
		/*ED_to_orig(ve) = orig; */
		ED_to_virt(orig) = ve;
		ED_edge_type(ve) = type;
		ED_count(ve)++;
		if ((ND_node_type(from) == NORMAL)
		    && (ND_node_type(to) == NORMAL))
		    other_edge(orig);
	    } else {
		ED_to_virt(orig) = NULL;
		ve = virtual_edge(from, to, orig);
		ED_edge_type(ve) = type;
	    }
	}
	if (ND_rank(to) - ND_rank(from) > 1) {
	    e = ve;
	    if (agtail(ve) != from) {
		ED_to_virt(orig) = NULL;
		e = ED_to_virt(orig) = virtual_edge(from, aghead(ve), orig);
		delete_fast_edge(ve);
	    } else
		e = ve;
	    while (ND_rank(aghead(e)) != ND_rank(to))
		e = ND_out(aghead(e)).list[0];
	    if (aghead(e) != to) {
		ve = e;
		e = virtual_edge(agtail(e), to, orig);
		ED_edge_type(e) = type;
		delete_fast_edge(ve);
	    }
	}
    }
}
Example #2
0
void class2(graph_t* g)
{
	int		c;
	node_t	*n,*t,*h;
	edge_t	*e,*prev,*opp;

	g->u.nlist = NULL;

	g->u.n_nodes = 0;	/* new */

	mark_clusters(g);
	for (c = 1; c <= g->u.n_cluster; c++)
		build_skeleton(g,g->u.clust[c]);
	for (n = agfstnode(g); n; n = agnxtnode(g,n))
		for (e = agfstout(g,n); e; e = agnxtout(g,e)) {
			if (e->head->u.weight_class <= 2) e->head->u.weight_class++;
			if (e->tail->u.weight_class <= 2) e->tail->u.weight_class++;
	}

	for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
		if ((n->u.clust == NULL) && (n == UF_find(n))) {fast_node(g,n); g->u.n_nodes++;}
		prev = NULL;
		for (e = agfstout(g,n); e; e = agnxtout(g,e)) {

				/* already processed */
			if (e->u.to_virt) continue;

				/* edges involving sub-clusters of g */
			if (is_cluster_edge(e)) {
				/* following is new cluster multi-edge code */
				if (mergeable(prev,e)) {
					if (prev->u.to_virt) { 
						merge_chain(g,e,prev->u.to_virt,FALSE);
						other_edge(e);
					}
					else if (e->tail->u.rank == e->head->u.rank) {
						merge_oneway(e,prev);
						other_edge(e);
					}
					/* else is an intra-cluster edge */
					continue;
				}
				interclrep(g,e);
				prev = e;
				continue;
			}
				/* merge multi-edges */
			if (prev && (e->tail == prev->tail) && (e->head == prev->head)) {
				if (e->tail->u.rank == e->head->u.rank) {
					merge_oneway(e,prev);
					other_edge(e);
					continue;
				}
				if ((e->u.label == NULL) && (prev->u.label == NULL) && ports_eq(e,prev)) {
					if (Concentrate) 
						e->u.edge_type = IGNORED;
					else{
					merge_chain(g,e,prev->u.to_virt,TRUE);
					other_edge(e);
					}
					continue;
				}
				/* parallel edges with different labels fall through here */
			}

				/* self edges */
			if (e->tail == e->head) {
				other_edge(e);
				prev = e;
				continue;
			}

			t = UF_find(e->tail);
			h = UF_find(e->head);

				/* non-leader leaf nodes */
			if ((e->tail != t) || (e->head != h)) {
					/* ### need to merge stuff */
				continue;	
			}


				/* flat edges */
			if (e->tail->u.rank == e->head->u.rank) {
				flat_edge(g,e);
				prev = e;
				continue;
			}

				/* forward edges */
			if (e->head->u.rank > e->tail->u.rank) {
				make_chain(g,e->tail,e->head,e);
				prev = e;
				continue;
			}

				/* backward edges */
			else {
				/*other_edge(e);*/
				if ((opp = agfindedge(g,e->head,e->tail))) {
					/* shadows a forward edge */
					if (opp->u.to_virt == NULL)
						make_chain(g,opp->tail,opp->head,opp);
					if ((e->u.label == NULL) && (opp->u.label == NULL) && ports_eq(e,opp)) {
						if (Concentrate) {
							e->u.edge_type = IGNORED;
							opp->u.conc_opp_flag = TRUE;
						}
						else{	/* see above.  this is getting out of hand */
						other_edge(e);
						merge_chain(g,e,opp->u.to_virt,TRUE);
						}
						continue;
					}
				}
				make_chain(g,e->head,e->tail,e);
				prev = e;
			}
		}
	}
	/* since decompose() is not called on subgraphs */
	if (g != g->root) {
		g->u.comp.list = ALLOC(1,g->u.comp.list,node_t*);
		g->u.comp.list[0] = g->u.nlist;
	}
Example #3
0
void map_path(node_t *from, node_t *to, edge_t *orig, edge_t *ve, int type)
{
	int			r;
	node_t		*u,*v;
	edge_t		*e;

	assert(from->u.rank < to->u.rank);

	if ((ve->tail == from) && (ve->head == to)) return;

	if (ve->u.count > 1)  {
		orig->u.to_virt = NULL;
		if (to->u.rank - from->u.rank == 1) {
			if ((e = find_fast_edge(from,to)) && (ports_eq(orig,e))) {
				merge_oneway(orig,e);
				if ((from->u.node_type == NORMAL)
					&& (to->u.node_type == NORMAL))
						other_edge(orig);
				return;
			}
		}
		u = from;
		for (r = from->u.rank; r < to->u.rank; r++) {
			if (r < to->u.rank - 1) v = clone_vn(from->graph,ve->head);
			else v = to;
			e = virtual_edge(u,v,orig);
			e->u.edge_type = type;
			u = v;
			ve->u.count--;
			ve = ve->head->u.out.list[0];
		}
	}
	else {
		if (to->u.rank - from->u.rank == 1) {
			if ((ve = find_fast_edge(from,to)) && (ports_eq(orig,ve))) {
				/*ve->u.to_orig = orig;*/
				orig->u.to_virt = ve;
				ve->u.edge_type = type;
				ve->u.count++;
				if ((from->u.node_type == NORMAL)
					&& (to->u.node_type == NORMAL))
						other_edge(orig);
			}
			else {
				orig->u.to_virt = NULL;
				ve = virtual_edge(from,to,orig);
				ve->u.edge_type = type;
			}
		}
		if (to->u.rank - from->u.rank > 1) {
			e = ve;
			if (ve->tail != from) {
				orig->u.to_virt = NULL;
				e = orig->u.to_virt = virtual_edge(from,ve->head,orig);
				delete_fast_edge(ve);
			}
			else e = ve;
			while (e->head->u.rank != to->u.rank) e = e->head->u.out.list[0];
			if (e->head != to) {
				ve = e;
				e = virtual_edge(e->tail,to,orig);
				e->u.edge_type = type;
				delete_fast_edge(ve);
			}
		}
	}
}
Example #4
0
/* finds another sharp edge which uses vert, by traversing faces around the
 * vert until it does one of the following:
 * - hits a loose edge (the edge is returned)
 * - hits a sharp edge (the edge is returned)
 * - returns to the start edge (NULL is returned)
 */
static SmoothEdge *find_other_sharp_edge(SmoothVert *vert, SmoothEdge *edge, LinkNode **visited_faces)
{
	SmoothFace *face = NULL;
	SmoothEdge *edge2 = NULL;
	/* holds the edges we've seen so we can avoid looping indefinitely */
	LinkNode *visited_edges = NULL;
#ifdef EDGESPLIT_DEBUG_1
	printf("=== START === find_other_sharp_edge(edge = %4d, vert = %4d)\n",
		edge->newIndex, vert->newIndex);
#endif

	/* get a face on which to start */
	if(edge->faces) face = edge->faces->link;
	else return NULL;

	/* record this edge as visited */
	BLI_linklist_prepend(&visited_edges, edge);

	/* get the next edge */
	edge2 = other_edge(face, vert, edge);

	/* record this face as visited */
	if(visited_faces)
		BLI_linklist_prepend(visited_faces, face);

	/* search until we hit a loose edge or a sharp edge or an edge we've
	* seen before
	*/
	while(face && !edge_is_sharp(edge2)
			 && !linklist_contains(visited_edges, edge2)) {
#ifdef EDGESPLIT_DEBUG_3
		printf("current face %4d; current edge %4d\n", face->newIndex,
			edge2->newIndex);
#endif
		/* get the next face */
		face = other_face(edge2, face);

		/* if face == NULL, edge2 is a loose edge */
		if(face) {
			/* record this face as visited */
			if(visited_faces)
				BLI_linklist_prepend(visited_faces, face);

			/* record this edge as visited */
			BLI_linklist_prepend(&visited_edges, edge2);

			/* get the next edge */
			edge2 = other_edge(face, vert, edge2);
#ifdef EDGESPLIT_DEBUG_3
			printf("next face %4d; next edge %4d\n",
				face->newIndex, edge2->newIndex);
		} else {
			printf("loose edge: %4d\n", edge2->newIndex);
#endif
		}
	}

	/* either we came back to the start edge or we found a sharp/loose edge */
	if(linklist_contains(visited_edges, edge2))
		/* we came back to the start edge */
		edge2 = NULL;

	BLI_linklist_free(visited_edges, NULL);

#ifdef EDGESPLIT_DEBUG_1
	printf("=== END === find_other_sharp_edge(edge = %4d, vert = %4d), "
		"returning edge %d\n",
		edge->newIndex, vert->newIndex, edge2 ? edge2->newIndex : -1);
#endif
	return edge2;
}