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); } }
public PolygonTreeNode() { parent = null; children = new PolygonTreeNodeList(); polygon = null; removed = false; }
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); }
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; } } }
public Node(Node parent) { PolygonTreeNodes = new PolygonTreeNodeList(); Parent = parent; }
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; } } } }
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; } } }
public Args(Node node, PolygonTreeNodeList polygonTreeNodes) { Node = node; PolygonTreeNodes = polygonTreeNodes; }
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; } } }