Ejemplo n.º 1
0
        public PrincipalCurvature ComputePrincipalCurvature(TriMesh.Vertex v)
        {
            Vector3D sum = Vector3D.Zero;
            Vector3D mid = v.Traits.Position;

            foreach (var hf in v.HalfEdges)
            {
                Vector3D buttom = hf.ToVertex.Traits.Position;
                Vector3D left   = hf.Opposite.Next.ToVertex.Traits.Position;
                Vector3D right  = hf.Next.ToVertex.Traits.Position;
                double   cota   = (mid - left).Dot(buttom - left) / (mid - left).Cross(buttom - left).Length();
                double   cotb   = (mid - right).Dot(buttom - right) / (mid - right).Cross(buttom - right).Length();
                sum += (cota + cotb) * (this.Normal[v.Index] - this.Normal[hf.ToVertex.Index]);
            }
            double   mixedArea = TriMeshUtil.ComputeAreaMixed(v);
            Vector3D laplace   = sum / mixedArea / 2d;
            double   square    = -laplace.Dot(this.Normal[v.Index]);
            double   k         = this.K[v.Index].Length();
            double   delta     = -k * k + 2d * square;

            if (delta < 0d)
            {
                delta = 0d;
            }
            PrincipalCurvature pc = new PrincipalCurvature();

            pc.max = (k + Math.Pow(delta, 0.5)) / 2d;
            pc.min = (k - Math.Pow(delta, 0.5)) / 2d;
            return(pc);
        }
Ejemplo n.º 2
0
 public static void SetUpCurvature(TriMesh mesh, PrincipalCurvature[] PrincipalCurv)
 {
     foreach (var v in mesh.Vertices)
     {
         PrincipalCurvature pc = PrincipalCurv[v.Index];
         v.Traits.MaxCurvature          = pc.max;
         v.Traits.MaxCurvatureDirection = pc.maxDir;
         v.Traits.MinCurvature          = pc.min;
         v.Traits.MinCurvatureDirection = pc.minDir;
         v.Traits.MeanCurvature         = (pc.max + pc.min) / 2d;
         v.Traits.GaussianCurvature     = pc.max * pc.min;
     }
 }
Ejemplo n.º 3
0
        public static void SetUpCurvature(TriMesh mesh, PrincipalCurvature[] PrincipalCurv)
        {
 

            foreach (var v in mesh.Vertices)
            {
                PrincipalCurvature pc = PrincipalCurv[v.Index];
                v.Traits.MaxCurvature = pc.max;
                v.Traits.MaxCurvatureDirection = pc.maxDir;
                v.Traits.MinCurvature = pc.min;
                v.Traits.MinCurvatureDirection = pc.minDir;
                v.Traits.MeanCurvature = (pc.max + pc.min) / 2d;
                v.Traits.GaussianCurvature = pc.max * pc.min;
            }
        }
