예제 #1
0
        public void AddFace(Vector3[] positions)
        {
            int length = positions.Length;

            HE_Vertex[] vertices = new HE_Vertex[length];
            HE_Edge[]   edges    = new HE_Edge[length];
            HE_Face     face     = new HE_Face();

            for (int i = 0; i < length; ++i)
            {
                vertices[i] = new HE_Vertex();
                edges[i]    = new HE_Edge();
            }

            for (int i = 0; i < length; ++i)
            {
                vertices[i].pos_  = positions[i];
                vertices[i].edge_ = edges[i];

                edges[i].vert_ = vertices[i];
                edges[i].next_ = edges[(i + 1) % length];
                edges[i].prev_ = edges[(i + length - 1) % length];
                edges[i].face_ = face;
            }

            face.edge_ = edges[0];
            faces.Add(face);
        }
예제 #2
0
        public void GetNeighboringVertices(out List <HE_Vertex> outVertices)
        {
            outVertices = new List <HE_Vertex>();
            HE_Edge edge      = edge_;
            bool    bCircular = true;

            do
            {
                outVertices.Add(edge.next_.vert_);
                if (edge.pair_ == null)
                {
                    bCircular = false;
                    break;
                }
                edge = edge.pair_.next_;
            } while (edge != edge_);

            if (bCircular)
            {
                return;
            }

            edge = edge_.prev_;
            do
            {
                outVertices.Add(edge.vert_);
                if (edge.pair_ == null)
                {
                    break;
                }
                edge = edge.pair_.prev_;
            } while (edge != edge_);

            return;
        }
예제 #3
0
        public int GetVertexCount()
        {
            int     count = 0;
            HE_Edge edge  = edge_;

            do
            {
                edge = edge.next_;
                ++count;
            }while (edge != edge_);
            return(count);
        }
예제 #4
0
        public int FillVertices(int offset, Vector3[] outVertices)
        {
            int     idx  = 0;
            HE_Edge edge = edge_;

            do
            {
                outVertices[offset + (idx++)] = edge.vert_.pos_;
                edge = edge.next_;
            } while (edge != edge_);

            return(offset + idx);
        }
예제 #5
0
        public HE_Edge FindEdge(Vector3 v0, Vector3 v1)
        {
            HE_Edge edge = edge_;

            do
            {
                if (v0 == edge.vert_.pos_ && v1 == edge.next_.vert_.pos_)
                {
                    return(edge);
                }
                edge = edge.next_;
            } while (edge != edge_);
            return(null);
        }
예제 #6
0
        void SolvePair(HE_Face face)
        {
            HE_Edge edge = face.edge_;

            do
            {
                foreach (HE_Face f in faces)
                {
                    if (f == face)
                    {
                        continue;
                    }

                    HE_Edge pair = f.FindEdge(edge.next_.vert_.pos_, edge.vert_.pos_);
                    if (pair != null)
                    {
                        edge.pair_ = pair;
                        pair.pair_ = edge;
                        break;
                    }
                }
                edge = edge.next_;
            } while (edge != face.edge_);
        }
예제 #7
0
        public static HalfEdgeMesh Subdivide(HalfEdgeMesh mesh)
        {
            HalfEdgeMesh nextLevelMesh = new HalfEdgeMesh();

            foreach (HE_Face face in mesh.faces)
            {
                Vector3[] next_edge_positions = new Vector3[3];
                Vector3[] next_vert_positions = new Vector3[3];

                {
                    int     count = 0;
                    HE_Edge edge  = face.edge_;
                    do
                    {
                        if (edge.pair_ != null)
                        {
                            next_edge_positions[count] =
                                edge.vert_.pos_ * 0.375f +
                                edge.next_.vert_.pos_ * 0.375f +
                                edge.prev_.vert_.pos_ * 0.125f +
                                edge.pair_.prev_.vert_.pos_ * 0.125f;
                        }
                        else
                        {
                            next_edge_positions[count] =
                                edge.vert_.pos_ * 0.5f +
                                edge.next_.vert_.pos_ * 0.5f;
                        }

                        {
                            List <HE_Vertex> neighbors;
                            edge.vert_.GetNeighboringVertices(out neighbors);
                            int   n    = neighbors.Count;
                            float beta = n > 3 ? 3.0f / (8.0f * n) : 3.0f / 16.0f;
                            next_vert_positions[count] = (1 - n * beta) * edge.vert_.pos_;
                            for (int k = 0; k < n; ++k)
                            {
                                next_vert_positions[count] += neighbors[k].pos_ * beta;
                            }
                        }

                        ++count;
                        edge = edge.next_;
                    } while (!edge.Equals(face.edge_) && count < 3);
                }

                {
                    for (int k = 0; k < 3; ++k)
                    {
                        int prev_k = (k + 2) % 3;

                        Vector3[] next_face =
                        {
                            next_vert_positions[k],
                            next_edge_positions[k],
                            next_edge_positions[prev_k]
                        };

                        nextLevelMesh.AddFace(next_face);
                    }

                    Vector3[] next_face_second = { next_edge_positions[0], next_edge_positions[1], next_edge_positions[2] };
                    nextLevelMesh.AddFace(next_face_second);
                }
            }

            nextLevelMesh.SolveAllPairs();
            return(nextLevelMesh);
        }