コード例 #1
0
ファイル: FileParser.cs プロジェクト: cedricporter/Clover
        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;
        }
コード例 #2
0
ファイル: FaceLayer.cs プロジェクト: cedricporter/Clover
        public void Initliaze( Face root )
        {
            this.root = root;
            root.UpdateVertices();

            facecellTree = new FacecellTree( root );
            this.controller = CloverController.GetInstance();
        }
コード例 #3
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);
        }
コード例 #4
0
ファイル: FoldingSystem.cs プロジェクト: cedricporter/Clover
        /// <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;
        }
コード例 #5
0
ファイル: CloverMath.cs プロジェクト: cedricporter/Clover
        //public  Point[] GetIntersectionPoints( Geometry g1, Geometry g2 )
        //{
        //    Geometry og1 = g1.GetWidenedPathGeometry( new Pen( Brushes.Black, 1.0 ) );
        //    Geometry og2 = g2.GetWidenedPathGeometry( new Pen( Brushes.Black, 1.0 ) );
        //    CombinedGeometry cg = new CombinedGeometry( GeometryCombineMode.Intersect, og1, og2 );
        //    PathGeometry pg = cg.GetFlattenedPathGeometry();
        //    Point[] result = new Point[ pg.Figures.Count ];
        //    for ( int i = 0; i < pg.Figures.Count; i++ )
        //    {
        //        Rect fig = new PathGeometry( new PathFigure[] { pg.Figures[ i ] } ).Bounds;
        //        result[ i ] = new Point( fig.Left + fig.Width / 2.0, fig.Top + fig.Height / 2.0 );
        //    }
        //    return result;
        //}
        /// <summary>
        /// 判断两个面是否位于同一个平面上
        /// </summary>
        /// <param name="f1"></param>
        /// <param name="f2"></param>
        /// <returns></returns>
        public static bool IsInSamePlane( Face f1, Face f2, double ErrorMargin = 0.00001 )
        {
            double A1, B1, C1, D1;
            double A2, B2, C2, D2;
            f1.UpdateVertices();
            f2.UpdateVertices();
            A1 = f1.Normal.X;
            A2 = f2.Normal.X;

            B1 = f1.Normal.Y;
            B2 = f2.Normal.Y;

            C1 = f1.Normal.Z;
            C2 = f2.Normal.Z;

            D1 = -( f1.Vertices[ 0 ].X * A1 + f1.Vertices[ 0 ].Y * B1 + f1.Vertices[ 0 ].Z * C1 );
            D2 = -( f1.Vertices[ 0 ].X * A2 + f1.Vertices[ 0 ].Y * B2 + f1.Vertices[ 0 ].Z * C2 );
            if (
                ( Math.Abs( A1 * B2 - A2 * B1 ) < ErrorMargin )  &&
                ( Math.Abs( B1 * C2 - B2 * C1 ) < ErrorMargin )  &&
                ( Math.Abs( C1 * D2 - C2 * D1 ) < ErrorMargin )
               )
            {
                return true;
            }
            else
                return false;
        }