Example #1
0
        // Token: 0x0600429C RID: 17052 RVA: 0x00152C8C File Offset: 0x0015108C
        public void ShowContourDBG(float duration)
        {
            List <Vector3[]> worldContours = this.GetWorldContours();

            foreach (Vector3[] array in worldContours)
            {
                Vector3 start = array[0];
                for (int i = 1; i < array.Length; i++)
                {
                    Debug.DrawLine(start, array[i], Color.red, duration);
                    start = array[i];
                }
                Debug.DrawLine(start, array[0], Color.red, duration);
                ContourData.GetNormal(worldContours[0]);
            }
        }
Example #2
0
        /// <summary>
        /// cut object by plane
        /// </summary>
        /// <param name="obj">game object</param>
        /// <param name="plane">cutting plane</param>
        /// <param name="triangulateHoles">triangulate holes</param>
        /// <param name="deleteOriginal">delete original object</param>
        /// <param name="cut0">first new game object after cut</param>
        /// <param name="cut1">second new game object after cut</param>
        /// <param name="intersectionData">contours data</param>
        /// <returns>cutting time</returns>
        public float Cut(GameObject obj, Utils.Plane plane, bool triangulateHoles, bool deleteOriginal, Vector4 crossSection, out GameObject cut0, out GameObject cut1, out ContourData intersectionData)
        {
            var meshFilter = obj.GetComponent <MeshFilter>();

            if (meshFilter == null || meshFilter.sharedMesh == null)
            {
                cut0             = null;
                cut1             = null;
                intersectionData = null;
                MeshUtils.Log("Cutting object has no mesh filter!");
                return(0.0f);
            }

            // get mesh of the primitive
            var      meshToCut = obj.GetComponent <MeshFilter>().sharedMesh;
            Material material  = null;

            var meshRenderer = obj.GetComponent <MeshRenderer>();

            if (meshRenderer != null)
            {
                material = meshRenderer.sharedMaterial;
            }

            Mesh mesh0 = null, mesh1 = null;

            cut0             = null;
            cut1             = null;
            intersectionData = null;

            var useCentroid = obj.transform.localScale == Vector3.one;

            var centroid0 = Vector3.zero;
            var centroid1 = Vector3.zero;

            var ms = 0.0f;

            // create 2 new objects
            if (useCentroid)
            {
                ms = Cut(meshToCut, obj.transform, plane, triangulateHoles, crossSection, out mesh0, out mesh1, out centroid0, out centroid1, out intersectionData);
            }
            else
            {
                ms = Cut(meshToCut, obj.transform, plane, triangulateHoles, crossSection, out mesh0, out mesh1, out intersectionData);
            }

            if (mesh0 != null)
            {
                var obj0        = new GameObject(obj.name + "_cut0");
                var meshFilter0 = obj0.AddComponent <MeshFilter>();

                if (meshFilter0 != null)
                {
                    meshFilter0.sharedMesh = mesh0;
                }

                var renderer0 = obj0.AddComponent <MeshRenderer>();

                if (renderer0 != null && material != null)
                {
                    renderer0.sharedMaterials = new Material[2] {
                        new Material(material), new Material(material)
                    };
                }

                obj0.transform.position   = obj.transform.position;
                obj0.transform.rotation   = obj.transform.rotation;
                obj0.transform.localScale = obj.transform.localScale;

                if (useCentroid)
                {
                    obj0.transform.Translate(centroid0);
                }

                cut0 = obj0;
            }

            if (mesh1 != null)
            {
                var obj1        = new GameObject(obj.name + "_cut1");
                var meshFilter1 = obj1.AddComponent <MeshFilter>();

                if (meshFilter1 != null)
                {
                    meshFilter1.sharedMesh = mesh1;
                }

                var renderer1 = obj1.AddComponent <MeshRenderer>();

                if (renderer1 != null && material != null)
                {
                    renderer1.sharedMaterials = new Material[2] {
                        new Material(material), new Material(material)
                    };
                }

                obj1.transform.position   = obj.transform.position;
                obj1.transform.rotation   = obj.transform.rotation;
                obj1.transform.localScale = obj.transform.localScale;

                if (useCentroid)
                {
                    obj1.transform.Translate(centroid1);
                }

                cut1 = obj1;

                if (deleteOriginal)
                {
#if UNITY_EDITOR
                    Object.DestroyImmediate(obj);
#else
                    Object.Destroy(obj);
#endif
                }
            }

            return(ms);
        }
Example #3
0
        private float Cut(Mesh mesh, Transform meshTransform, Utils.Plane plane, bool triangulateHoles, bool fixPivot, bool getContourList, bool dontCut,
                          Vector4 crossSection, out Mesh mesh0, out Mesh mesh1, out Vector3 centroid0, out Vector3 centroid1, out ContourData intersectionData)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();

#if PROFILING
            MeasureIt.Begin("CutAllocations");
#endif

            // cache mesh data
            var trianglesNum  = mesh.triangles.Length;
            var verticesNum   = mesh.vertices.Length;
            var meshTriangles = mesh.triangles;
            var meshVertices  = mesh.vertices;
            var meshNormals   = mesh.normals;
            var meshUV        = mesh.uv;

            this.crossSectionUV = crossSection;

            // preallocate buffers
            AllocateBuffers(trianglesNum, verticesNum);

#if PROFILING
            MeasureIt.End("CutAllocations");
            MeasureIt.Begin("CutCycleFirstPass");
#endif

            // inverse transform cutting plane
            plane.InverseTransform(meshTransform);

            // first pass - find complete triangles on both sides of the plane
            for (var i = 0; i < trianglesNum; i += 3)
            {
                // get triangle points
                var v0 = meshVertices[meshTriangles[i]];
                var v1 = meshVertices[meshTriangles[i + 1]];
                var v2 = meshVertices[meshTriangles[i + 2]];

                var side0 = plane.GetSideFix(ref v0);
                var side1 = plane.GetSideFix(ref v1);
                var side2 = plane.GetSideFix(ref v2);

                meshVertices[meshTriangles[i]]     = v0;
                meshVertices[meshTriangles[i + 1]] = v1;
                meshVertices[meshTriangles[i + 2]] = v2;

                // all points on one side
                if (side0 == side1 && side1 == side2)
                {
                    var idx = side0 ? 0 : 1;

                    if (triCache[meshTriangles[i]] == 0)
                    {
                        triangles[idx].Add(triCounter[idx]);
                        vertices[idx].Add(meshVertices[meshTriangles[i]]);
                        normals[idx].Add(meshNormals[meshTriangles[i]]);
                        uvs[idx].Add(meshUV[meshTriangles[i]]);

                        centroid[idx] += meshVertices[meshTriangles[i]];

                        triCache[meshTriangles[i]] = triCounter[idx] + 1;
                        triCounter[idx]++;
                    }
                    else
                    {
                        triangles[idx].Add(triCache[meshTriangles[i]] - 1);
                    }

                    if (triCache[meshTriangles[i + 1]] == 0)
                    {
                        triangles[idx].Add(triCounter[idx]);
                        vertices[idx].Add(meshVertices[meshTriangles[i + 1]]);
                        normals[idx].Add(meshNormals[meshTriangles[i + 1]]);
                        uvs[idx].Add(meshUV[meshTriangles[i + 1]]);

                        centroid[idx] += meshVertices[meshTriangles[i + 1]];

                        triCache[meshTriangles[i + 1]] = triCounter[idx] + 1;
                        triCounter[idx]++;
                    }
                    else
                    {
                        triangles[idx].Add(triCache[meshTriangles[i + 1]] - 1);
                    }

                    if (triCache[meshTriangles[i + 2]] == 0)
                    {
                        triangles[idx].Add(triCounter[idx]);
                        vertices[idx].Add(meshVertices[meshTriangles[i + 2]]);
                        normals[idx].Add(meshNormals[meshTriangles[i + 2]]);
                        uvs[idx].Add(meshUV[meshTriangles[i + 2]]);

                        centroid[idx] += meshVertices[meshTriangles[i + 2]];

                        triCache[meshTriangles[i + 2]] = triCounter[idx] + 1;
                        triCounter[idx]++;
                    }
                    else
                    {
                        triangles[idx].Add(triCache[meshTriangles[i + 2]] - 1);
                    }
                }
                else
                {
                    // intersection triangles add to list and process it in second pass
                    cutTris.Add(i);
                }
            }

            if (vertices[0].Count == 0)
            {
                centroid[0] = meshVertices[0];
            }
            else
            {
                centroid[0] /= vertices[0].Count;
            }

            if (vertices[1].Count == 0)
            {
                centroid[1] = meshVertices[1];
            }
            else
            {
                centroid[1] /= vertices[1].Count;
            }

