Skip to content

Commit 665c8f6

Browse files
committed
Add NoEmptyPolygons on Tess instance to remove zero area polygons.
1 parent 75d891a commit 665c8f6

File tree

5 files changed

+85
-6
lines changed

5 files changed

+85
-6
lines changed

LibTessDotNet/Sources/MeshUtils.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,5 +371,20 @@ public static void KillFace(Face fDel, Face newLFace)
371371
fNext._prev = fPrev;
372372
fPrev._next = fNext;
373373
}
374+
375+
/// <summary>
376+
/// Return signed area of face.
377+
/// </summary>
378+
public static float FaceArea(Face f)
379+
{
380+
float area = 0.0f;
381+
var e = f._anEdge;
382+
do
383+
{
384+
area += (e._Org._s - e._Dst._s) * (e._Org._t + e._Dst._t);
385+
e = e._Lnext;
386+
} while (e != f._anEdge);
387+
return area;
388+
}
374389
}
375390
}

LibTessDotNet/Sources/Tess.cs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
** LibTessDotNet: Remi Gillig, https://github.com/speps/LibTessDotNet
3232
*/
3333

34+
using System;
3435
using System.Diagnostics;
3536

3637
namespace LibTessDotNet
@@ -99,6 +100,8 @@ public partial class Tess
99100
public float SUnitY = 0.0f;
100101
public float SentinelCoord = 4e30f;
101102

103+
public bool NoEmptyPolygons = false;
104+
102105
public ContourVertex[] Vertices { get { return _vertices; } }
103106
public int VertexCount { get { return _vertexCount; } }
104107

@@ -187,15 +190,11 @@ private void CheckOrientation()
187190
float area = 0.0f;
188191
for (var f = _mesh._fHead._next; f != _mesh._fHead; f = f._next)
189192
{
190-
var e = f._anEdge;
191-
if (e._winding <= 0)
193+
if (f._anEdge._winding <= 0)
192194
{
193195
continue;
194196
}
195-
do {
196-
area += (e._Org._s - e._Dst._s) * (e._Org._t + e._Dst._t);
197-
e = e._Lnext;
198-
} while (e != f._anEdge);
197+
area += MeshUtils.FaceArea(f);
199198
}
200199
if (area < 0.0f)
201200
{
@@ -455,6 +454,15 @@ private void OutputPolymesh(ElementType elementType, int polySize)
455454
f._n = MeshUtils.Undef;
456455
if (!f._inside) continue;
457456

457+
if (NoEmptyPolygons)
458+
{
459+
float area = MeshUtils.FaceArea(f);
460+
if (Math.Abs(area) < float.Epsilon)
461+
{
462+
continue;
463+
}
464+
}
465+
458466
edge = f._anEdge;
459467
faceVerts = 0;
460468
do {
@@ -500,6 +508,15 @@ private void OutputPolymesh(ElementType elementType, int polySize)
500508
{
501509
if (!f._inside) continue;
502510

511+
if (NoEmptyPolygons)
512+
{
513+
float area = MeshUtils.FaceArea(f);
514+
if (Math.Abs(area) < float.Epsilon)
515+
{
516+
continue;
517+
}
518+
}
519+
503520
// Store polygon
504521
edge = f._anEdge;
505522
faceVerts = 0;

TessBed/MainForm.Designer.cs

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

TessBed/MainForm.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ public MainForm()
7272
RefreshAsset(toolStripAssets.SelectedIndex);
7373
};
7474

75+
toolStripButtonNoEmpty.CheckedChanged += delegate(object sender, EventArgs e)
76+
{
77+
_tess.NoEmptyPolygons = toolStripButtonNoEmpty.Checked;
78+
RefreshAsset(toolStripAssets.SelectedIndex);
79+
};
80+
7581
toolStripButtonBench.Click += delegate(object sender, EventArgs e)
7682
{
7783
new BenchForm().ShowDialog(this);

TessBed/UnitTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,33 @@ public void Tesselate_WithIssue1Quad_ReturnsSameResultAsLibtess2()
104104
}
105105
}
106106

107+
[Test]
108+
// From https://github.com/speps/LibTessDotNet/issues/1
109+
public void Tesselate_WithNoEmptyPolygonsTrue_RemovesEmptyPolygons()
110+
{
111+
string data = "2,0,4\n2,0,2\n4,0,2\n4,0,0\n0,0,0\n0,0,4";
112+
var indices = new List<int>();
113+
var expectedIndices = new int[] { 0, 1, 2, 2, 3, 4, 3, 1, 5 };
114+
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(data)))
115+
{
116+
var pset = DataLoader.LoadDat(stream);
117+
var tess = new Tess();
118+
PolyConvert.ToTess(pset, tess);
119+
tess.NoEmptyPolygons = true;
120+
tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3);
121+
indices.Clear();
122+
for (int i = 0; i < tess.ElementCount; i++)
123+
{
124+
for (int j = 0; j < 3; j++)
125+
{
126+
int index = tess.Elements[i * 3 + j];
127+
indices.Add(index);
128+
}
129+
}
130+
Assert.AreEqual(expectedIndices, indices.ToArray());
131+
}
132+
}
133+
107134
[Test]
108135
public void Tesselate_CalledTwiceOnSameInstance_DoesNotCrash()
109136
{

0 commit comments

Comments
 (0)