Пример #1
0
        public void Initialize(float width, float height)
        {
            // Create 4 original vertices
            Vertex[] vertices = new Vertex[4];
            vertices[0] = new Vertex(-width / 2, height / 2, 0);
            vertices[1] = new Vertex(width / 2, height / 2, 0);
            vertices[2] = new Vertex(width / 2, -height / 2, 0);
            vertices[3] = new Vertex(-width / 2, -height / 2, 0);

            // add to vertex layer
            foreach (Vertex v in vertices)
            {
                vertexLayer.InsertVertex(v);
            }

            // create a face
            Face face = new Face();

            // creates 4 edges
            Edge[] edges = new Edge[4];

            // create one face and four edges
            for (int i = 0; i < 4; i++)
            {
                edges[i] = new Edge(vertices[i], vertices[i + 1 < 4 ? i + 1 : 0]);
                EdgeTree tree = new EdgeTree(edges[i]);
                edgeLayer.AddTree(tree);

                face.AddEdge(edges[i]);
            }

            // use root to initialize facecell tree and lookuptable
            faceLayer.Initliaze(face);
        }
Пример #2
0
        public void EnterFoldingMode(Vertex pickedVertex, Face nearestFace)
        {
            this.cloverController = CloverController.GetInstance();

            // 寻找同group面中拥有pickedVertex的面中最下面的那个面作为baseFace
            this.group = cloverController.FaceGroupLookupTable.GetGroup(nearestFace);
            if (this.group == null)
            {
                System.Windows.MessageBox.Show("找不到Groups");
                return;
            }
            this.pickedVertex = pickedVertex;
            this.baseFace = nearestFace;
            foreach (Face face in group.GetFaceList())
            {
                if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer < baseFace.Layer)
                    baseFace = face;
            }

            // 将同Group的面分为在base面之上(含baseFace)和base面之下的两组
            foreach (Face face in group.GetFaceList())
            {
                if (face.Layer >= baseFace.Layer)
                    this.facesAboveBase.Add(face);
                else
                    this.facesBelowBase.Add(face);
            }

            // 保存pickedVertex的原始位置
            originPoint = new Point3D(pickedVertex.X, pickedVertex.Y, pickedVertex.Z);
        }
Пример #3
0
        public List<Face> EnterTuckingMode(Vertex pickedVertex, Face nearestFace)
        {
            this.cloverController = CloverController.GetInstance();
            //cloverController.ShadowSystem.CheckUndoTree();

            // 寻找同group面中拥有pickedVertex的面中最下面的那个面作为floorFace,最上面的那个面作为ceilingFace
            this.group = cloverController.FaceGroupLookupTable.GetGroup(nearestFace);
            this.pickedVertex = pickedVertex;
            this.floorFace = this.ceilingFace = nearestFace;

            // 是正向还是反向
            Vector3D currNormal = group.Normal * cloverController.RenderController.Entity.Transform.Value;
            Double judge = Vector3D.DotProduct(currNormal, new Vector3D(0, 0, 1));
            isPositive = judge < 0 ? false : true;

            if (isPositive)
            {
                foreach (Face face in group.GetFaceList())
                {
                    if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer < floorFace.Layer)
                        floorFace = face;
                    if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer > ceilingFace.Layer)
                        ceilingFace = face;
                }
                // 将同Group的面分为在floor和ceiling之间和在floor和ceiling之外两组
                foreach (Face face in group.GetFaceList())
                {
                    if (face.Layer >= floorFace.Layer && face.Layer <= ceilingFace.Layer)
                        this.facesInHouse.Add(face);
                    else
                        this.facesNotInHouse.Add(face);
                }
            }
            else
            {
                foreach (Face face in group.GetFaceList())
                {
                    if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer > floorFace.Layer)
                        floorFace = face;
                    if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer < ceilingFace.Layer)
                        ceilingFace = face;
                }
                // 将同Group的面分为在floor和ceiling之间和在floor和ceiling之外两组
                foreach (Face face in group.GetFaceList())
                {
                    if (face.Layer <= floorFace.Layer && face.Layer >= ceilingFace.Layer)
                        this.facesInHouse.Add(face);
                    else
                        this.facesNotInHouse.Add(face);
                }
            }

            // 保存pickedVertex的原始位置
            originPoint = new Point3D(pickedVertex.X, pickedVertex.Y, pickedVertex.Z);

            return facesInHouse;
        }
