Corner Table Corner operators Computing O Flipping edges
Corner Table § § § § § Corner operators Computing O Flipping edges Collapsing edges Geodesic distances, paths, and isolations Filling holes Smoothing Subdivision Compression Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 1
Flip edge void flip(int c) { // flip edge opposite to corner c if (b(c)) return; // no opposite triangle V[n(o(c))]=v(c); V[n(c)]=v(o(c)); int co=o(c); O[co]=r(c); if(!b(p(c))) O[r(c)]=co; if(!b(p(co))) O[c]=r(co); if(!b(p(co))) O[r(co)]=c; O[p(c)]=p(co); O[p(co)]=p(c); } Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 2
Shorten edges by flipping void flip. When. Longer() { for (int c=0; c<nc; c++) if (d(g(n(c)), g(p(c)))>d(g(c), g(o(c)))) flip(c); } Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 3
Collapse an edge void collapse(int c) { if (b(c)) return; int b=n(c), oc=o(c), vpc=v(p(c)); visible[t(c)]=false; visible[t(oc)]=false; for (int a=b; a!=p(oc); a=n(l(a))) V[a]=vpc; O[l(c)]=r(c); O[r(c)]=l(c); O[l(oc)]=r(oc); O[r(oc)]=l(oc); } Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 4
Find shortest edge int corner. Of. Shortest. Edge() { // assumes manifold float md=d(g(p(0)), g(n(0))); // init shortest length found so far int ma=0; // init facing corner for (int a=1; a<nc; a++) // for all other corners if (d(g(p(a)), g(n(a)))<md) { // if found a shorter edge ma=a; md=d(g(p(a)), g(n(a))); }; // update return ma; } Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 5
Collapse shortest edges M. find. Shortest. Edge(); M. collapse(); Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 6
Distance between a point and a T-mesh § The minimum distance may occur – In the middle of a face (p 1) – In the middle of an edge (p 7) – At a vertex (p 2) p 1 p 2 p 7 § The distance to the solid bounded by a T-mesh S is – 0 it p is inside the solid • use parity of the number of intersections of ray with S – D(p, S) otherwise Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 7
Exact point-triangle distance in 3 D T has vertices a, b, c Algorithm for computing point-triangle distance D(p, T) – – A: = (bc bc)(ba bp) > bc ba)(bc bp) B: = (ca ca)(cb cp) > (ca cb)(ca cp) C: = (ab ab)(ac ap) > (ab ac)(ab ap) RETURN 1. 2. 3. 4. 5. 6. 7. a p 2 if A B C then ap (ab ac)/||ab ac|| if A B C then ||ap|| if A B C then ||bp|| if A B C then ||cp|| if A B C then ||bc bp||/||bc|| if A B C then ||ca cp||/||ca|| if A B C then ||ab ap||/||ab|| Justification AB C i e p 7 a ABC c Nbc N b ABC c ABC – N : = bc ba – Nbc : = N bc = (bc ba) bc = (bc bc)ba–(bc ba)bc • p 1 ABC b AB C using u (v w)=(u w)v–(u v)w 1. A : = Nbc bp > 0 Cost: over 45 multiplications per triangle! Speed-ups? Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 8
Exact point-surface distance for T-meshes § D(p, S) Min( D(p, T) : T is a triangle of S ), using previous slide § Speed-up – d: = min(D(p, v) : v is a vertex of S) – For each triangle T of S do • D(p, plane(T))<d then if normal projection of P on T then d: = D(p, plane(T)) – For each edge E do • D(p, line(E))<d then if normal projection of P on E then d: = D(p, line(E)) § Further speed-up – Preprocessing • Compute a minimal sphere around each triangle • Group neighboring triangles and compute spheres around groups • Build tree of spherical containers by recursively merging groups – Query for a point p • Go down the tree, picking at each node the sphere whose center is closest to p • d: = distance to leaf triangle • Go down the tree again in depth first order, but only visit branches whose spheres are closer to p than d – At each visited leaf, update d Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 9
Distance between two T-meshes § Minimum of distances between all pairs: • face/vertex • edge/vertex • vertex/edge • vertex/face • edge/edge of an element of A and an element of B vf fv ve ee vv ev N: =(ab cd) / ||ab cd|| Dist: = N ac ee test ? Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 10
Collision prediction between T-meshes § Assume A moves with constant velocity v and B is fixed – If both move, compute collision in local coordinate system of B § Collision may occur between – A vertex p of A and (the closure of) a triangle T of B • Intersect Ray(p, v) with T – The closure of a triangle T of A with a vertex p of B • Intersect Ray(p, -v) with T – An edge (a, b) of A with an edge (c, d) of B • Check when the volume of tetrahedron (a+tv, b+tv, c, d) becomes zero – – – – solve (cd (ca+tv)) (cb+tv)=0 for t (cd (ca+tv)) cb + (cd (ca+tv)) tv)=0 (cd ca+t(cd v)) cb + (cd ca+t(cd v)) tv)=0 (cd ca) cb +t(cd v) cb + (cd ca) tv +t 2(cd v) v = 0 (cd ca) cb +t(cd v) cb + (cd ca) tv = 0, because (cd v) v = 0 t = (ca cd) cb / ((cd v) cb - (cd v) ca) t = (ca cd) cb / (ab cd) v b d • Make sure that, at that time, the two edges intersect – Not just the lines v a Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech c 11
Hausdorff distance between T-meshes § Expensive to compute, – because it can occur away from vertices and edges! A B The point of B that is furthest away from A is closest to 3 points on A that are inside faces Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 12
Intersection between T-meshes § The triangle meshes A and B intersect if and only if the closure of an edge of one intersects the closure of a triangle of the other • The closure of an edge is the union of the edge with its vertices • The closure of a triangle is the union of the triangle with its boundary – These include the cases where an edge intersects or touches an edge or when a vertex touches a triangle § How do we compute the intersection? – Assume A and B are represented by corner tables – Do all pairs of edge-triangle intersection tests • Each time you find an intersection, insert it in both meshes and subdivide the triangles to restore a valid triangulation and a correct corner table • With each vertex that you insert, associate the IDs of the 3 triangles involved – Two bounded by the edge and one intersected by it – Identify the intersection edges • They are new edges whose vertices share 2 IDs Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 13
Compact V & O tables void exclude. Invisible. Triangles () {for (int b=0; b<nc; b++) if (!visible[t(o(b))]) O[b]=-1; } void compact. VO() { int[] U = new int [nc]; int lc=-1; for (int c=0; c<nc; c++) {if (visible[t(c)]) {U[c]=++lc; }; }; for (int c=0; c<nc; c++) {if (!b(c)) {O[c]=U[o(c)]; } else {O[c]=-1; }; }; int lt=0; for (int t=0; t<nt; t++) { if (visible[t]) { V[3*lt]=V[3*t]; V[3*lt+1]=V[3*t+1]; V[3*lt+2]=V[3*t+2]; O[3*lt]=O[3*t]; O[3*lt+1]=O[3*t+1]; O[3*lt+2]=O[3*t+2]; visible[lt]=true; lt++; }; }; nt=lt; nc=3*nt; } Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 14
Compact the G and V tables void compact. V() { int[] U = new int [nv]; boolean[] deleted = new boolean [nv]; for (int v=0; v<nv; v++) {deleted[v]=true; }; for (int c=0; c<nc; c++) {deleted[v(c)]=false; }; int lv=-1; for (int v=0; v<nv; v++) {if (!deleted[v]) {U[v]=++lv; }; }; for (int c=0; c<nc; c++) {V[c]=U[v(c)]; }; lv=0; for (int v=0; v<nv; v++) { if (!deleted[v]) { G[lv]. set. To. Point(G[v]); deleted[lv]=false; lv++; }; }; nv=lv; } Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 15
Fill a hole void fan. This. Hole(int cc) {if(!b(cc)) return ; G[nv]. set. To(0, 0, 0); // tip vertex of fan int o=0; // tip corner of new fan triangle int n=0; // triangle count in fan int a=n(cc); // corner running along the border while (n(a)!=cc) {if(b(p(a))) { // walk around, if a is left-end of border edge G[nv]. add. Pt( M(M(g(a), g(n(a))), S(g(a), V(g(p(a)), g(n(a))))) ); o=3*nt; V[o]=nv; V[n(o)]=v(n(a)); V[p(o)]=v(a); visible[nt]=true; nt++; O[o]=p(a); O[p(a)]=o; O[n(o)]=-1; O[p(o)]=-1; // link opposites for o n++; }; // increase triangle-count in fan a=s(a); } // next corner along border G[nv]. mul(1. /n); // divide fan tip to make average a=o(cc); // reset a to walk around again int l=n(a); // keep track of previous int i=0; while(i<n) {a=s(a); if(v(a)==nv) {i++; O[p(a)]=l; O[l]=p(a); l=n(a); }; } nv++; nc=3*nt; }; // update vertex count and corner count Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 16
Find and fill all holes void fan. Holes() {for (int cc=0; cc<nc; cc++) if (visible[t(cc)]&&b(cc)) fan. This. Hole(cc); } Or may fill 2 holes to make a through-hole Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 17
Compute geodesic distance void compute. Distance(int maxr) { int tc=0; int r=1; for(int i=0; i<nt; i++) {Mt[i]=0; }; Mt[t(c)]=1; tc++; for(int i=0; i<nv; i++) {Mv[i]=0; }; while ((tc<nt)&&(r<=maxr)) { for(int i=0; i<nc; i++) {if ((Mv[v(i)]==0)&&(Mt[t(i)]==r)) Mv[v(i)]=r; }; for(int i=0; i<nc; i++) {if ((Mt[t(i)]==0)&&(Mv[v(i)]==r)) {Mt[t(i)]=r+1; tc++; }; }; r++; }; rings=r; } Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 18
Geodesic (graph) distance Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 19
Path and isolation Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 20
Isolation Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 21
Segmentation Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 22
More segmentation Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 23
Skeleton Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 24
More chicken? Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 25
Hamiltonian cycle § § § Cycle of edges that visits each vertex only once Splits mesh into 2 corridors Useful for compression May not exist or may be hard to find May often be computed, especially for subdivided meshes Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 26
Ride on a mesh § Propagate velocity from one triangle to the next § Compute new velocity using ray-reflection formula Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 27
Smoothing void compute. Laplace. Vectors() { for (int i=0; i<nv; i++) {Nv[i]. set. To(0, 0, 0); Valence[i]=0; }; for (int i=0; i<nc; i++) {Valence[v(i)]++; }; } for (int i=0; i<nc; i++) {Nv[v(p(i))]. add(g(p(i)). vec. To(g(n(i)))); }; for (int i=0; i<nv; i++) {Nv[i]. div(Valence[i]); }; }; void tuck(float s) {for (int i=0; i<nv; i++) {G[i]. add. Scaled. Vec(s, Nv[i]); }; }; if (key=='S') { M. compute. Laplace. Vectors(); M. tuck(0. 6); M. compute. Laplace. Vectors(); M. tuck(-0. 6); }; Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 28
Smoothing (Taubin) Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 29
Subdivision Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 30
Subdivision void split. Edges() {for (int i=0; i<nc; i++) { if(b(i)) {G[nv]=mid. Pt(g(n(i)), g(p(i))); W[i]=nv++; } else {if(i<o(i)) {G[nv]=mid. Pt(g(n(i)), g(p(i))); W[o(i)]=nv; W[i]=nv++; }}}} void bulge() { // tweaks the mid-edge vertices for (int i=0; i<nc; i++) { if((!b(i))&&(i<o(i))) { // no tweak for mid-vertices of border edges if (!b(p(i))&&!b(n(i))&&!b(p(o(i)))&&!b(n(o(i)))) {G[W[i]]. add. Scaled. Vec(0. 25, mid. Pt(g(l(i)), g(r(i))), mid. Pt(g(l(o(i))), g(r(o(i))))). vec. To(mid. Pt(g(i), g(o(i))))); } } void split. Triangles() { // splits each tirangle into 4 for (int i=0; i<3*nt; i=i+3) { V[3*nt+i]=v(i); V[n(3*nt+i)]=w(p(i)); V[p(3*nt+i)]=w(n(i)); V[6*nt+i]=v(n(i)); V[n(6*nt+i)]=w(i); V[p(6*nt+i)]=w(p(i)); V[9*nt+i]=v(p(i)); V[n(9*nt+i)]=w(n(i)); V[p(9*nt+i)]=w(i); V[i]=w(i); V[n(i)]=w(n(i)); V[p(i)]=w(p(i)); }; nt=4*nt; nc=3*nt; }; Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 31
Subdivision examples Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 32
Adaptive refinement Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 33
Self-crossing Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 34
Compression void EBcompress(int c) { Ccount=0; Lcount=0; Ecount=0; Rcount=0; Scount=0; reset. Stack(); for (int v=0; v<nv; v++) Visited. V[v]=false; for (int t=0; t<nt; t++) Visited. T[t]=false; Visited. T[t(c)]=true; triangle. Symbol[t(c)]='B'; Visited. V[v(c)]=true; Visited. V[v(n(c))]=true; Visited. V[v(p(c))]=true; c=r(c); symbols=0; boolean EBis. Done=false; while (!EBis. Done) { Visited. T[t(c)]=true; if (!Visited. V[v(c)]) {triangle. Symbol[t(c)]='C'; Ccount++; CLERS[symbols++]=triangle. Symbol[t(c)]; Visited. V[v(c)]=true; c=r(c); } else {if (Visited. T[t(r(c))]) { if (Visited. T[t(l(c))]) {triangle. Symbol[t(c)]='E'; Ecount++; CLERS[symbols++]=triangle. Symbol[t(c)]; c=stack[--stack. Height]; if (stack. Height==0) {EBis. Done=true; }; } else {triangle. Symbol[t(c)]='R'; Rcount++; CLERS[symbols++]=triangle. Symbol[t(c)]; c=l(c); }; } else { if (Visited. T[t(l(c))]) {triangle. Symbol[t(c)]='L'; Lcount++; CLERS[symbols++]=triangle. Symbol[t(c)]; c=r(c); } else {triangle. Symbol[t(c)]='S'; triangle. Symbol[t(l(c))]='w'; Scount++; CLERS[symbols++]=triangle. Symbol[t(c)]; stack[stack. Height++]=l(c); c=r(c); } }} }} Jarek Rossignac http: //www. gvu. gatech. edu/~jarek MAGIC Lab SIC / Co. C / Georgia Tech 35
- Slides: 35