From 83fd3423ec3810e4e04f1efc0e4e2d16bc4bb4e6 Mon Sep 17 00:00:00 2001 From: Lars Brubaker Date: Fri, 28 Dec 2018 16:00:21 -0800 Subject: [PATCH] Working on new supports refactoring tour classes --- .../ApplicationView/ApplicationController.cs | 20 ++- .../DesignTools/Primitives/SupportControls.cs | 150 ++++++++++++++++++ .../MatterControl/PrimitivesContainer.cs | 4 + .../{MakeSupport.cs => ToggleSupport.cs} | 15 +- .../{TourSite.cs => TourLocation.cs} | 2 +- MatterControlLib/SetupWizard/TourOverlay.cs | 32 ++-- MatterControlLib/SetupWizard/WelcomePage.cs | 2 +- 7 files changed, 192 insertions(+), 33 deletions(-) create mode 100644 MatterControlLib/DesignTools/Primitives/SupportControls.cs rename MatterControlLib/PartPreviewWindow/View3D/UndoCommands/{MakeSupport.cs => ToggleSupport.cs} (86%) rename MatterControlLib/SetupWizard/{TourSite.cs => TourLocation.cs} (98%) diff --git a/MatterControlLib/ApplicationView/ApplicationController.cs b/MatterControlLib/ApplicationView/ApplicationController.cs index ad70ce326..4254ce456 100644 --- a/MatterControlLib/ApplicationView/ApplicationController.cs +++ b/MatterControlLib/ApplicationView/ApplicationController.cs @@ -547,8 +547,6 @@ namespace MatterHackers.MatterControl public MainViewWidget MainView; - private EventHandler unregisterEvents; - private Dictionary> registeredLibraryActions = new Dictionary>(); private List registeredSceneOperations; @@ -665,14 +663,14 @@ namespace MatterHackers.MatterControl }, new SceneSelectionOperation() { - TitleResolver = () => "Make Support".Localize(), + TitleResolver = () => "Toggle Support".Localize(), Action = (sceneContext) => { var scene = sceneContext.Scene; - if (scene.SelectedItem != null - && !scene.SelectedItem.VisibleMeshes().All(i => i.OutputType == PrintOutputTypes.Support)) + var selectedItem = scene.SelectedItem; + if (selectedItem != null) { - scene.UndoBuffer.AddAndDo(new MakeSupport(scene.SelectedItem)); + scene.UndoBuffer.AddAndDo(new ToggleSupport(selectedItem)); } }, Icon = AggContext.StaticData.LoadIcon("support.png").SetPreMultiply(), @@ -849,7 +847,7 @@ namespace MatterHackers.MatterControl { UiThread.RunOnIdle(() => { - TourOverlay.ShowSite(this.MainView.TopmostParent(), 0); + TourOverlay.ShowLocation(this.MainView.TopmostParent(), 0); }); } @@ -2245,13 +2243,13 @@ namespace MatterHackers.MatterControl /// public bool AnyPrintTaskRunning => this.ActivePrinters.Any(p => p.Connection.PrinterIsPrinting || p.Connection.PrinterIsPaused); - private List _productTour; + private List _productTour; - public async Task> LoadProductTour() + public async Task> LoadProductTour() { if (_productTour == null) { - _productTour = await ApplicationController.LoadCacheableAsync>( + _productTour = await ApplicationController.LoadCacheableAsync>( "ProductTour.json", "MatterHackers", async () => @@ -2259,7 +2257,7 @@ namespace MatterHackers.MatterControl var httpClient = new HttpClient(); string json = await httpClient.GetStringAsync("https://matterhackers.github.io/MatterControl-Help/docs/product-tour.json"); - return JsonConvert.DeserializeObject>(json); + return JsonConvert.DeserializeObject>(json); }, Path.Combine("OemSettings", "ProductTour.json")); diff --git a/MatterControlLib/DesignTools/Primitives/SupportControls.cs b/MatterControlLib/DesignTools/Primitives/SupportControls.cs new file mode 100644 index 000000000..7d0286d68 --- /dev/null +++ b/MatterControlLib/DesignTools/Primitives/SupportControls.cs @@ -0,0 +1,150 @@ +/* +Copyright (c) 2018, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using MatterHackers.Agg; +using MatterHackers.Agg.UI; +using MatterHackers.DataConverters3D; +using MatterHackers.Localizations; +using MatterHackers.PolygonMesh; +using MatterHackers.VectorMath; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.ComponentModel; +using System.Linq; + +namespace MatterHackers.MatterControl.DesignTools +{ + [ShowUpdateButton] + public class SupportControls : Object3D + { + public SupportControls() + { + Name = "Support Controls".Localize(); + Color = Color.Yellow; + } + + public SupportControls(double width, double depth, double height) + : this() + { + Rebuild(null); + } + + //[JsonConverter(typeof(StringEnumConverter))] + //public enum SupportTypes { Solid, Pillars, Tree } + + //[Description("Sets the type of support will be added to the scene and output by the slicing engine.")] + //public SupportTypes SupportType { get; set; } = SupportTypes.Solid; + + [Description("The angle of the faces that need to be supported.")] + public double MaxOverHangAngle { get; set; } = 45; + + // Clear All Supports // Remove all the supports that are currently in the scene + // Group All Supports // Make supports into a sigle grouped object + // Generate Supports // anywhere we need support and there is not currently support there, add support + + public static SupportControls Create() + { + var item = new SupportControls(); + + item.Mesh = PlatonicSolids.CreateCube(20, 20, 20); + + PlatingHelper.PlaceMeshAtHeight(item, 0); + + return item; + } + + public override void OnInvalidate(InvalidateArgs invalidateType) + { + if (invalidateType.InvalidateType == InvalidateType.Properties + && invalidateType.Source == this) + { + Rebuild(null); + } + else + { + base.OnInvalidate(invalidateType); + } + } + + private void Rebuild(UndoBuffer undoBuffer) + { + var parent = this.Parent; + + // Find all the other objects of our parent + var peers = parent.Children.Where(i => i != this).ToArray(); + + // eventually we will not remove any support that is already in the scene + // but for now, remove all the stuff that is there first + var existingSupports = peers.Where(i => i.OutputType == PrintOutputTypes.Support); + + parent.Children.Modify((list) => + { + foreach (var item in existingSupports) + { + list.Remove(item); + } + }); + + // Get visible meshes for each of them + var visibleMeshes = peers.SelectMany(i => i.VisibleMeshes()); + + var supportCandidates = visibleMeshes.Where(i => i.OutputType != PrintOutputTypes.Support); + + // find all the faces that are candidates for support + var verts = new Vector3List(); + var faces = new FaceList(); + foreach(var item in supportCandidates) + { + var matrix = item.WorldMatrix(parent); + foreach(var face in item.Mesh.Faces) + { + var face0Normal = Vector3.TransformVector(face.Normal, matrix).GetNormal(); + var angle = MathHelper.RadiansToDegrees(Math.Acos(Vector3.Dot(Vector3.UnitZ, face0Normal))); + + if (angle < MaxOverHangAngle) + { + foreach (var triangle in face.AsTriangles()) + { + faces.Add(new int[] { verts.Count, verts.Count + 1, verts.Count + 2 }); + verts.Add(Vector3.Transform(triangle.p0, matrix)); + verts.Add(Vector3.Transform(triangle.p0, matrix)); + verts.Add(Vector3.Transform(triangle.p0, matrix)); + } + } + } + } + // separate the faces into face patch groups (these are the new support tops) + // project all the vertecies of each patch group down until they hit an up face in the scene (or 0) + // make a new patch group at the z of the hit (thes will bthe bottoms) + // find the outline of the patch groups (these will be the walls of the top and bottom patches + // make a new mesh object with the top, bottom and walls, add it to the scene and mark it as support + } + } +} \ No newline at end of file diff --git a/MatterControlLib/Library/Providers/MatterControl/PrimitivesContainer.cs b/MatterControlLib/Library/Providers/MatterControl/PrimitivesContainer.cs index 77fd597ab..dde746c11 100644 --- a/MatterControlLib/Library/Providers/MatterControl/PrimitivesContainer.cs +++ b/MatterControlLib/Library/Providers/MatterControl/PrimitivesContainer.cs @@ -145,6 +145,10 @@ namespace MatterHackers.MatterControl.Library }; }) { DateCreated = new System.DateTime(index++) }, + new GeneratorItem( + () => "Supports".Localize(), + () => SupportControls.Create()) + { DateCreated = new System.DateTime(index++) }, }; string title = "Primitive Shapes".Localize(); diff --git a/MatterControlLib/PartPreviewWindow/View3D/UndoCommands/MakeSupport.cs b/MatterControlLib/PartPreviewWindow/View3D/UndoCommands/ToggleSupport.cs similarity index 86% rename from MatterControlLib/PartPreviewWindow/View3D/UndoCommands/MakeSupport.cs rename to MatterControlLib/PartPreviewWindow/View3D/UndoCommands/ToggleSupport.cs index a8011c1ac..30c973035 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/UndoCommands/MakeSupport.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/UndoCommands/ToggleSupport.cs @@ -34,12 +34,12 @@ using MatterHackers.DataConverters3D; namespace MatterHackers.MatterControl.PartPreviewWindow { - public class MakeSupport : IUndoRedoCommand + public class ToggleSupport : IUndoRedoCommand { List itemsPrintOutputType = new List(); List itemsToChange = new List(); - public MakeSupport(IObject3D selectedItem) + public ToggleSupport(IObject3D selectedItem) { if (selectedItem is SelectionGroupObject3D) { @@ -62,9 +62,16 @@ namespace MatterHackers.MatterControl.PartPreviewWindow void IUndoRedoCommand.Do() { - foreach(var item in this.itemsToChange) + for (int i = 0; i < this.itemsToChange.Count; i++) { - item.OutputType = PrintOutputTypes.Support; + if (itemsPrintOutputType[i] == PrintOutputTypes.Support) + { + itemsToChange[i].OutputType = PrintOutputTypes.Default; + } + else + { + itemsToChange[i].OutputType = PrintOutputTypes.Support; + } } } diff --git a/MatterControlLib/SetupWizard/TourSite.cs b/MatterControlLib/SetupWizard/TourLocation.cs similarity index 98% rename from MatterControlLib/SetupWizard/TourSite.cs rename to MatterControlLib/SetupWizard/TourLocation.cs index fec8f34d9..b3e3ddd9f 100644 --- a/MatterControlLib/SetupWizard/TourSite.cs +++ b/MatterControlLib/SetupWizard/TourLocation.cs @@ -29,7 +29,7 @@ either expressed or implied, of the FreeBSD Project. namespace MatterControlLib.SetupWizard { - public class TourSite + public class TourLocation { public string WidgetName { get; set; } diff --git a/MatterControlLib/SetupWizard/TourOverlay.cs b/MatterControlLib/SetupWizard/TourOverlay.cs index 157580465..91edf79ce 100644 --- a/MatterControlLib/SetupWizard/TourOverlay.cs +++ b/MatterControlLib/SetupWizard/TourOverlay.cs @@ -45,15 +45,15 @@ namespace MatterControlLib.SetupWizard private GuiWidget targetWidget; private Popover popover; private GuiWidget tourWindow; - private int nextSiteIndex; + private int nextLocationIndex; private string description; private ThemeConfig theme; - public TourOverlay(GuiWidget tourWindow, GuiWidget targetWidget, string description, ThemeConfig theme, int nextSiteIndex) + public TourOverlay(GuiWidget tourWindow, GuiWidget targetWidget, string description, ThemeConfig theme, int nextLocationIndex) { this.tourWindow = tourWindow; - this.nextSiteIndex = nextSiteIndex; + this.nextLocationIndex = nextLocationIndex; this.theme = theme; this.targetWidget = targetWidget; this.description = description; @@ -85,13 +85,13 @@ namespace MatterControlLib.SetupWizard buttonRow.AddChild(new HorizontalSpacer()); - if (nextSiteIndex > 0) + if (nextLocationIndex > 0) { var nextButton = theme.CreateDialogButton("Next".Localize()); nextButton.Click += (s, e) => { this.Close(); - ShowSite(tourWindow, nextSiteIndex); + ShowLocation(tourWindow, nextLocationIndex); }; buttonRow.AddChild(nextButton); } @@ -207,7 +207,7 @@ namespace MatterControlLib.SetupWizard { var topWindow = this.TopmostParent(); this.Close(); - ShowSite(topWindow, nextSiteIndex); + ShowLocation(topWindow, nextLocationIndex); } base.OnKeyDown(keyEvent); @@ -244,21 +244,21 @@ namespace MatterControlLib.SetupWizard return this.TransformFromScreenSpace(childBounds); } - public static async void ShowSite(GuiWidget window, int siteIndex) + public static async void ShowLocation(GuiWidget window, int locationIndex) { - var tourSites = await ApplicationController.Instance.LoadProductTour(); + var tourLocations = await ApplicationController.Instance.LoadProductTour(); - if (siteIndex >= tourSites.Count) + if (locationIndex >= tourLocations.Count) { - siteIndex -= tourSites.Count; + locationIndex -= tourLocations.Count; } - GuiWidget GetSiteWidget(ref int findSiteIndex) + GuiWidget GetLocationWidget(ref int findLocationIndex) { - while (findSiteIndex < tourSites.Count) + while (findLocationIndex < tourLocations.Count) { var foundChildren = new List(); - window.FindNamedChildrenRecursive(tourSites[findSiteIndex].WidgetName, foundChildren); + window.FindNamedChildrenRecursive(tourLocations[findLocationIndex].WidgetName, foundChildren); foreach (var widgetAndPosition in foundChildren) { @@ -268,17 +268,17 @@ namespace MatterControlLib.SetupWizard } } - findSiteIndex++; + findLocationIndex++; } return null; } - GuiWidget targetWidget = GetSiteWidget(ref siteIndex); + GuiWidget targetWidget = GetLocationWidget(ref locationIndex); if (targetWidget != null) { - var tourOverlay = new TourOverlay(window, targetWidget, tourSites[siteIndex].Description, ApplicationController.Instance.Theme, siteIndex + 1); + var tourOverlay = new TourOverlay(window, targetWidget, tourLocations[locationIndex].Description, ApplicationController.Instance.Theme, locationIndex + 1); window.AddChild(tourOverlay); } } diff --git a/MatterControlLib/SetupWizard/WelcomePage.cs b/MatterControlLib/SetupWizard/WelcomePage.cs index 8cf13c164..5890ac5a1 100644 --- a/MatterControlLib/SetupWizard/WelcomePage.cs +++ b/MatterControlLib/SetupWizard/WelcomePage.cs @@ -98,7 +98,7 @@ Click 'Next' to continue the tour of the interface"; UiThread.RunOnIdle(() => { - TourOverlay.ShowSite(ApplicationController.Instance.MainView.TopmostParent(), 0); + TourOverlay.ShowLocation(ApplicationController.Instance.MainView.TopmostParent(), 0); }); };