void ApplyClipPlane(bool keepBothSides) { List <Object> newObjects = new List <Object>(); foreach (PrimitiveBrush brush in targetBrushes) { if (brush != null) { // Recalculate the clip plane from the world points, converting to local space for this transform Plane localClipPlane; // If the user has specified to flip the plane, flip the plane we just calculated if (isFlipped) { localClipPlane = new Plane(brush.transform.InverseTransformPoint(points[0]), brush.transform.InverseTransformPoint(points[1]), brush.transform.InverseTransformPoint(points[2])); } else { localClipPlane = new Plane(brush.transform.InverseTransformPoint(points[2]), brush.transform.InverseTransformPoint(points[1]), brush.transform.InverseTransformPoint(points[0])); } if (keepBothSides) { Undo.RecordObject(brush, "Split Brush"); Undo.RecordObject(brush.transform, "Split Brush"); } else { Undo.RecordObject(brush, "Clipped Brush"); Undo.RecordObject(brush.transform, "Clipped Brush"); } GameObject newObject = ClipUtility.ApplyClipPlane(brush, localClipPlane, keepBothSides); if (keepBothSides && newObject != null) { Undo.RegisterCreatedObjectUndo(newObject, "Split Brush"); newObjects.Add(newObject); } } } // Add any new objects to the selection if (newObjects.Count > 0) { // First of all add the existing selection to the start of the new objects list newObjects.InsertRange(0, Selection.objects); // Then replace the selected objects with the new objects list in array form Selection.objects = newObjects.ToArray(); } }
public static void SplitIntersecting(PrimitiveBrush[] brushes) { List <Brush> intersections = new List <Brush>(); foreach (PrimitiveBrush brush in brushes) { intersections.AddRange(brush.BrushCache.IntersectingVisualBrushes); } foreach (PrimitiveBrush brush in brushes) { List <PrimitiveBrush> newBrushes = new List <PrimitiveBrush>(); foreach (Brush intersectingBrush in intersections) { PrimitiveBrush brushToClip = (PrimitiveBrush)intersectingBrush; Polygon[] polygons = brush.GetPolygons(); // A brush may have several polygons that share a plane, find all the distinct polygon planes List <Plane> distinctPlanes = new List <Plane>(); for (int polygonIndex = 0; polygonIndex < polygons.Length; polygonIndex++) { Polygon polygon = polygons[polygonIndex]; Vertex vertex1, vertex2, vertex3; SurfaceUtility.GetPrimaryPolygonDescribers(polygon, out vertex1, out vertex2, out vertex3); Vector3 position1 = vertex1.Position; Vector3 position2 = vertex2.Position; Vector3 position3 = vertex3.Position; // Transform from local to brush to local to intersectingBrush position1 = intersectingBrush.transform.InverseTransformPoint(brush.transform.TransformPoint(position1)); position2 = intersectingBrush.transform.InverseTransformPoint(brush.transform.TransformPoint(position2)); position3 = intersectingBrush.transform.InverseTransformPoint(brush.transform.TransformPoint(position3)); // Calculate plane in intersectingBrush's local space Plane polygonPlane = new Plane(position1, position2, position3); bool found = false; // See if it already exists for (int i = 0; i < distinctPlanes.Count; i++) { if (MathHelper.PlaneEqualsLooser(distinctPlanes[i], polygonPlane)) { found = true; break; } } // Not added to an existing group, so add new if (!found) { // Add a new group for the polygon distinctPlanes.Add(polygonPlane); } } foreach (Plane clipPlane in distinctPlanes) { #if UNITY_EDITOR UnityEditor.Undo.RecordObject(brushToClip, "Split Intersecting Brushes"); UnityEditor.Undo.RecordObject(brushToClip.transform, "Split Intersecting Brushes"); #endif GameObject newObject = ClipUtility.ApplyClipPlane(brushToClip, clipPlane, true, false); if (newObject != null) { #if UNITY_EDITOR UnityEditor.Undo.RegisterCreatedObjectUndo(newObject, "Split Intersecting Brushes"); #endif newBrushes.Add(newObject.GetComponent <PrimitiveBrush>()); } } brushToClip.ResetPivot(); } foreach (PrimitiveBrush newBrush in newBrushes) { newBrush.ResetPivot(); } intersections.AddRange(newBrushes.ConvertAll <Brush>(item => (Brush)item)); } }