public void InsertLoopIntoLoopAfter() { //Arrange LinkedLoop <int> list1 = new LinkedLoop <int>(); LinkedLoop <int> list2 = new LinkedLoop <int>(); list1.AddLast(1); list1.AddLast(2); list1.AddLast(3); list2.AddLast(4); list2.AddLast(5); list2.AddLast(6); //Act list1.InsertAfter(list1.last, list2.first, list2.last); //Assert Assert.AreEqual(6, list1.size); Assert.AreEqual(0, list2.size); CheckConsistancy(list1); CheckConsistancy(list2); var items = GetArray(list1); Assert.AreEqual(1, items[0].value); Assert.AreEqual(2, items[1].value); Assert.AreEqual(3, items[2].value); Assert.AreEqual(4, items[3].value); Assert.AreEqual(5, items[4].value); Assert.AreEqual(6, items[5].value); }
public void RemoveFirst() { //Arrange LinkedLoop <int> list = new LinkedLoop <int>(); //Act list.AddLast(1); list.AddLast(2); list.AddLast(3); list.AddLast(4); var item1 = list.first; var item2 = item1.next; var item3 = item2.next; var item4 = item3.next; item1.Remove(); //Assert Assert.AreEqual(3, list.size); Assert.AreEqual(2, item2.value); Assert.AreEqual(3, item3.value); Assert.AreEqual(4, item4.value); Assert.AreEqual(item2.next, item3); Assert.AreEqual(item2.previous, item4); Assert.AreEqual(item3.next, item4); Assert.AreEqual(item3.previous, item2); Assert.AreEqual(item4.next, item2); Assert.AreEqual(item4.previous, item3); }
public void AddItem() { //Arrange LinkedLoop <int> list = new LinkedLoop <int>(); //Act list.AddLast(1); list.AddLast(2); list.AddLast(3); //Assert Assert.AreEqual(3, list.size); var item1 = list.first; var item2 = item1.next; var item3 = item2.next; Assert.AreEqual(1, item1.value); Assert.AreEqual(2, item2.value); Assert.AreEqual(3, item3.value); Assert.AreEqual(item1.next, item2); Assert.AreEqual(item1.previous, item3); Assert.AreEqual(item2.next, item3); Assert.AreEqual(item2.previous, item1); Assert.AreEqual(item3.next, item1); Assert.AreEqual(item3.previous, item2); }
/// <summary> /// Check if triangle in right sequence and other points does not in the triangle /// </summary> /// <param name="right">Clockwise if True</param> private bool IsAllowedToCreateTriangle(LinkedLoop <int> linkList, int i1, int i2, int i3) { var p1 = _loopPoints[i1]; var p2 = _loopPoints[i2]; var p3 = _loopPoints[i3]; Vector2 v1 = p1.vector2d; Vector2 v2 = p2.vector2d; Vector2 v3 = p3.vector2d; Vector3 vA = v1 - v2; Vector3 vB = v3 - v2; Vector3 vC = Vector3.Cross(vB, vA); if (vC.z >= 0.00001f) { return(false); } int ii1 = p1.indexPointer.value; int ii2 = p2.indexPointer.value; int ii3 = p3.indexPointer.value; var node = linkList.first; var pPrev = _loopPoints[node.previous.value]; int counter = linkList.size; while (counter != 0) { --counter; int i = node.value; node = node.next; var p = _loopPoints[i]; int ii = p.indexPointer.value; if (ii == ii1 | ii == ii2 | ii == ii3) { continue; } var v = p.vector2d; bool b1 = PointInTriangle(ref v, ref v1, ref v2, ref v3); if (b1) { return(false); } if (ii == ii2 && HaveLineSegmentsIntersection(pPrev.vector2d, p.vector2d, v3, v1)) { return(false); } pPrev = p; } return(true); }
private static LoopNode <int>[] GetArray(LinkedLoop <int> list) { var node = list.first; var items = new LoopNode <int> [list.size]; for (int i = 0; i < list.size; i++) { items[i] = node; node = node.next; } return(items); }
T[] LoopToArray <T>(LinkedLoop <T> loop) { T[] t = new T[loop.size]; var current = loop.first; for (int i = 0; i < loop.size; i++) { t[i] = current.value; current = current.next; } return(t); }
/// <summary> /// Try to make mesh /// </summary> /// <param name="right">Clockwise if True</param> /// <returns>True if polygon was created</returns> private List <int> MakeMesh(bool right) { var newTriangles = new List <int>(polyVertices2D.Length - 2); if (polyVertices2D.Length < 3) { return(newTriangles); } var linkList = new LinkedLoop <int>(); for (int i = 0; i < polyVertices2D.Length; ++i) { linkList.AddLast(i); } var node = linkList.first; int counter = 0; while (linkList.size > 2 & counter <= linkList.size) { var node1 = node; var node2 = node1.next; var node3 = node2.next; var i1 = node1.value; var i2 = node2.value; var i3 = node3.value; ++counter; bool allowed = IsAllowedToCreateTriangle(linkList, i1, i2, i3, right); if (allowed) { CreateTriangle(newTriangles, i1, i2, i3, right); node2.Remove(); node = node3; counter = 0; } else { node = node2; } } return(newTriangles); }
private static LoopIndexCollection GetIndexCollection(BzPolyLoop loop) { var loopData = new LinkedLoop <LoopIndex>(); var loopNode = loop.edgeLoop.first; for (int i = 0; i < loop.edgeLoop.size; i++) { loopData.AddLast(new LoopIndex(loop, loopNode, loop.polyVertices2D[i])); loopNode = loopNode.next; } var indexCollection = new LoopIndexCollection(loop, loopData); return(indexCollection); }
private static void CheckConsistancy(LinkedLoop <int> list) { if (list.size == 0) { Assert.IsNull(list.first); Assert.IsNull(list.last); return; } else { Assert.IsNotNull(list.first); Assert.IsNotNull(list.last); } var node = list.first; int count = 0; for (; ;) { ++count; if (list.last == node | count > list.size) { break; } node = node.next; } Assert.AreEqual(list.size, count); LoopNode <int>[] items = GetArray(list); for (int i = 0; i < count; i++) { int indexPrev = i == 0 ? items.Length - 1 : i - 1; int indexNext = i == items.Length - 1 ? 0 : i + 1; var n1 = items[indexPrev]; var n2 = items[i]; var n3 = items[indexNext]; Assert.AreEqual(n1, n2.previous); Assert.AreEqual(n3, n2.next); Assert.AreEqual(list, n2.list); } }
/// <summary> /// Check if triangle in right sequence and other points does not in it /// </summary> /// <param name="right">Clockwise if True</param> private bool IsAllowedToCreateTriangle(LinkedLoop <int> linkList, int i1, int i2, int i3, bool right) { Vector2 v1 = polyVertices2D[i1]; Vector2 v2 = polyVertices2D[i2]; Vector2 v3 = polyVertices2D[i3]; Vector3 vA = v1 - v2; Vector3 vB = v3 - v2; Vector3 vC = Vector3.Cross(vB, vA); if (right & vC.z >= 0) { return(false); } if (!right & vC.z < 0) { return(false); } var node = linkList.first; int counter = linkList.size; while (counter != 0) { --counter; int i = node.value; node = node.next; if (i == i1 | i == i2 | i == i3) { continue; } var p = polyVertices2D[i]; bool b1 = PointInTriangle(ref p, ref v1, ref v2, ref v3); if (b1) { return(false); } } return(true); }
public void RemoveAndZeroingSize() { //Arrange LinkedLoop <int> list = new LinkedLoop <int>(); //Act list.AddLast(1); var item1 = list.first; item1.Remove(); //Assert Assert.AreEqual(0, list.size); Assert.IsNull(list.first); Assert.IsNull(list.last); Assert.IsNull(item1.next); Assert.IsNull(item1.previous); }
public void RemoveConcat() { //Arrange LinkedLoop <int> list1 = new LinkedLoop <int>(); LinkedLoop <int> list2 = new LinkedLoop <int>(); //Act list1.AddLast(1); list1.AddLast(2); list2.AddLast(3); list2.AddLast(4); LinkedLoop <int> listS = LinkedLoop.ConcatList(list1, list2); //Assert var item1 = listS.first; var item2 = item1.next; var item3 = item2.next; var item4 = item3.next; Assert.AreEqual(4, listS.size); Assert.AreEqual(1, item1.value); Assert.AreEqual(2, item2.value); Assert.AreEqual(3, item3.value); Assert.AreEqual(4, item4.value); Assert.AreEqual(item1.next, item2); Assert.AreEqual(item1.previous, item4); Assert.AreEqual(item2.next, item3); Assert.AreEqual(item2.previous, item1); Assert.AreEqual(item3.next, item4); Assert.AreEqual(item3.previous, item2); Assert.AreEqual(item4.next, item1); Assert.AreEqual(item4.previous, item3); }
public void InsertValueAfter() { //Arrange LinkedLoop <int> list = new LinkedLoop <int>(); list.AddLast(1); list.AddLast(3); //Act list.InsertAfter(list.first, 2); //Assert Assert.AreEqual(3, list.size); CheckConsistancy(list); var n = list.first; for (int i = 0; i < list.size; i++) { Assert.AreEqual(i + 1, n.value); n = n.next; } }
/// <param name="vertices">Chain of vertices for polygon</param> /// <param name="normal">Normal the polygon is facing to</param> public BzPolyLoop(BzMeshData meshData, LinkedLoop <int> edgeLoop, Vector3 normal, IBzSliceAdapter adapter) { this.meshData = meshData; this.edgeLoop = edgeLoop; if (edgeLoop.size < 3) { return; } Profiler.BeginSample("ConvertV3ToV2"); polyVertices2D = ConvertV3ToV2(adapter, normal); Profiler.EndSample(); Profiler.BeginSample("MakeMesh"); var newTriangles1 = MakeMesh(true); var newTriangles2 = MakeMesh(false); Profiler.EndSample(); // get triangle list with more vertices OuterLoop = newTriangles1.Count >= newTriangles2.Count; if (OuterLoop) { triangles = newTriangles1; } else { triangles = newTriangles2; } if (triangles.Count != 0) { CalculateMetodata(); Created = true; } }
public void DiffDirections(bool diffDir) { // 1 4 2 // |--------|--------| // | |\ | // | t0 | | t3 | // | || \ | // | / | | | // | / | \ | // | | | | | // | / | \ | // | / | | | // | | | \ | // | / t1| t2 | | // | / | \ | // | | | | | // |/_______|_ | | // 0 5 `"--..\| // 3 //Arrange var vertices = new Vector3[] { new Vector3(-10, -10, 0), new Vector3(-10, 10, 0), new Vector3(10, 10, 0), new Vector3(10, diffDir ? -15 : -10, 0), new Vector3(0, 10, 0), // 4 new Vector3(0, -10, 0), // 5 }; List <BzTriangle> trianglesSliced = new List <BzTriangle>(); trianglesSliced.Add(new BzTriangle(1, 4, 0)); trianglesSliced.Add(new BzTriangle(4, 5, 0)); trianglesSliced.Add(new BzTriangle(4, 3, 5)); trianglesSliced.Add(new BzTriangle(4, 2, 3)); var mesh = new Mesh(); mesh.vertices = vertices; var meshData = new BzMeshData(mesh, null); var linkedLoops = new LinkedList <LinkedLoop <int> >(); var linkedLoop = new LinkedLoop <int>(); linkedLoops.AddLast(linkedLoop); linkedLoop.AddLast(2); linkedLoop.AddLast(4); linkedLoop.AddLast(1); //Act MeshTriangleOptimizer.OptimizeEdgeTriangles(linkedLoops, meshData, trianglesSliced); //Assert if (diffDir) { Assert.That(trianglesSliced.Count >= 3); } else { Assert.AreEqual(2, trianglesSliced.Count); } }
public void BigAngle(bool mirror) { // 0 1 2 // --|-----|.-------------------------|-- // \ \ *._ / // \ \ *._ / // \ \ *._ / // \ \ *._ / // \ \ *._ / // \ \ *_ / // \ \ | 3 // \ \ | // \ \ | // \ \ | // \ \ | // \ \ | // \\| // -----*----- // 4 //Arrange float m = mirror ? -1f : 1f; var vertices = new Vector3[] { new Vector3(m * -10, 0, 0), new Vector3(m * -5, 0, 0), new Vector3(m * 10, 0, 0), new Vector3(0, -1, 0), new Vector3(0, -5, 0), }; List <BzTriangle> trianglesSliced = new List <BzTriangle>(); trianglesSliced.Add(GetOrder(new BzTriangle(0, 1, 4), mirror)); trianglesSliced.Add(GetOrder(new BzTriangle(1, 3, 4), mirror)); trianglesSliced.Add(GetOrder(new BzTriangle(1, 2, 3), mirror)); var mesh = new Mesh(); mesh.vertices = vertices; var meshData = new BzMeshData(mesh, null); var linkedLoops = new LinkedList <LinkedLoop <int> >(); var linkedLoop = new LinkedLoop <int>(); linkedLoops.AddLast(linkedLoop); if (mirror) { linkedLoop.AddLast(0); linkedLoop.AddLast(1); linkedLoop.AddLast(2); } else { linkedLoop.AddLast(2); linkedLoop.AddLast(1); linkedLoop.AddLast(0); } //Act MeshTriangleOptimizer.OptimizeEdgeTriangles(linkedLoops, meshData, trianglesSliced); //Assert Assert.AreEqual(2, trianglesSliced.Count); var tr1 = trianglesSliced[0]; var tr2 = trianglesSliced[1]; bool case1 = TrAreEqual(tr1, GetOrder(new BzTriangle(0, 2, 3), mirror)) && TrAreEqual(tr2, GetOrder(new BzTriangle(0, 3, 4), mirror)); bool case2 = TrAreEqual(tr1, GetOrder(new BzTriangle(0, 3, 4), mirror)) && TrAreEqual(tr2, GetOrder(new BzTriangle(0, 2, 3), mirror)); Assert.That(case1 ^ case2); }
public void Optimize() { // 1 4 5 2 // |--------*-----------|--------| // | | \ \ | // | t0 / \ t3 | t4 | // | | | \ \ | // | / | \ \ | // | / \ \ | | // | | | \ \ | // | / | \ \ | // | / \ \ | | // | | | \ \ | // | / t1 | t2 \ \ | // | / \ \ | | // | | | \\ | // |/___________|_______________\| // 0 6 3 //Arrange var vertices = new Vector3[] { new Vector3(-10, -10, 0), new Vector3(-10, 10, 0), new Vector3(10, 10, 0), new Vector3(10, -10, 0), new Vector3(-5, 10, 0), // 4 new Vector3(5, 10, 0), // 5 new Vector3(0, -10, 0), // 6 }; List <BzTriangle> trianglesSliced = new List <BzTriangle>(); trianglesSliced.Add(new BzTriangle(1, 4, 0)); trianglesSliced.Add(new BzTriangle(4, 6, 0)); trianglesSliced.Add(new BzTriangle(4, 3, 6)); trianglesSliced.Add(new BzTriangle(4, 5, 3)); trianglesSliced.Add(new BzTriangle(5, 2, 3)); var mesh = new Mesh(); mesh.vertices = vertices; var meshData = new BzMeshData(mesh, null); var linkedLoops = new LinkedList <LinkedLoop <int> >(); var linkedLoop = new LinkedLoop <int>(); linkedLoops.AddLast(linkedLoop); linkedLoop.AddLast(2); linkedLoop.AddLast(5); linkedLoop.AddLast(4); linkedLoop.AddLast(1); //Act MeshTriangleOptimizer.OptimizeEdgeTriangles(linkedLoops, meshData, trianglesSliced); //Assert Assert.AreEqual(2, trianglesSliced.Count); var tr1 = trianglesSliced[0]; var tr2 = trianglesSliced[1]; bool case1 = TrAreEqual(tr1, new BzTriangle(1, 2, 0)) && TrAreEqual(tr2, new BzTriangle(1, 3, 0)); bool case2 = TrAreEqual(tr1, new BzTriangle(1, 2, 0)) && TrAreEqual(tr2, new BzTriangle(2, 3, 0)); Assert.That(case1 ^ case2); }
/// <summary> /// Calculate triangle list /// </summary> /// <param name="right">Clockwise if True</param> /// <returns>True if polygon was created</returns> private List <int> GetTriangles() { if (_loopPoints.Length < 3) { return(new List <int>()); } var newTriangles = new List <int>((_loopPoints.Length - 2) * 3); var linkList = new LinkedLoop <int>(); for (int i = 0; i < _loopPoints.Length; ++i) { linkList.AddLast(i); } while (linkList.size > 2) { int counter = 0; float minDist = float.MaxValue; int minI1 = 0; LoopNode <int> minNode2 = null; int minI3 = 0; var node = linkList.first; while (counter < linkList.size) { var node1 = node; var node2 = node1.next; var node3 = node2.next; var i1 = node1.value; var i2 = node2.value; var i3 = node3.value; ++counter; float dist = GetDistance(i1, i3); bool allowed = minDist > dist && IsAllowedToCreateTriangle(linkList, i1, i2, i3); if (allowed & minDist > dist) { minDist = dist; minNode2 = node2; minI1 = i1; minI3 = i3; //if (!optimization enabled) // TODO // break; } node = node2; } if (minNode2 == null) { break; } minNode2.Remove(); CreateTriangle(newTriangles, minI1, minNode2.value, minI3); } return(newTriangles); }
public LoopIndexCollection(BzPolyLoop loop, LinkedLoop <LoopIndex> items) { this.loop = loop; this.items = items; }