Ejemplo n.º 4
0
        public static PrincipalCurvature[] ComputePricipalCurvature(TriMesh mesh)
        {
            double[] mean  = ComputeMeanCurvature(mesh);
            double[] gauss = ComputeGaussianCurvatureIntegrated(mesh);

            int n = mesh.Vertices.Count;

            PrincipalCurvature[] pricipal = new PrincipalCurvature[n];

            for (int i = 0; i < n; i++)
            {
                pricipal[i] = ComputePricipalCurvature(mean[i], gauss[i]);
            }

            return(pricipal);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// A class containing static methods for computing curvature on a mesh.
        /// </summary>
        public static PrincipalCurvature DiagonalizeCurvature(UV src, KUV srcK, Vector3D dstNormal)
        {
            UV rotated = Transform.RotateCoordinateSystem(src, dstNormal);

            double c = 1.0;
            double s = 0.0;
            double t = 0.0;

            // Jacobi rotation to diagonalize
            if (srcK.UV != 0.0f)
            {
                double h = 0.5f * (srcK.V - srcK.U) / srcK.UV;

                if (h < 0.0f)
                {
                    t = 1.0f / (h - Math.Sqrt(1.0f + h * h));
                }
                else
                {
                    t = 1.0f / (h + Math.Sqrt(1.0f + h * h));
                }

                c = 1.0f / Math.Sqrt(1.0f + t * t);
                s = t * c;
            }

            PrincipalCurvature pc = new PrincipalCurvature();

            pc.max = srcK.U - t * srcK.UV;
            pc.min = srcK.V + t * srcK.UV;

            if (Math.Abs(pc.max) >= Math.Abs(pc.min))
            {
                pc.maxDir = c * rotated.U - s * rotated.V;
            }
            else
            {
                double temp = pc.min;
                pc.min    = pc.max;
                pc.max    = temp;
                pc.maxDir = s * rotated.U + c * rotated.V;
            }

            pc.minDir = dstNormal.Cross(pc.maxDir);

            return(pc);
        }
Ejemplo n.º 6
0
        public static PrincipalCurvature[] ComputeCurvature()
        {
            PrincipalCurvature[] pc = new PrincipalCurvature[nv];
            float[] buff            = new float[nv * 8];
            int     n = GetCurv(buff);

            for (int i = 0; i < nv; i++)
            {
                pc[i] = new PrincipalCurvature
                {
                    max    = buff[i * 8],
                    min    = buff[i * 8 + 1],
                    maxDir = new Vector3D(buff[i * 8 + 2], buff[i * 8 + 3], buff[i * 8 + 4]),
                    minDir = new Vector3D(buff[i * 8 + 5], buff[i * 8 + 6], buff[i * 8 + 7])
                };
            }
            return(pc);
        }
Ejemplo n.º 7
0
        public static PrincipalCurvature ComputePricipalCurvature(double mean, double gauss)
        {
            double rightTemp = mean * mean - gauss;
            double rightPart;

            if (rightTemp <= 0)
            {
                rightPart = 0;
            }
            else
            {
                rightPart = Math.Sqrt(rightTemp);
            }
            PrincipalCurvature pc = new PrincipalCurvature();

            pc.max = mean + rightPart;
            pc.min = mean - rightPart;
            return(pc);
        }
Ejemplo n.º 8
0
        public static PrincipalCurvature[] ComputePricipalCurvature(TriMesh mesh)
        {
            double[] mean = ComputeMeanCurvature(mesh);
            double[] gauss = ComputeGaussianCurvatureIntegrated(mesh);

            int n = mesh.Vertices.Count;

            PrincipalCurvature[] pricipal = new PrincipalCurvature[n];

            for (int i = 0; i < n; i++)
            {  
                pricipal[i] = ComputePricipalCurvature(mean[i], gauss[i]);
            }

            return pricipal;
        }
Ejemplo n.º 9
0
 public static PrincipalCurvature ComputePricipalCurvature(double mean, double gauss)
 {
     double rightTemp = mean * mean - gauss;
     double rightPart;
     if (rightTemp <= 0)
     {
         rightPart = 0;
     }
     else
     {
         rightPart = Math.Sqrt(rightTemp);
     }
     PrincipalCurvature pc = new PrincipalCurvature();
     pc.max = mean + rightPart;
     pc.min = mean - rightPart;
     return pc;
 }
Ejemplo n.º 10
0
 public PrincipalCurvature ComputePrincipalCurvature(TriMesh.Vertex v)
 {
     Vector3D sum = Vector3D.Zero;
     Vector3D mid = v.Traits.Position;
     foreach (var hf in v.HalfEdges)
     {
         Vector3D buttom = hf.ToVertex.Traits.Position;
         Vector3D left = hf.Opposite.Next.ToVertex.Traits.Position;
         Vector3D right = hf.Next.ToVertex.Traits.Position;
         double cota = (mid - left).Dot(buttom - left) / (mid - left).Cross(buttom - left).Length();
         double cotb = (mid - right).Dot(buttom - right) / (mid - right).Cross(buttom - right).Length();
         sum += (cota + cotb) * (this.Normal[v.Index] - this.Normal[hf.ToVertex.Index]);
     }
     double mixedArea = TriMeshUtil.ComputeAreaMixed(v);
     Vector3D laplace = sum / mixedArea / 2d;
     double square = -laplace.Dot(this.Normal[v.Index]);
     double k = this.K[v.Index].Length();
     double delta = -k * k + 2d * square;
     if (delta < 0d)
     {
         delta = 0d;
     }
     PrincipalCurvature pc = new PrincipalCurvature();
     pc.max = (k + Math.Pow(delta, 0.5)) / 2d;
     pc.min = (k - Math.Pow(delta, 0.5)) / 2d;
     return pc;
 }
Ejemplo n.º 11
0
        public static PrincipalCurvature[] ComputeCurvature()
        {
            PrincipalCurvature[] pc = new PrincipalCurvature[nv];
            float[] buff = new float[nv * 8];
            int n = GetCurv(buff);

            for (int i = 0; i < nv; i++)
            {
                pc[i] = new PrincipalCurvature
                {
                    max = buff[i * 8],
                    min = buff[i * 8 + 1],
                    maxDir = new Vector3D(buff[i * 8 + 2], buff[i * 8 + 3], buff[i * 8 + 4]),
                    minDir = new Vector3D(buff[i * 8 + 5], buff[i * 8 + 6], buff[i * 8 + 7])
                };
            }
            return pc;
        }
Ejemplo n.º 12
0
        public static PrincipalCurvature[] ComputePrincipleCurvatures(TriMesh mesh, double[] CornerArea, double[] PointArea)
        {

            Vector3D[] vertexNormal = TriMeshUtil.ComputeNormalVertex(mesh);

            // Add dynamic trait for principle curvature computation
            double[] curv = new double[mesh.Vertices.Count];
            PrincipalCurvature[] pc = new PrincipalCurvature[mesh.Vertices.Count];

            // Initialize a coordinate system for each vertex
            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                pc[v.Index] = new PrincipalCurvature();
                // Vector that points from this vertex to an adjacent one
                pc[v.Index].maxDir = (v.HalfEdge.ToVertex.Traits.Position - v.Traits.Position).Cross(vertexNormal[v.Index]).Normalize();
                // Get a vector orthogonal to this vector and the vertex normal
                pc[v.Index].minDir = vertexNormal[v.Index].Cross(pc[v.Index].maxDir);
            }

            TriMesh.HalfEdge[] fh = new TriMesh.HalfEdge[3];
            TriMesh.Vertex[] fv = new TriMesh.Vertex[3];
            Vector3D[] e = new Vector3D[3];
            Vector3D t, b, dn, faceNormal;

            // Compute curvature for each face
            foreach (TriMesh.Face f in mesh.Faces)
            {
                // Get halfedges for this face
                fh[0] = f.HalfEdge;
                fh[1] = fh[0].Next;
                fh[2] = fh[1].Next;

                // Get vertices for this face
                fv[0] = fh[0].ToVertex;
                fv[1] = fh[1].ToVertex;
                fv[2] = fh[2].ToVertex;

                // Edge vectors
                e[0] = fv[2].Traits.Position - fv[1].Traits.Position;
                e[1] = fv[0].Traits.Position - fv[2].Traits.Position;
                e[2] = fv[1].Traits.Position - fv[0].Traits.Position;

                t = e[0];
                t.Normalize();

                faceNormal = e[0].Cross(e[1]);
                faceNormal.Normalize();

                b = faceNormal.Cross(t);
                b.Normalize();

                // Estimate curvature by variation of normals along edges
                double[] m = new double[3];
                double[,] w = new double[3, 3];

                for (int i = 0; i < 3; ++i)
                {
                    double u = e[i].Dot(t);
                    double v = e[i].Dot(b);

                    w[0, 0] += u * u;
                    w[0, 1] += u * v;
                    w[2, 2] += v * v;

                    dn = vertexNormal[fv[(i + 2) % 3].Index] - vertexNormal[fv[(i + 1) % 3].Index];

                    double dnu = dn.Dot(t);
                    double dnv = dn.Dot(b);

                    m[0] += dnu * u;
                    m[1] += dnu * v + dnv * u;
                    m[2] += dnv * v;
                }

                w[1, 1] = w[0, 0] + w[2, 2];
                w[1, 2] = w[0, 1];

                // Least squares solution
                double[] diag = new double[3];
                if (Transform.LdlTransposeDecomp(w, diag))
                {
                    Transform.LdlTransposeSolveInPlace(w, diag, m);

                    // Adjust curvature for vertices of this face
                    for (int i = 0; i < 3; ++i)
                    {
                        UV tb = new UV { U = t, V = b };
                        KUV mk = new KUV { U = m[0], UV = m[1], V = m[2] };
                        UV dst = new UV { U = pc[fv[i].Index].maxDir, V = pc[fv[i].Index].minDir };
                        KUV c = Transform.ProjectCurvature(tb, mk, dst);

                        double weight =  CornerArea[fh[i].Index] /  PointArea[fv[i].Index];
                        pc[fv[i].Index].max += weight * c.U;
                        curv[fv[i].Index] += weight * c.UV;
                        pc[fv[i].Index].min += weight * c.V;
                    }
                }
            }

            // Compute curvature for each vertex
            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                UV src = new UV { U = pc[v.Index].maxDir, V = pc[v.Index].minDir };
                KUV srcK = new KUV { U = pc[v.Index].max, UV = curv[v.Index], V = pc[v.Index].min };
                pc[v.Index] = Transform.DiagonalizeCurvature(src, srcK, vertexNormal[v.Index]);
            }

            return pc;
        }
