コード例 #1
0
 public void SplitByPlane(Plane plane, ref PolygonTreeNodeList coplanarfrontnodes, ref PolygonTreeNodeList coplanarbacknodes, ref PolygonTreeNodeList frontnodes, ref PolygonTreeNodeList backnodes)
 {
     if (children.Count > 0)
     {
         var queue = new Queue <PolygonTreeNodeList>();
         queue.Enqueue(children);
         while (queue.Count > 0)
         {
             var nodes = queue.Dequeue();
             var l     = nodes.Count;
             for (int j = 0; j < l; j++)
             {
                 var node = nodes[j];
                 if (node.children.Count > 0)
                 {
                     queue.Enqueue(node.children);
                 }
                 else
                 {
                     node.SplitPolygonByPlane(plane, ref coplanarfrontnodes, ref coplanarbacknodes, ref frontnodes, ref backnodes);
                 }
             }
         }
     }
     else
     {
         SplitPolygonByPlane(plane, ref coplanarfrontnodes, ref coplanarbacknodes, ref frontnodes, ref backnodes);
     }
 }
コード例 #2
0
 public PolygonTreeNode()
 {
     parent   = null;
     children = new PolygonTreeNodeList();
     polygon  = null;
     removed  = false;
 }
コード例 #3
0
        public void AddPolygons(List <Polygon> polygons)
        {
            var n = polygons.Count;
            var polygontreenodes = new PolygonTreeNodeList(n);

            for (var i = 0; i < n; i++)
            {
                var p = polygonTree.AddChild(polygons[i]);
                polygontreenodes.Add(p);
            }
            rootnode.AddPolygonTreeNodes(polygontreenodes);
        }
コード例 #4
0
        public void ClipPolygons(PolygonTreeNodeList clippolygontreenodes, bool alsoRemoveCoplanarFront)
        {
            var args = new Args {
                Node = this, PolygonTreeNodes = clippolygontreenodes
            };
            Stack <Args> stack = null;

            while (args.Node != null)
            {
                var clippingNode     = args.Node;
                var polygontreenodes = args.PolygonTreeNodes;

                if (clippingNode.Plane != null)
                {
                    PolygonTreeNodeList backnodes  = null;
                    PolygonTreeNodeList frontnodes = null;
                    var plane = clippingNode.Plane;
                    var numpolygontreenodes = polygontreenodes.Count;
                    for (var i = 0; i < numpolygontreenodes; i++)
                    {
                        var polyNode = polygontreenodes[i];
                        if (!polyNode.IsRemoved)
                        {
                            if (alsoRemoveCoplanarFront)
                            {
                                polyNode.SplitByPlane(plane, ref backnodes, ref backnodes, ref frontnodes, ref backnodes);
                            }
                            else
                            {
                                polyNode.SplitByPlane(plane, ref frontnodes, ref backnodes, ref frontnodes, ref backnodes);
                            }
                        }
                    }

                    if (clippingNode.Front != null && (frontnodes != null))
                    {
                        if (stack == null)
                        {
                            stack = new Stack <Args>();
                        }
                        stack.Push(new Args {
                            Node = clippingNode.Front, PolygonTreeNodes = frontnodes
                        });
                    }
                    var numbacknodes = backnodes == null ? 0 : backnodes.Count;
                    if (clippingNode.Back != null && (numbacknodes > 0))
                    {
                        if (stack == null)
                        {
                            stack = new Stack <Args>();
                        }
                        stack.Push(new Args {
                            Node = clippingNode.Back, PolygonTreeNodes = backnodes
                        });
                    }
                    else
                    {
                        // there's nothing behind this plane. Delete the nodes behind this plane:
                        for (var i = 0; i < numbacknodes; i++)
                        {
                            backnodes[i].Remove();
                        }
                    }
                }
                if (stack != null && stack.Count > 0)
                {
                    args = stack.Pop();
                }
                else
                {
                    args.Node = null;
                }
            }
        }
コード例 #5
0
 public Node(Node parent)
 {
     PolygonTreeNodes = new PolygonTreeNodeList();
     Parent           = parent;
 }