Пример #4
0
 /// <summary>
 /// 返回两面的共边,如果没有则返回null
 /// </summary>
 /// <param name="face1"></param>
 /// <param name="face2"></param>
 /// <returns></returns>
 public static Edge GetSharedEdge(Face face1, Face face2)
 {
     foreach (Edge edge1 in face1.Edges)
     {
         foreach (Edge edge2 in face2.Edges)
         {
             if (edge1 == edge2)
                 return edge1;
         }
     }
     return null;
 }
Пример #5
0
        public List<Face> EnterFoldingMode(Vertex pickedVertex, Face nearestFace)
        {
            this.cloverController = CloverController.GetInstance();
            //cloverController.ShadowSystem.CheckUndoTree();

            // 寻找同group面中拥有pickedVertex的面中最下面的那个面作为baseFace
            this.group = cloverController.FaceGroupLookupTable.GetGroup(nearestFace);
            this.pickedVertex = pickedVertex;
            this.baseFace = nearestFace;

            // 是正向还是反向
            Vector3D currNormal = group.Normal * cloverController.RenderController.Entity.Transform.Value;
            Double judge = Vector3D.DotProduct(currNormal, new Vector3D(0, 0, 1));
            isPositive = judge < 0 ? false : true;
            if (isPositive)
            {
                foreach (Face face in group.GetFaceList())
                {
                    if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer < baseFace.Layer)
                        baseFace = face;
                }
                // 将同Group的面分为在base面之上(含baseFace)和base面之下的两组
                foreach (Face face in group.GetFaceList())
                {
                    if (face.Layer >= baseFace.Layer)
                        this.facesAboveBase.Add(face);
                    else
                        this.facesBelowBase.Add(face);
                }
            }
            else
            {
                foreach (Face face in group.GetFaceList())
                {
                    if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer > baseFace.Layer)
                        baseFace = face;
                }
                // 将同Group的面分为在base面之上(含baseFace)和base面之下的两组
                foreach (Face face in group.GetFaceList())
                {
                    if (face.Layer <= baseFace.Layer)
                        this.facesAboveBase.Add(face);
                    else
                        this.facesBelowBase.Add(face);
                }
            }

            // 保存pickedVertex的原始位置
            originPoint = new Point3D(pickedVertex.X, pickedVertex.Y, pickedVertex.Z);

            return facesAboveBase;
        }
Пример #6
0
        /// <summary>
        /// 删除looktable的某个face,不存在则会失败返回false
        /// </summary>
        /// <param name="f"></param>
        /// <returns></returns>
        bool RemoveFace( Face f )
        {
            foreach ( FaceGroup group in faceGroupList )
            {
                if ( group.HasFace( f ) )
                {
                    group.RemoveFace( f );
                    if ( group.Count == 0 )
                        faceGroupList.Remove( group );
                    return true;
                }
            }

            return false;
        }
Пример #7
0
 /// <summary>
 /// 往lookuptable中加入face,会自动匹配加入group中或新增group。
 /// 否则强制新建一个group
 /// </summary>
 /// <param name="f"></param>
 void AddFace( Face f )
 {
     foreach ( FaceGroup fg in faceGroupList )
     {
         if ( fg.HasFace( f ) )
         {
             return;
         }
         if ( fg.IsMatch( f ) )
         {
             fg.AddFace( f );
             return;
         }
     }
     FaceGroup newfgt = new FaceGroup( f );
     faceGroupList.Add( newfgt );
 }
Пример #8
0
 public FacecellTree( Face r )
 {
     root = r;
 }
Пример #9
0
 /// <summary>
 /// 判断一个3D点是否处在由points围成的平面内
 /// </summary>
 /// <param name="point">要检查的点</param>
 /// <param name="points">平面的边界</param>
 /// <returns>返回true如果点在平面内或平面边界上</returns>
 /// <author>kid</author>
 public static Boolean IsPointInAreaWithoutEdge(Point3D pe, Face f)
 {
     for (int i = 0; i < f.Vertices.Count; i++)
     {
          Vector3D v1 = pe - f.Vertices[i].GetPoint3D();
          Vector3D v2 = f.Vertices[(i + 1) % f.Vertices.Count].GetPoint3D() - f.Vertices[i].GetPoint3D();
          if (Vector3D.DotProduct(v1, v2) <= 0)
              return false;
     }
     return true;
 }
