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 Remove() { --list.size; if (list.size == 0) { list.first = null; list.last = null; list = null; next = null; previous = null; } else { if (list.first == this) { list.first = next; } if (list.last == this) { list.last = previous; } next.previous = previous; previous.next = next; } }
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 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); }
/// <param name="vertices">Chain of vertices for polygon</param> /// <param name="normal">Normal the polygon is facing to</param> public BzPoly(BzMeshData meshData, LinkedLoop <int> edgeLoop, Vector3 normal, IBzSliceAddapter adapter) { _meshData = meshData; _edgeLoop = edgeLoop; if (edgeLoop.size < 3) { return; } _polyVertices2D = ConvertV3ToV2(adapter, normal); var newTriangles1 = MakeMesh(false); var newTriangles2 = MakeMesh(true); // get triangle list with more vertices if (newTriangles1.Count > newTriangles2.Count) { _newTriangles = newTriangles1; } else { _newTriangles = newTriangles2; } if (_newTriangles.Count != 0) { Created = true; } }
static bool TryAttachEdgeToList(IndexVector segment, LinkedLoop <int> toList) { var first = toList.first.value; if (first == segment.From) { toList.AddFirst(segment.To); return(true); } if (first == segment.To) { toList.AddFirst(segment.From); return(true); } var last = toList.last.value; if (last == segment.From) { toList.AddLast(segment.To); return(true); } if (last == segment.To) { toList.AddLast(segment.From); return(true); } return(false); }
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); }
public void EdgeLoops_JoinBySameValue(LinkedList <LinkedLoop <int> > edgeLoops) { // join by the most close points var parrentListsNode = edgeLoops.First; while (parrentListsNode != null) { var childList = parrentListsNode.Value; bool jointFound = false; var listFirstValue = _meshData.Vertices[childList.first.value]; var listLastValue = _meshData.Vertices[childList.last.value]; var joinCandidate = parrentListsNode.Next; while (joinCandidate != null) { var restFirstValue = _meshData.Vertices[joinCandidate.Value.first.value]; var restLastValue = _meshData.Vertices[joinCandidate.Value.last.value]; if ((listLastValue - restFirstValue).sqrMagnitude < MinPointDistanceSqr) { joinCandidate.Value.first.Remove(); // to avoid duplication of the same index when concatinaiting childList = LinkedLoop.ConcatList(childList, joinCandidate.Value); jointFound = true; break; } else if ((listFirstValue - restLastValue).sqrMagnitude < MinPointDistanceSqr) { childList.first.Remove(); childList = LinkedLoop.ConcatList(joinCandidate.Value, childList); jointFound = true; break; } joinCandidate = joinCandidate.Next; } if (jointFound) { edgeLoops.Remove(joinCandidate); parrentListsNode.Value = childList; } else { parrentListsNode = parrentListsNode.Next; } } }
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]; 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); } } Vector3 vA = v1 - v2; Vector3 vB = v3 - v2; Vector3 vC = Vector3.Cross(vA, vB); if (right) { return(vC.z < 0); } else { return(vC.z > 0); } }
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 LinkedList <LinkedLoop <int> > GetEdgeLoopsByIndex() { var lists = new LinkedList <LinkedLoop <int> >(); // join by common indexes var capEdgesLoop = new LinkedLoop <IndexVector>(CapEdges); while (capEdgesLoop.size != 0) { var newList = new LinkedLoop <int>(); lists.AddLast(newList); IndexVector edge = capEdgesLoop.first.value; capEdgesLoop.first.Remove(); newList.AddLast(edge.From); newList.AddLast(edge.To); var current = capEdgesLoop.first; int counter = capEdgesLoop.size; while (counter != 0) { --counter; var next = current.next; if (TryAttachEdgeToList(current.value, newList)) { current.Remove(); counter = capEdgesLoop.size; } current = next; } } return(lists); }
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; } }
/// <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 node4 = node3.next; var i1 = node1.value; var i2 = node2.value; var i3 = node3.value; var i4 = node4.value; Vector2 v1 = _polyVertices2D[i1]; Vector2 v2 = _polyVertices2D[i2]; Vector2 v3 = _polyVertices2D[i3]; Vector2 v4 = _polyVertices2D[i4]; if ((v2 - v1).normalized == (v3 - v1).normalized) { node2.Remove(); continue; } if ((v3 - v2).normalized == (v4 - v2).normalized) { node3.Remove(); continue; } if (node1 == linkList.first) { var nodePrev = node1.previous; // needed only for start var iPrev = nodePrev.value; Vector2 vPrev = _polyVertices2D[iPrev]; if ((v2 - v1).normalized == (v1 - vPrev).normalized) { node1.Remove(); node = node2; continue; } } ++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); }
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); }
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 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 LoopNode(LinkedLoop <T> list, T value) { this.list = list; this.value = value; }
internal void EdgeLoops_JoinBySameValue(LinkedList <LinkedLoop <int> > edgeLoops) { // join by the most close points var parrentListsNode = edgeLoops.First; while (parrentListsNode != null) { var childList = parrentListsNode.Value; bool delete = false; var listFirstValue = _meshData.Vertices[childList.first.value]; var listLastValue = _meshData.Vertices[childList.last.value]; var rest = parrentListsNode.Next; while (rest != null) { var restFirstValue = _meshData.Vertices[rest.Value.first.value]; var restLastValue = _meshData.Vertices[rest.Value.last.value]; if (listLastValue == restFirstValue) { rest.Value.first.Remove(); var newList = LinkedLoop.ConcatList(childList, rest.Value); edgeLoops.AddAfter(parrentListsNode, newList); delete = true; break; } if (listFirstValue == restLastValue) { childList.first.Remove(); var newList = LinkedLoop.ConcatList(rest.Value, childList); edgeLoops.AddAfter(parrentListsNode, newList); delete = true; break; } if (listFirstValue == restFirstValue) { rest.Value.Reverse(); childList.first.Remove(); var newList = LinkedLoop.ConcatList(rest.Value, childList); edgeLoops.AddAfter(parrentListsNode, newList); delete = true; break; } if (listLastValue == restLastValue) { rest.Value.last.Remove(); rest.Value.Reverse(); var newList = LinkedLoop.ConcatList(childList, rest.Value); edgeLoops.AddAfter(parrentListsNode, newList); delete = true; break; } rest = rest.Next; } var tmp = parrentListsNode; parrentListsNode = parrentListsNode.Next; if (delete) { edgeLoops.Remove(tmp); edgeLoops.Remove(rest); } } }