Пример #1
0
        public double _MeanCurvature(Mesh3D m3d, int index)
        {
            double   meanCurvature   = 0.0;
            double   mixedArea       = 0;
            double   barycentricArea = 0;
            Vector3D normalOperator  = new Vector3D();

            int[]         nbrs = m3d.GetNeighbourVertices(index);
            HashSet <int> fi   = new HashSet <int>();

            for (int i = 0; i < nbrs.Length; i++)
            {
                int fii = m3d.FindFaceFromEdge(index, nbrs[i]);
                fi.Add(fii);
            }
            int m = fi.Count;

            int[] vLeft  = null;
            int[] vRight = null;
            if (m > 1)
            {
                vLeft = m3d.Faces.ElementAt(fi.ElementAt(0));
                //int[] vRight = m3d.Faces.ElementAt(fi.ElementAt((i + 1) % m));
                vRight = m3d.Faces.ElementAt(fi.ElementAt(1));
            }
            else if (m == 1)
            {
                //Console.WriteLine(m+" -- "+fi.ElementAt(i) + " - " + fi.ElementAt((i + 1) % m));
                vLeft  = m3d.Faces.ElementAt(fi.ElementAt(0));
                vRight = m3d.Faces.ElementAt(fi.ElementAt(0));
            }
            else
            {
                return(_infinity);
            }
            // This point is also center point.
            int vertexInCommon1 = -1;

            // This point is the other end of common edge between two triangles.
            int vertexInCommon2 = -1;

            // These two points are not shared between two triangles.
            int vertexUniqueForLeftFace  = -1;
            int vertexUniqueForRightFace = -1;

            // Find common vertexes in two adjacent triangles.
            for (int j = 0; j < 3; j++)
            {
                for (int k = 0; k < 3; k++)
                {
                    // If found vertex is pivotal point, save it as vertexInCommon1.
                    // If found vertex is not pivotal point, then this vertex is
                    // the other end of the common edge of two triangle. Save it as
                    // vertexInCommon2.
                    if (vLeft[j] == vRight[k])
                    {
                        if (vLeft[j] == index)
                        {
                            vertexInCommon1 = vLeft[j];
                            break;
                        }
                        else
                        {
                            vertexInCommon2 = vLeft[j];
                            break;
                        }
                    }
                    else
                    {
                        // If the vertex is not one of common vertexes, save it as
                        // vertexUniqueForLeftFace.
                        if (k == 2)
                        {
                            vertexUniqueForLeftFace = vLeft[j];
                        }
                    }
                }
            }

            // If two triangles share only center point, the index point is located
            // on the edge of the surface. For example, for the ucf file the margin
            // of contours might not lap around, therefore the contour  might have
            // boundary.
            if (vertexInCommon2 == -1)
            {
                return(_infinity);
            }

            // Now task is finding a vertex which is unique to right triangle.
            // Go over each vertex in right face and find a vertex which is
            // not shared with left triangle. then save it as
            // vertexUniqueForLeftFace.
            for (int l = 0; l < 3; l++)
            {
                if (vRight[l] == vertexInCommon1)
                {
                }
                else if (vRight[l] == vertexInCommon2)
                {
                }
                else
                {
                    vertexUniqueForRightFace = vRight[l];
                    break;
                }
            }

            if (vertexUniqueForLeftFace == -1)
            {
                vertexUniqueForLeftFace = vertexInCommon1;
            }

            // Obtain vector represent of vertex locations.
            Point3D pivotalCommonPoint  = m3d.Vertices.ElementAt(vertexInCommon1);
            Point3D theOtherCommonPoint = m3d.Vertices.ElementAt(vertexInCommon2);
            Point3D leftUniquePoint     = m3d.Vertices.ElementAt(vertexUniqueForLeftFace);
            Point3D rightUniquePoint    = m3d.Vertices.ElementAt(vertexUniqueForRightFace);

            Vector3D centerEdgeVector = Vector3D.Subtract(theOtherCommonPoint.ToVector3D(), pivotalCommonPoint.ToVector3D());

            if (!_isAbsoluteMeanCurvature)
            {
                Vector3D v1 = Vector3D.Subtract(leftUniquePoint.ToVector3D(), pivotalCommonPoint.ToVector3D());
                Vector3D v2 = Vector3D.Subtract(rightUniquePoint.ToVector3D(), pivotalCommonPoint.ToVector3D());

                // Normal vector of the first face.
                Vector3D normal1 = Vector3D.CrossProduct(v1, centerEdgeVector);

                // Normal vector of the second face.
                Vector3D normal2 = Vector3D.CrossProduct(centerEdgeVector, v2);

                // Dihedral angle between adjacent triangular faces and is computed
                // as the angle between the corresponding normals.
                double dihedralAngle =
                    Math.Acos(Vector3D.DotProduct(normal1, normal2) /
                              (normal1.Length * normal2.Length));
                // Edge is convex edge if the edge type is greater than 0, and edge
                // is concave edge if the edge type is smaller than 0, and edge is
                // planner if edge type is 0;
                double edgeType =
                    Vector3D.DotProduct(
                        Vector3D.CrossProduct(normal1, normal2), centerEdgeVector);

                double edgeVectorEuclideanNorm = centerEdgeVector.Length;

                if (edgeType < 0)
                {
                    meanCurvature += -1 * edgeVectorEuclideanNorm * dihedralAngle;
                }
                else if (edgeType > 0)
                {
                    meanCurvature += edgeVectorEuclideanNorm * dihedralAngle;
                }
                else
                {
                    meanCurvature += 0;
                }
            }
            // Calculate cot x and cot y where x and y are the angles opposite
            // common edge in two incident triangles.
            try
            {
                double angleAlpha = Vector3D.AngleBetween(pivotalCommonPoint.ToVector3D(), leftUniquePoint.ToVector3D());
                //theOtherCommonPoint.ToVector3D()));

                double angleBetha = Vector3D.AngleBetween(pivotalCommonPoint.ToVector3D(), rightUniquePoint.ToVector3D());
                //,theOtherCommonPoint);

                // angleAlpha, angleTheta, and angleOmega are three angles of left triangles.
                // Test if any of these angles is obtuse.
                double angleTheta = Vector3D.AngleBetween(leftUniquePoint.ToVector3D(),
                                                          pivotalCommonPoint.ToVector3D());
                //,theOtherCommonPoint);
                double angleOmega = Vector3D.AngleBetween(leftUniquePoint.ToVector3D(),
                                                          theOtherCommonPoint.ToVector3D());
                //,pivotalCommonPoint);

                // Obtain Mean Curvature Normal Operator.
                double   cotAlpha = 1 / Math.Tan(angleAlpha);
                double   cotBetha = 1 / Math.Tan(angleBetha);
                double   scalar   = (cotAlpha + cotBetha);
                Vector3D centerEdgeVectorScalarMultiplied = Vector3D.Multiply(centerEdgeVector, scalar);

                normalOperator = Vector3D.Add(normalOperator, centerEdgeVectorScalarMultiplied);

                // Calculate area of the left triangle.
                Vector3D leftEdgeVector      = Vector3D.Subtract(pivotalCommonPoint.ToVector3D(), leftUniquePoint.ToVector3D());
                double   magnitudeOfLeftEdge = leftEdgeVector.Length;

                Vector3D rightEdgeVector      = Vector3D.Subtract(theOtherCommonPoint.ToVector3D(), leftUniquePoint.ToVector3D());
                double   magnitudeOfRightEdge = rightEdgeVector.Length;

                double areaOfLeftTriangle =
                    Math.Sin(angleAlpha) * magnitudeOfLeftEdge * magnitudeOfRightEdge / 2.0;

                if (_areaCalMethod == BARYCENTRIC_AREA)
                {
                    barycentricArea = barycentricArea + areaOfLeftTriangle / 3.0;
                }
                else if (_areaCalMethod == VORONOI_AREA)
                {
                    // Obtuse angle exists at pivot vertex.
                    if (angleTheta > Math.PI / 2)
                    {
                        mixedArea = mixedArea + areaOfLeftTriangle / 2.0;
                    }
                    // Obtuse angle exists at other vertex beside the pivot vertex.
                    else if (angleAlpha > Math.PI / 2 || angleOmega > Math.PI / 2)
                    {
                        mixedArea = mixedArea + areaOfLeftTriangle / 4.0;
                    }
                    // No obtuse angle exists
                    else
                    {
                        double magnitudeOfCenterVector = centerEdgeVector.Length;

                        double voronoiAreaInATriangle = magnitudeOfLeftEdge *
                                                        magnitudeOfLeftEdge * (1 / Math.Tan(angleOmega)) +
                                                        magnitudeOfCenterVector * magnitudeOfCenterVector *
                                                        (1 / Math.Tan(angleAlpha));

                        mixedArea = mixedArea + voronoiAreaInATriangle / 8.0;
                    }
                }
            }
            catch (Exception ige)
            {
                Console.WriteLine(
                    "Unable to calculate curvature of face # " + index +
                    " Reason " + ige.Message);
            }


            if (_areaCalMethod == BARYCENTRIC_AREA)
            {
                normalOperator = Vector3D.Multiply(normalOperator, 1.0 / (2.0 * barycentricArea));
                meanCurvature  = meanCurvature * (1.0 / (4.0 * barycentricArea));
            }
            else if (_areaCalMethod == VORONOI_AREA)
            {
                normalOperator = Vector3D.Multiply(normalOperator, 1.0 / (2.0 * mixedArea));
                meanCurvature  = meanCurvature * (1.0 / (4.0 * mixedArea));
            }

            double curvature = meanCurvature;

            if (_isAbsoluteMeanCurvature)
            {
                // The mean curvature value is half of the magnitude of Normal Operator.
                curvature = normalOperator.Length / 2;
            }

            return(meanCurvature);
        }
