Ejemplo n.º 1
0
        // Compute cotan-weighted neighbour sum around a vertex.
        // These weights are numerically unstable if any of the triangles are degenerate.
        // We catch these problems and return input vertex as centroid
        // http://www.geometry.caltech.edu/pubs/DMSB_III.pdf
        public static Vector3d CotanCentroid(DMesh3 mesh, int v_i)
        {
            Vector3d vSum = Vector3d.Zero;
            double   wSum = 0;
            Vector3d Vi   = mesh.GetVertex(v_i);

            int  v_j = DMesh3.InvalidID, opp_v1 = DMesh3.InvalidID, opp_v2 = DMesh3.InvalidID;
            int  t1 = DMesh3.InvalidID, t2 = DMesh3.InvalidID;
            bool bAborted = false;

            foreach (int eid in mesh.VtxEdgesItr(v_i))
            {
                opp_v2 = DMesh3.InvalidID;
                mesh.GetVtxNbrhood(eid, v_i, ref v_j, ref opp_v1, ref opp_v2, ref t1, ref t2);
                Vector3d Vj = mesh.GetVertex(v_j);

                Vector3d Vo1          = mesh.GetVertex(opp_v1);
                double   cot_alpha_ij = MathUtil.VectorCot(
                    (Vi - Vo1).Normalized, (Vj - Vo1).Normalized);
                if (cot_alpha_ij == 0)
                {
                    bAborted = true;
                    break;
                }
                double w_ij = cot_alpha_ij;

                if (opp_v2 != DMesh3.InvalidID)
                {
                    Vector3d Vo2         = mesh.GetVertex(opp_v2);
                    double   cot_beta_ij = MathUtil.VectorCot(
                        (Vi - Vo2).Normalized, (Vj - Vo2).Normalized);
                    if (cot_beta_ij == 0)
                    {
                        bAborted = true;
                        break;
                    }
                    w_ij += cot_beta_ij;
                }

                vSum += w_ij * Vj;
                wSum += w_ij;
            }
            if (bAborted || Math.Abs(wSum) < MathUtil.ZeroTolerance)
            {
                return(Vi);
            }

            return(vSum / wSum);
        }
Ejemplo n.º 2
0
        // http://128.148.32.110/courses/cs224/papers/mean_value.pdf
        public static Vector3d MeanValueCentroid(DMesh3 mesh, int v_i)
        {
            Vector3d vSum = Vector3d.Zero;
            double   wSum = 0;
            Vector3d Vi   = mesh.GetVertex(v_i);

            int v_j = DMesh3.InvalidID, opp_v1 = DMesh3.InvalidID, opp_v2 = DMesh3.InvalidID;
            int t1 = DMesh3.InvalidID, t2 = DMesh3.InvalidID;

            foreach (int eid in mesh.VtxEdgesItr(v_i))
            {
                opp_v2 = DMesh3.InvalidID;
                mesh.GetVtxNbrhood(eid, v_i, ref v_j, ref opp_v1, ref opp_v2, ref t1, ref t2);

                Vector3d Vj      = mesh.GetVertex(v_j);
                Vector3d vVj     = (Vj - Vi);
                double   len_vVj = vVj.Normalize();
                // [RMS] is this the right thing to do? if vertices are coincident,
                //   weight of this vertex should be very high!
                if (len_vVj < MathUtil.ZeroTolerance)
                {
                    continue;
                }

                Vector3d vVdelta = (mesh.GetVertex(opp_v1) - Vi).Normalized;
                double   w_ij    = VectorTanHalfAngle(vVj, vVdelta);

                if (opp_v2 != DMesh3.InvalidID)
                {
                    Vector3d vVgamma = (mesh.GetVertex(opp_v2) - Vi).Normalized;
                    w_ij += VectorTanHalfAngle(vVj, vVgamma);
                }

                w_ij /= len_vVj;

                vSum += w_ij * Vj;
                wSum += w_ij;
            }
            if (wSum < MathUtil.ZeroTolerance)
            {
                return(Vi);
            }

            return(vSum / wSum);
        }