コード例 #1
0
 public void Cleanup()
 {
     _parameters      = null;
     progressDelegate = null;
     pdePerVertex     = null;
     heapNodes        = null;
     heap             = null;
     mesh             = null;
 }
コード例 #2
0
        // the mesh needs to have its edge list and creases calculated
        public void InitializeCollapsing(MeshEdges _mesh, SimplifyParameters parameters)
        {
            mesh        = _mesh;
            _parameters = parameters;
            // Gain some time by avoiding unecessary calculations
            if (_mesh.hasBoneWeights == false)
            {
                parameters.boneWeightProtection = 0.0f;
            }
            if (_mesh.hasVertexColors == false)
            {
                parameters.vertexColorProtection = 0.0f;
            }

            _calculatePdePerVertex();
            // construct heap
            int numEdges = mesh.edgeCount();

            heapNodes = new HeapNode <CollapseInfo> [numEdges];
            heap      = new MinHeap <CollapseInfo>();
            int   progressCounter = kProgressGroups;
            float t = Time.realtimeSinceStartup;

            for (int i = 0; i < numEdges; ++i)
            {
                CollapseInfo pc = new CollapseInfo();
                _calculateEdgeCost(i, pc);
                heapNodes[i] = heap.Insert(new HeapNode <CollapseInfo>(pc.cost, pc));
                progressCounter--;
                if (progressCounter <= 0)
                {
                    progressCounter = kProgressGroups;
                    if (Time.realtimeSinceStartup - t > kProgressInterval && progressDelegate != null)
                    {
                        t = Time.realtimeSinceStartup;
                        progressDelegate("Initialize Edge " + i + "/" + numEdges, 0.1f * ((float)i) / ((float)numEdges));
                    }
                }
            }

            // shortcut for fastest calc
            noPenalties = (parameters.checkTopology == false &&
                           parameters.maxEdgesPerVertex == 0 &&
                           parameters.preventNonManifoldEdges == false &&
                           parameters.boneWeightProtection <= 0.0f &&
                           parameters.vertexColorProtection <= 0.0f);
            //sharpnessLimitSqr = parameters.minTriangleShape*parameters.minTriangleShape;
            //if (parameters.minTriangleShape < 0.0f) sharpnessLimitSqr = 0.0f;
        }
コード例 #3
0
    override public void Calculate(ref KrablMesh.MeshEdges mesh, KMProcessorProgram parentProgram = null)
    {
        base.Calculate(ref mesh);

        KrablMesh.Simplify           sim = new KrablMesh.Simplify();
        KrablMesh.SimplifyParameters par = new KrablMesh.SimplifyParameters();

        sim.progressDelegate = delegate(string text, float val) {
            ReportProgress(text, val);
        };

        //	par.maximumError = maximumError;
        par.targetFaceCount = targetTriangleCount;
        if (platformID != null)
        {
            for (int i = 0; i < ttcOverridePlatform.Length; ++i)
            {
                if (platformID.Equals(ttcOverridePlatform[i]))
                {
                    par.targetFaceCount = ttcOverrideTargetTriangleCount[i];
                    break;
                }
            }
        }

        par.recalculateVertexPositions = allowVertexReposition;
        par.preventNonManifoldEdges    = preventNonManifoldEdges;

        par.borderWeight       = borders;
        par.creaseWeight       = creases;
        par.uvSeamWeight       = uvSeams;
        par.uv2SeamWeight      = uv2Seams;
        par.materialSeamWeight = materialSeams;

        // par.minTriangleShape = minTriangleShape;

        par.boneWeightProtection  = boneWeightProtection;
        par.vertexColorProtection = vertexColorProtection;
        //	par.vertexNormalProtection  = vertexNormalProtection;

        sim.Execute(ref mesh, par);
    }