Пример #2
0
        internal MeshGeometry3D AutoSnake(MeshGeometry3D mesh, ref MeshBuilder newmbP)
        {
            //Dictionary<Int32, SmileEdge> neighbours = SmileVisual3D.findNeighbours(mesh);

            Point3DCollection positions       = mesh.Positions;
            Int32Collection   triangleIndices = mesh.TriangleIndices;
            Mesh3D            m3d             = new Mesh3D(positions, triangleIndices);

            Vector3DCollection t          = new Vector3DCollection(positions.Count);
            Vector3DCollection b          = new Vector3DCollection(positions.Count);
            Vector3DCollection n          = new Vector3DCollection(positions.Count);
            double             eThreshold = -0.5;
            double             nThreshold = 0.8;
            double             minEnergy  = 10;
            double             alpha      = 1;
            double             betha      = 1;
            double             ballon     = 1;
            double             lambda     = 1;
            Vector3DCollection e          = new Vector3DCollection(positions.Count);
            Vector3DCollection eInt       = new Vector3DCollection(positions.Count);
            Vector3DCollection eExt       = new Vector3DCollection(positions.Count);

            Vector3DCollection delta = new Vector3DCollection(positions.Count);
            Vector3DCollection f     = new Vector3DCollection(positions.Count);
            Vector3DCollection tETF  = new Vector3DCollection(positions.Count);

            //Vector3DCollection k = new Vector3DCollection();
            //DoubleCollection kH = new DoubleCollection();
            Dictionary <int, Double> kH = new Dictionary <int, double>();
            MeshBuilder newmbD          = new MeshBuilder(false, false);

            for (int i = 0; i < triangleIndices.Count; i += 3)
            {
                for (int a = 0; a < 3; a++)
                {
                    int vi = triangleIndices[i + a];

                    if (!kH.ContainsKey(vi))
                    {
                        double kHi = _MeanCurvature(m3d, vi);
                        kH.Add(vi, kHi);
                    }
                    //Console.WriteLine("start mean");
                    //kH.Add(kHi);
                    //Console.WriteLine("end mean");
                    if (a == 2)
                    {
                        int    vi1 = triangleIndices[i + a - 1];
                        int    vi2 = triangleIndices[i + a - 2];
                        double kH3 = 0;
                        kH.TryGetValue(vi, out kH3);
                        double kH2 = 0;
                        kH.TryGetValue(vi1, out kH2);
                        double kH1 = 0;
                        kH.TryGetValue(vi2, out kH1);

                        if ((kH3 < eThreshold || kH2 < eThreshold || kH1 < eThreshold))
                        {
                            newmbD.Positions.Add(positions[vi]);
                            newmbD.Positions.Add(positions[vi1]);
                            newmbD.Positions.Add(positions[vi2]);
                            newmbD.TriangleIndices.Add(i + a);
                            newmbD.TriangleIndices.Add(i + a - 1);
                            newmbD.TriangleIndices.Add(i + a - 2);
                        }
                        if ((kH3 > nThreshold || kH2 > nThreshold || kH1 > nThreshold))
                        {
                            newmbP.Positions.Add(positions[vi]);
                            newmbP.Positions.Add(positions[vi1]);
                            newmbP.Positions.Add(positions[vi2]);
                            newmbP.TriangleIndices.Add(i + a);
                            newmbP.TriangleIndices.Add(i + a - 1);
                            newmbP.TriangleIndices.Add(i + a - 2);
                        }
                    }

                    int[] nbrs            = m3d.GetNeighbourVertices(vi);
                    Vector3DCollection N  = new Vector3DCollection(positions.Count);
                    Point3D            pi = positions[vi];
                    int i0 = triangleIndices[i + a];
                    if (i + a - 1 >= 0)
                    {
                        i0 = triangleIndices[i + a - 1];
                    }
                    Point3D pi0 = positions[i0];
                    int     i1  = vi;
                    if (i + a + i < triangleIndices.Count)
                    {
                        i1 = triangleIndices[i + a + 1];
                    }
                    Point3D pi1 = positions[i1];

                    t.Insert(vi, (pi1 - pi0) / (Point3D.Subtract(pi1, pi0).Length));
                    //t[i] = (pi1 - pi0) / Math.Sqrt((Point3D.Subtract(pi1, pi0).Length));
                    n.Insert(vi, SmileVisual3D.CalculateNormal(pi0, pi, pi1));
                    b.Insert(vi, Vector3D.CrossProduct(t[vi], n[vi]));

                    Vector3D eIntV        = new Vector3D(); //eInt[vi];
                    Vector3D eExtV        = new Vector3D(); //eExt[vi];
                    Vector3D eV           = new Vector3D(); //e[vi];
                    Vector3D sumDeltaNbrs = new Vector3D();
                    Vector3D sumFNbrs     = new Vector3D();
                    int      maxNbrs      = (nbrs.Length > 2 ? 2 : nbrs.Length);
                    for (int j = 0; j < maxNbrs; j++)
                    {
                        Point3D nbj = positions[nbrs[j]];
                        N.Add(nbj.ToVector3D());
                    }
                    double determinantVi = determinant(N);
                    double kv            = 0;
                    kH.TryGetValue(vi, out kv);
                    double  jminEnergy = minEnergy;
                    Point3D tempNbj    = pi;
                    for (int j = 0; j < maxNbrs; j++)
                    {
                        Point3D nbj = positions[nbrs[j]];

                        double ku = 0;
                        kH.TryGetValue(nbrs[j], out ku);
                        sumDeltaNbrs += Vector3D.Multiply((kv - ku), Vector3D.Divide(Point3D.Subtract(nbj, pi), (Point3D.Subtract(nbj, pi).Length)));
                        delta.Insert(vi, (1 / determinantVi) * sumDeltaNbrs);
                        f.Insert(vi, Vector3D.Multiply((1 - lambda), Vector3D.Multiply((1 / determinantVi), new Vector3D())) + Vector3D.Multiply(lambda, delta[vi]));
                        double eIntj   = alpha * (Point3D.Subtract(pi0, nbj).Length) + betha * (Point3D.Subtract(pi0, Point3D.Add(pi1, (Vector3D)nbj)).Length);                    //TODO: crosscheck
                        double eFaej   = ballon * (-(f[vi].Length) - Vector3D.DotProduct((f[vi] / f[vi].Length), (Point3D.Subtract(nbj, pi) / Point3D.Subtract(nbj, pi).Length))); //TODO: crosscheck
                        double ePressj = ballon * Vector3D.DotProduct(b[vi], (Point3D.Subtract(pi0, nbj) / Point3D.Subtract(pi0, nbj).Length));
                        double eExtj   = eFaej + ePressj;
                        double ej      = eIntj + eExtj;

                        if (j == 0)
                        {
                            eIntV.X = eIntj;
                            eExtV.X = eExtj;
                            eV.X    = ej;
                        }
                        if (j == 1)
                        {
                            eIntV.Y = eIntj;
                            eExtV.Y = eExtj;
                            eV.Y    = ej;
                        }
                        if (j == 2)
                        {
                            eIntV.Z = eIntj;
                            eExtV.Z = eExtj;
                            eV.Z    = ej;
                        }

                        if (ej < jminEnergy)
                        {
                            jminEnergy = ej;
                            tempNbj    = nbj;
                            //TODO: snake movement
                            //AddSnakeElement(nbj);
                        }
                    }
                    AddSnakeElement(tempNbj);

                    eInt.Insert(vi, eIntV);
                    eExt.Insert(vi, eExtV);
                    e.Insert(vi, eV);

                    //delta.Insert(vi,  (1 / determinant(N[vi])) * sumDeltaNbrs); //TODO:implemenet
                    //f.Insert(vi, n[vi]);// (1 - lambda) * (1 / (Math.Abs(nbrs.Count))) + lambda *delta[i]; //TODO:implemenet

                    tETF.Insert(vi, Vector3D.CrossProduct(delta[vi], n[vi]));
                }
            }
            return(newmbD.ToMesh());

/*
 *          for (int i = 0; i < positions.Count; i++)
 *          {
 *              Int32Collection nbrs = neighbours[i].neighbours;
 *
 *              Point3D pi = positions[i];
 *              int i0 = i;
 *              if (i - 1 >= 0) i0 = i - 1;
 *              Point3D pi0 = positions[i0];
 *              int i1 = i;
 *              if (i + i < triangleIndices.Count) i = i + 1;
 *              Point3D pi1 = positions[i1];
 *
 *              t[i] = (pi1 - pi0) / (Point3D.Subtract(pi1, pi0).Length);
 *              //t[i] = (pi1 - pi0) / Math.Sqrt((Point3D.Subtract(pi1, pi0).Length));
 *              n[i] = SmileVisual3D.CalculateNormal(pi0, pi, pi1);
 *              b[i] = Vector3D.CrossProduct(t[i], n[i]);
 *
 *
 *              Vector3D eIntV = eInt[i];
 *              Vector3D eExtV = eExt[i];
 *              Vector3D eV = e[i];
 *              int maxNbrs = (nbrs.Count > 2 ? 2 : nbrs.Count);
 *              for (int j = 0; j < maxNbrs; j++)
 *              {
 *                  Point3D nbj = positions[nbrs[j]];
 *                  double eIntj = alpha * (Point3D.Subtract(pi0, nbj).Length) + betha * (Point3D.Subtract(pi0, Point3D.Add(pi1, (Vector3D)nbj)).Length); //TODO: crosscheck
 *
 *
 *                  delta[i] = n[i];// 1 / determinant(N[i]); //TODO:implemenet
 *                  f[i] = n[i];// (1 - lambda) * (1 / (Math.Abs(nbrs.Count))) + lambda *delta[i]; //TODO:implemenet
 *
 *
 *                  double eFaej = ballon * (-(f[i].Length) - Vector3D.DotProduct((f[i] / f[i].Length), (Point3D.Subtract(nbj, pi) / Point3D.Subtract(nbj, pi).Length))); //TODO: crosscheck
 *                  double ePressj = ballon * Vector3D.DotProduct(b[i], (Point3D.Subtract(pi0, nbj) / Point3D.Subtract(pi0, nbj).Length));
 *                  double eExtj = eFaej + ePressj;
 *                  double ej = eIntj + eExtj;
 *
 *                  if (j == 0)
 *                  {
 *                      eIntV.X = eIntj;
 *                      eExtV.X = eExtj;
 *                      eV.X = ej;
 *                  }
 *                  if (j == 1)
 *                  {
 *                      eIntV.Y = eIntj;
 *                      eExtV.Y = eExtj;
 *                      eV.Y = ej;
 *                  }
 *                  if (j == 2)
 *                  {
 *                      eIntV.Z = eIntj;
 *                      eExtV.Z = eExtj;
 *                      eV.Z = ej;
 *                  }
 *
 *                  if (ej < minEnergy)
 *                  {
 *                      minEnergy = ej;
 *                      //TODO: snake movement
 *                      AddSnakeElement(nbj);
 *                  }
 *
 *                  eInt[i] = eIntV;
 *                  eExt[i] = eExtV;
 *                  e[i] = eV;
 *              }
 *
 *              tETF[i] = Vector3D.CrossProduct(delta[i], n[i]);
 *
 *          }
 * */
        }