Пример #10
0
 /// <summary>
 /// 判断一个点是否在一个面中
 /// </summary>
 /// <param name="vervex"></param>
 /// <param name="face"></param>
 /// <returns></returns>
 public static Boolean IsVertexInFace(Vertex vervex, Face face)
 {
     foreach (Vertex v in face.Vertices)
     {
         if (v == vervex)
             return true;
     }
     return false;
 }
Пример #11
0
        /// <summary>
        /// 创建半透明面
        /// </summary>
        /// <param name="face"></param>
        public void CreateTransparentFace(Face face)
        {
            transparentFaces.Add(face);

            RenderController render = CloverController.GetInstance().RenderController;

            render.New(face);
            render.ToGas(face);
        }
Пример #12
0
        void Travel(Face root, int ID, ref Face target)
        {
            if (root == null)
                return;

            if (root.ID == ID)
            {
                target = root;
                return;
            }

            Travel(root.LeftChild, ID, ref target);
            Travel(root.RightChild, ID, ref target);
        }
Пример #13
0
 bool IsLeave( Face face )
 {
     return face.LeftChild == null && face.RightChild == null;
 }
Пример #14
0
        /// <summary>
        /// 更新叶节点
        /// </summary>
        /// <param name="oldFace">改变了的节点</param>
        /// <remarks>如果输入一个面,则将这个面移除并将他的两个孩子加到叶节点表。否则重建整棵树。</remarks>
        public void UpdateLeaves( Face oldFace = null )
        {
            if ( oldFace == null )
            {
                leaves.Clear();
                Travel( root );
                return;
            }

            Debug.Assert( oldFace.LeftChild != null && oldFace.RightChild != null );
            leaves.Remove( oldFace );
            leaves.Add( oldFace.LeftChild );
            leaves.Add( oldFace.RightChild );
        }
