public void MakeHollow() { if (_document.Selection.IsEmpty() || _document.Selection.InFaceSelection) { return; } var solids = _document.Selection.GetSelectedObjects().OfType <Solid>().ToList(); if (!solids.Any()) { return; } if (solids.Count > 1) { if (MessageBox.Show("This will hollow out every selected solid, are you sure?", "Multiple solids selected", MessageBoxButtons.YesNo) != DialogResult.Yes) { return; } } var qf = new QuickForm("Select wall width") { UseShortcutKeys = true }.NumericUpDown("Wall width (negative to hollow outwards)", -1024, 1024, 0, 32).OkCancel(); decimal width; do { if (qf.ShowDialog() == DialogResult.Cancel) { return; } width = qf.Decimal("Wall width (negative to hollow outwards)"); if (width == 0) { MessageBox.Show("Please select a non-zero value."); } } while (width == 0); _document.PerformAction("Make objects hollow", new MakeHollow(solids, width)); }
public void ScreenshotViewport(object parameter) { var focused = (parameter as ViewportBase) ?? ViewportManager.Viewports.FirstOrDefault(x => x.IsFocused); if (focused == null) { return; } var screen = Screen.FromControl(this); var area = screen.Bounds; using (var qf = new QuickForm("Select screenshot size") { UseShortcutKeys = true } .NumericUpDown("Width", 640, 5000, 0, area.Width) .NumericUpDown("Height", 480, 5000, 0, area.Height) .OkCancel()) { if (qf.ShowDialog() != DialogResult.OK) { return; } var shot = ViewportManager.CreateScreenshot(focused, (int)qf.Decimal("Width"), (int)qf.Decimal("Height")); if (shot == null) { return; } var ext = focused is Viewport2D || (focused is Viewport3D && ((Viewport3D)focused).Type != Viewport3D.ViewType.Textured) ? ".png" : ".jpg"; using (var sfd = new SaveFileDialog()) { sfd.FileName = "Sledge - " + (DocumentManager.CurrentDocument != null ? DocumentManager.CurrentDocument.MapFileName : "untitled") + " - " + DateTime.Now.ToString("yyyy-MM-ddThh-mm-ss") + ext; sfd.Filter = "Image Files (*.png, *.jpg, *.bmp)|*.png;*.jpg;*.bmp"; if (sfd.ShowDialog() == DialogResult.OK) { if (sfd.FileName.EndsWith("jpg")) { var encoder = GetJpegEncoder(); if (encoder != null) { var p = new EncoderParameter(Encoder.Quality, 90L); var ep = new EncoderParameters(1); ep.Param[0] = p; shot.Save(sfd.FileName, encoder, ep); } else { shot.Save(sfd.FileName); } } else { shot.Save(sfd.FileName); } } } shot.Dispose(); } }
protected override async Task Invoke(MapDocument document, CommandParameters parameters) { var objects = document.Selection.OfType <Solid>().ToList(); // Prompt the user for the wall width. If more than 1 solid is selected, show a little warning notice. var qf = new QuickForm(PromptTitle) { UseShortcutKeys = true }; if (objects.Count > 1) { qf.Label(String.Format(WarningMessage, objects.Count)); } qf.NumericUpDown("Width", PromptWallWidth, -1024, 1024, 0, 32); qf.OkCancel(OK, Cancel); if (await qf.ShowDialogAsync() != DialogResult.OK) { return; } var width = (float)qf.Decimal("Width"); var ops = new List <IOperation>(); 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.BoundingBox.Center; var current = obj.BoundingBox.Dimensions; var target = current - new Vector3(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 = Vector3.Divide(target, current); var carver = (Solid)solid.Clone(); carver.Transform(Matrix4x4.CreateTranslation(-origin) * Matrix4x4.CreateScale(scale) * Matrix4x4.CreateTranslation(origin)); // 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(document.Map.NumberGenerator, plane, out back, out front)) { 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 (solid.IsSelected) { front.IsSelected = true; } ops.Add(new Attach(obj.Hierarchy.Parent.ID, front)); } if (back == null || !back.IsValid()) { break; } // Use the back solid as the new clipping target if (solid.IsSelected) { back.IsSelected = true; } solid = back; } if (!split) { continue; } ops.Add(new Detatch(obj.Hierarchy.Parent.ID, obj)); } if (ops.Any()) { await MapDocumentOperation.Perform(document, new Transaction(ops)); } }