예제 #1
0
        public static void GrowByFaceAngle(TriMesh mesh)
        {
            Queue <TriMesh.Face> queue = new Queue <HalfEdgeMesh.Face>();

            Vector3D[] normal = TriMeshUtil.ComputeNormalFace(mesh);
            foreach (var face in mesh.Faces)
            {
                if (face.Traits.SelectedFlag != 0)
                {
                    queue.Enqueue(face);
                }
            }

            double k = 0.449;

            while (queue.Count != 0)
            {
                TriMesh.Face center = queue.Dequeue();
                foreach (var round in center.Faces)
                {
                    if (round.Traits.SelectedFlag == 0)
                    {
                        if (normal[center.Index].Dot(normal[round.Index]) > k)
                        {
                            round.Traits.SelectedFlag = center.Traits.SelectedFlag;
                            queue.Enqueue(round);
                        }
                    }
                }
            }
        }
예제 #2
0
        public void DrawTrivialConnection(TriMesh mesh,
                                          Vector3D[] faceVectors, int N)
        {
            double eps = 1e-3;

            double perAngle = 2 * Math.PI / N;

            for (int i = 0; i < mesh.Faces.Count; i++)
            {
                Vector3D     vector   = Vector3D.Normalize(faceVectors[i]);
                TriMesh.Face face     = mesh.Faces[i];
                Vector3D     center   = TriMeshUtil.GetMidPoint(face);
                Vector3D     normal   = TriMeshUtil.ComputeNormalFace(face);
                double       inradius = TriMeshUtil.ComputeInradius(face);

                Quaternion rotate = Quaternion.RotationAxis(normal, perAngle);
                Quaternion v      = new Quaternion(vector, 0);

                for (int j = 0; j < N; j++)
                {
                    Vector3D a = center + inradius * v.ImagePart;
                    //Vector3D b = center - inradius * v.ImagePart;

                    v = rotate * v * rotate.Conjugate();
                    GL.Begin(BeginMode.Lines);
                    GL.Vertex3(a.x, a.y, a.z);
                    GL.Vertex3(center.x, center.y, center.z);
                    GL.End();
                }
            }
        }
예제 #3
0
        public bool Backward()
        {
            if (this.index == 0)
            {
                return(false);
            }
            else
            {
                index--;
                EdgeContext ctx = this.method.Logs[this.index];
                SplitVertex.Split(this.Mesh, ctx);
                TriMesh.Vertex left  = null;
                TriMesh.Vertex right = null;
                foreach (var v in this.Mesh.Vertices)
                {
                    if (v.Index == ctx.Left)
                    {
                        left = v;
                    }
                    else if (v.Index == ctx.Right)
                    {
                        right = v;
                    }
                }

                TriMesh.HalfEdge hf = left.FindHalfedgeTo(right);
                hf.Face.Traits.Normal          = TriMeshUtil.ComputeNormalFace(hf.Face);
                hf.Opposite.Face.Traits.Normal = TriMeshUtil.ComputeNormalFace(hf.Opposite.Face);
                left.Traits.Normal             = TriMeshUtil.ComputeNormalAreaWeight(left);
                right.Traits.Normal            = TriMeshUtil.ComputeNormalAreaWeight(right);
                return(true);
            }
        }
예제 #4
0
 public static void SetUpNormalFace(TriMesh mesh)
 {
     Vector3D[] normal = TriMeshUtil.ComputeNormalFace(mesh);
     for (int i = 0; i < mesh.Faces.Count; i++)
     {
         mesh.Faces[i].Traits.Normal = normal[i];
     }
 }
예제 #5
0
        Vector3D GetMoveVector(TriMesh.HalfEdge hf)
        {
            Vector3D normal = TriMeshUtil.ComputeNormalFace(hf.Face);
            Vector3D vec    = hf.ToVertex.Traits.Position - hf.FromVertex.Traits.Position;
            Vector3D dir    = normal.Cross(vec).Normalize();

            return(dir * this.move);
        }
예제 #6
0
        void CutInner(TriMesh.HalfEdge cur, TriMesh.HalfEdge next)
        {
            TriMesh.Vertex share1 = cur.FromVertex;
            TriMesh.Vertex share2 = next.ToVertex;
            TriMesh.Vertex mid    = cur.ToVertex;

            Vector3D normal = TriMeshUtil.ComputeNormalFace(cur.Face);
            Vector3D vec    = next.ToVertex.Traits.Position - cur.FromVertex.Traits.Position;
            Vector3D dir    = normal.Cross(vec).Normalize();


            TriMesh.Vertex v2 = TriMeshModify.VertexSplit(mid, share1, share2,
                                                          mid.Traits.Position - dir * move, mid.Traits.Position + dir * move);

            TriMesh.HalfEdge hf = mid.FindHalfedgeTo(v2);
            TriMeshModify.RemoveEdge(hf.Edge);
            this.vertexMap.Add(mid, v2);
        }