Пример #15
0
        /// <summary>
        /// 切割一个面为两个面
        /// </summary>
        /// <param name="face">要切割的面</param>
        /// <param name="edge">割线,不一定要在边层里面的边,只要两个端点的坐标在面的边上即可</param>
        /// <returns>被边引用的割线</returns>
        Edge CutFace(Face face, Edge edge)
        {
            Debug.Assert(edge != null);
            if (edge == null)
            {
                throw new System.ArgumentNullException();
            }

            CloverController controller = CloverController.GetInstance();
            RenderController render = controller.RenderController;
            VertexLayer vertexLayer = controller.VertexLayer;
            //ShadowSystem shadowSystem = controller.ShadowSystem;

            Vertex newVertex1 = edge.Vertex1.Clone() as Vertex;
            Vertex newVertex2 = edge.Vertex2.Clone() as Vertex;
            Vertex newVertexOld1 = newVertex1;
            Vertex newVertexOld2 = newVertex2;

            // 生成一个面的周围的顶点的环形表
            face.UpdateVertices();
            List<Vertex> vertexList = new List<Vertex>();
            vertexList.AddRange(face.Vertices);
            int count = vertexList.Count + 1;
            while (true)
            {
                if (
                    (
                    !CloverMath.IsTwoPointsEqual(newVertex1.GetPoint3D(), vertexList[1].GetPoint3D())
                    && CloverMath.IsPointInTwoPoints(newVertex1.GetPoint3D(), vertexList[0].GetPoint3D(), vertexList[1].GetPoint3D(), 0.001)
                    )
                    ||
                    (
                     !CloverMath.IsTwoPointsEqual(newVertex2.GetPoint3D(), vertexList[1].GetPoint3D())
                    && CloverMath.IsPointInTwoPoints(newVertex2.GetPoint3D(), vertexList[0].GetPoint3D(), vertexList[1].GetPoint3D(), 0.001)
                    )
                    )
                {
                    break;
                }
                vertexList.Add(vertexList[0]);
                vertexList.RemoveAt(0);

                // 防止死循环
                if (count-- == 0)
                    return null;
            }
            vertexList.Add(vertexList[0]);

            // 要被分割的边
            Edge beCutEdge1 = null;
            Edge beCutEdge2 = null;

            // 原始边
            List<Edge> rangeA = new List<Edge>();
            List<Edge> rangeB = new List<Edge>();

            // 分割出来的子面
            Face f1 = new Face(face.Layer);
            Face f2 = new Face(face.Layer);
            face.LeftChild = f1;
            face.RightChild = f2;

            List<Edge> currentEdgeList = null;
            for (int i = 0; i < vertexList.Count - 1; i++)
            {
                Edge currentEdge = CloverTreeHelper.FindEdge(face, vertexList[i], vertexList[i + 1]);

                // 割线过顶点
                if (CloverMath.IsTwoPointsEqual(newVertex1.GetPoint3D(), vertexList[i].GetPoint3D(), 0.1))
                {
                    currentEdgeList = rangeA;
                    newVertex1 = vertexList[i];
                }
                else if (CloverMath.IsTwoPointsEqual(newVertex2.GetPoint3D(), vertexList[i].GetPoint3D(), 0.1))
                {
                    currentEdgeList = rangeB;
                    newVertex2 = vertexList[i];
                }
                // 割线过边
                else if (CloverMath.IsPointInTwoPoints(newVertex1.GetPoint3D(), vertexList[i].GetPoint3D(), vertexList[i + 1].GetPoint3D(), 0.001)
                    && !CloverMath.IsTwoPointsEqual(newVertex1.GetPoint3D(), vertexList[i + 1].GetPoint3D(), 0.1))
                {
                    currentEdgeList = rangeA;

                    beCutEdge1 = currentEdge;
                    Edge cutEdge1 = null;
                    Edge cutEdge2 = null;

                    // 两个孩子为空,新建两条边

                    if (beCutEdge1.LeftChild == null && beCutEdge1.RightChild == null)
                    {
                        // 没人用过的共边
                        Debug.Assert(newVertex1 != null);
                        // 分割一条边生成两条新的边
                        cutEdge1 = new Edge(vertexList[i], newVertex1);
                        cutEdge2 = new Edge(newVertex1, vertexList[i + 1]);
                        beCutEdge1.LeftChild = cutEdge1;
                        beCutEdge1.RightChild = cutEdge2;
                        rangeB.Add(cutEdge1);
                        rangeA.Add(cutEdge2);

                        cutEdge1.Face1 = f2;
                        cutEdge2.Face1 = f1;
                    }
                    else
                    {
                        // 对于已经割过的边,我们“必须”使用它原来的顶点
                        if (CloverMath.IsTwoPointsEqual(newVertex1.GetPoint3D(), beCutEdge1.LeftChild.Vertex1.GetPoint3D()))
                        {
                            newVertex1 = beCutEdge1.LeftChild.Vertex1;
                        }
                        else if (CloverMath.IsTwoPointsEqual(newVertex1.GetPoint3D(), beCutEdge1.LeftChild.Vertex2.GetPoint3D()))
                        {
                            newVertex1 = beCutEdge1.LeftChild.Vertex2;
                        }
                        else if (CloverMath.IsTwoPointsEqual(newVertex1.GetPoint3D(), beCutEdge1.RightChild.Vertex1.GetPoint3D()))
                        {
                            newVertex1 = beCutEdge1.RightChild.Vertex1;
                        }
                        else if (CloverMath.IsTwoPointsEqual(newVertex1.GetPoint3D(), beCutEdge1.RightChild.Vertex2.GetPoint3D()))
                        {
                            newVertex1 = beCutEdge1.RightChild.Vertex2;
                        }
                        else
                        {
                            System.Windows.MessageBox.Show("fuck2");
                            return null;
                        }

                        if (CloverMath.IsTwoPointsEqual(vertexList[i].GetPoint3D(), beCutEdge1.LeftChild.Vertex1.GetPoint3D(), 0.001)
                            || CloverMath.IsTwoPointsEqual(vertexList[i].GetPoint3D(), beCutEdge1.LeftChild.Vertex2.GetPoint3D(), 0.001))
                        {
                            rangeB.Add(beCutEdge1.LeftChild);
                            rangeA.Add(beCutEdge1.RightChild);

                            beCutEdge1.LeftChild.Face2 = f2;
                            beCutEdge1.RightChild.Face2 = f1;
                        }
                        else
                        {
                            rangeA.Add(beCutEdge1.LeftChild);
                            rangeB.Add(beCutEdge1.RightChild);

                            beCutEdge1.LeftChild.Face2 = f1;
                            beCutEdge1.RightChild.Face2 = f2;
                        }
                    }

                    // 计算newVertex1和newVertex2的纹理坐标
                    CalculateTexcoord(newVertex1, beCutEdge1);

                    continue;
                }
                else if (CloverMath.IsPointInTwoPoints(newVertex2.GetPoint3D(), vertexList[i].GetPoint3D(), vertexList[i + 1].GetPoint3D(), 0.001)
                    && !CloverMath.IsTwoPointsEqual(newVertex2.GetPoint3D(), vertexList[i + 1].GetPoint3D(), 0.1))
                {
                    currentEdgeList = rangeB;

                    beCutEdge2 = currentEdge;

                    // 两个孩子为空,新建两条边
                    if (beCutEdge2.LeftChild == null && beCutEdge2.RightChild == null)
                    {
                        Debug.Assert(newVertex2 != null);
                        // 分割一条边生成两条新的边
                        Edge cutEdge1 = new Edge(vertexList[i], newVertex2);
                        Edge cutEdge2 = new Edge(newVertex2, vertexList[i + 1]);
                        beCutEdge2.LeftChild = cutEdge1;
                        beCutEdge2.RightChild = cutEdge2;

                        rangeA.Add(cutEdge1);
                        rangeB.Add(cutEdge2);

                        cutEdge1.Face1 = f1;
                        cutEdge2.Face1 = f2;
                    }
                    else
                    {
                        // 对于已经割过的边,我们“必须”使用它原来的顶点
                        if (CloverMath.IsTwoPointsEqual(newVertex2.GetPoint3D(), beCutEdge2.LeftChild.Vertex1.GetPoint3D()))
                        {
                            newVertex2 = beCutEdge2.LeftChild.Vertex1;
                        }
                        else if (CloverMath.IsTwoPointsEqual(newVertex2.GetPoint3D(), beCutEdge2.LeftChild.Vertex2.GetPoint3D()))
                        {
                            newVertex2 = beCutEdge2.LeftChild.Vertex2;
                        }
                        else if (CloverMath.IsTwoPointsEqual(newVertex2.GetPoint3D(), beCutEdge2.RightChild.Vertex1.GetPoint3D()))
                        {
                            newVertex2 = beCutEdge2.RightChild.Vertex1;
                        }
                        else if (CloverMath.IsTwoPointsEqual(newVertex2.GetPoint3D(), beCutEdge2.RightChild.Vertex2.GetPoint3D()))
                        {
                            newVertex2 = beCutEdge2.RightChild.Vertex2;
                        }
                        else
                        {
                            System.Windows.MessageBox.Show("f**k");
                            return null;
                        }

                        if (CloverMath.IsTwoPointsEqual(vertexList[i].GetPoint3D(), beCutEdge2.LeftChild.Vertex1.GetPoint3D(), 0.001)
                            || CloverMath.IsTwoPointsEqual(vertexList[i].GetPoint3D(), beCutEdge2.LeftChild.Vertex2.GetPoint3D(), 0.001))
                        {
                            rangeA.Add(beCutEdge2.LeftChild);
                            rangeB.Add(beCutEdge2.RightChild);

                            beCutEdge2.LeftChild.Face2 = f1;
                            beCutEdge2.RightChild.Face2 = f2;
                        }
                        else
                        {
                            rangeB.Add(beCutEdge2.LeftChild);
                            rangeA.Add(beCutEdge2.RightChild);

                            beCutEdge2.LeftChild.Face2 = f2;
                            beCutEdge2.RightChild.Face2 = f1;
                        }
                    }
                    // 计算newVertex1和newVertex2的纹理坐标
                    CalculateTexcoord(newVertex2, beCutEdge2);
                    continue;
                }
                currentEdgeList.Add(currentEdge);
            }

            Edge newEdge = new Edge(newVertex1, newVertex2);

            controller.EdgeLayer.AddTree(new EdgeTree(newEdge));

            // 是否是新的顶点
            if (newVertex1 == newVertexOld1)
            {
                vertexLayer.InsertVertex(newVertex1);
                render.AddVisualInfoToVertex(newVertex1);
            }
            if (newVertex2 == newVertexOld2)
            {
                vertexLayer.InsertVertex(newVertex2);
                render.AddVisualInfoToVertex(newVertex2);
            }

            // 更新新边的Faces指针
            newEdge.Face1 = f1;
            newEdge.Face2 = f2;

            // 给两个新面加新的边
            rangeA.Add(newEdge);
            rangeB.Add(newEdge);

            foreach (Edge e in rangeA)
            {
                f1.AddEdge(e);
            }
            foreach (Edge e in rangeB)
            {
                f2.AddEdge(e);
            }

            // 更新两个新面的法向量标杆
            f1.StartVertex1 = newVertex2;
            f1.StartVertex2 = newVertex1;

            f2.StartVertex1 = newVertex1;
            f2.StartVertex2 = newVertex2;

            // 更新面的都为顶点的顺序
            f1.UpdateVertices();
            f2.UpdateVertices();

            // 更新渲染层的部分
            render.Delete(face);
            render.New(f1);
            render.New(f2);

            controller.FaceLayer.UpdateLeaves();

            return newEdge;
        }
