/// <summary> /// for each vertex of input triangle set, select vertex if all /// one-ring triangles are contained in triangle set (ie vertex is not on boundary of triangle set). /// </summary> public void SelectInteriorVertices(MeshFaceSelection triangles) { var borderv = new HashSet <int>(); foreach (int tid in triangles) { Index3i tv = Mesh.GetTriangle(tid); for (int j = 0; j < 3; ++j) { int vid = tv[j]; if (Selected.Contains(vid) || borderv.Contains(vid)) { continue; } bool full_ring = true; foreach (int ring_tid in Mesh.VtxTrianglesItr(vid)) { if (triangles.IsSelected(ring_tid) == false) { full_ring = false; break; } } if (full_ring) { add(vid); } else { borderv.Add(vid); } } } }
/// <summary> /// Actually computes the insertion. In some cases we would like more info /// coming back than we get by using Generate() api. Note that resulting /// mesh is *not* compacted. /// </summary> public DMesh3 ComputeResult(out MeshInsertPolygon insertion) { AxisAlignedBox2d bounds = Polygon.Bounds; double padding = 0.1 * bounds.DiagonalLength; bounds.Expand(padding); TrivialRectGenerator rectgen = (Subdivisions == 1) ? new TrivialRectGenerator() : new GriddedRectGenerator() { EdgeVertices = Subdivisions }; rectgen.Width = (float)bounds.Width; rectgen.Height = (float)bounds.Height; rectgen.IndicesMap = new Index2i(1, 2); rectgen.UVMode = UVMode; rectgen.Clockwise = true; // MeshPolygonInserter assumes mesh faces are CW? (except code says CCW...) rectgen.Generate(); var base_mesh = new DMesh3(); rectgen.MakeMesh(base_mesh); var shiftPolygon = new GeneralPolygon2d(Polygon); Vector2d shift = bounds.Center; shiftPolygon.Translate(-shift); var insert = new MeshInsertPolygon() { Mesh = base_mesh, Polygon = shiftPolygon }; bool bOK = insert.Insert(); if (!bOK) { throw new Exception("TriangulatedPolygonGenerator: failed to Insert()"); } MeshFaceSelection selected = insert.InteriorTriangles; var editor = new MeshEditor(base_mesh); editor.RemoveTriangles((tid) => { return(selected.IsSelected(tid) == false); }, true); var shift3 = new Vector3d(shift.x, shift.y, 0); MeshTransforms.Translate(base_mesh, shift3); insertion = insert; return(base_mesh); }
// convert face selection to edge selection. Require at least minCount tris of edge to be selected public MeshEdgeSelection(DMesh3 mesh, MeshFaceSelection convertT, int minCount = 1) : this(mesh) { minCount = MathUtil.Clamp(minCount, 1, 2); if (minCount == 1) { foreach (int tid in convertT) { Index3i te = mesh.GetTriEdges(tid); add(te.a); add(te.b); add(te.c); } } else { foreach (int eid in mesh.EdgeIndices()) { Index2i et = mesh.GetEdgeT(eid); if (convertT.IsSelected(et.a) && convertT.IsSelected(et.b)) { add(eid); } } } }
public void SelectBoundaryTriEdges(MeshFaceSelection triangles) { foreach (int tid in triangles) { Index3i te = Mesh.GetTriEdges(tid); for (int j = 0; j < 3; ++j) { Index2i et = Mesh.GetEdgeT(te[j]); int other_tid = (et.a == tid) ? et.b : et.a; if (triangles.IsSelected(other_tid) == false) { add(te[j]); } } } }