forked from gradientspace/geometry3Sharp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MeshInsertPolygon.cs
86 lines (73 loc) · 3.3 KB
/
MeshInsertPolygon.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using System.Collections.Generic;
namespace g3
{
/// <summary>
/// Insert Polygon into Mesh. Assumption is that Mesh has 3D coordinates (u,v,0).
/// This is basically a helper/wrapper around MeshInsertUVPolyCurve.
/// Inserted edge set is avaliable as .InsertedPolygonEdges, and
/// triangles inside polygon as .InteriorTriangles
/// </summary>
public class MeshInsertPolygon
{
public DMesh3 Mesh;
public GeneralPolygon2d Polygon;
public bool SimplifyInsertion = true;
public MeshInsertUVPolyCurve OuterInsert;
public List<MeshInsertUVPolyCurve> HoleInserts;
public HashSet<int> InsertedPolygonEdges;
public MeshFaceSelection InteriorTriangles;
public bool Insert()
{
OuterInsert = new MeshInsertUVPolyCurve(Mesh, Polygon.Outer);
Util.gDevAssert(OuterInsert.Validate() == ValidationStatus.Ok);
bool outerApplyOK = OuterInsert.Apply();
if (outerApplyOK == false || OuterInsert.Loops.Count == 0)
return false;
if (SimplifyInsertion)
OuterInsert.Simplify();
HoleInserts = new List<MeshInsertUVPolyCurve>(Polygon.Holes.Count);
for (int hi = 0; hi < Polygon.Holes.Count; ++hi) {
MeshInsertUVPolyCurve insert = new MeshInsertUVPolyCurve(Mesh, Polygon.Holes[hi]);
Util.gDevAssert(insert.Validate() == ValidationStatus.Ok);
insert.Apply();
if (SimplifyInsertion)
insert.Simplify();
HoleInserts.Add(insert);
}
// find a triangle connected to loop that is inside the polygon
// [TODO] maybe we could be a bit more robust about this? at least
// check if triangle is too degenerate...
int seed_tri = -1;
EdgeLoop outer_loop = OuterInsert.Loops[0];
for (int i = 0; i < outer_loop.EdgeCount; ++i) {
if ( ! Mesh.IsEdge(outer_loop.Edges[i]) )
continue;
Index2i et = Mesh.GetEdgeT(outer_loop.Edges[i]);
Vector3d ca = Mesh.GetTriCentroid(et.a);
bool in_a = Polygon.Outer.Contains(ca.xy);
Vector3d cb = Mesh.GetTriCentroid(et.b);
bool in_b = Polygon.Outer.Contains(cb.xy);
if (in_a && in_b == false) {
seed_tri = et.a;
break;
} else if (in_b && in_a == false) {
seed_tri = et.b;
break;
}
}
if (seed_tri == -1)
throw new Exception("MeshPolygonsInserter: could not find seed triangle!");
// make list of all outer & hole edges
InsertedPolygonEdges = new HashSet<int>(outer_loop.Edges);
foreach (var insertion in HoleInserts) {
foreach (int eid in insertion.Loops[0].Edges)
InsertedPolygonEdges.Add(eid);
}
// flood-fill inside loop from seed triangle
InteriorTriangles = new MeshFaceSelection(Mesh);
InteriorTriangles.FloodFill(seed_tri, null, (eid) => { return InsertedPolygonEdges.Contains(eid) == false; });
return true;
}
}
}