コード例 #4
0
    /// <summary>
    /// Simplify a mesh by collapsing edges until the target face count is reached.
    /// </summary>
    /// <param name='unityMesh'>
    /// The mesh to simplify.
    /// </param>
    /// <param name='targetFaceCount'>
    /// The number of triangles to reduce the mesh to. If this is higher than the initial
    /// number of triangles, no processing will occur.
    /// </param>
    /// <param name='highQuality'>
    /// Use slower, but more precise calculations.
    /// </param>

    public static void SimplifyMesh(Mesh unityMesh, int targetFaceCount, bool highQuality = true)
    {
        KrablMesh.MeshEdges          kmesh   = new KrablMesh.MeshEdges();
        KrablMesh.Simplify           sim     = new KrablMesh.Simplify();
        KrablMesh.SimplifyParameters simpars = new KrablMesh.SimplifyParameters();

        KrablMesh.ImportExport.UnityMeshToMeshEdges(unityMesh, kmesh);
        simpars.targetFaceCount            = targetFaceCount;
        simpars.recalculateVertexPositions = highQuality;
        simpars.checkTopology     = !highQuality;
        simpars.maxEdgesPerVertex = highQuality ? 18 : 0;
        if (highQuality == false)
        {
            simpars.preventNonManifoldEdges = false;
            simpars.boneWeightProtection    = 0.0f;
            simpars.vertexColorProtection   = 0.0f;
        }

        sim.Execute(ref kmesh, simpars);
        KrablMesh.ImportExport.MeshEdgesToUnityMesh(kmesh, unityMesh);
    }
コード例 #5
0
        /// <summary>
        /// Perform mesh simplification.
        /// </summary>
        /// <param name='mesh'>
        /// A mesh (KrablMesh.MeshEdges) to simplify. The mesh will be changed and might even be replaced by a new mesh structure.
        /// </param>
        /// <param name='parameters'>
        /// The parameters to use during the simplification.
        /// </param>
        public void Execute(ref MeshEdges mesh, SimplifyParameters parameters)
        {
            if (mesh.vertCount() == 0)
            {
                return;
            }

            if (mesh.topology != MeshTopology.Triangles)
            {
                Ops.TriangulateWithEdges(mesh);
            }

            if (progressDelegate != null)
            {
                progressDelegate("Initialize", 0.0f);
            }
            InitializeCollapsing(mesh, parameters);
            if (parameters.edgesToCollapse > 0)
            {
                Collapse(parameters.edgesToCollapse);
            }
            else if (parameters.targetFaceCount > 0)
            {
                int   totalFacesToRemove = mesh.numValidFaces - parameters.targetFaceCount;
                int   progressCounter    = 0;
                float t = Time.realtimeSinceStartup + kProgressInterval;
                while (mesh.numValidFaces > parameters.targetFaceCount)
                {
                    Collapse(1);
                    progressCounter--;
                    if (progressCounter <= 0)
                    {
                        progressCounter = kProgressGroups;
                        if (Time.realtimeSinceStartup - t > kProgressInterval && progressDelegate != null)
                        {
                            t = Time.realtimeSinceStartup;
                            int facesRemoved = totalFacesToRemove - (mesh.numValidFaces - parameters.targetFaceCount);
                            progressDelegate("Mesh Faces " + mesh.numValidFaces + "->" + parameters.targetFaceCount, 0.1f + 0.9f * ((float)facesRemoved) / ((float)totalFacesToRemove));
                        }
                    }
                }
            }
            else if (parameters.maximumError > 0)
            {
                // Determine size of mesh to scale errors
                meshSize = _determineMeshSize(mesh);
                int   totalFacesToRemove = mesh.numValidFaces;
                float t             = Time.realtimeSinceStartup + kProgressInterval;
                float costThreshold = meshSize * parameters.maximumError * 0.001f;
                costThreshold *= costThreshold;
                int progressCounter = 0;
                while (true)
                {
                    int num = Collapse(1, costThreshold);
                    if (num == 0)
                    {
                        break;
                    }
                    progressCounter--;
                    if (progressCounter <= 0)
                    {
                        progressCounter = kProgressGroups;
                        if (Time.realtimeSinceStartup - t > kProgressInterval && progressDelegate != null)
                        {
                            t = Time.realtimeSinceStartup;
                            int facesRemoved = totalFacesToRemove - (mesh.numValidFaces - parameters.targetFaceCount);
                            progressDelegate("Mesh Faces " + mesh.numValidFaces + "->" + parameters.targetFaceCount, 0.1f + 0.9f * ((float)facesRemoved) / ((float)totalFacesToRemove));                         // TODO: do this better
                        }
                    }
                }
            }
            //Debugging.CheckMeshIntegrity(mesh);
            mesh.RebuildMesh();

            /*float minShape = Debugging.CalculateMinTriangleShape(mesh);
             * Debug.LogError("MIN TRIANGLE SHAPE" + Mathf.Sqrt(minShape) + " param " + Mathf.Sqrt(sharpnessLimitSqr));
             */
            Cleanup();
        }