Пример #16
0
 /// <summary>
 /// 自动在折纸过程中旋转摄像机
 /// </summary>
 /// <param name="beRotatedFaceList"></param>
 private void AutoCamera(Face face)
 {
     // 自动旋转摄像头
     Vector3D vector1 = face.Normal;
     Vector3D vector2 = new Vector3D(0, 0, 1);
     Quaternion quat;
     if (vector1 == new Vector3D(0, 0, 1))
         quat = new Quaternion();
     else if (vector1 == new Vector3D(0, 0, -1))
         quat = new Quaternion(new Vector3D(0, 1, 0), 180);
     else
     {
         Vector3D axis = Vector3D.CrossProduct(vector1, vector2);
         axis.Normalize();
         Double deg = Vector3D.AngleBetween(vector1, vector2);
         quat = new Quaternion(axis, deg);
     }
     renderController.BeginRotationSlerp(quat);
 }
Пример #17
0
        /// <summary>
        /// 根据给定的长和宽初始化纸张
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void Initialize(float width, float height)
        {
            Vertex.Vertex_count = 0;
            Face.Face_count = 0;
            Edge.Edge_count = 0;

            faceLayer = new FaceLayer();
            edgeLayer = new EdgeLayer();
            vertexLayer = new VertexLayer();

            // Create 4 original vertices
            Vertex[] vertices = new Vertex[4];
            vertices[0] = new Vertex(-width / 2, height / 2, 0);
            vertices[1] = new Vertex(-width / 2, -height / 2, 0);
            vertices[2] = new Vertex(width / 2, -height / 2, 0);
            vertices[3] = new Vertex(width / 2, height / 2, 0);
            // 初始化纹理坐标
            vertices[0].u = 0; vertices[0].v = 0;
            vertices[1].u = 0; vertices[1].v = 1;
            vertices[2].u = 1; vertices[2].v = 1;
            vertices[3].u = 1; vertices[3].v = 0;

            // add to vertex layer
            foreach (Vertex v in vertices)
            {
                vertexLayer.InsertVertex(v);

                renderController.AddVisualInfoToVertex(v);
            }

            // create a face
            Face face = new Face(0);

            // creates 4 edges
            Edge[] edges = new Edge[4];

            // create one face and four edges
            for (int i = 0; i < 4; i++)
            {
                edges[i] = new Edge(vertices[i], vertices[i + 1 < 4 ? i + 1 : 0]);
                EdgeTree tree = new EdgeTree(edges[i]);
                edgeLayer.AddTree(tree);

                face.AddEdge(edges[i]);
                edges[i].Face1 = face;
            }

            // use root to initialize facecell tree and lookuptable
            faceLayer.Initliaze(face);

            face.UpdateVertices();
            faceLayer.UpdateLeaves();

            faceGroupLookupTable = new FaceGroupLookupTable(face);

            // 此处也应该拍一张快照
            SnapshotNode node = new SnapshotNode(faceLayer.Leaves);
            // 为了方便revert设计,详情联系 ET
            node.Type = SnapshotNodeKind.CutKind;
            node.OriginVertexListCount = vertexLayer.VertexCellTable.Count;
            node.OriginEdgeListCount = edgeLayer.Count;
            shadowSystem.Snapshot(node);

            // 调用渲染层,更新纸张
            CreatePaper(face);
        }
