示例#1
0
        public void GetEdgeLoopsByIndex()
        {
            //Arrange
            BzMeshDataEditor editor = new BzMeshDataEditor(null, new Plane(), null);

            editor.CapEdges.Add(new IndexVector(1, 5));
            editor.CapEdges.Add(new IndexVector(5, 3));
            editor.CapEdges.Add(new IndexVector(3, 6));
            editor.CapEdges.Add(new IndexVector(6, 7));
            editor.CapEdges.Add(new IndexVector(7, 8));

            editor.CapEdges.Add(new IndexVector(2, 4));
            editor.CapEdges.Add(new IndexVector(4, 9));
            editor.CapEdges.Add(new IndexVector(9, 10));

            //Act
            var loops = editor.GetEdgeLoopsByIndex();

            //Assert
            Assert.AreEqual(2, loops.Count);

            var loop1 = loops.Single(loop => loop.size == 6);
            var loop2 = loops.Single(loop => loop.size == 4);

            Assert.IsTrue(Enumerable.SequenceEqual(new[] { 1, 5, 3, 6, 7, 8 }, LoopToArray(loop1)));
            Assert.IsTrue(Enumerable.SequenceEqual(new[] { 2, 4, 9, 10 }, LoopToArray(loop2)));
        }
示例#2
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)));
        }
示例#3
0
        private SliceResult SliceMesh(Material sectionViewMaterial)
        {
            Profiler.BeginSample("SliceMesh");
            var planeInverted = new Plane(-_plane.normal, -_plane.distance);

            bool skipIfNotClosed = Configuration == null ? false : Configuration.SkipIfNotClosed;

            BzMeshDataEditor meshEditorNeg = new BzMeshDataEditor(_meshDataNeg, _plane, _adapter, skipIfNotClosed);
            BzMeshDataEditor meshEditorPos = new BzMeshDataEditor(_meshDataPos, planeInverted, _adapter, skipIfNotClosed);

            for (int subMeshIndex = 0; subMeshIndex < _subMeshes.Length; ++subMeshIndex)
            {
                int[] newTriangles = _subMeshes[subMeshIndex];

                int trCount            = newTriangles.Length / 3;
                var trianglesNeg       = new List <BzTriangle>(trCount);
                var trianglesPos       = new List <BzTriangle>(trCount);
                var trianglesNegSliced = new List <BzTriangle>(trCount / 10);
                var trianglesPosSliced = new List <BzTriangle>(trCount / 10);

                for (int i = 0; i < trCount; ++i)
                {
                    int trIndex    = i * 3;
                    var bzTriangle = new BzTriangle(
                        newTriangles[trIndex + 0],
                        newTriangles[trIndex + 1],
                        newTriangles[trIndex + 2]);

                    Vector3 v1      = _adapter.GetWorldPos(bzTriangle.i1);
                    Vector3 v2      = _adapter.GetWorldPos(bzTriangle.i2);
                    Vector3 v3      = _adapter.GetWorldPos(bzTriangle.i3);
                    bool    side1   = _plane.GetSide(v1);
                    bool    side2   = _plane.GetSide(v2);
                    bool    side3   = _plane.GetSide(v3);
                    bool    PosSide = side1 | side2 | side3;
                    bool    NegSide = !side1 | !side2 | !side3;

                    if (NegSide & PosSide)
                    {
                        bzTriangle.DivideByPlane(
                            meshEditorNeg, meshEditorPos,
                            trianglesNegSliced, trianglesPosSliced,
                            side1, side2, side3);
                    }
                    else if (NegSide)
                    {
                        trianglesNeg.Add(bzTriangle);
                    }
                    else if (PosSide)
                    {
                        trianglesPos.Add(bzTriangle);
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }
                }

                MeshTriangleOptimizer.OptimizeEdgeTriangles(meshEditorNeg.GetEdgeLoopsByIndex(), _meshDataNeg, trianglesNegSliced);
                MeshTriangleOptimizer.OptimizeEdgeTriangles(meshEditorPos.GetEdgeLoopsByIndex(), _meshDataPos, trianglesPosSliced);
                _meshDataNeg.SubMeshes[subMeshIndex] = MakeTriangleToList(trianglesNeg, trianglesNegSliced);
                _meshDataPos.SubMeshes[subMeshIndex] = MakeTriangleToList(trianglesPos, trianglesPosSliced);
            }

            CapsNeg = meshEditorNeg.CapSlice(sectionViewMaterial);
            CapsPos = meshEditorPos.CapSlice(sectionViewMaterial);

            meshEditorNeg.DeleteUnusedVertices();
            meshEditorPos.DeleteUnusedVertices();

            Profiler.EndSample();

            if (!CheckNewMesh(_meshDataNeg))
            {
                return(SliceResult.Pos);
            }
            if (!CheckNewMesh(_meshDataPos))
            {
                return(SliceResult.Neg);
            }

            return(SliceResult.Sliced);
        }
示例#4
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);
        }