/// <summary> /// Remove vertices that are colinear w/ their two neighbours, within angle tolerance /// </summary> public void CollapseFlatVertices(double fMaxDeviationDeg = 5) { bool done = false; int max_passes = 200; int pass_count = 0; while (done == false && pass_count++ < max_passes) { done = true; // [RMS] do modulo-indexing here to avoid pathological cases where we do things like // continually collapse a short edge adjacent to a long edge (which will result in crazy over-collapse) int N = Graph.MaxVertexID; const int nPrime = 31337; // any prime will do... int cur_vid = 0; do { int vid = cur_vid; cur_vid = (cur_vid + nPrime) % N; if (!Graph.IsVertex(vid)) { continue; } if (Graph.GetVtxEdgeCount(vid) != 2) { continue; } double open = Math.Abs(Graph.OpeningAngle(vid)); if (open < 180 - fMaxDeviationDeg) { continue; } var edges = Graph.GetVtxEdges(vid); int eid = edges.First(); int eid2 = edges.Last(); if (FixedEdgeFilterF(eid) || FixedEdgeFilterF(eid2)) { continue; } Index2i ev = Graph.GetEdgeV(eid); int other_v = (ev.a == vid) ? ev.b : ev.a; DGraph2.EdgeCollapseInfo collapseInfo; MeshResult result = Graph.CollapseEdge(other_v, vid, out collapseInfo); if (result == MeshResult.Ok) { done = false; } else { throw new Exception("DGraph2Resampler.CollapseFlatVertices: failed!"); } } while (cur_vid != 0); } }
/// <summary> /// If we are at edge eid, which as one vertex prev_vid, find 'other' vertex, and other edge connected to that vertex, /// and return pair [next_edge, shared_vtx] /// Returns [int.MaxValue, shared_vtx] if shared_vtx is not valence=2 (ie stops at boundaries and complex junctions) /// </summary> public static Index2i NextEdgeAndVtx(int eid, int prev_vid, DGraph2 graph) { Index2i ev = graph.GetEdgeV(eid); if (ev.a == DGraph2.InvalidID) { return(Index2i.Max); } int next_vid = (ev.a == prev_vid) ? ev.b : ev.a; if (graph.GetVtxEdgeCount(next_vid) != 2) { return(new Index2i(int.MaxValue, next_vid)); } foreach (int next_eid in graph.VtxEdgesItr(next_vid)) { if (next_eid != eid) { return(new Index2i(next_eid, next_vid)); } } return(Index2i.Max); }