Ejemplo n.º 13
0
        /// <summary>
        /// A class containing static methods for computing curvature on a mesh.
        /// </summary>
        public static PrincipalCurvature DiagonalizeCurvature(UV src, KUV srcK, Vector3D dstNormal)
        {
            UV rotated = Transform.RotateCoordinateSystem(src, dstNormal);

            double c = 1.0;
            double s = 0.0;
            double t = 0.0;

            // Jacobi rotation to diagonalize
            if (srcK.UV != 0.0f)
            {
                double h = 0.5f * (srcK.V - srcK.U) / srcK.UV;

                if (h < 0.0f)
                {
                    t = 1.0f / (h - Math.Sqrt(1.0f + h * h));
                }
                else
                {
                    t = 1.0f / (h + Math.Sqrt(1.0f + h * h));
                }

                c = 1.0f / Math.Sqrt(1.0f + t * t);
                s = t * c;
            }

            PrincipalCurvature pc = new PrincipalCurvature();

            pc.max = srcK.U - t * srcK.UV;
            pc.min = srcK.V + t * srcK.UV;

            if (Math.Abs(pc.max) >= Math.Abs(pc.min))
            {
                pc.maxDir = c * rotated.U - s * rotated.V;
            }
            else
            {
                double temp = pc.min;
                pc.min = pc.max;
                pc.max = temp;
                pc.maxDir = s * rotated.U + c * rotated.V;
            }

            pc.minDir = dstNormal.Cross(pc.maxDir);

            return pc;
        }