Пример #18
0
        /// <summary>
        /// 在渲染层创建纸张的模型
        /// </summary>
        /// <param name="face">初始的face</param>
        public void CreatePaper(Face face)
        {
            if (model != null)
            {
                renderController.DeleteAll();
            }

            // 初始化模型
            renderController.InitializeRenderController();
            renderController.New(face);
            model = renderController.Entity;

            // 初始化纹理
            ImageBrush imb = new ImageBrush();
            imb.ImageSource = new BitmapImage(new Uri(@"media/paper/paper1.jpg", UriKind.Relative));
            DiffuseMaterial mgf = new DiffuseMaterial(imb);
            DiffuseMaterial mgb = new DiffuseMaterial(new SolidColorBrush(Colors.OldLace));
            renderController.FrontMaterial = mgf;
            renderController.BackMaterial = mgb;
        }
Пример #19
0
 /// <summary>
 /// 判断两个面是否相连,即有无公共边
 /// </summary>
 /// <param name="f1"></param>
 /// <param name="f2"></param>
 /// <returns></returns>
 public static bool IsTwoFaceConected(Face f1, Face f2)
 {
     foreach (Edge e1 in f1.Edges)
     {
         foreach (Edge e2 in f2.Edges)
         {
             if (e1 == e2)
                 return true;
         }
     }
     return false;
 }
