예제 #1
0
        /// <summary>
        /// Split edge in half
        /// </summary>
        /// <param name="m">Polymesh</param>
        /// <param name="eh">Edge Handle</param>
        /// <returns>New Half-edge Handle for the new Edge</returns>
        public static int SplitEdge(PolyMesh m, int eh)
        {
            int heh     = m.GetHalfedgeEdgeH(eh, 0);
            int opp_heh = m.GetHalfedgeEdgeH(eh, 1);

            int new_heh, opp_new_heh, t_heh;
            int vh, vh1 = m.GetEndVertexH(heh);

            Vector3 midP = m.GetPoint(vh1);

            midP += m.GetPoint(m.GetEndVertexH(opp_heh));
            midP *= 0.5f;

            // new vertex
            vh = m.AddVertex(midP);

            // Re-link mesh entities
            if (m.IsBoundaryEdge(eh))
            {
                for (t_heh = heh;
                     m.GetNextHalfedgeH(t_heh) != opp_heh;
                     t_heh = m.GetOppositeHalfedgeH(m.GetNextHalfedgeH(t_heh)))
                {
                }
            }
            else
            {
                for (t_heh = m.GetNextHalfedgeH(opp_heh);
                     m.GetNextHalfedgeH(t_heh) != opp_heh;
                     t_heh = m.GetNextHalfedgeH(t_heh))
                {
                }
            }

            new_heh     = m.NewEdge(vh, vh1);
            opp_new_heh = m.GetOppositeHalfedgeH(new_heh);
            m.SetVertexH(heh, vh);

            m.SetNextHalfedgeH(t_heh, opp_new_heh);
            m.SetNextHalfedgeH(new_heh, m.GetNextHalfedgeH(heh));
            m.SetNextHalfedgeH(heh, new_heh);
            m.SetNextHalfedgeH(opp_new_heh, opp_heh);

            if (m.GetFaceH(opp_heh).isValidHandle())
            {
                m.SetFaceH(opp_new_heh, m.GetFaceH(opp_heh));
                m.SetHalfedgeFaceH(m.GetFaceH(opp_new_heh), opp_new_heh);
            }

            m.SetFaceH(new_heh, m.GetFaceH(heh));
            m.SetHalfedgeVertexH(vh, new_heh);
            m.SetHalfedgeFaceH(m.GetFaceH(heh), heh);
            m.SetHalfedgeVertexH(vh1, opp_new_heh);

            // Never forget this, when playing with the topology
            m.AdjustOutgoingHalfedge(vh);
            m.AdjustOutgoingHalfedge(vh1);

            return(new_heh);
        }
예제 #2
0
        public static Vector3 ComputeMidPoint(PolyMesh m, int heh)
        {
            var     opp_heh = m.GetOppositeHalfedgeH(heh);
            Vector3 pos     = m.GetPoint(m.GetEndVertexH(heh));

            pos += m.GetPoint(m.GetEndVertexH(opp_heh));
            if (m.IsBoundaryHalfedge(heh) || m.IsBoundaryHalfedge(opp_heh))
            {
                return(pos * 0.5f);
            }
            else
            {
                pos *= 3.0f;
                pos += m.GetPoint(m.GetEndVertexH(m.GetNextHalfedgeH(heh)));
                pos += m.GetPoint(m.GetEndVertexH(m.GetNextHalfedgeH(opp_heh)));
                pos *= 0.125f;
            }
            return(pos);
        }
예제 #3
0
        /// TODO: make the smooth generic with the subdivision type
        /// <summary>
        /// Smooth the vertex with loop subdivision
        /// </summary>
        /// <param name="m">Polymesh</param>
        /// <param name="vh">Vertex Handle to smooth</param>
        /// <param name="p">new position for the vertex</param>
        /// <returns>false indicates that the vertex is not in the Polymesh which can be removed</returns>
        public static bool Smooth(PolyMesh m, int vh, out Vector3 p)
        {
            p = Vector3.zero;
            if (m.IsBoundaryVertex(vh))
            {
                int heh = m.GetHalfedgeVertexH(vh), prev_heh;
                if (heh.isValidHandle())
                {
                    //Debug.Assert(m.IsBoundaryEdge(m.GetEdgeH(heh)));

                    prev_heh = m.GetPrevHalfedgeH(heh);

                    int to_vh   = m.GetEndVertexH(heh),
                        from_vh = m.GetStartVertexH(prev_heh);

                    p  = m.GetPoint(vh);
                    p *= 6.0f;
                    p += m.GetPoint(to_vh);
                    p += m.GetPoint(from_vh);
                    p *= 0.125f;
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                var vit     = m.GetVertexVertexIter(vh);
                int valence = 0;
                foreach (var vvh in vit)
                {
                    valence++;
                    p += m.GetPoint(vvh);
                }

                var w = SmoothUtils.loopWeights[valence];
                p *= w.second;
                p += m.GetPoint(vh) * w.first;
            }
            return(true);
        }