Пример #3
0
        public double __MeanCurvature(Mesh3D m3d, int verticeIndex)
        {
            return(0);

            /*
             * // Initializing all necessary local variables.
             * double meanCurvature = 0.0;
             * double mixedArea = 0;
             * double barycentricArea = 0;
             * Vector3D normalOperator = new Vector3D();
             * //double[] normalOperator = new double[3];
             *
             * //for(int i=0; i<3; i++){
             * //  normalOperator[i] = 0.0;
             * //}
             *
             * // no neighbors of this face.
             * if(nbrs == null){
             * return _infinity;
             * }
             *
             * // If the index point is connected with only one triangle, the index point
             * // is located on the edge of the surface. For example, for the ucf file the
             * // margin of contours might not lap around, therefore the contour  might have
             * // boundary.
             * if(nbrs.Count== 1){
             * return _infinity;
             * }
             *
             *
             * // Orientation Specification:
             * // Look at surface from outside such a way that the pivotal vertex is
             * // located upward. Then I call a triangle in the left is left triangle
             * // and the other triangle in the right is right triangle.
             * //
             * //  Up       pivotal vertex
             * //                *
             * //             *  *  *
             * //          *     *     *
             * //        *       *        *
             * //      *   *  *  *  *  *  *  *
             * //         Left      Right
             * //  Down
             * //
             * //
             * // 1. Absolute Mean Curvature Computation Algorithm Summary:
             * // Xo - pivot vertex
             * // X1,..,Xj,..,Xn - the first ring neighbor vertices of the vertex o.
             * // n - number of the first ring neighbor vertices of the vertex o.
             * //
             * //                                               Xo
             * //          * * * *                               o
             * //       *   *   *   *                        *   *   *
             * //     *      * *      *                   *      *      *
             * //   * *  *  * O *  * *  * Xj+1     Xj-1  * Aoj   *     Boj* Xj+1
             * //     *      *  *     *                    *     *     *
             * //       *  *     *   *                        *  *  *
             * //         *  *  * *                              *
             * //        Xj-1      Xj                            Xj
             * //
             * //                                  Aoj is angle at the vertex Xj-1
             * //                                  Boj is angle at the vertex Xj+1
             * //
             * //
             * // Mean Curvature Normal Operator is calculated by following 2 steps:
             * // First, calculate summation of (cot Aoj + cot Boj)(Xo - Xj) over j
             * // from 1 to n, where Xo is the pivot vertex and Xj's are elements of
             * // first ring neighbors vertices of the pivot vertex.
             * // Second, divide above value by 2*AreaMixed.
             * //
             * // Area Mixed can be calculated by either Barycentric method or
             * // Voronoi method.
             * // 1. Barycentric method calculate AreaMixed by adding one third of each
             * // triangle area.
             * //
             * // 2. Voronoi method is following
             * // if there is obtuse angle at pivot vertex, add half of the triangle
             * // area.
             * // else if there is obtuse angle beside pivot vertex, add one fourth of
             * // triangle area.
             * // else if there is no obtuse angle, add Voronoi area of triangle.
             * //
             * // Finally the Mean Curvature value is computed by taking half of the
             * // magnitude of the Mean Curvature Normal Operator.
             *
             * // 2. Mean Curvature Computation Algorithm Summary: The mean curvature
             * // (non absolute mean curvature) is computed as a summation over the
             * // edges adjacent to a vertex of the angle between the faces adjacent to
             * // the edge multiplied by the edge length, and divided by four times the
             * // area associated with the vertex.
             *
             *
             *
             * // Go over two neighbor faces which are connected to pivotal point
             * // and which share an edge between.
             * for (int i = 0; i < nbrs.Count; i++) {
             *
             * // Obtain vertices which are consist of faces.
             * Point3D vertiesInLeftFace = points[nbrs[i]];
             * Point3D vertiesInRightFace = points[nbrs[i]];
             *
             * if (i + 1 == nbrs.Count)
             * {
             * vertiesInRightFace = points[nbrs[0]];
             * }
             * else{
             * vertiesInRightFace = points[nbrs[i+1]];
             * }
             *
             * // This point is also center point.
             * int vertexInCommon1 = -1;
             *
             * // This point is the other end of common edge between two triangles.
             * int vertexInCommon2 = -1;
             *
             * // These two points are not shared between two triangles.
             * int vertexUniqueForLeftFace = -1;
             * int vertexUniqueForRightFace = -1;
             *
             * // Find common vertexes in two adjacent triangles.
             * for(int j=0; j<3; j++){
             * for(int k=0; k<3; k++){
             *
             * // If found vertex is pivotal point, save it as vertexInCommon1.
             * // If found vertex is not pivotal point, then this vertex is
             * // the other end of the common edge of two triangle. Save it as
             * // vertexInCommon2.
             * if(vertiesInLeftFace[j] == vertiesInRightFace[k]){
             *  if(vertiesInLeftFace[j] == index){
             *    vertexInCommon1 = vertiesInLeftFace[j];
             *    break;
             *  }
             *  else{
             *    vertexInCommon2 = vertiesInLeftFace[j];
             *    break;
             *  }
             * }
             * else{
             *  // If the vertex is not one of common vertexes, save it as
             *  // vertexUniqueForLeftFace.
             *  if(k==2){
             *    vertexUniqueForLeftFace = vertiesInLeftFace[j];
             *  }
             * }
             * }
             * }
             *
             * // If two triangles share only center point, the index point is located
             * // on the edge of the surface. For example, for the ucf file the margin
             * // of contours might not lap around, therefore the contour  might have
             * // boundary.
             * if(vertexInCommon2 == -1){
             * return _infinity;
             * }
             *
             * // Now task is finding a vertex which is unique to right triangle.
             * // Go over each vertex in right face and find a vertex which is
             * // not shared with left triangle. then save it as
             * // vertexUniqueForLeftFace.
             * for(int l=0; l<3; l++){
             * if(vertiesInRightFace[l] == vertexInCommon1 ){
             * }
             * else if(vertiesInRightFace[l] == vertexInCommon2){
             * }
             * else{
             * vertexUniqueForRightFace = vertiesInRightFace[l];
             * break;
             * }
             * }
             *
             * // Obtain vector represent of vertex locations.
             * double[] pivotalCommonPoint = new  double[_dimension];
             * double[] theOtherCommonPoint = new  double[_dimension];
             * double[] leftUniquePoint = new  double[_dimension];
             * double[] rightUniquePoint = new  double[_dimension];
             *
             * for(int dim=0; dim<_dimension; dim++){
             *
             * pivotalCommonPoint[dim] = _points.getPoint(vertexInCommon1)[dim];
             * theOtherCommonPoint[dim] = _points.getPoint(vertexInCommon2)[dim];
             * leftUniquePoint[dim] = _points.getPoint(vertexUniqueForLeftFace)[dim];
             * rightUniquePoint[dim] = _points.getPoint(vertexUniqueForRightFace)[dim];
             * }
             *
             * double[]  centerEdgeVector =
             *    VectorMathDouble.difference(theOtherCommonPoint, pivotalCommonPoint);
             *
             * if(!_isAbsoluteMeanCurvature){
             *
             * // The mean curvature (non absolute mean curvature) is computed as a
             * // summation over the edges adjacent to a vertex of the angle between
             * // the faces adjacent to the edge multiplied by the edge length, and
             * // divided by four times the area associated with the vertex.
             *
             *  // Reference:
             *  // Anupama Jagannathan, "Segmentation and Recognition of 3D Point Clouds
             *  // within Graph-theoretic and Thermodynamic Frameworks.", the Department
             *  // of Electrical and Computer Engineering, 61-62, 2005.
             *  // http://www.ece.neu.edu/faculty/elmiller/laisir/pdfs/jagannathan_phd.pdf
             *
             *  // Seungbum Koo, Kunwoo Lee, "Wrap-around operation to make
             *  // multi-resolution model of part and assembly.", department of Machanical
             *  // and Aerospace Engineering, Seoul National University, 3, 2002,
             *  // http://www.ece.tufts.edu/~elmiller/laisr/pdfs/jagannathan_phd.pdf.
             *
             *  double[] v1 = VectorMathDouble.difference(leftUniquePoint, pivotalCommonPoint);
             *  double[] v2 = VectorMathDouble.difference(rightUniquePoint, pivotalCommonPoint);
             *
             * // Normal vector of the first face.
             *  double[] normal1 = VectorMathDouble.cross(v1, centerEdgeVector);
             *
             * // Normal vector of the second face.
             *  double[] normal2 = VectorMathDouble.cross(centerEdgeVector, v2);
             *
             * // Dihedral angle between adjacent triangular faces and is computed
             * // as the angle between the corresponding normals.
             *  double dihedralAngle =
             *            Math.acos(VectorMathDouble.dot(normal1, normal2)/
             *                            (VectorMathDouble.magnitude(normal1)*VectorMathDouble.magnitude(normal2)));
             *
             *  // Edge is convex edge if the edge type is greater than 0, and edge
             *  // is concave edge if the edge type is smaller than 0, and edge is
             * // planner if edge type is 0;
             *  double edgeType =
             *            VectorMathDouble.dot(
             *                            VectorMathDouble.cross(normal1, normal2), centerEdgeVector);
             *
             *  double edgeVectorEuclideanNorm =
             *             VectorMathDouble.magnitude(centerEdgeVector);
             *
             *  if(edgeType < 0){
             *    meanCurvature += -1*edgeVectorEuclideanNorm*dihedralAngle;
             *  }
             *  else if(edgeType > 0){
             *    meanCurvature += edgeVectorEuclideanNorm*dihedralAngle;
             *  }
             *  else{
             *    meanCurvature += 0;
             *  }
             * }
             *
             * // Calculate cot x and cot y where x and y are the angles opposite
             * // common edge in two incident triangles.
             * try {
             *
             *    double angleAlpha = VectorMathDouble.vectorAngle(pivotalCommonPoint,
             *        leftUniquePoint,
             *        theOtherCommonPoint);
             *
             *    double angleBetha = VectorMathDouble.vectorAngle(pivotalCommonPoint,
             *        rightUniquePoint,
             *        theOtherCommonPoint);
             *
             *    // angleAlpha, angleTheta, and angleOmega are three angles of left triangles.
             *    // Test if any of these angles is obtuse.
             *    double angleTheta = VectorMathDouble.vectorAngle(leftUniquePoint,
             *        pivotalCommonPoint,
             *        theOtherCommonPoint);
             *    double angleOmega = VectorMathDouble.vectorAngle(leftUniquePoint,
             *        theOtherCommonPoint,
             *        pivotalCommonPoint);
             *
             *    // Obtain Mean Curvature Normal Operator.
             *    double cotAlpha = 1/Math.tan(angleAlpha);
             *    double cotBetha = 1/Math.tan(angleBetha);
             *    double scalar = (cotAlpha + cotBetha);
             *    double[] centerEdgeVectorScalarMultiplied =
             *         VectorMathDouble.multiply(centerEdgeVector, scalar);
             *
             *    normalOperator =
             *            VectorMath.add(normalOperator, centerEdgeVectorScalarMultiplied);
             *
             *    // Calculate area of the left triangle.
             *    double[] leftEdgeVector = VectorMathDouble.difference(pivotalCommonPoint,
             *        leftUniquePoint);
             *    double magnitudeOfLeftEdge = VectorMathDouble.magnitude(leftEdgeVector);
             *
             *    double[] rightEdgeVector = VectorMathDouble.difference(theOtherCommonPoint,
             *        leftUniquePoint);
             *    double magnitudeOfRightEdge = VectorMathDouble.magnitude(rightEdgeVector);
             *
             *    double areaOfLeftTriangle =
             *            Math.sin(angleAlpha)*magnitudeOfLeftEdge*magnitudeOfRightEdge/2.0;
             *
             *    if(_areaCalMethod == BARYCENTRIC_AREA){
             *      barycentricArea = barycentricArea + areaOfLeftTriangle/3.0;
             *    }
             *    else if(_areaCalMethod ==  VORONOI_AREA){
             *      // Obtuse angle exists at pivot vertex.
             *      if(angleTheta > Math.PI/2){
             *        mixedArea = mixedArea + areaOfLeftTriangle/2.0;
             *      }
             *      // Obtuse angle exists at other vertex beside the pivot vertex.
             *      else if(angleAlpha > Math.PI/2 || angleOmega > Math.PI/2){
             *        mixedArea = mixedArea + areaOfLeftTriangle/4.0;
             *      }
             *      // No obtuse angle exists
             *      else{
             *        double magnitudeOfCenterVector = VectorMathDouble.magnitude(centerEdgeVector);
             *
             *        double voronoiAreaInATriangle = magnitudeOfLeftEdge*
             *        magnitudeOfLeftEdge*
             *        (1/Math.tan(angleOmega)) +
             *        magnitudeOfCenterVector*
             *        magnitudeOfCenterVector*
             *        (1/Math.tan(angleAlpha));
             *
             *        mixedArea = mixedArea + voronoiAreaInATriangle/8.0;
             *      }
             *    }
             * }
             * catch (InappropriateGeometryException ige) {
             * throw new CalculationException(
             *   "Unable to calculate curvature of face # " +i +
             *   " Reason " + ige.getMessage());
             * }
             * }
             *
             * if(_areaCalMethod == BARYCENTRIC_AREA){
             * normalOperator = VectorMathDouble.multiply(normalOperator, 1.0/(2.0*barycentricArea));
             * meanCurvature =  meanCurvature*(1.0/(4.0*barycentricArea));
             * }
             * else if(_areaCalMethod == VORONOI_AREA){
             *
             * normalOperator = VectorMathDouble.multiply(normalOperator, 1.0/(2.0*mixedArea));
             * meanCurvature =  meanCurvature*(1.0/(4.0*mixedArea));
             * }
             *
             * double curvature = meanCurvature;
             *
             * if(_isAbsoluteMeanCurvature){
             *
             * // The mean curvature value is half of the magnitude of Normal Operator.
             * curvature =  VectorMath.magnitude(normalOperator) / 2;
             * }
             *
             * return curvature;
             * */
        }