예제 #1
0
        /// <summary>
        /// Divides a 3D block into two
        /// </summary>
        /// <param name="block">The block to divide</param>
        /// <param name="p0">The plane point for division</param>
        /// <param name="pn">The plane normal for division</param>
        /// <param name="newFaceConstructor">Constructor for the new face. Defaults to new NGon()</param>
        /// <param name="threshold">The floating point threshold for division, defaults to 0.001 or 1mm</param>
        /// <returns></returns>
        public static object[] Divide(IBlock block, Vector3 p0, Vector3 pn, Func <IEnumerable <Vector3>, IPoly> newFaceConstructor = null, float threshold = 0.001f)
        {
            if (newFaceConstructor == null)
            {
                newFaceConstructor = x => new NGon(x);
            }

            List <IPoly>   insideFaces  = new List <IPoly>();
            List <IPoly>   outsideFaces = new List <IPoly>();
            List <Vector3> newPoints    = new List <Vector3>();

            foreach (IPoly face in block.GetFaces())
            {
                object[] o        = Divide(face, p0, pn, threshold);
                var      inside   = o[0];
                var      outside  = o[1];
                var      newPoint = o[2];

                if (inside != null)
                {
                    insideFaces.Add(inside as IPoly);
                }
                if (outside != null)
                {
                    outsideFaces.Add(outside as IPoly);
                }
                if (newPoint != null)
                {
                    newPoints.Add((Vector3)newPoint);
                }
            }

            //construct new face
            if (newPoints.Count > 3)
            {
                Vector3 center = Vector3.zero;
                foreach (var point in newPoints)
                {
                    center += point;
                }
                center    = center / (float)newPoints.Count;
                newPoints = Math3d.CircleSort(center, pn, newPoints.ToArray()).ToList();
            }

            outsideFaces.Add(newFaceConstructor(newPoints));
            newPoints.Reverse();
            insideFaces.Add(newFaceConstructor(newPoints));

            return(new object[] {
                insideFaces.Count >= 4 ? block.Clone(insideFaces) : null,
                insideFaces.Count >= 4 ? block.Clone(outsideFaces) : null
            });
        }