Ejemplo n.º 14
0
        public static PrincipalCurvature[] ComputePrincipleCurvatures(TriMesh mesh, double[] CornerArea, double[] PointArea)
        {
            Vector3D[] vertexNormal = TriMeshUtil.ComputeNormalVertex(mesh);

            // Add dynamic trait for principle curvature computation
            double[]             curv = new double[mesh.Vertices.Count];
            PrincipalCurvature[] pc   = new PrincipalCurvature[mesh.Vertices.Count];

            // Initialize a coordinate system for each vertex
            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                pc[v.Index] = new PrincipalCurvature();
                // Vector that points from this vertex to an adjacent one
                pc[v.Index].maxDir = (v.HalfEdge.ToVertex.Traits.Position - v.Traits.Position).Cross(vertexNormal[v.Index]).Normalize();
                // Get a vector orthogonal to this vector and the vertex normal
                pc[v.Index].minDir = vertexNormal[v.Index].Cross(pc[v.Index].maxDir);
            }

            TriMesh.HalfEdge[] fh = new TriMesh.HalfEdge[3];
            TriMesh.Vertex[]   fv = new TriMesh.Vertex[3];
            Vector3D[]         e = new Vector3D[3];
            Vector3D           t, b, dn, faceNormal;

            // Compute curvature for each face
            foreach (TriMesh.Face f in mesh.Faces)
            {
                // Get halfedges for this face
                fh[0] = f.HalfEdge;
                fh[1] = fh[0].Next;
                fh[2] = fh[1].Next;

                // Get vertices for this face
                fv[0] = fh[0].ToVertex;
                fv[1] = fh[1].ToVertex;
                fv[2] = fh[2].ToVertex;

                // Edge vectors
                e[0] = fv[2].Traits.Position - fv[1].Traits.Position;
                e[1] = fv[0].Traits.Position - fv[2].Traits.Position;
                e[2] = fv[1].Traits.Position - fv[0].Traits.Position;

                t = e[0];
                t.Normalize();

                faceNormal = e[0].Cross(e[1]);
                faceNormal.Normalize();

                b = faceNormal.Cross(t);
                b.Normalize();

                // Estimate curvature by variation of normals along edges
                double[] m = new double[3];
                double[,] w = new double[3, 3];

                for (int i = 0; i < 3; ++i)
                {
                    double u = e[i].Dot(t);
                    double v = e[i].Dot(b);

                    w[0, 0] += u * u;
                    w[0, 1] += u * v;
                    w[2, 2] += v * v;

                    dn = vertexNormal[fv[(i + 2) % 3].Index] - vertexNormal[fv[(i + 1) % 3].Index];

                    double dnu = dn.Dot(t);
                    double dnv = dn.Dot(b);

                    m[0] += dnu * u;
                    m[1] += dnu * v + dnv * u;
                    m[2] += dnv * v;
                }

                w[1, 1] = w[0, 0] + w[2, 2];
                w[1, 2] = w[0, 1];

                // Least squares solution
                double[] diag = new double[3];
                if (Transform.LdlTransposeDecomp(w, diag))
                {
                    Transform.LdlTransposeSolveInPlace(w, diag, m);

                    // Adjust curvature for vertices of this face
                    for (int i = 0; i < 3; ++i)
                    {
                        UV tb = new UV {
                            U = t, V = b
                        };
                        KUV mk = new KUV {
                            U = m[0], UV = m[1], V = m[2]
                        };
                        UV dst = new UV {
                            U = pc[fv[i].Index].maxDir, V = pc[fv[i].Index].minDir
                        };
                        KUV c = Transform.ProjectCurvature(tb, mk, dst);

                        double weight = CornerArea[fh[i].Index] / PointArea[fv[i].Index];
                        pc[fv[i].Index].max += weight * c.U;
                        curv[fv[i].Index]   += weight * c.UV;
                        pc[fv[i].Index].min += weight * c.V;
                    }
                }
            }

            // Compute curvature for each vertex
            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                UV src = new UV {
                    U = pc[v.Index].maxDir, V = pc[v.Index].minDir
                };
                KUV srcK = new KUV {
                    U = pc[v.Index].max, UV = curv[v.Index], V = pc[v.Index].min
                };
                pc[v.Index] = Transform.DiagonalizeCurvature(src, srcK, vertexNormal[v.Index]);
            }

            return(pc);
        }
