/// <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 }); }