Skip to content

Commit

Permalink
Add NoEmptyPolygons on Tess instance to remove zero area polygons.
Browse files Browse the repository at this point in the history
  • Loading branch information
speps committed Feb 6, 2016
1 parent 75d891a commit 665c8f6
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 6 deletions.
15 changes: 15 additions & 0 deletions LibTessDotNet/Sources/MeshUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -371,5 +371,20 @@ public static void KillFace(Face fDel, Face newLFace)
fNext._prev = fPrev;
fPrev._next = fNext;
}

/// <summary>
/// Return signed area of face.
/// </summary>
public static float FaceArea(Face f)
{
float area = 0.0f;
var e = f._anEdge;
do
{
area += (e._Org._s - e._Dst._s) * (e._Org._t + e._Dst._t);
e = e._Lnext;
} while (e != f._anEdge);
return area;
}
}
}
29 changes: 23 additions & 6 deletions LibTessDotNet/Sources/Tess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
** LibTessDotNet: Remi Gillig, https://github.com/speps/LibTessDotNet
*/

using System;
using System.Diagnostics;

namespace LibTessDotNet
Expand Down Expand Up @@ -99,6 +100,8 @@ public partial class Tess
public float SUnitY = 0.0f;
public float SentinelCoord = 4e30f;

public bool NoEmptyPolygons = false;

public ContourVertex[] Vertices { get { return _vertices; } }
public int VertexCount { get { return _vertexCount; } }

Expand Down Expand Up @@ -187,15 +190,11 @@ private void CheckOrientation()
float area = 0.0f;
for (var f = _mesh._fHead._next; f != _mesh._fHead; f = f._next)
{
var e = f._anEdge;
if (e._winding <= 0)
if (f._anEdge._winding <= 0)
{
continue;
}
do {
area += (e._Org._s - e._Dst._s) * (e._Org._t + e._Dst._t);
e = e._Lnext;
} while (e != f._anEdge);
area += MeshUtils.FaceArea(f);
}
if (area < 0.0f)
{
Expand Down Expand Up @@ -455,6 +454,15 @@ private void OutputPolymesh(ElementType elementType, int polySize)
f._n = MeshUtils.Undef;
if (!f._inside) continue;

if (NoEmptyPolygons)
{
float area = MeshUtils.FaceArea(f);
if (Math.Abs(area) < float.Epsilon)
{
continue;
}
}

edge = f._anEdge;
faceVerts = 0;
do {
Expand Down Expand Up @@ -500,6 +508,15 @@ private void OutputPolymesh(ElementType elementType, int polySize)
{
if (!f._inside) continue;

if (NoEmptyPolygons)
{
float area = MeshUtils.FaceArea(f);
if (Math.Abs(area) < float.Epsilon)
{
continue;
}
}

// Store polygon
edge = f._anEdge;
faceVerts = 0;
Expand Down
14 changes: 14 additions & 0 deletions TessBed/MainForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions TessBed/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ public MainForm()
RefreshAsset(toolStripAssets.SelectedIndex);
};

toolStripButtonNoEmpty.CheckedChanged += delegate(object sender, EventArgs e)
{
_tess.NoEmptyPolygons = toolStripButtonNoEmpty.Checked;
RefreshAsset(toolStripAssets.SelectedIndex);
};

toolStripButtonBench.Click += delegate(object sender, EventArgs e)
{
new BenchForm().ShowDialog(this);
Expand Down
27 changes: 27 additions & 0 deletions TessBed/UnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,33 @@ public void Tesselate_WithIssue1Quad_ReturnsSameResultAsLibtess2()
}
}

[Test]
// From https://github.com/speps/LibTessDotNet/issues/1
public void Tesselate_WithNoEmptyPolygonsTrue_RemovesEmptyPolygons()
{
string data = "2,0,4\n2,0,2\n4,0,2\n4,0,0\n0,0,0\n0,0,4";
var indices = new List<int>();
var expectedIndices = new int[] { 0, 1, 2, 2, 3, 4, 3, 1, 5 };
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(data)))
{
var pset = DataLoader.LoadDat(stream);
var tess = new Tess();
PolyConvert.ToTess(pset, tess);
tess.NoEmptyPolygons = true;
tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3);
indices.Clear();
for (int i = 0; i < tess.ElementCount; i++)
{
for (int j = 0; j < 3; j++)
{
int index = tess.Elements[i * 3 + j];
indices.Add(index);
}
}
Assert.AreEqual(expectedIndices, indices.ToArray());
}
}

[Test]
public void Tesselate_CalledTwiceOnSameInstance_DoesNotCrash()
{
Expand Down

0 comments on commit 665c8f6

Please sign in to comment.