示例#1
0
        public Vector3D ComputeFaceNormals(TriMesh.Face f)
        {
            Vector3D p0 = f.GetVertex(0).Traits.Position;
            Vector3D p1 = f.GetVertex(1).Traits.Position;
            Vector3D p2 = f.GetVertex(2).Traits.Position;

            return((p1 - p0).Cross(p2 - p0).Normalize());
        }
示例#2
0
        public Vector3D[] ComputeVectorField(double initAngle)
        {
            Vector3D[] vectorFields = new Vector3D[mesh.Faces.Count];
            bool[]     visitedFlags = new bool[mesh.Faces.Count];
            for (int i = 0; i < visitedFlags.Length; i++)
            {
                visitedFlags[i] = false;
            }

            //Find a initial root to expend
            TriMesh.Face rootFace = mesh.Faces[0];
            var          v1       = rootFace.GetVertex(0);
            var          v3       = rootFace.GetVertex(2);
            var          v2       = rootFace.GetVertex(1);

            Vector3D w0 = (rootFace.GetVertex(2).Traits.Position - rootFace.GetVertex(0).Traits.Position).Normalize();

            //Init transpot
            Vector3D av = v1.Traits.Position;
            Vector3D bv = v2.Traits.Position;
            Vector3D cv = v3.Traits.Position;
            Matrix3D Ei = Orthogonalize(bv - av, cv - av);

            Vector3D w0i = (Ei * Matrix3D.Rotate(initAngle) * Ei.Inverse() * w0);

            vectorFields[rootFace.Index] = w0i;
            visitedFlags[rootFace.Index] = true;

            //Recurse all faces
            Queue <TriMesh.Face> queue = new Queue <HalfEdgeMesh.Face>();

            queue.Enqueue(rootFace);

            int ii = 0;

            while (queue.Count > 0)
            {
                TriMesh.Face currentFace = queue.Dequeue();
                Vector3D     wI          = vectorFields[currentFace.Index];

                foreach (TriMesh.Face neighbor in currentFace.Faces)
                {
                    if (visitedFlags[neighbor.Index] == false)
                    {
                        Vector3D wj = Transport2(wI, currentFace, neighbor);
                        vectorFields[neighbor.Index] = wj;
                        queue.Enqueue(neighbor);
                        visitedFlags[neighbor.Index] = true;
                    }
                }

                ii++;
            }

            return(vectorFields);
        }
示例#3
0
        //face area


        public static double ComputeAreaFaceTwo(TriMesh.Face face)
        {
            Vector3D v1 = new Vector3D(face.GetVertex(0).Traits.Position.x,
                                       face.GetVertex(0).Traits.Position.y,
                                       face.GetVertex(0).Traits.Position.z);
            Vector3D v2 = new Vector3D(face.GetVertex(1).Traits.Position.x,
                                       face.GetVertex(1).Traits.Position.y,
                                       face.GetVertex(1).Traits.Position.z);
            Vector3D v3 = new Vector3D(face.GetVertex(2).Traits.Position.x,
                                       face.GetVertex(2).Traits.Position.y,
                                       face.GetVertex(2).Traits.Position.z);

            double a = Math.Sqrt((v1.x - v2.x) * (v1.x - v2.x)
                                 + (v1.y - v2.y) * (v1.y - v2.y)
                                 + (v1.z - v2.z) * (v1.z - v2.z));
            double b = Math.Sqrt((v3.x - v2.x) * (v3.x - v2.x)
                                 + (v3.y - v2.y) * (v3.y - v2.y)
                                 + (v3.z - v2.z) * (v3.z - v2.z));
            double c = Math.Sqrt((v1.x - v3.x) * (v1.x - v3.x)
                                 + (v1.y - v3.y) * (v1.y - v3.y)
                                 + (v1.z - v3.z) * (v1.z - v3.z));
            double p    = (a + b + c) / 2;
            double area = Math.Sqrt(p * (p - a) * (p - b) * (p - c));

            return(area);
        }