Пример #20
0
        public void Initliaze( Face root )
        {
            this.root = root;
            root.UpdateVertices();

            facecellTree = new FacecellTree( root );
            this.controller = CloverController.GetInstance();
        }
Пример #21
0
 public void UpdateLeaves( Face oldFace = null )
 {
     facecellTree.UpdateLeaves( oldFace );
 }
Пример #22
0
        /// <summary>
        /// 后续遍历
        /// </summary>
        /// <param name="r">根节点</param>
        /// <remarks>请在调用Travel前清空leaves!</remarks>
        void Travel( Face r )
        {
            if ( r == null )
                return;

            Travel( r.LeftChild );
            Travel( r.RightChild );

            if ( IsLeave( r ) )
                leaves.Add( r );
        }
Пример #23
0
 /// <summary>
 /// 判断一个面是否在一个组中
 /// </summary>
 /// <param name="face"></param>
 /// <param name="group"></param>
 /// <returns></returns>
 public static Boolean IsFaceInGroup(Face face, FaceGroup group)
 {
     // 等待杨旭瑜写完group,。。。
     // todo
     return false;
 }
Пример #24
0
        /// <summary>
        /// 计算两个face的二面角
        /// </summary>
        /// <param name="f1"></param>
        /// <param name="f2"></param>
        /// <returns></returns>
        public static double CalculatePlaneAngle(Face f1, Face f2)
        {
            // 找出面面交线的方向向量
            Vector3D intersectionlinevec = Vector3D.CrossProduct(f1.Normal, f2.Normal);

            // 两个平面平行时候
            if (intersectionlinevec.Length == 0)
            {
                return 0.0;
            }

            // 找出与面垂直的分割面
            Vector3D cutFacenor = Vector3D.CrossProduct(intersectionlinevec, f1.Normal);

            double A = cutFacenor.X;
            double B = cutFacenor.Y;
            double C = cutFacenor.Z;
            double D = 0;
            Point3D p = new Point3D();
            foreach (Edge e in f1.Edges)
            {
                Vector3D ve = e.Vertex2.GetPoint3D() - e.Vertex1.GetPoint3D();
                if (IsTwoVectorTheSameDir(ve, cutFacenor))
                {
                    p = e.Vertex1.GetPoint3D();
                    break;
                }

            }

            D = -(cutFacenor.X * p.X + cutFacenor.Y * p.Y + cutFacenor.Z * p.Z);

            // 检测两个面的夹角是钝角还是锐角
            bool IsObtuseAngle = false;
            foreach (Vertex vertice1 in f1.Vertices)
            {
                foreach (Vertex vertice2 in f2.Vertices)
                {
                    double space1 = A * vertice1.X + B * vertice1.Y + C * vertice1.Z + D;
                    double space2 = A * vertice2.X + B * vertice2.Y + C * vertice2.Z + D;

                    if (space1 * space2 < 0)
                    {
                        IsObtuseAngle = true;
                        break;
                    }
                }
                if (IsObtuseAngle)
                {
                    break;
                }
            }

            // 可以开始计算二面角了
            double cosAngle = Vector3D.DotProduct(f1.Normal, f2.Normal);
            cosAngle = cosAngle / (f1.Normal.Length * f2.Normal.Length);

            double angle = Math.Acos(Math.Abs(cosAngle));
            if (IsObtuseAngle)
            {
                return Math.PI - angle;
            }
            return angle;
        }
