public BzMeshDataEditor(BzMeshData meshData, Plane planeLocal, IBzSliceAddapter adapter) { _meshData = meshData; _adapter = adapter; _planeLocal = planeLocal; _chashedOuterLines = new Dictionary <IndexVector, int>(); }
private static BzPolyLoop GetLoop(Vector2[] vertices, int[] outerIndexes) { BzMeshData meshData = GetMeshData(vertices); BzPolyLoop outer = GetLoop(outerIndexes, meshData); return(outer); }
private static BzPolyLoop GetLoop(int[] outerIndexes, BzMeshData meshData) { return(new BzPolyLoop(meshData, new LinkedLoop <int>( outerIndexes.ToList()), Vector3.back, new SliceAdapterMock())); }
public void GetEdgeLoops() { //Arrange var vertices = new Vector3[] { new Vector3(0f, 0f, 0), new Vector3(0f, 1f, 0), new Vector3(0f, 1f, 0), new Vector3(0.5f, 1f, 0), new Vector3(1f, 1f, 0), }; var mesh = new Mesh(); mesh.vertices = vertices; var meshData = new BzMeshData(mesh, null); var adapter = new BzMockAdapter(vertices); BzMeshDataEditor editor = new BzMeshDataEditor(meshData, new Plane(), adapter); editor.CapEdges.Add(new IndexVector(0, 1)); editor.CapEdges.Add(new IndexVector(1, 2)); editor.CapEdges.Add(new IndexVector(2, 3)); editor.CapEdges.Add(new IndexVector(3, 4)); //Act var loops = editor.GetEdgeLoops(); //Assert Assert.AreEqual(1, loops.Count); var loop = loops.Single(); CollectionAssert.AreEqual(new[] { 0, 1, 4 }, LoopToArray(loop)); }
/// <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; } }
public BzMeshDataEditor(BzMeshData meshData, Plane plane, IBzSliceAdapter adapter, bool skipIfNotClosed) { _meshData = meshData; _adapter = adapter; _skipIfNotClosed = skipIfNotClosed; _plane = plane; _chashedOuterLines = new Dictionary <IndexVector, int>(); }
private static BzMeshData GetMeshData(Vector2[] vertices) { var mesh = new Mesh(); mesh.vertices = vertices.Select(v => new Vector3(v.x, v.y, 0f)).ToArray(); var meshData = new BzMeshData(mesh, null); return(meshData); }
private bool CheckNewMesh(BzMeshData meshData) { if (meshData.SubMeshes.All(s => s.Length == 0)) { return(false); } if (!CheckMinWidth(meshData)) { return(false); } return(_adapter.Check(meshData)); }
public BzMeshDataDissector(Mesh mesh, Plane plane, Material[] materials, IBzSliceAdapter adapter, SliceConfigurationDto configuration) { _adapter = adapter; _plane = plane; Configuration = configuration; _meshDataNeg = new BzMeshData(mesh, materials); _meshDataPos = new BzMeshData(mesh, materials); _subMeshes = new int[mesh.subMeshCount][]; for (int subMeshIndex = 0; subMeshIndex < mesh.subMeshCount; ++subMeshIndex) { _subMeshes[subMeshIndex] = mesh.GetTriangles(subMeshIndex); } }
public void JoinBySameValue() { //Arrange var vertices = new Vector3[] { new Vector3(0, 0, 0), new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(3, 0, 0), new Vector3(4, 0, 0), new Vector3(5, 0, 0), new Vector3(5, 0, 0), new Vector3(7, 0, 0), }; var mesh = new Mesh(); mesh.vertices = vertices; var meshData = new BzMeshData(mesh, null); var adapter = new BzMockAdapter(vertices); BzMeshDataEditor editor = new BzMeshDataEditor(meshData, new Plane(), adapter); editor.CapEdges.Add(new IndexVector(2, 3)); editor.CapEdges.Add(new IndexVector(0, 1)); editor.CapEdges.Add(new IndexVector(4, 5)); editor.CapEdges.Add(new IndexVector(5, 6)); editor.CapEdges.Add(new IndexVector(6, 7)); //Act var loops = editor.GetEdgeLoopsByIndex(); Assert.AreEqual(3, loops.Count); editor.EdgeLoops_JoinBySameValue(loops); //Assert Assert.AreEqual(2, loops.Count); var loop1 = loops.Single(loop => loop.first.value == 0 | loop.last.value == 0); var loop2 = loops.Single(loop => loop.first.value == 4 | loop.last.value == 4); Assert.IsTrue(Enumerable.SequenceEqual(new[] { 0, 1, 3 }, LoopToArray(loop1))); Assert.IsTrue(Enumerable.SequenceEqual(new[] { 4, 5, 6, 7 }, LoopToArray(loop2))); }
private bool CheckMinWidth(BzMeshData meshData) { if (meshData.Vertices.Count < 3) { return(false); } for (int i = 0; i < meshData.Vertices.Count; i++) { var pos = _adapter.GetWorldPos(meshData, i); float dist = _plane.GetDistanceToPoint(pos); if (Math.Abs(dist) > MinWidth) { return(true); } } return(false); }
public bool Check(BzMeshData meshData) { int trCount = 0; for (int i = 0; i < meshData.SubMeshes.Length; i++) { trCount += meshData.SubMeshes[i].Length; } if (trCount < 3) { throw new Exception("FFFFF3"); } if (trCount % 3 != 0) { throw new Exception("FFFFF4"); } return(true); }
private bool CheckMinWidth(BzMeshData meshData) { if (meshData.Vertices.Count < 3) { return(false); } for (int si = 0; si < meshData.SubMeshes.Length; si++) { var subMesh = meshData.SubMeshes[si]; for (int i = 0; i < subMesh.Length; i++) { var pos = _adapter.GetWorldPos(meshData, subMesh[i]); float dist = _plane.GetDistanceToPoint(pos); if (Math.Abs(dist) > MinWidth) { return(true); } } } return(false); }
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 Vector3 GetWorldPos(BzMeshData meshData, int index) { var v = meshData.Vertices[index]; return(new Vector3(v.x, v.y, v.z)); }
public bool Check(BzMeshData meshData) { throw new System.NotImplementedException(); }
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 Vector3 GetWorldPos(BzMeshData meshData, int index) { return(_ltw.MultiplyPoint3x4(meshData.Vertices[index])); }
public bool Check(BzMeshData meshData) { return(true); }
public static void OptimizeEdgeTriangles(LinkedList <LinkedLoop <int> > edgeLoopsByIndex, BzMeshData meshData, List <BzTriangle> bzTriangles) { bool[] trToDelete = new bool[bzTriangles.Count]; var edgeLoopsNode = edgeLoopsByIndex.First; while (edgeLoopsNode != null) { var edgeLoop = edgeLoopsNode.Value; edgeLoopsNode = edgeLoopsNode.Next; var edge = edgeLoop.first; int counter = edgeLoop.size; while (counter > 0 & edgeLoop.size >= 3) { var edgeItem1 = edge; var edgeItem2 = edgeItem1.next; var edgeItem3 = edgeItem2.next; int i1 = edgeItem1.value; int i2 = edgeItem2.value; int i3 = edgeItem3.value; var v1 = meshData.Vertices[i1]; var v2 = meshData.Vertices[i2]; var v3 = meshData.Vertices[i3]; var dir1 = v2 - v1; var dir2 = v3 - v2; float angle = GetAngleRad(dir1, dir2); if (angle < _angleTrashold && EmptyRedundantIndex(i3, i2, i1, meshData.Vertices, bzTriangles, trToDelete)) { edgeItem2.Remove(); } else { edge = edge.next; --counter; } } } // remove empty int count = 0; for (int i = 0; i < bzTriangles.Count; i++) { if (!trToDelete[i]) { var value = bzTriangles[i]; bzTriangles[count] = value; ++count; } } bzTriangles.RemoveRange(count, bzTriangles.Count - count); }
private static void OptimizeEdgeTriangles(BzMeshDataEditor meshEditor, BzMeshData meshData, List <BzTriangle> bzTriangles) { var edgeLoops = meshEditor.GetEdgeLoopsByIndex(); bool[] trToDelete = new bool[bzTriangles.Count]; var edgeLoopsNode = edgeLoops.First; while (edgeLoopsNode != null) { var edgeLoop = edgeLoopsNode.Value; edgeLoopsNode = edgeLoopsNode.Next; var edge = edgeLoop.first; int counter = edgeLoop.size; while (counter > 0 & edgeLoop.size >= 3) { --counter; var edgeItem1 = edge; var edgeItem2 = edgeItem1.next; var edgeItem3 = edgeItem2.next; int i1 = edgeItem1.value; int i2 = edgeItem2.value; int i3 = edgeItem3.value; var v1 = meshData.Vertices[i1]; var v2 = meshData.Vertices[i2]; var v3 = meshData.Vertices[i3]; if (v1 == v2) { EmptyRedundantIndex(i2, i3, bzTriangles, trToDelete); edgeItem2.Remove(); continue; } var dir1 = (v2 - v1).normalized; var dir2 = (v3 - v2).normalized; if (dir1 == dir2) { EmptyRedundantIndex(i2, i3, bzTriangles, trToDelete); edgeItem2.Remove(); } else { edge = edge.next; } } } // remove empty int count = 0; for (int i = 0; i < bzTriangles.Count; i++) { var value = bzTriangles[i]; bzTriangles[count] = value; if (!trToDelete[i]) { ++count; } } bzTriangles.RemoveRange(count, bzTriangles.Count - count); }
public Vector3 GetWorldPos(BzMeshData meshData, int index) { return(meshData.Vertices[index]); }