Exemplo n.º 1
0
        protected Vector3D Transport(Vector3D wI, TriMesh.Face faceI, TriMesh.Face faceJ, double angle)
        {
            /*
             * triangles i and j according to the following labels:
             *
             *              b
             *             /|\
             *            / | \
             *           /  |  \
             *          /   |   \
             *         c  i | j  d
             \   |   /
             \  |  /
             \ | /
             \|/
             \              a
             \
             */

            //Find Shared edge IJ
            TriMesh.HalfEdge sharedEdgeI = null;
            TriMesh.HalfEdge sharedEdgeJ = null;
            TriMesh.Edge     sharedEdge  = null;

            foreach (TriMesh.HalfEdge edgeI in faceI.Halfedges)
            {
                foreach (TriMesh.HalfEdge edgeJ in faceJ.Halfedges)
                {
                    if (edgeI.Opposite == edgeJ)
                    {
                        sharedEdge  = edgeI.Edge;
                        sharedEdgeI = edgeI;
                        sharedEdgeJ = edgeJ;
                        break;
                    }
                }
            }

            if (sharedEdge == null)
            {
                throw new Exception("Error");
            }

            //Find vertex correspondent to figure above
            Vector3D av = sharedEdgeI.FromVertex.Traits.Position;
            Vector3D bv = sharedEdgeJ.FromVertex.Traits.Position;
            Vector3D cv = sharedEdgeI.Next.ToVertex.Traits.Position;
            Vector3D dv = sharedEdgeJ.Next.ToVertex.Traits.Position;

            //Compute the basis
            Matrix3D Ei = Orthogonalize(bv - av, cv - av);
            Matrix3D Ej = Orthogonalize(bv - av, bv - dv);

            //Build Rotate Matrix between two Faces
            Matrix3D rotateMatrix = Matrix3D.Rotate(angle);

            Vector3D wj = (Ej * rotateMatrix * Ei.Inverse() * wI);

            return(wj);
        }
Exemplo n.º 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);
        }
Exemplo n.º 3
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);
        }