Ejemplo n.º 15
0
        public static Vector4D[] ComputeDCruv(TriMesh mesh, double[] CornerArea, double[] PointArea)
        {
            PrincipalCurvature[] PrincipalCurv = ComputePrincipleCurvatures(mesh, CornerArea, PointArea);

            Vector4D[] dcurv = new Vector4D[mesh.Vertices.Count];

            TriMesh.HalfEdge[] fh = new TriMesh.HalfEdge[3];
            TriMesh.Vertex[]   fv = new TriMesh.Vertex[3];
            Vector3D[]         e = new Vector3D[3];
            Vector3D           t, b, faceNormal;

            // Compute curvature for each face
            foreach (TriMesh.Face f in mesh.Faces)
            {
                // Get halfedges for this face
                fh[0] = f.HalfEdge;
                fh[1] = fh[0].Next;
                fh[2] = fh[1].Next;

                // Get vertices for this face
                fv[0] = fh[0].ToVertex;
                fv[1] = fh[1].ToVertex;
                fv[2] = fh[2].ToVertex;

                // Edge vectors
                e[0] = fv[2].Traits.Position - fv[1].Traits.Position;
                e[1] = fv[0].Traits.Position - fv[2].Traits.Position;
                e[2] = fv[1].Traits.Position - fv[0].Traits.Position;

                t = e[0];
                t.Normalize();

                faceNormal = e[0].Cross(e[1]);

                b = faceNormal.Cross(t);
                b.Normalize();

                KUV[] fcurv = new KUV[3];
                for (int i = 0; i < 3; i++)
                {
                    PrincipalCurvature pc = PrincipalCurv[fv[i].Index];
                    UV src = new UV {
                        U = pc.maxDir, V = pc.minDir
                    };
                    KUV mk = new KUV {
                        U = pc.max, UV = 0, V = pc.min
                    };
                    UV tb = new UV {
                        U = t, V = b
                    };
                    fcurv[i] = Transform.ProjectCurvature(src, mk, tb);
                }

                double[] m = new double[4];
                double[,] w = new double[4, 4];
                for (int i = 0; i < 3; i++)
                {
                    KUV prev   = fcurv[(i + 2) % 3];
                    KUV next   = fcurv[(i + 1) % 3];
                    KUV dfcurv = new KUV {
                        U = prev.U - next.U, UV = prev.UV - next.UV, V = prev.V - next.V
                    };
                    double u = e[i].Dot(t);
                    double v = e[i].Dot(b);
                    w[0, 0] += u * u;
                    w[0, 1] += u * v;
                    w[3, 3] += v * v;
                    m[0]    += u * dfcurv.U;
                    m[1]    += v * dfcurv.U + 2d * u * dfcurv.UV;
                    m[2]    += 2d * v * dfcurv.UV + u * dfcurv.V;
                    m[3]    += v * dfcurv.V;
                }
                w[1, 1] = 2d * w[0, 0] + w[3, 3];
                w[1, 2] = 2d * w[0, 1];
                w[2, 2] = w[0, 0] + 2d * w[3, 3];
                w[2, 3] = w[0, 1];

                double[] diag = new double[4];
                if (Transform.LdlTransposeDecomp(w, diag))
                {
                    Transform.LdlTransposeSolveInPlace(w, diag, m);
                    Vector4D d = new Vector4D(m);
                    // Adjust curvature for vertices of this face
                    for (int i = 0; i < 3; ++i)
                    {
                        UV tb = new UV {
                            U = t, V = b
                        };

                        PrincipalCurvature pc = PrincipalCurv[fv[i].Index];
                        UV dst = new UV {
                            U = pc.maxDir, V = pc.minDir
                        };
                        Vector4D c = Transform.ProjectDCurvature(tb, d, dst);

                        double weight = CornerArea[fh[i].Index] / PointArea[fv[i].Index];
                        dcurv[fv[i].Index] += weight * d;
                    }
                }
            }

            return(dcurv);
        }