Пример #1
0
 public BzMeshDataEditor(BzMeshData meshData, Plane planeLocal, IBzSliceAddapter adapter)
 {
     _meshData          = meshData;
     _adapter           = adapter;
     _planeLocal        = planeLocal;
     _chashedOuterLines = new Dictionary <IndexVector, int>();
 }
Пример #2
0
        private static BzPolyLoop GetLoop(Vector2[] vertices, int[] outerIndexes)
        {
            BzMeshData meshData = GetMeshData(vertices);
            BzPolyLoop outer    = GetLoop(outerIndexes, meshData);

            return(outer);
        }
Пример #3
0
 private static BzPolyLoop GetLoop(int[] outerIndexes, BzMeshData meshData)
 {
     return(new BzPolyLoop(meshData, new LinkedLoop <int>(
                               outerIndexes.ToList()),
                           Vector3.back,
                           new SliceAdapterMock()));
 }
Пример #4
0
        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));
        }
Пример #5
0
        /// <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;
            }
        }
Пример #6
0
 public BzMeshDataEditor(BzMeshData meshData, Plane plane, IBzSliceAdapter adapter, bool skipIfNotClosed)
 {
     _meshData          = meshData;
     _adapter           = adapter;
     _skipIfNotClosed   = skipIfNotClosed;
     _plane             = plane;
     _chashedOuterLines = new Dictionary <IndexVector, int>();
 }
Пример #7
0
        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);
        }
Пример #8
0
        private bool CheckNewMesh(BzMeshData meshData)
        {
            if (meshData.SubMeshes.All(s => s.Length == 0))
            {
                return(false);
            }

            if (!CheckMinWidth(meshData))
            {
                return(false);
            }

            return(_adapter.Check(meshData));
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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)));
        }
Пример #11
0
        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);
        }
Пример #12
0
        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);
        }
Пример #13
0
        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);
        }
Пример #16
0
            public Vector3 GetWorldPos(BzMeshData meshData, int index)
            {
                var v = meshData.Vertices[index];

                return(new Vector3(v.x, v.y, v.z));
            }
Пример #17
0
 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);
 }
Пример #21
0
        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);
        }
Пример #22
0
        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);
        }
Пример #23
0
 public Vector3 GetWorldPos(BzMeshData meshData, int index)
 {
     return(meshData.Vertices[index]);
 }