示例#4
0
        public static double ComputeInradius(TriMesh.Face face)
        {
            Vector3D a = face.GetVertex(0).Traits.Position;
            Vector3D b = face.GetVertex(1).Traits.Position;
            Vector3D c = face.GetVertex(2).Traits.Position;

            double u = (a - b).Length();
            double v = (b - c).Length();
            double w = (c - a).Length();

            return(0.5 * Math.Sqrt(((u + v - w) * (w + u - v) * (v + w - u)) / (u + v + w)));
        }
示例#5
0
        public static List <double> ComputeAngle(TriMesh.Face face)
        {
            List <double> angles = new List <double>();

            double angle1 = ComputeAngle(face.GetVertex(0).HalfEdge);
            double angle2 = ComputeAngle(face.GetVertex(1).HalfEdge);
            double angle3 = ComputeAngle(face.GetVertex(2).HalfEdge);

            angles.Add(angle1);
            angles.Add(angle2);
            angles.Add(angle3);

            return(angles);
        }
示例#6
0
        //public void ComputeFrameAngles(double initialAngle)
        //{
        //    TreeNode<TriMesh.Face> Root = transportTree.Root;

        //    Queue<TreeNode<HalfEdgeMesh.Face>> queue = new Queue<TreeNode<HalfEdgeMesh.Face>>();
        //    queue.Enqueue(transportTree.Root);

        //    bool[] processedFlag = new bool[Mesh.Faces.Count];

        //    while (queue.Count != 0)
        //    {
        //        TreeNode<HalfEdgeMesh.Face> currentFaceNode = queue.Dequeue();

        //        TriMesh.HalfEdge startHf = currentFaceNode.Attribute.HalfEdge;
        //        TriMesh.HalfEdge currentHf = startHf;
        //        do
        //        {
        //            TriMesh.Face neighborFace = currentHf.Opposite.Face;

        //            TransportData td = transDatas[currentHf.Index];

        //            td.alphaJ = td.alphaI + td.delta - td.sign * td.omega;

        //            currentHf = currentHf.Next;
        //        } while (currentHf != startHf);


        //    }


        //}


        //public void UpdateAngles(int initAngle)
        //{
        //    TriMesh.Face faceTransport = Mesh.Faces[3];
        //    FaceAngle[faceTransport.Index] = initAngle;
        //    Queue<TriMesh.Face> queue = new Queue<TriMesh.Face>();
        //    queue.Enqueue(faceTransport);

        //    bool[] processedFlag = new bool[Mesh.Faces.Count];

        //    while (queue.Count != 0)
        //    {
        //        TriMesh.Face currentFace = queue.Dequeue();

        //        TriMesh.HalfEdge startHf = currentFace.HalfEdge;
        //        TriMesh.HalfEdge currentHf = startHf;
        //        double currentDelta = Deltas[currentFace.Index];

        //        do
        //        {
        //            TriMesh.Face neighborFace = currentHf.Opposite.Face;


        //            if (processedFlag[neighborFace.Index] == false &&
        //                neighborFace != faceTransport &&
        //                !neighborFace.OnBoundary
        //                )
        //            {
        //                processedFlag[neighborFace.Index] = true;
        //                queue.Enqueue(neighborFace);

        //                double delta = ComputeParallTransport(currentDelta, currentHf);
        //                Deltas[neighborFace.Index] = delta;

        //                double omega = EdgeTheta[currentHf.Edge.Index];
        //                double sign = currentHf.FromVertex.Index > currentHf.ToVertex.Index ? -1 : 1;
        //                FaceAngle[neighborFace.Index] = FaceAngle[currentFace.Index] + delta - sign * omega;

        //            }
        //            currentHf = currentHf.Next;
        //        } while (currentHf != startHf);


        //    }
        //}


        //public void AppendDirectionalConstraints(TriMesh mesh, List<List<TriMesh.HalfEdge>> cycles)
        //{
        //    transDatas = new TransportData[mesh.HalfEdges.Count];
        //    TriMesh.Face faceTransport = mesh.Faces[3];
        //    transportTree = new DynamicTree<HalfEdgeMesh.Face>();
        //    transportTree.Root = new TreeNode<HalfEdgeMesh.Face>(faceTransport);

        //    Queue<TreeNode<HalfEdgeMesh.Face>> queue = new Queue<TreeNode<HalfEdgeMesh.Face>>();
        //    queue.Enqueue(transportTree.Root);

        //    bool[] processedFlag = new bool[mesh.Faces.Count];

        //    while (queue.Count != 0)
        //    {
        //        TreeNode<HalfEdgeMesh.Face> currentFaceNode = queue.Dequeue();

        //        TriMesh.HalfEdge startHf = currentFaceNode.Attribute.HalfEdge;
        //        TriMesh.HalfEdge currentHf = startHf;
        //        do
        //        {
        //            TriMesh.Face neighborFace = currentHf.Opposite.Face;

        //            if (processedFlag[neighborFace.Index] == false &&
        //                neighborFace != faceTransport &&
        //                !neighborFace.OnBoundary
        //                )
        //            {
        //                TreeNode<HalfEdgeMesh.Face> neighNode = new TreeNode<HalfEdgeMesh.Face>(neighborFace);
        //                processedFlag[neighborFace.Index] = true;
        //                currentFaceNode.AddChild(neighNode);
        //                queue.Enqueue(neighNode);


        //                TransportData td = new TransportData();
        //                td.delta = ComputeParallTransport(0, currentHf);
        //                td.sign = currentHf.FromVertex.Index > currentHf.ToVertex.Index ? 1 : -1;
        //                td.omega = EdgeTheta[currentHf.Edge.Index];
        //                td.alphaI = FaceAngle[currentHf.Face.Index];
        //                td.alphaJ = FaceAngle[currentHf.Opposite.Face.Index];
        //                transDatas[currentHf.Index] = td;
        //                Deltas[currentHf.Face.Index] = td.delta;

        //            }
        //            currentHf = currentHf.Next;
        //        } while (currentHf != startHf);


        //    }


        //}

        public Vector3D[] ComputeVectorField(double initAngle)
        {
            Vector3D[] vectorFields = new Vector3D[Mesh.Faces.Count];
            bool[]     visitedFlags = new bool[Mesh.Faces.Count];
            for (int i = 0; i < visitedFlags.Length; i++)
            {
                visitedFlags[i] = false;
            }

            //Find a initial root to expend
            TriMesh.Face rootFace = Mesh.Faces[0];
            var          v1       = rootFace.GetVertex(0);
            var          v3       = rootFace.GetVertex(2);
            var          v2       = rootFace.GetVertex(1);

            Vector3D w0 = (rootFace.GetVertex(2).Traits.Position - rootFace.GetVertex(0).Traits.Position).Normalize();

            //Init transpot
            Vector3D av = v1.Traits.Position;
            Vector3D bv = v2.Traits.Position;
            Vector3D cv = v3.Traits.Position;
            Matrix3D Ei = Orthogonalize(bv - av, cv - av);

            Vector3D w0i = (Ei * Matrix3D.Rotate(initAngle) * Ei.Inverse() * w0);

            vectorFields[rootFace.Index] = w0i;
            visitedFlags[rootFace.Index] = true;

            //Recurse all faces
            Queue <TriMesh.Face> queue = new Queue <HalfEdgeMesh.Face>();

            queue.Enqueue(rootFace);

            int ii = 0;

            while (queue.Count > 0)
            {
                TriMesh.Face currentFace = queue.Dequeue();
                Vector3D     wI          = vectorFields[currentFace.Index];

                TriMesh.HalfEdge cuHe = currentFace.HalfEdge;

                do
                {
                    TriMesh.Face neighbor = cuHe.Opposite.Face;

                    if (neighbor == null)
                    {
                        cuHe = cuHe.Next;
                        continue;
                    }

                    if (visitedFlags[neighbor.Index] == false)
                    {
                        double angle = EdgeTheta[cuHe.Edge.Index];
                        int    i     = cuHe.FromVertex.Index;
                        int    j     = cuHe.ToVertex.Index;

                        if (i > j)
                        {
                            angle = -angle;
                        }

                        Vector3D wj = Transport(wI, currentFace, neighbor, angle);
                        vectorFields[neighbor.Index] = wj;
                        queue.Enqueue(neighbor);
                        visitedFlags[neighbor.Index] = true;
                    }
                    cuHe = cuHe.Next;
                } while (cuHe != currentFace.HalfEdge);


                ii++;
            }

            return(vectorFields);
        }