예제 #7
0
        public static void BoundaryExpand(TriMesh mesh)
        {
            double length = TriMeshUtil.ComputeEdgeAvgLength(mesh);
            List <List <TriMesh.HalfEdge> > holes = TriMeshUtil.RetrieveBoundaryEdgeAll(mesh);

            foreach (var hole in holes)
            {
                TriMesh.Vertex[] arr = new HalfEdgeMesh.Vertex[hole.Count];
                for (int i = 0; i < hole.Count; i++)
                {
                    Vector3D normal = Vector3D.UnitX;
                    if (hole[i].Opposite.Face != null)
                    {
                        normal = TriMeshUtil.ComputeNormalFace(hole[i].Opposite.Face);
                    }
                    Vector3D toPos   = hole[i].ToVertex.Traits.Position;
                    Vector3D fromPos = hole[i].FromVertex.Traits.Position;
                    Vector3D hfDir   = toPos - fromPos;
                    Vector3D hfMid   = (toPos + fromPos) / 2;
                    Vector3D pos     = hfMid + normal.Cross(hfDir).Normalize() * length;
                    arr[i] = mesh.Vertices.Add(new VertexTraits(pos));
                }
                for (int i = 0; i < hole.Count; i++)
                {
                    int          next = (i + 1) % hole.Count;
                    TriMesh.Face face = mesh.Faces.Add(arr[i],
                                                       hole[i].ToVertex,
                                                       hole[next].ToVertex);
                    face.Traits.SelectedFlag = 1;
                    face = mesh.Faces.Add(arr[i],
                                          hole[next].ToVertex,
                                          arr[next]);
                    face.Traits.SelectedFlag = 1;
                }
            }
        }
예제 #8
0
        public static void RegionGrow(TriMesh mesh)
        {
            Vector3D[] normal = TriMeshUtil.ComputeNormalFace(mesh);
            double[]   area   = TriMeshUtil.ComputeAreaFace(mesh);
            SortedList <double, TriMesh.Face> sort = new SortedList <double, HalfEdgeMesh.Face>();

            foreach (var center in mesh.Faces)
            {
                List <double> list = new List <double>();
                double        sum  = 0;
                foreach (var round in center.Faces)
                {
                    double l = (normal[round.Index] - normal[center.Index]).Length();// * area[round.Index]);
                    sum += l;
                    list.Add(l);
                }
                sum /= list.Count;
                double d = 0;
                foreach (var item in list)
                {
                    d += Math.Pow(item - sum, 2);
                }
                d /= list.Count;
                if (sum < 1 && d < 0.1)
                {
                    sort.Add(sum, center);
                }
            }

            Stack <TriMesh.Face>      stack = new Stack <HalfEdgeMesh.Face>();
            Dictionary <int, Cluster> dict  = new Dictionary <int, Cluster>();
            double k    = 1;
            int    flag = 0;

            do
            {
                if (stack.Count == 0)
                {
                    bool run = false;
                    if (flag > 100)
                    {
                        return;
                    }
                    for (int i = flag; i < sort.Count; i++)
                    {
                        TriMesh.Face next = sort.Values[i];
                        if (next.Traits.SelectedFlag == 0)
                        {
                            flag++;
                            next.Traits.SelectedFlag = (byte)flag;
                            stack.Push(next);
                            dict[flag] = new Cluster();
                            dict[flag].Add(normal[sort.Values[i].Index]);
                            run = true;
                            break;
                        }
                    }
                    if (!run)
                    {
                        return;
                    }
                }
                TriMesh.Face center = stack.Pop();

                foreach (var round in center.Faces)
                {
                    if (round.Traits.SelectedFlag == 0 &&
                        (normal[round.Index] - normal[center.Index]).Length() < k &&
                        (normal[round.Index] - dict[flag].Center).Length() < k)
                    {
                        dict[flag].Add(normal[round.Index]);
                        round.Traits.SelectedFlag = (byte)flag;
                        stack.Push(round);
                    }
                }
            } while (true);
        }