Пример #25
0
        Face FaceTree()
        {
            int faceID = reader.ReadInt32();
            if (faceID == -1)
                return null;

            int startVertex1ID = reader.ReadInt32();
            int startVertex2ID = reader.ReadInt32();

            int edgeCount = reader.ReadInt32();

            Face face = new Face(0);
            face.ID = faceID;
            faceIDDict[face.ID] = face;

            for (int i = 0; i < edgeCount; i++)
            {
                int edgeID = reader.ReadInt32();
                face.AddEdge(edgeIDDict[edgeID]);
            }

            face.StartVertex1 = vertexIDDict[startVertex1ID];
            face.StartVertex2 = vertexIDDict[startVertex2ID];

            face.LeftChild = FaceTree();
            face.RightChild = FaceTree();

            face.UpdateVertices();

            return face;
        }
Пример #26
0
 /// <summary>
 /// 得到面所在的分组,如果获取失败返回null,当获取失败时检查一下是否忘记add了。
 /// </summary>
 /// <param name="f"></param>
 /// <returns></returns>
 public FaceGroup GetGroup( Face f )
 {
     foreach ( FaceGroup fg in faceGroupList )
     {
         if ( fg.GetFaceList().Contains( f ) )
             return fg;
     }
     return null;
 }
Пример #27
0
 /// <summary>
 /// 构造第一个面的时候初始化。
 /// </summary>
 /// <param name="f"></param>
 public FaceGroupLookupTable( Face f )
 {
     FaceGroup g = new FaceGroup( f );
     faceGroupList.Add( g );
 }
Пример #28
0
        /// <summary>
        /// 判断一个3D点是否处在由points围成的平面内
        /// </summary>
        /// <param name="point">要检查的点</param>
        /// <param name="points">平面的边界</param>
        /// <returns>返回true如果点在平面内或平面边界上</returns>
        /// <author>kid</author>
        public static Boolean IsPointInArea(Point3D pe, Face f)
        {
            foreach (Vertex v in f.Vertices)
            {
                if (AreTwoPointsSameWithDeviation(pe, v.GetPoint3D()))
                    return true;
            }

               Vector3D lastN = new Vector3D(0, 0, 0);
               for (int i = 0; i < f.Vertices.Count; i++)
               {
               Point3D p1 = f.Vertices[i].GetPoint3D();
               Point3D p2 = f.Vertices[(i + 1) % f.Vertices.Count].GetPoint3D();
               Vector3D v1 = pe - p1;
               Vector3D v2 =  p2 - pe;
               Vector3D currN = Vector3D.CrossProduct(v1, v2);
               if (currN.Length < 0.0001)
               {
                   if (IsPointInTwoPoints(pe, p1, p2))
                       return true;
                   else
                       return false;
               }
               if (Vector3D.DotProduct(currN, lastN) < 0)
                   return false;
               lastN = currN;
               }
               // for (int i = 0; i < f.Vertices.Count; i++)
               // {
               //      Vector3D v1 = pe - f.Vertices[i].GetPoint3D();
               //      Vector3D v2 = f.Vertices[(i + 1) % f.Vertices.Count].GetPoint3D() - f.Vertices[i].GetPoint3D();
               //      if (Vector3D.DotProduct(v1, v2) < 0)
               //          return false;
               // }
            return true;
        }
Пример #29
0
        public void AddTuckingAction(List<Face> faceList, List<Face> rotatedFace, List<Face> fixedFace, 
            Edge edge, Face ceilingFace, Face floorFace, bool isPositive)
        {
            ActionCore(faceList, rotatedFace, fixedFace, edge, isPositive);

            string scripts = "";

            scripts += "ceilingFace = clover.FindFacesByID(" + ceilingFace.ID.ToString() + ")\r\n";
            scripts += "floorFace = clover.FindFacesByID(" + floorFace.ID.ToString() + ")\r\n";
            scripts += "clover.UpdateTableAfterTucking(ceilingFace, floorFace, edge, "
                + (isPositive ? "True" : "False")
                + ")\r\n";
            scripts += "clover.AntiOverlap()\r\n";

            totalScript += scripts;

            writer.Write(scripts);
            writer.Flush();
        }
Пример #30
0
 public List<Face> GetFaceExcludeGroupFoundByFace( Face f )
 {
     List<Face> result = new List<Face>();
     FaceGroup excludefg = GetGroup( f );
     foreach ( FaceGroup fg in faceGroupList )
     {
         if ( fg != excludefg )
         {
             foreach ( Face face in fg.GetFaceList() )
             {
                 result.Add( f );
             }
         }
     }
     return result;
 }