#if PROFILING
            MeasureIt.End("CutCycleFirstPass");
            MeasureIt.Begin("CutCycleSecondPass");
#endif
            mesh0            = null;
            mesh1            = null;
            centroid0        = centroid[0];
            centroid1        = centroid[1];
            intersectionData = null;

            if (cutTris.Count < 1)
            {
                stopWatch.Stop();
                return(stopWatch.ElapsedMilliseconds);
            }

            AllocateContours(cutTris.Count);

            // second pass - cut intersecting triangles in half
            foreach (var cutTri in cutTris)
            {
                var triangle = new Triangle
                {
                    ids    = new[] { meshTriangles[cutTri + 0], meshTriangles[cutTri + 1], meshTriangles[cutTri + 2] },
                    pos    = new[] { meshVertices[meshTriangles[cutTri + 0]], meshVertices[meshTriangles[cutTri + 1]], meshVertices[meshTriangles[cutTri + 2]] },
                    normal = new[] { meshNormals[meshTriangles[cutTri + 0]], meshNormals[meshTriangles[cutTri + 1]], meshNormals[meshTriangles[cutTri + 2]] },
                    uvs    = new[] { meshUV[meshTriangles[cutTri + 0]], meshUV[meshTriangles[cutTri + 1]], meshUV[meshTriangles[cutTri + 2]] }
                };

                // check points with a plane
                var side0 = plane.GetSide(triangle.pos[0]);
                var side1 = plane.GetSide(triangle.pos[1]);
                var side2 = plane.GetSide(triangle.pos[2]);

                float   t0, t1;
                Vector3 s0, s1;

                var idxLeft  = side0 ? 0 : 1;
                var idxRight = 1 - idxLeft;

                if (side0 == side1)
                {
                    var a = plane.IntersectSegment(triangle.pos[2], triangle.pos[0], out t0, out s0);
                    var b = plane.IntersectSegment(triangle.pos[2], triangle.pos[1], out t1, out s1);

                    MeshUtils.Assert(a && b, "!!!!!!!!!!!!!!!");

                    // left side ... 2 triangles
                    var s0Left = AddIntersectionPoint(s0, triangle, triangle.ids[2], triangle.ids[0], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var s1Left = AddIntersectionPoint(s1, triangle, triangle.ids[2], triangle.ids[1], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var v0Left = AddTrianglePoint(triangle.pos[0], triangle.normal[0], triangle.uvs[0], triangle.ids[0], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var v1Left = AddTrianglePoint(triangle.pos[1], triangle.normal[1], triangle.uvs[1], triangle.ids[1], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);

                    // Triangle (s0, v0, s1)
                    triangles[idxLeft].Add(s0Left);
                    triangles[idxLeft].Add(v0Left);
                    triangles[idxLeft].Add(s1Left);

                    // Triangle (s1, v0, v1)
                    triangles[idxLeft].Add(s1Left);
                    triangles[idxLeft].Add(v0Left);
                    triangles[idxLeft].Add(v1Left);

                    // right side ... 1 triangle
                    var s0Right = AddIntersectionPoint(s0, triangle, triangle.ids[2], triangle.ids[0], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var s1Right = AddIntersectionPoint(s1, triangle, triangle.ids[2], triangle.ids[1], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var v2Right = AddTrianglePoint(triangle.pos[2], triangle.normal[2], triangle.uvs[2], triangle.ids[2], triCache, cornerVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);

                    // Triangle (v2, s0, s1)
                    triangles[idxRight].Add(v2Right);
                    triangles[idxRight].Add(s0Right);
                    triangles[idxRight].Add(s1Right);

                    // buffer intersection vertices for triangulation
                    if (triangulateHoles)
                    {
                        if (idxLeft == 0)
                        {
                            contour.AddTriangle(cutTri, s0Left, s1Left, s0, s1);
                        }
                        else
                        {
                            contour.AddTriangle(cutTri, s0Right, s1Right, s0, s1);
                        }
                    }
                }
                else if (side0 == side2)
                {
                    var a = plane.IntersectSegment(triangle.pos[1], triangle.pos[0], out t0, out s1);
                    var b = plane.IntersectSegment(triangle.pos[1], triangle.pos[2], out t1, out s0);

                    MeshUtils.Assert(a && b, "!!!!!!!!!!!!!");

                    // left side ... 2 triangles
                    var s0Left = AddIntersectionPoint(s0, triangle, triangle.ids[1], triangle.ids[2], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var s1Left = AddIntersectionPoint(s1, triangle, triangle.ids[1], triangle.ids[0], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var v0Left = AddTrianglePoint(triangle.pos[0], triangle.normal[0], triangle.uvs[0], triangle.ids[0], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var v2Left = AddTrianglePoint(triangle.pos[2], triangle.normal[2], triangle.uvs[2], triangle.ids[2], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);

                    // Triangle (v2, s1, s0)
                    triangles[idxLeft].Add(v2Left);
                    triangles[idxLeft].Add(s1Left);
                    triangles[idxLeft].Add(s0Left);

                    // Triangle (v2, v0, s1)
                    triangles[idxLeft].Add(v2Left);
                    triangles[idxLeft].Add(v0Left);
                    triangles[idxLeft].Add(s1Left);

                    // right side ... 1 triangle
                    var s0Right = AddIntersectionPoint(s0, triangle, triangle.ids[1], triangle.ids[2], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var s1Right = AddIntersectionPoint(s1, triangle, triangle.ids[1], triangle.ids[0], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var v1Right = AddTrianglePoint(triangle.pos[1], triangle.normal[1], triangle.uvs[1], triangle.ids[1], triCache, cornerVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);

                    // Triangle (s0, s1, v1)
                    triangles[idxRight].Add(s0Right);
                    triangles[idxRight].Add(s1Right);
                    triangles[idxRight].Add(v1Right);

                    // buffer intersection vertices for triangulation
                    if (triangulateHoles)
                    {
                        if (idxLeft == 0)
                        {
                            contour.AddTriangle(cutTri, s0Left, s1Left, s0, s1);
                        }
                        else
                        {
                            contour.AddTriangle(cutTri, s0Right, s1Right, s0, s1);
                        }
                    }
                }
                else
                {
                    var a = plane.IntersectSegment(triangle.pos[0], triangle.pos[1], out t0, out s0);
                    var b = plane.IntersectSegment(triangle.pos[0], triangle.pos[2], out t1, out s1);

                    MeshUtils.Assert(a && b, "!!!!!!!!!!!!!");

                    // right side ... 2 triangles
                    var s0Right = AddIntersectionPoint(s0, triangle, triangle.ids[0], triangle.ids[1], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var s1Right = AddIntersectionPoint(s1, triangle, triangle.ids[0], triangle.ids[2], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var v1Right = AddTrianglePoint(triangle.pos[1], triangle.normal[1], triangle.uvs[1], triangle.ids[1], triCache, cornerVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var v2Right = AddTrianglePoint(triangle.pos[2], triangle.normal[2], triangle.uvs[2], triangle.ids[2], triCache, cornerVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);

                    // Triangle (v2, s1, v1)
                    triangles[idxRight].Add(v2Right);
                    triangles[idxRight].Add(s1Right);
                    triangles[idxRight].Add(v1Right);

                    // Triangle (s1, s0, v1)
                    triangles[idxRight].Add(s1Right);
                    triangles[idxRight].Add(s0Right);
                    triangles[idxRight].Add(v1Right);

                    // left side ... 1 triangle
                    var s0Left = AddIntersectionPoint(s0, triangle, triangle.ids[0], triangle.ids[1], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var s1Left = AddIntersectionPoint(s1, triangle, triangle.ids[0], triangle.ids[2], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var v0Left = AddTrianglePoint(triangle.pos[0], triangle.normal[0], triangle.uvs[0], triangle.ids[0], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);

                    // Triangle (s1, v0, s0)
                    triangles[idxLeft].Add(s1Left);
                    triangles[idxLeft].Add(v0Left);
                    triangles[idxLeft].Add(s0Left);

                    // buffer intersection vertices for triangulation
                    if (triangulateHoles)
                    {
                        if (idxLeft == 0)
                        {
                            contour.AddTriangle(cutTri, s0Left, s1Left, s0, s1);
                        }
                        else
                        {
                            contour.AddTriangle(cutTri, s0Right, s1Right, s0, s1);
                        }
                    }
                }
            }

#if PROFILING
            MeasureIt.End("CutCycleSecondPass");
#endif


            if (triangulateHoles || getContourList)
            {
#if PROFILING
                MeasureIt.Begin("FindContours");
#endif

                contour.FindContours();

#if PROFILING
                MeasureIt.End("FindContours");
#endif
            }

            List <int>[] trianglesCut = null;

            if (triangulateHoles)
            {
#if PROFILING
                MeasureIt.Begin("Triangulate");
#endif

                trianglesCut = new List <int>[2] {
                    new List <int>(contour.MidPointsCount), new List <int>(contour.MidPointsCount)
                };
                Triangulate(contour.contour, plane, vertices, normals, uvs, trianglesCut, true);

#if PROFILING
                MeasureIt.End("Triangulate");
#endif
            }

            intersectionData = null;

            if (getContourList)
            {
#if PROFILING
                MeasureIt.Begin("GetContourList");
#endif
                List <Vector3[]> contoursList = null;

                GetContourList(contour.contour, vertices[0], out contoursList);

                intersectionData = new ContourData(contoursList, meshTransform);

#if PROFILING
                MeasureIt.End("GetContourList");
#endif
            }

            centroid0 = centroid[0];
            centroid1 = centroid[1];

            if (dontCut)
            {
                MeshUtils.Assert(intersectionData != null, "F**k");
                MeshUtils.Assert(getContourList != false, "Fuck2");
                mesh0 = null;
                mesh1 = null;
                return(stopWatch.ElapsedMilliseconds);
            }

            if (vertices[0].Count > 0 && vertices[1].Count > 0)
            {
#if PROFILING
                MeasureIt.Begin("CutEndCopyBack");
#endif

                mesh0 = new Mesh();
                mesh1 = new Mesh();

                var verticesArray0 = vertices[0].ToArray();
                var verticesArray1 = vertices[1].ToArray();

#if PROFILING
                MeasureIt.Begin("FixPivot");
#endif

                if (fixPivot)
                {
                    MeshUtils.CenterPivot(verticesArray0, centroid[0]);
                    MeshUtils.CenterPivot(verticesArray1, centroid[1]);
                }

#if PROFILING
                MeasureIt.End("FixPivot");
#endif

                mesh0.vertices = verticesArray0;
                mesh0.normals  = normals[0].ToArray();
                mesh0.uv       = uvs[0].ToArray();

                mesh1.vertices = verticesArray1;
                mesh1.normals  = normals[1].ToArray();
                mesh1.uv       = uvs[1].ToArray();

                if (triangulateHoles && trianglesCut[0].Count > 0)
                {
                    mesh0.subMeshCount = 2;
                    mesh0.SetTriangles(triangles[0].ToArray(), 0);
                    mesh0.SetTriangles(trianglesCut[0].ToArray(), 1);

                    mesh1.subMeshCount = 2;
                    mesh1.SetTriangles(triangles[1].ToArray(), 0);
                    mesh1.SetTriangles(trianglesCut[1].ToArray(), 1);
                }
                else
                {
                    mesh0.triangles = triangles[0].ToArray();
                    mesh1.triangles = triangles[1].ToArray();
                }

#if PROFILING
                MeasureIt.End("CutEndCopyBack");
#endif

                stopWatch.Stop();
                return(stopWatch.ElapsedMilliseconds);
            }

            mesh0 = null;
            mesh1 = null;
            stopWatch.Stop();

//            UnityEngine.Debug.Log("Empty cut! " + vertices[0].Count + " " + vertices[1].Count);

            return(stopWatch.ElapsedMilliseconds);
        }
Example #4
0
        /// <summary>
        /// cut mesh by plane and output list of contour vertices
        /// </summary>
        /// <param name="mesh">mesh to cut</param>
        /// <param name="meshTransform">transformation of the mesh</param>
        /// <param name="plane">cutting plane</param>
        /// <param name="mesh0">first part of the new mesh</param>
        /// <param name="mesh1">second part of the new mesh</param>
        /// <param name="triangulateHoles">flag for triangulation of holes</param>
        /// <param name="intersectionData">list of contours</param>
        /// <returns>processing time</returns>
        public float Cut(Mesh mesh, Transform meshTransform, Utils.Plane plane, bool triangulateHoles, Vector4 crossSection, out Mesh mesh0, out Mesh mesh1, out ContourData intersectionData)
        {
            Vector3 c0, c1;

            return(Cut(mesh, meshTransform, plane, triangulateHoles, false, true, false, crossSection, out mesh0, out mesh1, out c0, out c1, out intersectionData));
        }
Example #5
0
        /// <summary>
        /// cut object by plane
        /// </summary>
        /// <param name="obj">game object</param>
        /// <param name="plane">cutting plane</param>
        /// <param name="triangulateHoles">triangulate holes</param>
        /// <param name="deleteOriginal">delete original object</param>
        /// <param name="cut0">first new game object after cut</param>
        /// <param name="cut1">second new game object after cut</param>
        /// <param name="intersectionData">contours data</param>
        /// <returns>cutting time</returns>
        public float Cut(GameObject obj, Utils.Plane plane, bool triangulateHoles, bool deleteOriginal, out GameObject cut0, out GameObject cut1, out ContourData intersectionData)
        {
            var meshFilter = obj.GetComponent<MeshFilter>();

            if (meshFilter == null || meshFilter.sharedMesh == null)
            {
                cut0 = null;
                cut1 = null;
                intersectionData = null;
                MeshUtils.Log("Cutting object has no mesh filter!");
                return 0.0f;
            }

            // get mesh of the primitive
            var meshToCut = obj.GetComponent<MeshFilter>().sharedMesh;
            Material material = null;

            var meshRenderer = obj.GetComponent<MeshRenderer>();
            if (meshRenderer != null)
            {
                material = meshRenderer.sharedMaterial;
            }

            Mesh mesh0 = null, mesh1 = null;

            cut0 = null;
            cut1 = null;
            intersectionData = null;

            bool useCentroid = obj.transform.localScale == Vector3.one;

            Vector3 centroid0 = Vector3.zero;
            Vector3 centroid1 = Vector3.zero;

            var ms = 0.0f;

            // create 2 new objects
            if (useCentroid)
            {
                ms = Cut(meshToCut, obj.transform, plane, triangulateHoles, out mesh0, out mesh1, out centroid0, out centroid1, out intersectionData);
            }
            else
            {
                ms = Cut(meshToCut, obj.transform, plane, triangulateHoles, out mesh0, out mesh1, out intersectionData);
            }

            if (mesh0 != null)
            {
                var obj0 = new GameObject(obj.name + "_cut0");
                var meshFilter0 = obj0.AddComponent<MeshFilter>();

                if (meshFilter0 != null)
                {
                    meshFilter0.sharedMesh = mesh0;
                }

                var renderer0 = obj0.AddComponent<MeshRenderer>();

                if (renderer0 != null && material != null)
                {
                    renderer0.sharedMaterials = new Material[2] { new Material(material), new Material(material) };
                }

                obj0.transform.position = obj.transform.position;
                obj0.transform.rotation = obj.transform.rotation;
                obj0.transform.localScale = obj.transform.localScale;

                if (useCentroid)
                {
                    obj0.transform.Translate(centroid0);
                }

                cut0 = obj0;
            }

            if (mesh1 != null)
            {
                var obj1 = new GameObject(obj.name + "_cut1");
                var meshFilter1 = obj1.AddComponent<MeshFilter>();

                if (meshFilter1 != null)
                {
                    meshFilter1.sharedMesh = mesh1;
                }

                var renderer1 = obj1.AddComponent<MeshRenderer>();

                if (renderer1 != null && material != null)
                {
                    renderer1.sharedMaterials = new Material[2] { new Material(material), new Material(material) };
                }

                obj1.transform.position = obj.transform.position;
                obj1.transform.rotation = obj.transform.rotation;
                obj1.transform.localScale = obj.transform.localScale;

                if (useCentroid)
                {
                    obj1.transform.Translate(centroid1);
                }

                cut1 = obj1;

                if (deleteOriginal)
                {
            #if UNITY_EDITOR
                    Object.DestroyImmediate(obj);
            #else
                    Object.Destroy(obj);
            #endif
                }
            }

            return ms;
        }
Example #6
0
        float Cut(Mesh mesh, Transform meshTransform, Utils.Plane plane, bool triangulateHoles, bool fixPivot, bool getContourList, bool dontCut,
                         out Mesh mesh0, out Mesh mesh1, out Vector3 centroid0, out Vector3 centroid1, out ContourData intersectionData)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();

            #if PROFILING
            MeasureIt.Begin("CutAllocations");
            #endif

            // cache mesh data
            var trianglesNum = mesh.triangles.Length;
            var verticesNum = mesh.vertices.Length;
            var meshTriangles = mesh.triangles;
            var meshVertices = mesh.vertices;
            var meshNormals = mesh.normals;
            var meshUV = mesh.uv;

            // preallocate buffers
            AllocateBuffers(trianglesNum, verticesNum);

            #if PROFILING
            MeasureIt.End("CutAllocations");
            MeasureIt.Begin("CutCycleFirstPass");
            #endif

            // inverse transform cutting plane
            plane.InverseTransform(meshTransform);

            // first pass - find complete triangles on both sides of the plane
            for (int i = 0; i < trianglesNum; i += 3)
            {
                // get triangle points
                var v0 = meshVertices[meshTriangles[i]];
                var v1 = meshVertices[meshTriangles[i + 1]];
                var v2 = meshVertices[meshTriangles[i + 2]];

                var side0 = plane.GetSideFix(ref v0);
                var side1 = plane.GetSideFix(ref v1);
                var side2 = plane.GetSideFix(ref v2);

                meshVertices[meshTriangles[i]] = v0;
                meshVertices[meshTriangles[i + 1]] = v1;
                meshVertices[meshTriangles[i + 2]] = v2;

                // all points on one side
                if (side0 == side1 && side1 == side2)
                {
                    var idx = side0 ? 0 : 1;

                    if (triCache[meshTriangles[i]] == 0)
                    {
                        triangles[idx].Add(triCounter[idx]);
                        vertices[idx].Add(meshVertices[meshTriangles[i]]);
                        normals[idx].Add(meshNormals[meshTriangles[i]]);
                        uvs[idx].Add(meshUV[meshTriangles[i]]);

                        centroid[idx] += meshVertices[meshTriangles[i]];

                        triCache[meshTriangles[i]] = triCounter[idx] + 1;
                        triCounter[idx]++;
                    }
                    else
                    {
                        triangles[idx].Add(triCache[meshTriangles[i]] - 1);
                    }

                    if (triCache[meshTriangles[i + 1]] == 0)
                    {
                        triangles[idx].Add(triCounter[idx]);
                        vertices[idx].Add(meshVertices[meshTriangles[i + 1]]);
                        normals[idx].Add(meshNormals[meshTriangles[i + 1]]);
                        uvs[idx].Add(meshUV[meshTriangles[i + 1]]);

                        centroid[idx] += meshVertices[meshTriangles[i + 1]];

                        triCache[meshTriangles[i + 1]] = triCounter[idx] + 1;
                        triCounter[idx]++;
                    }
                    else
                    {
                        triangles[idx].Add(triCache[meshTriangles[i + 1]] - 1);
                    }

                    if (triCache[meshTriangles[i + 2]] == 0)
                    {
                        triangles[idx].Add(triCounter[idx]);
                        vertices[idx].Add(meshVertices[meshTriangles[i + 2]]);
                        normals[idx].Add(meshNormals[meshTriangles[i + 2]]);
                        uvs[idx].Add(meshUV[meshTriangles[i + 2]]);

                        centroid[idx] += meshVertices[meshTriangles[i + 2]];

                        triCache[meshTriangles[i + 2]] = triCounter[idx] + 1;
                        triCounter[idx]++;
                    }
                    else
                    {
                        triangles[idx].Add(triCache[meshTriangles[i + 2]] - 1);
                    }
                }
                else
                {
                    // intersection triangles add to list and process it in second pass
                    cutTris.Add(i);
                }
            }

            if (vertices[0].Count == 0)
            {
                centroid[0] = meshVertices[0];
            }
            else
            {
                centroid[0] /= vertices[0].Count;
            }

            if (vertices[1].Count == 0)
            {
                centroid[1] = meshVertices[1];
            }
            else
            {
                centroid[1] /= vertices[1].Count;
            }

            #if PROFILING
            MeasureIt.End("CutCycleFirstPass");
            MeasureIt.Begin("CutCycleSecondPass");
            #endif
            mesh0 = null;
            mesh1 = null;
            centroid0 = centroid[0];
            centroid1 = centroid[1];
            intersectionData = null;

            if (cutTris.Count < 1)
            {
                stopWatch.Stop();
                return stopWatch.ElapsedMilliseconds;
            }

            AllocateContours(cutTris.Count);

            // second pass - cut intersecting triangles in half
            foreach (var cutTri in cutTris)
            {
                var triangle = new Triangle
                {
                    ids = new[] { meshTriangles[cutTri + 0], meshTriangles[cutTri + 1], meshTriangles[cutTri + 2] },
                    pos = new[] { meshVertices[meshTriangles[cutTri + 0]], meshVertices[meshTriangles[cutTri + 1]], meshVertices[meshTriangles[cutTri + 2]] },
                    normal = new[] { meshNormals[meshTriangles[cutTri + 0]], meshNormals[meshTriangles[cutTri + 1]], meshNormals[meshTriangles[cutTri + 2]] },
                    uvs = new[] { meshUV[meshTriangles[cutTri + 0]], meshUV[meshTriangles[cutTri + 1]], meshUV[meshTriangles[cutTri + 2]] }
                };

                // check points with a plane
                var side0 = plane.GetSide(triangle.pos[0]);
                var side1 = plane.GetSide(triangle.pos[1]);
                var side2 = plane.GetSide(triangle.pos[2]);

                float t0, t1;
                Vector3 s0, s1;

                var idxLeft = side0 ? 0 : 1;
                var idxRight = 1 - idxLeft;

                if (side0 == side1)
                {
                    var a = plane.IntersectSegment(triangle.pos[2], triangle.pos[0], out t0, out s0);
                    var b = plane.IntersectSegment(triangle.pos[2], triangle.pos[1], out t1, out s1);

                    MeshUtils.Assert(a && b, "!!!!!!!!!!!!!!!");

                    // left side ... 2 triangles
                    var s0Left = AddIntersectionPoint(s0, triangle, triangle.ids[2], triangle.ids[0], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var s1Left = AddIntersectionPoint(s1, triangle, triangle.ids[2], triangle.ids[1], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var v0Left = AddTrianglePoint(triangle.pos[0], triangle.normal[0], triangle.uvs[0], triangle.ids[0], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var v1Left = AddTrianglePoint(triangle.pos[1], triangle.normal[1], triangle.uvs[1], triangle.ids[1], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);

                    // Triangle (s0, v0, s1)
                    triangles[idxLeft].Add(s0Left);
                    triangles[idxLeft].Add(v0Left);
                    triangles[idxLeft].Add(s1Left);

                    // Triangle (s1, v0, v1)
                    triangles[idxLeft].Add(s1Left);
                    triangles[idxLeft].Add(v0Left);
                    triangles[idxLeft].Add(v1Left);

                    // right side ... 1 triangle
                    var s0Right = AddIntersectionPoint(s0, triangle, triangle.ids[2], triangle.ids[0], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var s1Right = AddIntersectionPoint(s1, triangle, triangle.ids[2], triangle.ids[1], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var v2Right = AddTrianglePoint(triangle.pos[2], triangle.normal[2], triangle.uvs[2], triangle.ids[2], triCache, cornerVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);

                    // Triangle (v2, s0, s1)
                    triangles[idxRight].Add(v2Right);
                    triangles[idxRight].Add(s0Right);
                    triangles[idxRight].Add(s1Right);

                    // buffer intersection vertices for triangulation
                    if (triangulateHoles)
                    {
                        if (idxLeft == 0)
                        {
                            contour.AddTriangle(cutTri, s0Left, s1Left, s0, s1);
                        }
                        else
                        {
                            contour.AddTriangle(cutTri, s0Right, s1Right, s0, s1);
                        }
                    }
                }
                else if (side0 == side2)
                {
                    var a = plane.IntersectSegment(triangle.pos[1], triangle.pos[0], out t0, out s1);
                    var b = plane.IntersectSegment(triangle.pos[1], triangle.pos[2], out t1, out s0);

                    MeshUtils.Assert(a && b, "!!!!!!!!!!!!!");

                    // left side ... 2 triangles
                    var s0Left = AddIntersectionPoint(s0, triangle, triangle.ids[1], triangle.ids[2], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var s1Left = AddIntersectionPoint(s1, triangle, triangle.ids[1], triangle.ids[0], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var v0Left = AddTrianglePoint(triangle.pos[0], triangle.normal[0], triangle.uvs[0], triangle.ids[0], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var v2Left = AddTrianglePoint(triangle.pos[2], triangle.normal[2], triangle.uvs[2], triangle.ids[2], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);

                    // Triangle (v2, s1, s0)
                    triangles[idxLeft].Add(v2Left);
                    triangles[idxLeft].Add(s1Left);
                    triangles[idxLeft].Add(s0Left);

                    // Triangle (v2, v0, s1)
                    triangles[idxLeft].Add(v2Left);
                    triangles[idxLeft].Add(v0Left);
                    triangles[idxLeft].Add(s1Left);

                    // right side ... 1 triangle
                    var s0Right = AddIntersectionPoint(s0, triangle, triangle.ids[1], triangle.ids[2], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var s1Right = AddIntersectionPoint(s1, triangle, triangle.ids[1], triangle.ids[0], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var v1Right = AddTrianglePoint(triangle.pos[1], triangle.normal[1], triangle.uvs[1], triangle.ids[1], triCache, cornerVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);

                    // Triangle (s0, s1, v1)
                    triangles[idxRight].Add(s0Right);
                    triangles[idxRight].Add(s1Right);
                    triangles[idxRight].Add(v1Right);

                    // buffer intersection vertices for triangulation
                    if (triangulateHoles)
                    {
                        if (idxLeft == 0)
                        {
                            contour.AddTriangle(cutTri, s0Left, s1Left, s0, s1);
                        }
                        else
                        {
                            contour.AddTriangle(cutTri, s0Right, s1Right, s0, s1);
                        }
                    }
                }
                else
                {
                    var a = plane.IntersectSegment(triangle.pos[0], triangle.pos[1], out t0, out s0);
                    var b = plane.IntersectSegment(triangle.pos[0], triangle.pos[2], out t1, out s1);

                    MeshUtils.Assert(a && b, "!!!!!!!!!!!!!");

                    // right side ... 2 triangles
                    var s0Right = AddIntersectionPoint(s0, triangle, triangle.ids[0], triangle.ids[1], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var s1Right = AddIntersectionPoint(s1, triangle, triangle.ids[0], triangle.ids[2], cutVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var v1Right = AddTrianglePoint(triangle.pos[1], triangle.normal[1], triangle.uvs[1], triangle.ids[1], triCache, cornerVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);
                    var v2Right = AddTrianglePoint(triangle.pos[2], triangle.normal[2], triangle.uvs[2], triangle.ids[2], triCache, cornerVertCache[idxRight], vertices[idxRight], normals[idxRight], uvs[idxRight]);

                    // Triangle (v2, s1, v1)
                    triangles[idxRight].Add(v2Right);
                    triangles[idxRight].Add(s1Right);
                    triangles[idxRight].Add(v1Right);

                    // Triangle (s1, s0, v1)
                    triangles[idxRight].Add(s1Right);
                    triangles[idxRight].Add(s0Right);
                    triangles[idxRight].Add(v1Right);

                    // left side ... 1 triangle
                    var s0Left = AddIntersectionPoint(s0, triangle, triangle.ids[0], triangle.ids[1], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var s1Left = AddIntersectionPoint(s1, triangle, triangle.ids[0], triangle.ids[2], cutVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);
                    var v0Left = AddTrianglePoint(triangle.pos[0], triangle.normal[0], triangle.uvs[0], triangle.ids[0], triCache, cornerVertCache[idxLeft], vertices[idxLeft], normals[idxLeft], uvs[idxLeft]);

                    // Triangle (s1, v0, s0)
                    triangles[idxLeft].Add(s1Left);
                    triangles[idxLeft].Add(v0Left);
                    triangles[idxLeft].Add(s0Left);

                    // buffer intersection vertices for triangulation
                    if (triangulateHoles)
                    {
                        if (idxLeft == 0)
                        {
                            contour.AddTriangle(cutTri, s0Left, s1Left, s0, s1);
                        }
                        else
                        {
                            contour.AddTriangle(cutTri, s0Right, s1Right, s0, s1);
                        }
                    }
                }
            }

            #if PROFILING
            MeasureIt.End("CutCycleSecondPass");
            #endif

            if (triangulateHoles || getContourList)
            {
            #if PROFILING
                MeasureIt.Begin("FindContours");
            #endif

                contour.FindContours();

            #if PROFILING
                MeasureIt.End("FindContours");
            #endif
            }

            List<int>[] trianglesCut = null;

            if (triangulateHoles)
            {
            #if PROFILING
                MeasureIt.Begin("Triangulate");
            #endif

                trianglesCut = new List<int>[2] { new List<int>(contour.MidPointsCount), new List<int>(contour.MidPointsCount) };
                Triangulate(contour.contour, plane, vertices, normals, uvs, trianglesCut, true);

            #if PROFILING
                MeasureIt.End("Triangulate");
            #endif
            }

            intersectionData = null;

            if (getContourList)
            {

            #if PROFILING
                MeasureIt.Begin("GetContourList");
            #endif
                List<Vector3[]> contoursList = null;

                GetContourList(contour.contour, vertices[0], out contoursList);

                intersectionData = new ContourData(contoursList, meshTransform);

            #if PROFILING
                MeasureIt.End("GetContourList");
            #endif
            }

            centroid0 = centroid[0];
            centroid1 = centroid[1];

            if (dontCut)
            {
                MeshUtils.Assert(intersectionData != null, "F**k");
                MeshUtils.Assert(getContourList != false, "Fuck2");
                mesh0 = null;
                mesh1 = null;
                return stopWatch.ElapsedMilliseconds;
            }

            if (vertices[0].Count > 0 && vertices[1].Count > 0)
            {
            #if PROFILING
                MeasureIt.Begin("CutEndCopyBack");
            #endif

                mesh0 = new Mesh();
                mesh1 = new Mesh();

                var verticesArray0 = vertices[0].ToArray();
                var verticesArray1 = vertices[1].ToArray();

            #if PROFILING
                MeasureIt.Begin("FixPivot");
            #endif

                if (fixPivot)
                {
                    MeshUtils.CenterPivot(verticesArray0, centroid[0]);
                    MeshUtils.CenterPivot(verticesArray1, centroid[1]);
                }

            #if PROFILING
                MeasureIt.End("FixPivot");
            #endif

                mesh0.vertices = verticesArray0;
                mesh0.normals = normals[0].ToArray();
                mesh0.uv = uvs[0].ToArray();

                mesh1.vertices = verticesArray1;
                mesh1.normals = normals[1].ToArray();
                mesh1.uv = uvs[1].ToArray();

                if (triangulateHoles && trianglesCut[0].Count > 0)
                {
                    mesh0.subMeshCount = 2;
                    mesh0.SetTriangles(triangles[0].ToArray(), 0);
                    mesh0.SetTriangles(trianglesCut[0].ToArray(), 1);

                    mesh1.subMeshCount = 2;
                    mesh1.SetTriangles(triangles[1].ToArray(), 0);
                    mesh1.SetTriangles(trianglesCut[1].ToArray(), 1);
                }
                else
                {
                    mesh0.triangles = triangles[0].ToArray();
                    mesh1.triangles = triangles[1].ToArray();
                }

            #if PROFILING
                MeasureIt.End("CutEndCopyBack");
            #endif

                stopWatch.Stop();
                return stopWatch.ElapsedMilliseconds;
            }

            mesh0 = null;
            mesh1 = null;
            stopWatch.Stop();

            //            UnityEngine.Debug.Log("Empty cut! " + vertices[0].Count + " " + vertices[1].Count);

            return stopWatch.ElapsedMilliseconds;
        }
Example #7
0
 /// <summary>
 /// cut mesh by plane and output list of contour vertices
 /// </summary>
 /// <param name="mesh">mesh to cut</param>
 /// <param name="meshTransform">transformation of the mesh</param>
 /// <param name="plane">cutting plane</param>
 /// <param name="mesh0">first part of the new mesh</param>
 /// <param name="mesh1">second part of the new mesh</param>
 /// <param name="triangulateHoles">flag for triangulation of holes</param>
 /// <param name="intersectionData">list of contours</param>
 /// <returns>processing time</returns>
 public float Cut(Mesh mesh, Transform meshTransform, Utils.Plane plane, bool triangulateHoles, out Mesh mesh0, out Mesh mesh1, out ContourData intersectionData)
 {
     Vector3 c0, c1;
     return Cut(mesh, meshTransform, plane, triangulateHoles, false, true, false, out mesh0, out mesh1, out c0, out c1, out intersectionData);
 }
Example #8
0
        // Token: 0x060042AA RID: 17066 RVA: 0x00153634 File Offset: 0x00151A34
        private float Cut(Mesh mesh, Transform meshTransform, PrimitivesPro.Utils.Plane plane, bool triangulateHoles, bool fixPivot, bool getContourList, bool dontCut, Vector4 crossSection, out Mesh mesh0, out Mesh mesh1, out Vector3 centroid0, out Vector3 centroid1, out ContourData intersectionData)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            int num         = mesh.triangles.Length;
            int verticesNum = mesh.vertices.Length;

            int[]     array  = mesh.triangles;
            Vector3[] array2 = mesh.vertices;
            Vector3[] array3 = mesh.normals;
            Vector2[] uv     = mesh.uv;
            this.crossSectionUV = crossSection;
            this.AllocateBuffers(num, verticesNum);
            plane.InverseTransform(meshTransform);
            for (int i = 0; i < num; i += 3)
            {
                Vector3 vector   = array2[array[i]];
                Vector3 vector2  = array2[array[i + 1]];
                Vector3 vector3  = array2[array[i + 2]];
                bool    sideFix  = plane.GetSideFix(ref vector);
                bool    sideFix2 = plane.GetSideFix(ref vector2);
                bool    sideFix3 = plane.GetSideFix(ref vector3);
                array2[array[i]]     = vector;
                array2[array[i + 1]] = vector2;
                array2[array[i + 2]] = vector3;
                if (sideFix == sideFix2 && sideFix2 == sideFix3)
                {
                    int num2 = (!sideFix) ? 1 : 0;
                    if (this.triCache[array[i]] == 0)
                    {
                        this.triangles[num2].Add(this.triCounter[num2]);
                        this.vertices[num2].Add(array2[array[i]]);
                        this.normals[num2].Add(array3[array[i]]);
                        this.uvs[num2].Add(uv[array[i]]);
                        this.centroid[num2]    += array2[array[i]];
                        this.triCache[array[i]] = this.triCounter[num2] + 1;
                        this.triCounter[num2]++;
                    }
                    else
                    {
                        this.triangles[num2].Add(this.triCache[array[i]] - 1);
                    }
                    if (this.triCache[array[i + 1]] == 0)
                    {
                        this.triangles[num2].Add(this.triCounter[num2]);
                        this.vertices[num2].Add(array2[array[i + 1]]);
                        this.normals[num2].Add(array3[array[i + 1]]);
                        this.uvs[num2].Add(uv[array[i + 1]]);
                        this.centroid[num2]        += array2[array[i + 1]];
                        this.triCache[array[i + 1]] = this.triCounter[num2] + 1;
                        this.triCounter[num2]++;
                    }
                    else
                    {
                        this.triangles[num2].Add(this.triCache[array[i + 1]] - 1);
                    }
                    if (this.triCache[array[i + 2]] == 0)
                    {
                        this.triangles[num2].Add(this.triCounter[num2]);
                        this.vertices[num2].Add(array2[array[i + 2]]);
                        this.normals[num2].Add(array3[array[i + 2]]);
                        this.uvs[num2].Add(uv[array[i + 2]]);
                        this.centroid[num2]        += array2[array[i + 2]];
                        this.triCache[array[i + 2]] = this.triCounter[num2] + 1;
                        this.triCounter[num2]++;
                    }
                    else
                    {
                        this.triangles[num2].Add(this.triCache[array[i + 2]] - 1);
                    }
                }
                else
                {
                    this.cutTris.Add(i);
                }
            }
            if (this.vertices[0].Count == 0)
            {
                this.centroid[0] = array2[0];
            }
            else
            {
                this.centroid[0] /= (float)this.vertices[0].Count;
            }
            if (this.vertices[1].Count == 0)
            {
                this.centroid[1] = array2[1];
            }
            else
            {
                this.centroid[1] /= (float)this.vertices[1].Count;
            }
            mesh0            = null;
            mesh1            = null;
            centroid0        = this.centroid[0];
            centroid1        = this.centroid[1];
            intersectionData = null;
            if (this.cutTris.Count < 1)
            {
                stopwatch.Stop();
                return((float)stopwatch.ElapsedMilliseconds);
            }
            this.AllocateContours(this.cutTris.Count);
            foreach (int num3 in this.cutTris)
            {
                MeshCutter.Triangle tri = new MeshCutter.Triangle
                {
                    ids = new int[]
                    {
                        array[num3],
                        array[num3 + 1],
                        array[num3 + 2]
                    },
                    pos = new Vector3[]
                    {
                        array2[array[num3]],
                        array2[array[num3 + 1]],
                        array2[array[num3 + 2]]
                    },
                    normal = new Vector3[]
                    {
                        array3[array[num3]],
                        array3[array[num3 + 1]],
                        array3[array[num3 + 2]]
                    },
                    uvs = new Vector2[]
                    {
                        uv[array[num3]],
                        uv[array[num3 + 1]],
                        uv[array[num3 + 2]]
                    }
                };
                bool side  = plane.GetSide(tri.pos[0]);
                bool side2 = plane.GetSide(tri.pos[1]);
                bool side3 = plane.GetSide(tri.pos[2]);
                int  num4  = (!side) ? 1 : 0;
                int  num5  = 1 - num4;
                if (side == side2)
                {
                    float   num6;
                    Vector3 vector4;
                    bool    flag = plane.IntersectSegment(tri.pos[2], tri.pos[0], out num6, out vector4);
                    float   num7;
                    Vector3 vector5;
                    bool    flag2 = plane.IntersectSegment(tri.pos[2], tri.pos[1], out num7, out vector5);
                    int     num8  = this.AddIntersectionPoint(vector4, tri, tri.ids[2], tri.ids[0], this.cutVertCache[num4], this.vertices[num4], this.normals[num4], this.uvs[num4]);
                    int     num9  = this.AddIntersectionPoint(vector5, tri, tri.ids[2], tri.ids[1], this.cutVertCache[num4], this.vertices[num4], this.normals[num4], this.uvs[num4]);
                    int     item  = this.AddTrianglePoint(tri.pos[0], tri.normal[0], tri.uvs[0], tri.ids[0], this.triCache, this.cornerVertCache[num4], this.vertices[num4], this.normals[num4], this.uvs[num4]);
                    int     item2 = this.AddTrianglePoint(tri.pos[1], tri.normal[1], tri.uvs[1], tri.ids[1], this.triCache, this.cornerVertCache[num4], this.vertices[num4], this.normals[num4], this.uvs[num4]);
                    this.triangles[num4].Add(num8);
                    this.triangles[num4].Add(item);
                    this.triangles[num4].Add(num9);
                    this.triangles[num4].Add(num9);
                    this.triangles[num4].Add(item);
                    this.triangles[num4].Add(item2);
                    int num10 = this.AddIntersectionPoint(vector4, tri, tri.ids[2], tri.ids[0], this.cutVertCache[num5], this.vertices[num5], this.normals[num5], this.uvs[num5]);
                    int num11 = this.AddIntersectionPoint(vector5, tri, tri.ids[2], tri.ids[1], this.cutVertCache[num5], this.vertices[num5], this.normals[num5], this.uvs[num5]);
                    int item3 = this.AddTrianglePoint(tri.pos[2], tri.normal[2], tri.uvs[2], tri.ids[2], this.triCache, this.cornerVertCache[num5], this.vertices[num5], this.normals[num5], this.uvs[num5]);
                    this.triangles[num5].Add(item3);
                    this.triangles[num5].Add(num10);
                    this.triangles[num5].Add(num11);
                    if (triangulateHoles)
                    {
                        if (num4 == 0)
                        {
                            this.contour.AddTriangle(num3, num8, num9, vector4, vector5);
                        }
                        else
                        {
                            this.contour.AddTriangle(num3, num10, num11, vector4, vector5);
                        }
                    }
                }
                else if (side == side3)
                {
                    float   num6;
                    Vector3 vector5;
                    bool    flag3 = plane.IntersectSegment(tri.pos[1], tri.pos[0], out num6, out vector5);
                    Vector3 vector4;
                    float   num7;
                    bool    flag4 = plane.IntersectSegment(tri.pos[1], tri.pos[2], out num7, out vector4);
                    int     num12 = this.AddIntersectionPoint(vector4, tri, tri.ids[1], tri.ids[2], this.cutVertCache[num4], this.vertices[num4], this.normals[num4], this.uvs[num4]);
                    int     num13 = this.AddIntersectionPoint(vector5, tri, tri.ids[1], tri.ids[0], this.cutVertCache[num4], this.vertices[num4], this.normals[num4], this.uvs[num4]);
                    int     item4 = this.AddTrianglePoint(tri.pos[0], tri.normal[0], tri.uvs[0], tri.ids[0], this.triCache, this.cornerVertCache[num4], this.vertices[num4], this.normals[num4], this.uvs[num4]);
                    int     item5 = this.AddTrianglePoint(tri.pos[2], tri.normal[2], tri.uvs[2], tri.ids[2], this.triCache, this.cornerVertCache[num4], this.vertices[num4], this.normals[num4], this.uvs[num4]);
                    this.triangles[num4].Add(item5);
                    this.triangles[num4].Add(num13);
                    this.triangles[num4].Add(num12);
                    this.triangles[num4].Add(item5);
                    this.triangles[num4].Add(item4);
                    this.triangles[num4].Add(num13);
                    int num14 = this.AddIntersectionPoint(vector4, tri, tri.ids[1], tri.ids[2], this.cutVertCache[num5], this.vertices[num5], this.normals[num5], this.uvs[num5]);
                    int num15 = this.AddIntersectionPoint(vector5, tri, tri.ids[1], tri.ids[0], this.cutVertCache[num5], this.vertices[num5], this.normals[num5], this.uvs[num5]);
                    int item6 = this.AddTrianglePoint(tri.pos[1], tri.normal[1], tri.uvs[1], tri.ids[1], this.triCache, this.cornerVertCache[num5], this.vertices[num5], this.normals[num5], this.uvs[num5]);
                    this.triangles[num5].Add(num14);
                    this.triangles[num5].Add(num15);
                    this.triangles[num5].Add(item6);
                    if (triangulateHoles)
                    {
                        if (num4 == 0)
                        {
                            this.contour.AddTriangle(num3, num12, num13, vector4, vector5);
                        }
                        else
                        {
                            this.contour.AddTriangle(num3, num14, num15, vector4, vector5);
                        }
                    }
                }
                else
                {
                    float   num6;
                    Vector3 vector4;
                    bool    flag5 = plane.IntersectSegment(tri.pos[0], tri.pos[1], out num6, out vector4);
                    float   num7;
                    Vector3 vector5;
                    bool    flag6 = plane.IntersectSegment(tri.pos[0], tri.pos[2], out num7, out vector5);
                    int     num16 = this.AddIntersectionPoint(vector4, tri, tri.ids[0], tri.ids[1], this.cutVertCache[num5], this.vertices[num5], this.normals[num5], this.uvs[num5]);
                    int     num17 = this.AddIntersectionPoint(vector5, tri, tri.ids[0], tri.ids[2], this.cutVertCache[num5], this.vertices[num5], this.normals[num5], this.uvs[num5]);
                    int     item7 = this.AddTrianglePoint(tri.pos[1], tri.normal[1], tri.uvs[1], tri.ids[1], this.triCache, this.cornerVertCache[num5], this.vertices[num5], this.normals[num5], this.uvs[num5]);
                    int     item8 = this.AddTrianglePoint(tri.pos[2], tri.normal[2], tri.uvs[2], tri.ids[2], this.triCache, this.cornerVertCache[num5], this.vertices[num5], this.normals[num5], this.uvs[num5]);
                    this.triangles[num5].Add(item8);
                    this.triangles[num5].Add(num17);
                    this.triangles[num5].Add(item7);
                    this.triangles[num5].Add(num17);
                    this.triangles[num5].Add(num16);
                    this.triangles[num5].Add(item7);
                    int num18 = this.AddIntersectionPoint(vector4, tri, tri.ids[0], tri.ids[1], this.cutVertCache[num4], this.vertices[num4], this.normals[num4], this.uvs[num4]);
                    int num19 = this.AddIntersectionPoint(vector5, tri, tri.ids[0], tri.ids[2], this.cutVertCache[num4], this.vertices[num4], this.normals[num4], this.uvs[num4]);
                    int item9 = this.AddTrianglePoint(tri.pos[0], tri.normal[0], tri.uvs[0], tri.ids[0], this.triCache, this.cornerVertCache[num4], this.vertices[num4], this.normals[num4], this.uvs[num4]);
                    this.triangles[num4].Add(num19);
                    this.triangles[num4].Add(item9);
                    this.triangles[num4].Add(num18);
                    if (triangulateHoles)
                    {
                        if (num4 == 0)
                        {
                            this.contour.AddTriangle(num3, num18, num19, vector4, vector5);
                        }
                        else
                        {
                            this.contour.AddTriangle(num3, num16, num17, vector4, vector5);
                        }
                    }
                }
            }
            if (triangulateHoles || getContourList)
            {
                this.contour.FindContours();
            }
            List <int>[] array4 = null;
            if (triangulateHoles)
            {
                array4 = new List <int>[]
                {
                    new List <int>(this.contour.MidPointsCount),
                    new List <int>(this.contour.MidPointsCount)
                };
                this.Triangulate(this.contour.contour, plane, this.vertices, this.normals, this.uvs, array4, true);
            }
            intersectionData = null;
            if (getContourList)
            {
                List <Vector3[]> contourList = null;
                this.GetContourList(this.contour.contour, this.vertices[0], out contourList);
                intersectionData = new ContourData(contourList, meshTransform);
            }
            centroid0 = this.centroid[0];
            centroid1 = this.centroid[1];
            if (dontCut)
            {
                mesh0 = null;
                mesh1 = null;
                return((float)stopwatch.ElapsedMilliseconds);
            }
            if (this.vertices[0].Count > 0 && this.vertices[1].Count > 0)
            {
                mesh0 = new Mesh();
                mesh1 = new Mesh();
                Vector3[] array5 = this.vertices[0].ToArray();
                Vector3[] array6 = this.vertices[1].ToArray();
                if (fixPivot)
                {
                    MeshUtils.CenterPivot(array5, this.centroid[0]);
                    MeshUtils.CenterPivot(array6, this.centroid[1]);
                }
                mesh0.vertices = array5;
                mesh0.normals  = this.normals[0].ToArray();
                mesh0.uv       = this.uvs[0].ToArray();
                mesh1.vertices = array6;
                mesh1.normals  = this.normals[1].ToArray();
                mesh1.uv       = this.uvs[1].ToArray();
                if (triangulateHoles && array4[0].Count > 0)
                {
                    mesh0.subMeshCount = 2;
                    mesh0.SetTriangles(this.triangles[0].ToArray(), 0);
                    mesh0.SetTriangles(array4[0].ToArray(), 1);
                    mesh1.subMeshCount = 2;
                    mesh1.SetTriangles(this.triangles[1].ToArray(), 0);
                    mesh1.SetTriangles(array4[1].ToArray(), 1);
                }
                else
                {
                    mesh0.triangles = this.triangles[0].ToArray();
                    mesh1.triangles = this.triangles[1].ToArray();
                }
                stopwatch.Stop();
                return((float)stopwatch.ElapsedMilliseconds);
            }
            mesh0 = null;
            mesh1 = null;
            stopwatch.Stop();
            return((float)stopwatch.ElapsedMilliseconds);
        }
Example #9
0
        // Token: 0x060042A7 RID: 17063 RVA: 0x0015336C File Offset: 0x0015176C
        public float Cut(Mesh mesh, Transform meshTransform, PrimitivesPro.Utils.Plane plane, bool triangulateHoles, Vector4 crossSection, out Mesh mesh0, out Mesh mesh1, out ContourData intersectionData)
        {
            Vector3 vector;
            Vector3 vector2;

            return(this.Cut(mesh, meshTransform, plane, triangulateHoles, false, true, false, crossSection, out mesh0, out mesh1, out vector, out vector2, out intersectionData));
        }
Example #10
0
        // Token: 0x060042A3 RID: 17059 RVA: 0x00152FF4 File Offset: 0x001513F4
        public float Cut(GameObject obj, PrimitivesPro.Utils.Plane plane, bool triangulateHoles, bool deleteOriginal, Vector4 crossSection, out GameObject cut0, out GameObject cut1, out ContourData intersectionData)
        {
            MeshFilter component = obj.GetComponent <MeshFilter>();

            if (component == null || component.sharedMesh == null)
            {
                cut0             = null;
                cut1             = null;
                intersectionData = null;
                return(0f);
            }
            Mesh         sharedMesh = obj.GetComponent <MeshFilter>().sharedMesh;
            Material     material   = null;
            MeshRenderer component2 = obj.GetComponent <MeshRenderer>();

            if (component2 != null)
            {
                material = component2.sharedMaterial;
            }
            Mesh mesh  = null;
            Mesh mesh2 = null;

            cut0             = null;
            cut1             = null;
            intersectionData = null;
            bool    flag  = obj.transform.localScale == Vector3.one;
            Vector3 zero  = Vector3.zero;
            Vector3 zero2 = Vector3.zero;
            float   result;

            if (flag)
            {
                result = this.Cut(sharedMesh, obj.transform, plane, triangulateHoles, crossSection, out mesh, out mesh2, out zero, out zero2, out intersectionData);
            }
            else
            {
                result = this.Cut(sharedMesh, obj.transform, plane, triangulateHoles, crossSection, out mesh, out mesh2, out intersectionData);
            }
            if (mesh != null)
            {
                GameObject gameObject = new GameObject(obj.name + "_cut0");
                MeshFilter meshFilter = gameObject.AddComponent <MeshFilter>();
                if (meshFilter != null)
                {
                    meshFilter.sharedMesh = mesh;
                }
                MeshRenderer meshRenderer = gameObject.AddComponent <MeshRenderer>();
                if (meshRenderer != null && material != null)
                {
                    meshRenderer.sharedMaterials = new Material[]
                    {
                        new Material(material),
                        new Material(material)
                    };
                }
                gameObject.transform.position   = obj.transform.position;
                gameObject.transform.rotation   = obj.transform.rotation;
                gameObject.transform.localScale = obj.transform.localScale;
                if (flag)
                {
                    gameObject.transform.Translate(zero);
                }
                cut0 = gameObject;
            }
            if (mesh2 != null)
            {
                GameObject gameObject2 = new GameObject(obj.name + "_cut1");
                MeshFilter meshFilter2 = gameObject2.AddComponent <MeshFilter>();
                if (meshFilter2 != null)
                {
                    meshFilter2.sharedMesh = mesh2;
                }
                MeshRenderer meshRenderer2 = gameObject2.AddComponent <MeshRenderer>();
                if (meshRenderer2 != null && material != null)
                {
                    meshRenderer2.sharedMaterials = new Material[]
                    {
                        new Material(material),
                        new Material(material)
                    };
                }
                gameObject2.transform.position   = obj.transform.position;
                gameObject2.transform.rotation   = obj.transform.rotation;
                gameObject2.transform.localScale = obj.transform.localScale;
                if (flag)
                {
                    gameObject2.transform.Translate(zero2);
                }
                cut1 = gameObject2;
                if (deleteOriginal)
                {
                    UnityEngine.Object.Destroy(obj);
                }
            }
            return(result);
        }
Example #11
0
 /// <summary>
 /// cut mesh by plane
 /// </summary>
 /// <param name="mesh">mesh to cut</param>
 /// <param name="meshTransform">transformation of the mesh</param>
 /// <param name="plane">cutting plane</param>
 /// <param name="mesh0">first part of the new mesh</param>
 /// <param name="mesh1">second part of the new mesh</param>
 /// <param name="triangulateHoles">flag for triangulation of holes</param>
 /// <param name="centroid0">center position of the new mesh0 - apply to transform.position to stay on the same position</param>
 /// <param name="centroid1">center position of the new mesh1 - apply to transform.position to stay on the same position</param>
 /// <param name="intersectionData">contour data</param>
 /// <returns>processing time</returns>
 public float Cut(Mesh mesh, Transform meshTransform, Utils.Plane plane, bool triangulateHoles, Vector4 crossSection, out Mesh mesh0, out Mesh mesh1, out Vector3 centroid0, out Vector3 centroid1, out ContourData intersectionData)
 {
     return Cut(mesh, meshTransform, plane, triangulateHoles, true, true, false, crossSection, out mesh0, out mesh1, out centroid0, out centroid1, out intersectionData);
 }
Example #12
0
        // Token: 0x06004299 RID: 17049 RVA: 0x0015278C File Offset: 0x00150B8C
        public GameObject CreateGameObject(bool doubleSide)
        {
            if (this.contours.Count == 0 || this.contours[0].Length < 3)
            {
                return(null);
            }
            List <Vector3[]> worldContours = this.GetWorldContours();
            List <Polygon>   list          = new List <Polygon>(worldContours.Count);
            Mesh             mesh          = new Mesh();
            List <int>       list2         = new List <int>();
            List <Vector3>   list3         = new List <Vector3>();
            List <Vector3>   list4         = new List <Vector3>();
            List <Vector2>   list5         = new List <Vector2>();
            int num = 0;

            PrimitivesPro.Utils.Plane plane = new PrimitivesPro.Utils.Plane(ContourData.GetNormal(worldContours[0]), worldContours[0][0]);
            Matrix4x4 planeMatrix           = plane.GetPlaneMatrix();
            Matrix4x4 inverse = planeMatrix.inverse;
            float     z       = (inverse * worldContours[0][0]).z;

            foreach (Vector3[] array in worldContours)
            {
                Vector2[] array2 = new Vector2[array.Length];
                for (int i = 0; i < array.Length; i++)
                {
                    array2[i] = inverse * array[i];
                }
                list.Add(new Polygon(array2));
            }
            ContourData.CollapsePolygons(list);
            foreach (Polygon polygon in list)
            {
                List <int> list6 = polygon.Triangulate();
                float      num2  = Mathf.Min(polygon.Min.x, polygon.Min.y);
                float      num3  = Mathf.Max(polygon.Max.x, polygon.Max.y);
                float      num4  = num2 - num3;
                foreach (Vector2 vector in polygon.Points)
                {
                    Vector3 item = planeMatrix * new Vector3(vector.x, vector.y, z);
                    list3.Add(item);
                    list4.Add(plane.Normal);
                    list5.Add(new Vector2((vector.x - num2) / num4, (vector.y - num2) / num4));
                }
                foreach (int num5 in list6)
                {
                    list2.Add(num5 + num);
                }
                num += list6.Count;
            }
            if (doubleSide)
            {
                int count = list3.Count;
                for (int k = 0; k < count; k++)
                {
                    list3.Add(list3[k]);
                    list4.Add(-list4[0]);
                    list5.Add(list5[k]);
                }
                count = list2.Count;
                for (int l = 0; l < count; l++)
                {
                    list2.Add(list2[count - l - 1]);
                }
            }
            mesh.vertices  = list3.ToArray();
            mesh.normals   = list3.ToArray();
            mesh.uv        = list5.ToArray();
            mesh.triangles = list2.ToArray();
            GameObject gameObject = GameObject.Find("ContourObject");

            if (gameObject)
            {
                UnityEngine.Object.Destroy(gameObject);
            }
            GameObject gameObject2 = new GameObject("ContourObject");

            gameObject2.AddComponent <MeshFilter>().sharedMesh       = mesh;
            gameObject2.AddComponent <MeshRenderer>().sharedMaterial = new Material(Shader.Find("Diffuse"));
            return(gameObject2);
        }
Example #13
0
 /// <summary>
 /// cut mesh by plane
 /// </summary>
 /// <param name="mesh">mesh to cut</param>
 /// <param name="meshTransform">transformation of the mesh</param>
 /// <param name="plane">cutting plane</param>
 /// <param name="mesh0">first part of the new mesh</param>
 /// <param name="mesh1">second part of the new mesh</param>
 /// <param name="triangulateHoles">flag for triangulation of holes</param>
 /// <param name="centroid0">center position of the new mesh0 - apply to transform.position to stay on the same position</param>
 /// <param name="centroid1">center position of the new mesh1 - apply to transform.position to stay on the same position</param>
 /// <param name="intersectionData">contour data</param>
 /// <returns>processing time</returns>
 public float Cut(Mesh mesh, Transform meshTransform, Utils.Plane plane, bool triangulateHoles, out Mesh mesh0, out Mesh mesh1, out Vector3 centroid0, out Vector3 centroid1, out ContourData intersectionData)
 {
     return(Cut(mesh, meshTransform, plane, triangulateHoles, true, true, false, out mesh0, out mesh1, out centroid0, out centroid1, out intersectionData));
 }