private bool Initialize() { bool returnFalse = false; _mesheFilters = GetComponentsInChildren <MeshFilter>(); foreach (MeshFilter meshFilter in _mesheFilters) { CurvatureFilter.DuplicateMeshVertices(meshFilter.sharedMesh); } if (_meshInfosMerged == null) { Mesh[] smoothMesh; GetAllSmoothMeshes(out smoothMesh, out _mapFromNew); _meshInfosMerged = new MeshInfo[smoothMesh.Length]; _meshInfosDuplicated = new MeshInfo[smoothMesh.Length]; _curvatureDatas = new CurvatureData[smoothMesh.Length]; for (int i = 0; i < _mesheFilters.Length; i++) { _meshInfosMerged[i] = new MeshInfo(smoothMesh[i]); _curvatureDatas[i] = new CurvatureData(smoothMesh[i].vertexCount); } returnFalse = true; } if (returnFalse) { return(false); } return(true); }
public static void ComputeCurvature(ref MeshInfo meshInfo, out CurvatureData outData) { int n = meshInfo.vertexCount; outData = new CurvatureData(n); int[] cornerTable = BuildCornerTable(meshInfo.mesh); for (int i = 0; i < n; i++) { List <int> neighboors = GetOrderedNeighboors(meshInfo.mesh, i, cornerTable); meshInfo.neighboohood.Add(neighboors); float[] r, phi; Matrix <float> F; MakeExponentialMap(meshInfo.mesh, i, neighboors, out r, out phi); GetUVF(meshInfo.mesh, r, phi, neighboors.ToArray(), i, out F); GetCurvatures(F, i, ref outData, meshInfo.mesh.normals[i]); Vector3[] pds = GetTransformedValues(F, ref outData, i); FixPdsOrder(ref pds, outData.normal); meshInfo.approximatedNormals[i] = outData.normal; meshInfo.principalDirections[i] = pds[0]; for (int j = 0; j < 4; j++) { meshInfo.AllPrincipalDirections[i, j] = pds[j]; } //Debug.Log(String.Format("Vert: {0}, Curv: {1}, {2}", meshInfo.mesh.vertices[i], // meshInfo.AllPrincipalDirections[i, 0], meshInfo.AllPrincipalDirections[i, 1])); } meshInfo.curvatureRatios = ComputeCurvatureRatio(outData.k1, outData.k2); }
private static Vector3[] GetTransformedValues(Matrix <float> F, ref CurvatureData outData, int i) { Vector3 pd1 = ParametricTo3D(vectorToUnity(F.Row(0)), vectorToUnity(F.Row(1)), outData.d1[i][0], outData.d1[i][1]); Vector3 pd2 = ParametricTo3D(vectorToUnity(F.Row(0)), vectorToUnity(F.Row(1)), outData.d2[i][0], outData.d2[i][1]); Vector3 pd3 = ParametricTo3D(vectorToUnity(F.Row(0)), vectorToUnity(F.Row(1)), // inverse pd1 -outData.d1[i][0], -outData.d1[i][1]); Vector3 pd4 = ParametricTo3D(vectorToUnity(F.Row(0)), vectorToUnity(F.Row(1)), // inverse pd2 -outData.d2[i][0], -outData.d2[i][1]); return(new Vector3[] { pd1, pd2, pd3, pd4 }); //Check order //Debug.Log(String.Format("{0}, {1}, {2}, {3}", pd1, pd2, pd3, pd4)); }
static void GetCurvatures(Matrix <float> F, int v, ref CurvatureData outData, Vector3 normal) // F: Fu, Fv, Fuu, Fuv, Fvv //float lambda1, lambda2, k1, k2; { Vector3 Fu = new Vector3(F[0, 0], F[0, 1], F[0, 2]); Vector3 Fv = new Vector3(F[1, 0], F[1, 1], F[1, 2]); Vector3 Nu = Vector3.Cross(Fv, Fu).normalized; Vector <float> N = DenseVector.OfArray(new float[] { Nu.x, Nu.y, Nu.z }); //DEBUG real normmal vs approximated normal //float normalDifference = (normal.normalized - Nu.normalized).magnitude; //if(normalDifference > 0.028) Debug.Log(Nu.ToString() + normal.ToString() + ", " + normalDifference.ToString()); float e = F.Row(0).DotProduct(F.Row(0)); float f = F.Row(1).DotProduct(F.Row(0)); float g = F.Row(1).DotProduct(F.Row(1)); float l = F.Row(2).DotProduct(N); float m = F.Row(3).DotProduct(N); float n = F.Row(4).DotProduct(N); Matrix <float> mat = DenseMatrix.OfArray(new float[2, 2] { { e, f }, { f, g } }) * DenseMatrix.OfArray(new float[2, 2] { { l, m }, { m, n } }); Evd <float> eigen = mat.Evd(); Matrix <float> eigenVectors = eigen.EigenVectors; Vector <Complex> eigenValues = eigen.EigenValues; outData.d1[v] = eigenVectors.Row(0); outData.d2[v] = eigenVectors.Row(1); outData.k1[v] = (float)eigenValues.At(0).Real; outData.k2[v] = (float)eigenValues.At(1).Real; outData.normal = Nu; if (outData.k1[v] < outData.k2[v]) { return; } swap(ref outData.k1[v], ref outData.k2[v]); swap(ref outData.d1[v], ref outData.d2[v]); }