コード例 #6
0
        void SplitPolygonByPlane(Plane plane, ref PolygonTreeNodeList coplanarfrontnodes, ref PolygonTreeNodeList coplanarbacknodes, ref PolygonTreeNodeList frontnodes, ref PolygonTreeNodeList backnodes)
        {
            var polygon = this.polygon;

            if (polygon != null)
            {
                var bound        = polygon.BoundingSphere;
                var sphereradius = bound.Radius + 1.0e-4;
                var planenormal  = plane.Normal;
                var spherecenter = bound.Center;
                var d            = planenormal.Dot(spherecenter) - plane.W;
                if (d > sphereradius)
                {
                    if (frontnodes == null)
                    {
                        frontnodes = new PolygonTreeNodeList();
                    }
                    frontnodes.Add(this);
                }
                else if (d < -sphereradius)
                {
                    if (backnodes == null)
                    {
                        backnodes = new PolygonTreeNodeList();
                    }
                    backnodes.Add(this);
                }
                else
                {
                    SplitPolygonResult splitresult;
                    plane.SplitPolygon(polygon, out splitresult);
                    switch (splitresult.Type)
                    {
                    case 0:
                        if (coplanarfrontnodes == null)
                        {
                            coplanarfrontnodes = new PolygonTreeNodeList();
                        }
                        coplanarfrontnodes.Add(this);
                        break;

                    case 1:
                        if (coplanarbacknodes == null)
                        {
                            coplanarbacknodes = new PolygonTreeNodeList();
                        }
                        coplanarbacknodes.Add(this);
                        break;

                    case 2:
                        if (frontnodes == null)
                        {
                            frontnodes = new PolygonTreeNodeList();
                        }
                        frontnodes.Add(this);
                        break;

                    case 3:
                        if (backnodes == null)
                        {
                            backnodes = new PolygonTreeNodeList();
                        }
                        backnodes.Add(this);
                        break;

                    default:
                        if (splitresult.Front != null)
                        {
                            var frontnode = AddChild(splitresult.Front);
                            if (frontnodes == null)
                            {
                                frontnodes = new PolygonTreeNodeList();
                            }
                            frontnodes.Add(frontnode);
                        }
                        if (splitresult.Back != null)
                        {
                            var backnode = AddChild(splitresult.Back);
                            if (backnodes == null)
                            {
                                backnodes = new PolygonTreeNodeList();
                            }
                            backnodes.Add(backnode);
                        }
                        break;
                    }
                }
            }
        }
コード例 #7
0
        public void AddPolygonTreeNodes(PolygonTreeNodeList addpolygontreenodes)
        {
            var args = new Args {
                Node = this, PolygonTreeNodes = addpolygontreenodes
            };
            var stack = new Stack <Args>();

            while (args.Node != null)
            {
                var node             = args.Node;
                var polygontreenodes = args.PolygonTreeNodes;

                if (polygontreenodes.Count == 0)
                {
                    // Nothing to do
                }
                else
                {
                    var _this = node;
                    if (node.Plane == null)
                    {
                        var bestplane = polygontreenodes[0].GetPolygon().Plane;
                        node.Plane = bestplane;
                    }

                    var frontnodes = new PolygonTreeNodeList();
                    var backnodes  = new PolygonTreeNodeList();

                    for (int i = 0, n = polygontreenodes.Count; i < n; i++)
                    {
                        polygontreenodes[i].SplitByPlane(_this.Plane, ref _this.PolygonTreeNodes, ref backnodes, ref frontnodes, ref backnodes);
                    }

                    if (frontnodes.Count > 0)
                    {
                        if (node.Front == null)
                        {
                            node.Front = new Node(node);
                        }
                        stack.Push(new Args {
                            Node = node.Front, PolygonTreeNodes = frontnodes
                        });
                    }
                    if (backnodes.Count > 0)
                    {
                        if (node.Back == null)
                        {
                            node.Back = new Node(node);
                        }
                        stack.Push(new Args {
                            Node = node.Back, PolygonTreeNodes = backnodes
                        });
                    }
                }

                if (stack.Count > 0)
                {
                    args = stack.Pop();
                }
                else
                {
                    args.Node = null;
                }
            }
        }
コード例 #8
0
ファイル: Tree.cs プロジェクト: sta1216/Csg
 public Args(Node node, PolygonTreeNodeList polygonTreeNodes)
 {
     Node             = node;
     PolygonTreeNodes = polygonTreeNodes;
 }
コード例 #9
0
ファイル: Tree.cs プロジェクト: sta1216/Csg
        public void AddPolygonTreeNodes(PolygonTreeNodeList addpolygontreenodes)
        {
            var          args  = new Args(node: this, polygonTreeNodes: addpolygontreenodes);
            Stack <Args>?stack = null;

            while (true)
            {
                var node             = args.Node;
                var polygontreenodes = args.PolygonTreeNodes;

                if (polygontreenodes.Count == 0)
                {
                    // Nothing to do
                }
                else
                {
                    var _this      = node;
                    var _thisPlane = _this.Plane;
                    if (_thisPlane == null)
                    {
                        var bestplane = polygontreenodes[0].GetPolygon().Plane;
                        node.Plane = bestplane;
                        _thisPlane = bestplane;
                    }

                    var frontnodes = default(PolygonTreeNodeList);
                    var backnodes  = default(PolygonTreeNodeList);

                    for (int i = 0, n = polygontreenodes.Count; i < n; i++)
                    {
                        polygontreenodes[i].SplitByPlane(_thisPlane, ref _this.PolygonTreeNodes, ref backnodes, ref frontnodes, ref backnodes);
                    }

                    if (frontnodes != null && frontnodes.Count > 0)
                    {
                        if (node.Front == null)
                        {
                            node.Front = new Node(node);
                        }
                        if (stack == null)
                        {
                            stack = new Stack <Args> ();
                        }
                        stack.Push(new Args(node: node.Front, polygonTreeNodes: frontnodes));
                    }
                    if (backnodes != null && backnodes.Count > 0)
                    {
                        if (node.Back == null)
                        {
                            node.Back = new Node(node);
                        }
                        if (stack == null)
                        {
                            stack = new Stack <Args> ();
                        }
                        stack.Push(new Args(node: node.Back, polygonTreeNodes: backnodes));
                    }
                }

                if (stack != null && stack.Count > 0)
                {
                    args = stack.Pop();
                }
                else
                {
                    break;
                }
            }
        }