/// <summary> /// Subdivides a mesh by applying a quads-based subdivision algorithm. Optionally, triangles are first merged to quads if possible to produce a better topology. /// For every iteration the face count of the mesh quadruples. The result mesh has quad topology. /// </summary> /// <param name='unityMesh'> /// The mesh to subdivide. /// </param> /// <param name='iterations'> /// The number of iterations the algorithm should perform. High numbers (>3) quickly lead to producing more triangles than /// unity can handle! (>65k). /// </param> /// <param name='trisToQuads'> /// Attempt to convert triangles to quads before the subdivision (highly recommended). /// </param> public static void SubdivideQuadsMesh(Mesh unityMesh, int iterations, bool trisToQuads = true) { KrablMesh.MeshEdges kmesh = new KrablMesh.MeshEdges(); KrablMesh.SubdivideQ sub = new KrablMesh.SubdivideQ(); KrablMesh.SubdivideQParameters subpars = new KrablMesh.SubdivideQParameters(); KrablMesh.ImportExport.UnityMeshToMeshEdges(unityMesh, kmesh); subpars.trisToQuads = trisToQuads; subpars.iterations = iterations; sub.Execute(ref kmesh, subpars); KrablMesh.ImportExport.MeshEdgesToUnityMesh(kmesh, unityMesh); }
/// <summary> /// Perform quad-based mesh subdivision /// </summary> /// <param name='mesh'> /// A mesh (KrablMesh.MeshEdges) to subdivide. The mesh will be replaced by a new mesh structure. /// </param> /// <param name='parameters'> /// The parameters to use during the subdivison. /// </param> public void Execute(ref MeshEdges mesh, SubdivideQParameters parameters) { float progSteps = (float)parameters.iterations; if (parameters.trisToQuads) { progSteps += 1.0f; } if (parameters.recalculateNormals) { progSteps += 1.0f; } float progStep = (progSteps > 0.0f) ? (1.0f / progSteps) : 1.0f; float progress = 0.0f; smooth = parameters.smooth; recalculateNormals = parameters.recalculateNormals; if (parameters.trisToQuads) { if (progressDelegate != null) { progressDelegate("TrisToQuads", progress); progress += progStep; } Ops.TrisToQuads(mesh, parameters.trisToQuadsMaxAngle); } for (int i = 0; i < parameters.iterations; ++i) { if (progressDelegate != null) { progressDelegate("Iteration " + (i + 1), progress); progress += progStep; } Subdivide(ref mesh); } if (recalculateNormals) { if (progressDelegate != null) { progressDelegate("Recalculate Normals", progress); progress += progStep; } mesh.CalculateFaceVertexNormalsFromEdgeCreases(); } }