Edge GRAPHmaxFlow(Graph G){ int i,j; Edge e; e=EDGE(0,0,0); for(i=0;i<G->V;i++){ for(j=0;j<G->V;j++){ if(G->adj[i][j]>e.cost){ e=EDGE(i,j,G->adj[i][j]); }}} return e; }
Edge* EDGEget(Graph G, int *n){ int i,j,cont=0,k=0; Edge *e,a; for(i=0;i<G->V;i++){ for(j=0;j<G->V;j++){ if(G->adj[i][j]!=0) cont++; }} *n=cont; e=malloc(cont*sizeof(Edge)); for(i=0;i<G->V;i++){ for(j=0;j<G->V;j++){ if(G->adj[i][j]!=0){ a=EDGE(i,j,G->adj[i][j]); e[k]=a; k++; } }} return e; }
Graph generate_network (char *filename) { FILE *finn; int n; int v, w; double weight; Edge e; Graph G = malloc(sizeof(Graph)); finn = fopen(filename, "r"); if (finn == NULL) { fprintf(stderr, "Error in opening file %s.\n", filename); exit(EXIT_FAILURE); } fscanf (finn, "%d", &n); G = GRAPHinit(n); while ( (fscanf(finn, "%d-%d %lf", &v, &w, &weight)) > 0 ) { e = EDGE(v, w, weight); GRAPHinsertE(G, e); } fclose(finn); return G; }
void dfsR(Graph G, Edge e) { link t; int v, w = e.w; Edge x; if (e.v != e.w) printf("edge (%d, %d) is tree \n", e.v, e.w) ; st[e.w] = e.v; pre[w] = time++; for (t = G->adj[w]; t != NULL; t = t->next) if (pre[t->v] == -1) dfsR(G, EDGE(w, t->v)); else { v = t->v; x = EDGE(w, v); if (pre[w] < pre[v]) printf("edge (%d, %d) is back \n", x.v, x.w) ; } post[w] = time++; }
/// Preenche o vetor de Edges @a com todas as arestas existentes no grafo. /// @a: vetor de arestas. /// @G: grafo de busca. /// @return: número de arestas existentes. int GRAPHedges( Edge a[], Graph *G ) { int v, w, E = 0; for( v = 0; v < G->V; v++) for( w = v+1; w < G->V; w++) if( G->adj[v][w] == 1 ) a[E++] = EDGE( v, w ); return E; }
edge_set transform_figure(edge_set es, float A[4][4]) { size_t s = es.size(); edge_set to_return(s); for (int i = 0 ; i < s ; i++) { to_return[i] = EDGE(transform(es.at(i).first, A), transform(es.at(i).second, A)); } return to_return; }
// edges with probability p Graph GRAPHrand(Graph G, int V, int E) { int i, j; double p = 2.0 * E / (V * (V-1)); for ( i = 0; i < V; i++) for ( j = i+1; j < V; j++) if (rand() < p * RAND_MAX) GRAPHinsertE(G, EDGE(i, j)); return G; }
Graph GRAPHrand(int V, int E) { int i, j; double p = 2.0*E/V/(V-1); Graph G = GRAPHinit(V); for (i = 0; i < V; i++) for (j = 0; j < i; j++) if (rand() < p*RAND_MAX) GRAPHinsertE(G, EDGE(i, j)); return G; }
int GRAPHedges(Graph G, Edge a[]) { int v, E = 0; link t; for (v=0; v < G->V; v++) for (t=G->adj[v]; t != NULL; t = t->next) if (v < t->v) a[E++] = EDGE(v, t->v); return E; }
int igraph_i_create_start(igraph_vector_t *res, igraph_vector_t *el, igraph_vector_t *index, igraph_integer_t nodes) { # define EDGE(i) (VECTOR(*el)[ (long int) VECTOR(*index)[(i)] ]) long int no_of_nodes; long int no_of_edges; long int i, j, idx; no_of_nodes=nodes; no_of_edges=igraph_vector_size(el); /* result */ IGRAPH_CHECK(igraph_vector_resize(res, nodes+1)); /* create the index */ if (igraph_vector_size(el)==0) { /* empty graph */ igraph_vector_null(res); } else { idx=-1; for (i=0; i<=EDGE(0); i++) { idx++; VECTOR(*res)[idx]=0; } for (i=1; i<no_of_edges; i++) { long int n=EDGE(i) - EDGE((long int)VECTOR(*res)[idx]); for (j=0; j<n; j++) { idx++; VECTOR(*res)[idx]=i; } } j=EDGE((long int)VECTOR(*res)[idx]); for (i=0; i<no_of_nodes-j; i++) { idx++; VECTOR(*res)[idx]=no_of_edges; } } /* clean */ # undef EDGE return 0; }
int path(Graph g, int v) { int w; for( ; g->adj[v] != NULL; v=w){ STACKpush(v); w = g->adj[v]->v; GRAPHremoveE(g,EDGE(v,w)); } return v; }
static void findstats(Pos p, Ori o) { /* Recalculate cross assert and score total at 'p' */ Pos left, right; Word lword, rword; Node n; Edge e; int s; lword.n = rword.n = 0; if(EDGE(p)) return; /* find word to the left */ s = 0; for(left=PREV(p,o); HASLETTER(left); left = PREV(left,o)) ; left = NEXT(left,o); while (HASLETTER(left)) { lword.c[lword.n++] = LETTER(left); s += SCORE(left); left = NEXT(left,o); } /* find word to the right */ for(right=NEXT(p,o); HASLETTER(right); right = NEXT(right,o)) { rword.c[rword.n++] = LETTER(right); s += SCORE(right); } if(DBG) { wordprint(&lword); print("X"); wordprint(&rword); print(" [%d] ", s); } SIDE(p,o) = s; ISANCHOR(p) = true; /* calculate cross asserts */ CROSS(p,o) = 0; n = traverse(root, &lword, 0); assert(n>=0); if(n>0) do { e = dict[n++]; if ( (rword.n && isword(NODE(e), &rword)) || (!rword.n && TERM(e)) ) { CROSS(p,o) |= 1 << LET(e); DPRINT("%c, ", LET(e)+'a'); } } while (!(LAST(e))); DPRINT("\n"); }
edge_set translate_figure(edge_set es, float dx, float dy, float dz) { float A[4][4]; generate_translation_matrix(A, dx, dy, dz); size_t s = es.size(); edge_set to_return(s); for (int i = 0 ; i < s ; i++) { to_return[i] = EDGE(transform(es.at(i).first, A), transform(es.at(i).second, A)); } return to_return; }
Graph graphScan(char *file){ int v,w; int V; FILE *in = fopen(file, "r"); fscanf(in, "%d",&V); Graph g = GRAPHinit(V); while(fscanf(in,"%d %d",&v,&w) == 2){ GRAPHinsertE(g,EDGE(v,w)); } fclose(in); return g; }
int GRAPHedges(Edge a[], Graph g) { int v, e=0; link t; for (v = 0; v < g->v; v++) { for(t = g->adj[v]; t != NULL; t = t->next) if(v < t->v) a[e++] = EDGE(v,t->v); } retrun e; }
void GRAPHbridge(Graph G) { int v; time = 0, bcnt =0; for (v=0; v < G->V; v++) pre[v] = -1; for (v=0; v < G->V; v++) if (pre[v]== -1) bridgeR(G, EDGE(v, v)); if (bcnt == 0) printf("No bridge found!\n"); }
int GRAPHedges (Edge edges[], Graph g) { int v, E = 0; vlink t; for (v = 0; v < g->V; v++) { for (t = g->adj[v]; t != NULL; t = t->next) { if (v < t->v) { edges[E++] = EDGE(v, t->v); } } } return E; }
edge_set rotate_figure(edge_set es, int axis, float angle) { float A[4][4]; generate_rotation_matrix(A, axis, angle); size_t s = es.size(); edge_set to_return(s); for (int i = 0 ; i < s ; i++) { to_return[i] = EDGE(transform(es.at(i).first, A), transform(es.at(i).second, A)); } return to_return; }
void gtk_graph_clear(GtkGraph *graph) { int i; g_return_if_fail(graph); g_return_if_fail(GTK_IS_GRAPH(graph)); for (i=0; i<graph->nodes->len; i++) { if (NODE(graph, i)->label) g_free(NODE(graph, i)->label); g_free(NODE(graph, i)); } for (i=0; i<graph->edges->len; i++) g_free(EDGE(graph, i)); graph->nodes->len = graph->edges->len = 0; gtk_graph_update(graph); }
void bridgeR(Graph G, Edge e) { link t; int v, w = e.w; pre[w] = time++; low[w] = pre[w]; for (t = G->adj[w]; t != NULL; t = t->next) if (pre[v = t->v] == -1) { bridgeR(G, EDGE(w, v)); if (low[w] > low[v]) low[w] = low[v]; if (low[v] == pre[v]) { bcnt++; printf("edge %d - %d is a bridge \n", w, v); } } else if (v != e.v) if(low[w] > pre[v]) low[w] = pre[v]; }
Edge* EdgegetOUT(Graph G,int a,int *n){ Edge *e; int i,j=0,cont=0; for(i=0;i<G->V;i++){ if(G->adj[a][i]!=0) cont++; } *n=cont; e=malloc(cont*sizeof(Edge)); for(i=0;i<G->V;i++){ if(G->adj[a][i]!=0){ e[j]=EDGE(a,i,G->adj[a][i]); j++; } } return e; }
void GRAPHdfs(Graph G) { int v; time = 0; for (v=0; v < G->V; v++) { pre[v] = -1; post[v] = -1; st[v] = -1; } for (v=0; v < G->V; v++) if (pre[v]== -1) dfsR(G, EDGE(v,v)); printf("discovery/endprocessing time labels \n"); for (v=0; v < G->V; v++) printf("vertex %d : %d/%d \n", v, pre[v], post[v]); printf("resulting DFS tree \n"); for (v=0; v < G->V; v++) printf("parent of vertex %d is vertex %d \n", v, st[v]); }
void expand() { RESET(7) NODE(7) ORFAIL RESET(8) EDTO(7, 8) ORBACK RESET(9) EDFR(7, 9) ORBACK RESET(10) EDGE(7, 10) ORBACK } void Modify() { CALL(inc) ORFAIL ALAP(prepare) ALAP(expand) } void GPMAIN() { CALL(init) ORFAIL
edge rotate(edge e, int axis, float angle) { float A[4][4]; generate_rotation_matrix(A, axis, angle); return EDGE(transform(e.first, A), transform(e.second, A)); }
edge translate(edge e, float dx, float dy, float dz) { float A[4][4]; generate_translation_matrix(A, dx, dy, dz); return EDGE(transform(e.first, A), transform(e.second, A)); }
edge transform(edge e, float A[4][4]) { return EDGE(transform(e.first, A), transform(e.second, A)); }
/* Main */ int main(int argc, char* argv[]) { int nnF = 200000, nnV = 200000, nnT = 1100000; int nF = 0, nV = 0, nT = 0; int *face = 0, *facematerial = 0, *facedup = 0, *facematdup = 0; int *tetra = 0, *tetramaterial = 0; double *vertex = 0; int i, nFdup, r, j, medge, msurf, m, k, p; int nVVert, nLine, nSurface; int *LineD, *LineP; double *LineT; int *SurfL, *SurfI; double *SurfT; double *VVert; int *expCrv; int nE = 0, nnE = 100000, *edge, *edgematerial; int va, vb, vc, vd, ve, vf, vg, vh; int vc1a, vc1b, vc2a, vc2b, vc3a, vc3b; int arc1a, arc1b, arc2a, arc2b, arc3a, arc3b; int eab, ebc, ecd, eda, eef, efg, egh, ehe, eae, ebf, ecg, edh; int ntfix = 0, nvfix = 0; int izero = 0; // allocate memory for mesh ctructures vertex = (double*)malloc(sizeof(double) * 3 * nnV); face = (int*) malloc(sizeof(int) * 3 * nnF); facedup = (int*) malloc(sizeof(int) * 3 * nnF); facematerial = (int*) malloc(sizeof(int) * nnF); facematdup = (int*) malloc(sizeof(int) * nnF); tetra = (int*) malloc(sizeof(int) * 4 * nnT); tetramaterial = (int*) malloc(sizeof(int) * nnT); edge = (int*) malloc(sizeof(int) * 2 * nnE); edgematerial = (int*) malloc(sizeof(int) * nnE); // allocate memory for boundary representation structure VVert = (double*)malloc(sizeof(double) * 3*100); nVVert = 0; LineD = (int*) malloc(sizeof(int) * 3*100); LineP = (int*) malloc(sizeof(int) * 2*2*100); LineT = (double*)malloc(sizeof(double) * 2*2*100); nLine = 0; SurfL = (int*) malloc(sizeof(int) * 5*100); SurfI = (int*) malloc(sizeof(int) * 2*2*100); SurfT = (double*)malloc(sizeof(double) * 4*100); nSurface = 0; expCrv = (int*) malloc(sizeof(int) * 100); memset(expCrv, 0, sizeof(int) * 100); /***/ #define ADD_VERTEX(X, Y, Z) (VVert[3*nVVert+0] = X, VVert[3*nVVert+1] = Y, VVert[3*nVVert+2] = Z, ++nVVert) #define EDGE(V1, V2, N, ...) add_edge(LineD, LineP, LineT, &nLine, &medge, V1, V2, N, __VA_ARGS__) #define SURF(P, C1, C2, D, U1, U2, V1, V2, N, ...) add_surf(SurfL, SurfT, SurfI, &nSurface, &msurf, P, C1, C2, D, U1, U2, V1, V2, N, __VA_ARGS__) /***/ vc1a = ADD_VERTEX( R1, 0, 0); vc1b = ADD_VERTEX(-R1, 0, 0); vc2a = ADD_VERTEX( R2, 0, 0); vc2b = ADD_VERTEX(-R2, 0, 0); vc3a = ADD_VERTEX( R3, 0, 0); vc3b = ADD_VERTEX(-R3, 0, 0); va = ADD_VERTEX(-Db, -Db, 0); vb = ADD_VERTEX(-Db, Db, 0); vc = ADD_VERTEX( Db, Db, 0); vd = ADD_VERTEX( Db, -Db, 0); ve = ADD_VERTEX(-Db, -Db, -Db); vf = ADD_VERTEX(-Db, Db, -Db); vg = ADD_VERTEX( Db, Db, -Db); vh = ADD_VERTEX( Db, -Db, -Db); medge = 0; /* EDGE(v1, v2, nSurf, [iSurf, iLine, t_0, t1,] ...); */ arc1a = EDGE(vc1a, vc1b, 1, 1, 1, 0.0, M_PI); arc1b = EDGE(vc1b, vc1a, 1, 1, 1, M_PI, 2.0*M_PI); arc2a = EDGE(vc2a, vc2b, 1, 1, 2, M_PI, 0.0); arc2b = EDGE(vc2b, vc2a, 1, 1, 2, 2.0*M_PI, M_PI); arc3a = EDGE(vc3a, vc3b, 1, 1, 3, 0.0, M_PI); arc3b = EDGE(vc3b, vc3a, 1, 1, 3, M_PI, 2.0*M_PI); expCrv[arc1a-1] = 1, expCrv[arc1b-1] = 1; expCrv[arc2a-1] = 1, expCrv[arc2b-1] = 1; expCrv[arc3a-1] = 1, expCrv[arc3b-1] = 1; eab = EDGE(va, vb, 1, 0, 0, 0.0, 0.0); ebc = EDGE(vb, vc, 1, 0, 0, 0.0, 0.0); ecd = EDGE(vc, vd, 1, 0, 0, 0.0, 0.0); eda = EDGE(vd, va, 1, 0, 0, 0.0, 0.0); eef = EDGE(ve, vf, 1, 0, 0, 0.0, 0.0); efg = EDGE(vf, vg, 1, 0, 0, 0.0, 0.0); egh = EDGE(vg, vh, 1, 0, 0, 0.0, 0.0); ehe = EDGE(vh, ve, 1, 0, 0, 0.0, 0.0); eae = EDGE(va, ve, 1, 0, 0, 0.0, 0.0); ebf = EDGE(vb, vf, 1, 0, 0, 0.0, 0.0); ecg = EDGE(vc, vg, 1, 0, 0, 0.0, 0.0); edh = EDGE(vd, vh, 1, 0, 0, 0.0, 0.0); msurf = 0; /* SURF(iSurf, color1, color2, direction, u0, u1, v0, v1, n, [edge, edge_dir,] ...); */ SURF(1, 2, 11, 0, -Db, Db, -Db, Db, 2, arc1a, 0, arc1b, 0); SURF(1, 1, 0, 0, -Db, Db, -Db, Db, 4, arc2a, 1, arc2b, 1, arc1a, 1, arc1b, 1); SURF(1, 2, 12, 0, -Db, Db, -Db, Db, 4, arc3a, 0, arc3b, 0, arc2a, 0, arc2b, 0); SURF(0, 1, 0, 0, 0.0, 0.0, 0.0, 0.0, 6, arc3a, 1, arc3b, 1, eab, 1, ebc, 1, ecd, 1, eda, 1); SURF(0, 1, 0, 0, 0.0, 0.0, 0.0, 0.0, 4, eef, 0, efg, 0, egh, 0, ehe, 0); SURF(0, 1, 0, 0, 0.0, 0.0, 0.0, 0.0, 4, eab, 0, ebf, 0, eef, 1, eae, 1); SURF(0, 1, 0, 0, 0.0, 0.0, 0.0, 0.0, 4, ebc, 0, ecg, 0, efg, 1, ebf, 1); SURF(0, 1, 0, 0, 0.0, 0.0, 0.0, 0.0, 4, ecd, 0, edh, 0, egh, 1, ecg, 1); SURF(0, 1, 0, 0, 0.0, 0.0, 0.0, 0.0, 4, eda, 0, eae, 0, ehe, 1, edh, 1); tria_dump_front = 0; tria_debug_front = 0; region_dump_face = 0; printf("\n * Generating surface mesh\n"); i = ani3d_surface_edges_boundary_(&nVVert, VVert, &nLine, LineD, LineP, LineT, &nSurface, SurfL, SurfI, SurfT, NULL, surface_param, line_param, NULL/*periodic*/, fsize, expCrv, &nV, vertex, &nF, face, facematerial, &nE, edge, edgematerial, &nnV, &nnF, &nnE ); free(VVert), free(LineD), free(LineP), free(LineT), free(SurfL), free(SurfI), free(SurfT); printf("INFO: nV = %d, nE = %d, nF = %d, nT = %d\n", nV, nE, nF, nT); /* Generate skin mesh */ printf("\n * Generating skin mesh\n"); nFdup = 0; addlayer(electrodesize, &nV, vertex-3, nE, edge, edgematerial, &nF, face, facematerial, &nT, tetra, tetramaterial, &nFdup, facedup, facematdup, nnV, nnF, nnT); fix_vertices(&nV, vertex-3, nF, face, nT, tetra, nFdup, facedup, nE, edge); printf("INFO: nV = %d, nF = %d, nT = %d\n", nV, nF, nT); // It could be usefull to dump the triangulation of the surface in case we want to check // that boundary representation is correct and represents the desired region if (0) { write_mesh_gmv("surf.gmv", nV, vertex, nF, face, facematerial, nT, tetra, tetramaterial); // for GMV write_front ("surf.smv", nV, vertex, nF, face, facematerial); // for smv // return 0; // do not mesh the volume, just exit write_mesh_gmv("dups.gmv", nV, vertex, nFdup, facedup, facematdup, nT, tetra, tetramaterial); // for GMV write_front ("dups.smv", nV, vertex, nFdup, facedup, facematdup); // for smv } // We will copy the front, so that it could be used in output in future. ntfix = nT; nvfix = nV; for (i=0; i<nF; i++) { facedup[3*nFdup+0] = face[3*i+0]; facedup[3*nFdup+1] = face[3*i+1]; facedup[3*nFdup+2] = face[3*i+2]; facematdup[nFdup] = facematerial[i]; nFdup++; } // Generate 3D mesh using our own size function fsize() printf("\n * Generating volume mesh\n"); r = mesh_3d_aft_func_(&nV, vertex, &nF, face, facematerial, &nT, tetra, tetramaterial, &nnV, &nnF, &nnT, fsize); printf("\nINFO: nV = %d, nF = %d, nT = %d\n", nV, nF, nT); if (r) { write_mesh_gmv("fail.gmv", nV, vertex, nF, face, facematerial, nT, tetra, tetramaterial); } else { /* Check that 3D mesh corresponds with surface mesh */ /*printf("Checking topology: "), fflush(stdout);*/ if (0 && check_mesh_topology_(&nV, vertex, &nFdup, facedup, &nT, tetra)) printf("FAILED!\n"); else { /*printf("ok.\n");*/ if (0) { write_mesh ("bfix.out", nV, vertex, nFdup, facedup, facematdup, nT, tetra, tetramaterial); write_mesh_gmv_qual("bfix.gmv", nV, vertex, nFdup, facedup, facematdup, nT, tetra, tetramaterial); } for (i=0; i<nT; i++) tetramaterial[i] = (tetramaterial[i]==1) ? 2 : tetramaterial[i]; keepskin(&nFdup, facedup, facematdup); /* Improve mesh quality */ printf("\n * Smoothing volume mesh\n"); fixshape(&nV, vertex, &nT, tetra, tetramaterial, &nFdup, facedup, facematdup, 0, ntfix, nFdup, nnV, nnT, nnF); keepskin(&nFdup, facedup, facematdup); // Write output files write_mesh_gmv_qual("mesh.gmv", nV, vertex, nFdup, facedup, facematdup, nT, tetra, tetramaterial); /*write_mesh ("mesh.out", nV, vertex, nFdup, facedup, facematdup, nT, tetra, tetramaterial);*/ saveMani(&nV, &nFdup, &nT, vertex, facedup, tetra, facematdup, tetramaterial, &izero, &izero, &izero, NULL, NULL, NULL, &izero, NULL, NULL, "mesh.ani"); } } free(vertex); free(face); free(facedup); free(facematerial); free(facematdup); free(tetra); free(tetramaterial); return 0; }
Mesh * mesh_triangulate_polygon( const Polygon *poly ) { g_return_val_if_fail( poly != NULL, NULL ); g_return_val_if_fail( poly->vertices != NULL, NULL ); g_return_val_if_fail( g_list_length( poly->vertices ) >= 3, NULL ); reflex_vertices = g_hash_table_new( NULL, NULL ); convex_vertices = g_hash_table_new( NULL, NULL ); ears = g_hash_table_new( NULL, NULL ); /* create a new mesh */ Mesh *mesh = mesh_new(); /* add polygon's nodes and edges to the mesh */ add_polygon_to_mesh( mesh, poly ); /* take the first half-edge of the first edge as the starting half-edge */ HalfEdge *he_start = &EDGE(mesh->edges->data)->he[0]; HalfEdge *he_iter = he_start; /* iterate over half-edges lying on the inner side of the boundary */ do { /* classify half-edge's origin according to its convexity */ if ( halfedge_origin_is_convex( he_iter ) ) g_hash_table_insert( convex_vertices, he_iter->origin, he_iter ); else g_hash_table_insert( reflex_vertices, he_iter->origin, he_iter ); he_iter = he_iter->next; } while ( he_iter != he_start ); /* iterate over convex vertices */ GHashTableIter convex_vert_iter; g_hash_table_iter_init( &convex_vert_iter, convex_vertices ); gpointer key, value; while ( g_hash_table_iter_next( &convex_vert_iter, &key, &value ) ) { HalfEdge *conv_he = HALFEDGE(value); /* check if the convex vertex is an ear */ if ( halfedge_origin_is_ear( conv_he ) ) g_hash_table_insert( ears, conv_he->origin, conv_he ); } /* iterate over ears */ GHashTableIter ears_iter; g_hash_table_iter_init( &ears_iter, ears ); while ( g_hash_table_iter_next( &ears_iter, &key, &value) ) { /* since we will cut it off, remove the ear from ears and convex vertex * hash table */ g_hash_table_remove( ears, key ); g_hash_table_remove( convex_vertices, key ); HalfEdge *he2 = HALFEDGE(value); HalfEdge *he1 = he2->previous; Node *n1 = he1->origin; Node *n3 = he2->pair->origin; /* cut off the ear: */ /* add an edge connecting the ear's neighbours */ Edge *e = mesh_add_edge( mesh, n3, n1 ); HalfEdge *he3 = &e->he[0]; /* add ear's triangle to the mesh */ mesh_add_element( mesh, he1, he2, he3 ); he1 = &e->he[1]; he2 = he1->next; gboolean was_reflex_1 = FALSE; gboolean was_reflex_became_convex_1 = FALSE; gboolean was_reflex_2 = FALSE; gboolean was_reflex_became_convex_2 = FALSE; /* update the status of the ear's neighbours */ /* first, we need to update the reflex status of both neighbours, as * we need up-to-date info about reflex vertices in the "ear-ness" test */ if ( g_hash_table_lookup( reflex_vertices, n1 ) ) { was_reflex_1 = TRUE; /* reflex vertex can become convex */ if ( halfedge_origin_is_convex( he1 ) ) { was_reflex_became_convex_1 = TRUE; /* is now convex, remove from reflex vertices */ g_hash_table_remove( reflex_vertices, n1 ); } } if ( g_hash_table_lookup( reflex_vertices, n3 ) ) { was_reflex_2 = TRUE; if ( halfedge_origin_is_convex( he2 ) ) { was_reflex_became_convex_2 = TRUE; g_hash_table_remove( reflex_vertices, n3 ); } } /* now we can proceed with the other tests */ if ( was_reflex_1 ) { if ( was_reflex_became_convex_1 ) { /* add to convex vertices */ g_hash_table_insert( convex_vertices, n1, he1 ); /* if was reflex and became convex and even an ear, add it to * ears */ if ( halfedge_origin_is_ear( he1 ) ) g_hash_table_insert( ears, n1, he1 ); } else /* if it stayed reflex, just update it with a new half-edge */ g_hash_table_insert( reflex_vertices, n1, he1 ); } else if ( g_hash_table_lookup( ears, n1 ) ) { /* if it was an ear and now is not, remove it from ears (but it * stays convex) */ if ( ! halfedge_origin_is_ear( he1 ) ) g_hash_table_remove( ears, n1 ); else /* if it stayed an ear, just update it with a new half-edge */ g_hash_table_insert( ears, n1, he1 ); } else if ( g_hash_table_lookup( convex_vertices, n1 ) ) { /* if it was convex and now became an ear, insert it into ears */ if ( halfedge_origin_is_ear( he1 ) ) g_hash_table_insert( ears, n1, he1 ); else /* otherwise just update it with a new half-edge */ g_hash_table_insert( convex_vertices, n1, he1 ); } /* the same process with the other neighbour */ if ( was_reflex_2 ) { if ( was_reflex_became_convex_2 ) { g_hash_table_insert( convex_vertices, n3, he2 ); if ( halfedge_origin_is_ear( he2 ) ) g_hash_table_insert( ears, n3, he2 ); } } else if ( g_hash_table_lookup( ears, n3 ) ) { if ( ! halfedge_origin_is_ear( he2 ) ) g_hash_table_remove( ears, n3 ); } else if ( g_hash_table_lookup( convex_vertices, n3 ) ) { if ( halfedge_origin_is_ear( he2 ) ) g_hash_table_insert( ears, n3, he2 ); } /* we changed the ears, so update the iterator */ g_hash_table_iter_init( &ears_iter, ears ); he3 = he2->next; /* check if there are only three edges left */ if ( he3->next == he1 ) { /* if there are, so just add this last element and break out from * the loop */ mesh_add_element( mesh, he1, he2, he3 ); break; } } /* clean up */ g_hash_table_destroy( reflex_vertices ); g_hash_table_destroy( convex_vertices ); g_hash_table_destroy( ears ); /* return the resulting mesh */ return mesh; }
edge dilate(edge e, float sx, float sy, float sz) { float A[4][4]; generate_dilation_matrix(A, sx, sy, sz); return EDGE(transform(e.first, A), transform(e.second, A)); }
X3D_BoundRegion* x3d_construct_boundregion_from_clip_data(X3D_ClipData* clip, uint16* edge_list, uint16 total_e, X3D_BoundRegion* region, _Bool clockwise) { X3D_BoundRegion* result_region = region; region->total_bl = 0; int16 reverse_edge_list[total_e]; // If not clockwise, reverse the list of edges if(!clockwise) { uint16 i; for(i = 0; i < total_e; ++i) { reverse_edge_list[i] = edge_list[total_e - i - 1]; SWAP(EDGE(i).v[0], EDGE(i).v[1]); } edge_list = reverse_edge_list; } uint16 edge_id = 0; // Skip over edges that are totally invisible while(edge_id < total_e && EDGE(edge_id).v[0].clip_status == CLIP_INVISIBLE) { ++edge_id; } uint16 first_visible_edge = 0xFFFF; if(edge_id < total_e) { while(edge_id != first_visible_edge) { // Alright, so we've encountered an edge that is at least partially visible X3D_ClippedEdge* edge = &EDGE(edge_id); // We're only interested in edges that are either totally visible, or begin in the // bounding region and exit if(edge->v[0].clip_status == CLIP_VISIBLE || edge->v[0].clip_status == CLIP_CLIPPED) { if(first_visible_edge == 0xFFFF) { first_visible_edge = edge_id; region->point_inside = edge->v[0].v; } if(edge->v[1].clip_status == CLIP_CLIPPED) { // Construct a bounding line for the edge x3d_construct_boundline(region->line + region->total_bl, &EDGE(edge_id).v[0].v, &EDGE(edge_id).v[1].v); if(region->total_bl == 0 || diff_boundline(region->line + region->total_bl, region->line + region->total_bl - 1)) ++region->total_bl; uint16 start_edge = edge_id; // Walk along the old bounding region until we find an edge where we reenter it do { edge_id = x3d_single_wrap(edge_id + 1, total_e); } while(EDGE(edge_id).v[1].clip_status != CLIP_VISIBLE && EDGE(edge_id).v[1].clip_status != CLIP_CLIPPED); // Add the edges along the old bound region uint16 start = EDGE(start_edge).v[1].clip_line; uint16 end = EDGE(edge_id).v[0].clip_line; if(diff_boundline(clip->region->line + start, region->line + region->total_bl - 1)) region->line[region->total_bl++] = clip->region->line[start]; // Prevent special case of when it enters and exits on the same edge if(start != end) { uint16 e = start; do { e = x3d_single_wrap(e + 1, clip->region->total_bl); if(diff_boundline(clip->region->line + e, region->line + region->total_bl - 1)) region->line[region->total_bl++] = clip->region->line[e]; } while(e != end); } else { } continue; } x3d_construct_boundline(region->line + region->total_bl, &EDGE(edge_id).v[0].v, &EDGE(edge_id).v[1].v); if(region->total_bl == 0 || diff_boundline(region->line + region->total_bl, region->line + region->total_bl - 1)) ++region->total_bl; } edge_id = x3d_single_wrap(edge_id + 1, total_e); } } else { uint16 i; uint32 edge_mask = (1L << clip->region->total_bl) - 1;// = clip->outside_mask[clip->edge->v[0]]; printf("Begin: %ld\n", edge_mask); for(i = 0; i < total_e; ++i) { printf("Mask: %ld\n", clip->outside_mask[clip->edge[edge_list[i]].v[0]]); edge_mask &= clip->outside_mask[clip->edge[edge_list[i]].v[0]]; } if(edge_mask != 0) { result_region = NULL; printf("EDGE FAIL\n"); } else { for(i = 0; i < total_e; ++i) { if(x3d_is_clockwise_turn(&EDGE(i).v[0].v, &clip->region->point_inside, &EDGE(i).v[1].v)) { result_region = NULL; break; } } // If we got through testing all the edges, and the point is inside, the // old region must be inside the new region if(result_region != NULL) { result_region = clip->region; printf("ASSIGN OLD\n"); } } } // Swap them back if(!clockwise) { uint16 i; for(i = 0; i < total_e; ++i) { SWAP(EDGE(i).v[0], EDGE(i).v[1]); } } return result_region; }