public void Perform(Document document) { _clipped = new List<MakeHollowReference>(); _results = new List<long>(); var deselect = new List<MapObject>(); var reselect = new List<MapObject>(); foreach (var obj in _objects) { var split = false; var solid = obj; var parent = obj.Parent; // Make a scaled version of the solid for the "inside" of the hollowed solid var origin = solid.GetOrigin(); var current = obj.BoundingBox.Dimensions; var target = current - (new Coordinate(_width, _width, _width) * 2); // Double the width to take from both sides // Ensure we don't have any invalid target sizes if (target.X < 1) target.X = 1; if (target.Y < 1) target.Y = 1; if (target.Z < 1) target.Z = 1; // Clone and scale the solid var scale = target.ComponentDivide(current); var transform = new UnitScale(scale, origin); var carver = (Solid) solid.Clone(); carver.Transform(transform, document.Map.GetTransformFlags()); solid.SetParent(null); carver.SetParent(null); // For a negative width, we want the original solid to be the inside instead if (_width < 0) { var temp = carver; carver = solid; solid = temp; } // Carve the outside solid with the inside solid foreach (var plane in carver.Faces.Select(x => x.Plane)) { // Split solid by plane Solid back, front; try { if (!solid.Split(plane, out back, out front, document.Map.IDGenerator)) continue; } catch { // We're not too fussy about over-complicated carving, just get out if we've broken it. break; } split = true; if (back == null || !back.IsValid()) break; // Retain the front solid _results.Add(front.ID); if (obj.IsSelected) reselect.Add(front); front.SetParent(parent); // Use the back solid as the new clipping target solid = back; } if (!split) continue; _clipped.Add(new MakeHollowReference(obj.ID, parent.ID, obj.IsSelected)); obj.SetParent(null); if (obj.IsSelected) deselect.Add(obj); } document.Selection.Deselect(deselect); document.Selection.Select(reselect); Mediator.Publish(EditorMediator.DocumentTreeStructureChanged); }
private void FlipObjects(Coordinate scale) { if (_document.Selection.IsEmpty() || _document.Selection.InFaceSelection) return; var selected = _document.Selection.GetSelectedParents(); var box = _document.Selection.GetSelectionBoundingBox(); var transform = new UnitScale(scale, box.Center); _document.PerformAction("Flip Objects", new Edit(selected, new TransformEditOperation(transform, _document.Map.GetTransformFlags()))); }
public void Transform() { if (_document.Selection.IsEmpty() || _document.Selection.InFaceSelection) return; var box = _document.Selection.GetSelectionBoundingBox(); using (var td = new TransformDialog(box)) { if (td.ShowDialog() != DialogResult.OK) return; var value = td.TransformValue; IUnitTransformation transform = null; switch (td.TransformType) { case TransformType.Rotate: var mov = Matrix.Translation(-box.Center); // Move to zero var rot = Matrix.Rotation(Quaternion.EulerAngles(value * DMath.PI / 180)); // Do rotation var fin = Matrix.Translation(box.Center); // Move to final origin transform = new UnitMatrixMult(fin * rot * mov); break; case TransformType.Translate: transform = new UnitTranslate(value); break; case TransformType.Scale: transform = new UnitScale(value, box.Center); break; } if (transform == null) return; var selected = _document.Selection.GetSelectedParents(); _document.PerformAction("Transform selection", new Edit(selected, new TransformEditOperation(transform, _document.Map.GetTransformFlags()))); } }
public override void Perform(Document document) { if (_firstRun) { _firstRun = false; foreach (var obj in _objects) { var split = false; var solid = obj; // Make a scaled version of the solid for the "inside" of the hollowed solid var origin = solid.GetOrigin(); var current = obj.BoundingBox.Dimensions; var target = current - (new Coordinate(_width, _width, _width) * 2); // Double the width to take from both sides // Ensure we don't have any invalid target sizes if (target.X < 1) target.X = 1; if (target.Y < 1) target.Y = 1; if (target.Z < 1) target.Z = 1; // Clone and scale the solid var scale = target.ComponentDivide(current); var transform = new UnitScale(scale, origin); var carver = (Solid) solid.Clone(); carver.Transform(transform, document.Map.GetTransformFlags()); // For a negative width, we want the original solid to be the inside instead if (_width < 0) { var temp = carver; carver = solid; solid = temp; } // Carve the outside solid with the inside solid foreach (var plane in carver.Faces.Select(x => x.Plane)) { // Split solid by plane Solid back, front; try { if (!solid.Split(plane, out back, out front, document.Map.IDGenerator)) continue; } catch { // We're not too fussy about over-complicated carving, just get out if we've broken it. break; } split = true; if (front != null) { // Retain the front solid if (obj.IsSelected) front.IsSelected = true; Create(obj.Parent.ID, front); } if (back == null || !back.IsValid()) break; // Use the back solid as the new clipping target solid = back; } if (!split) continue; Delete(obj.ID); } } base.Perform(document); }