// Return a new CSG solid representing space both this solid and in the
        // solid `csg`. Neither this solid nor the solid `csg` are modified.
        public static List <Mesh> Intersect(CSGNode _nodeAIn, CSGNode _nodeBIn, CSGMeshingSettings _meshSettings)
        {
            List <Mesh> resultantMeshes = new List <Mesh>();

            CSGNode nodeA = _nodeAIn.Clone();
            CSGNode nodeB = _nodeBIn.Clone();

            nodeA.Invert();
            nodeB.ClipTo(nodeA);
            nodeB.Invert();
            nodeA.ClipTo(nodeB);
            nodeB.ClipTo(nodeA);
            nodeA.Build(nodeB.AllPolygons());
            nodeA.Invert();

            CSGModel resultModel = new CSGModel(nodeA.AllPolygons());

            if (resultModel.SubDivideMesh(_meshSettings))
            {
                for (int subMeshIter = 0; subMeshIter < resultModel.m_subModels.Count; subMeshIter++)
                {
                    resultantMeshes.Add(resultModel.m_subModels[subMeshIter].ToMesh());
                }
            }
            else
            {
                resultantMeshes.Add(resultModel.ToMesh());
            }

            return(resultantMeshes);
        }
        // Build a BSP tree out of `polygons`. When called on an existing tree, the
        // new polygons are filtered down to the bottom of the tree and become new
        // nodes there. Each set of polygons is partitioned using the first polygon
        // (no heuristic is used to pick a good split).
        public void Build(List <CSGPolygon> _polygons, int _recursionCount = 0)
        {
            if (_recursionCount > C_MaxRecursions)
            {
                Debug.LogWarning("Hit RecursionCap");
                return;
            }

            if (_polygons.Count < 1)
            {
                return;
            }

            if (m_plane == null || !m_plane.Valid())
            {
                m_plane              = new CSGPlane();
                m_plane.m_normal     = _polygons[0].m_plane.m_normal;
                m_plane.m_planeWidth = _polygons[0].m_plane.m_planeWidth;
            }


            if (m_polygons == null)
            {
                m_polygons = new List <CSGPolygon>();
            }

            List <CSGPolygon> frontPolygons = new List <CSGPolygon>();
            List <CSGPolygon> backPolygons  = new List <CSGPolygon>();

            for (int i = 0; i < _polygons.Count; i++)
            {
                m_plane.SplitPolygon(_polygons[i], m_polygons, m_polygons, frontPolygons, backPolygons);
            }

            if (frontPolygons.Count > 0)
            {
                if (m_frontNode == null)
                {
                    m_frontNode = new CSGNode();
                }

                m_frontNode.Build(frontPolygons, _recursionCount + 1);
            }

            if (backPolygons.Count > 0)
            {
                if (m_backNode == null)
                {
                    m_backNode = new CSGNode();
                }

                m_backNode.Build(backPolygons, _recursionCount + 1);
            }
        }
        // Return a new CSG solid representing space in either this solid or in the
        // solid `csg`. Neither this solid nor the solid `csg` are modified.
        public static List <Mesh> NVUnion(CSGNode _nodeAIn, CSGNode _nodeBIn, CSGMeshingSettings _meshSettings)
        {
            List <Mesh> resultantMeshes = new List <Mesh>();

            CSGNode nodeA = _nodeAIn.Clone();
            CSGNode nodeB = _nodeBIn.Clone();

            nodeA.Build(nodeB.AllPolygons());

            CSGModel resultantModel = new CSGModel(nodeA.AllPolygons());

            resultantModel.SubDivideMesh(_meshSettings);
            resultantMeshes.Add(resultantModel.ToMesh());

            return(resultantMeshes);
        }