From b5302eb1f446bb92ae2013d8397a38cbdc3b28d9 Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Tue, 11 May 2021 08:00:25 -0700 Subject: [PATCH 1/6] Fixing null and improving help text --- .../ScaleControls/ScaleHeightControl.cs | 2 +- .../DesignTools/Operations/ScaleObject3D_2.cs | 37 ++++++++++++++++--- .../Primitives/DescriptionObject3D.cs | 1 + .../Primitives/MeasureToolObject3D.cs | 2 +- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleHeightControl.cs b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleHeightControl.cs index a3b75d160..f6b353d07 100644 --- a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleHeightControl.cs +++ b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleHeightControl.cs @@ -86,7 +86,7 @@ namespace MatterHackers.Plugins.EditorTools // if another control gets a hover if (Object3DControlContext.HoveredObject3DControl != this - && Object3DControlContext.HoveredObject3DControl != null) + && Object3DControlContext.HoveredObject3DControl != null) { return true; } diff --git a/MatterControlLib/DesignTools/Operations/ScaleObject3D_2.cs b/MatterControlLib/DesignTools/Operations/ScaleObject3D_2.cs index 797a3a60f..028fa3694 100644 --- a/MatterControlLib/DesignTools/Operations/ScaleObject3D_2.cs +++ b/MatterControlLib/DesignTools/Operations/ScaleObject3D_2.cs @@ -121,12 +121,21 @@ namespace MatterHackers.MatterControl.DesignTools.Operations { get { + var children = UntransformedChildren; + if (children == null) + { + return 0; + } return ScaleRatio.X * UntransformedChildren.GetAxisAlignedBoundingBox().XSize; } set { - FixIfLockedProportions(0, value / UntransformedChildren.GetAxisAlignedBoundingBox().XSize); + var children = UntransformedChildren; + if (children != null) + { + FixIfLockedProportions(0, value / UntransformedChildren.GetAxisAlignedBoundingBox().XSize); + } } } @@ -136,12 +145,21 @@ namespace MatterHackers.MatterControl.DesignTools.Operations { get { - return ScaleRatio.Y * UntransformedChildren.GetAxisAlignedBoundingBox().YSize; + var children = UntransformedChildren; + if (children == null) + { + return 0; + } + return ScaleRatio.Y * children.GetAxisAlignedBoundingBox().YSize; } set { - FixIfLockedProportions(1, value / UntransformedChildren.GetAxisAlignedBoundingBox().YSize); + var children = UntransformedChildren; + if (children != null) + { + FixIfLockedProportions(1, value / children.GetAxisAlignedBoundingBox().YSize); + } } } @@ -151,12 +169,21 @@ namespace MatterHackers.MatterControl.DesignTools.Operations { get { - return ScaleRatio.Z * UntransformedChildren.GetAxisAlignedBoundingBox().ZSize; + var children = UntransformedChildren; + if (children == null) + { + return 0; + } + return ScaleRatio.Z * children.GetAxisAlignedBoundingBox().ZSize; } set { - FixIfLockedProportions(2, value / UntransformedChildren.GetAxisAlignedBoundingBox().ZSize); + var children = UntransformedChildren; + if (children != null) + { + FixIfLockedProportions(2, value / children.GetAxisAlignedBoundingBox().ZSize); + } } } diff --git a/MatterControlLib/DesignTools/Primitives/DescriptionObject3D.cs b/MatterControlLib/DesignTools/Primitives/DescriptionObject3D.cs index 558204a00..d8d47960e 100644 --- a/MatterControlLib/DesignTools/Primitives/DescriptionObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/DescriptionObject3D.cs @@ -50,6 +50,7 @@ namespace MatterHackers.MatterControl.DesignTools [HideChildrenFromTreeView] [HideMeterialAndColor] [WebPageLink("Resources", "Markdown Help", "https://guides.github.com/features/mastering-markdown/")] + [MarkDownDescription("Used to add description within then scene. The object on the bed will not print.")] public class DescriptionObject3D : Object3D, IObject3DControlsProvider, IAlwaysEditorDraw, IEditorButtonProvider { private MarkdownWidget markdownWidget; diff --git a/MatterControlLib/DesignTools/Primitives/MeasureToolObject3D.cs b/MatterControlLib/DesignTools/Primitives/MeasureToolObject3D.cs index 8ad2294da..28903b060 100644 --- a/MatterControlLib/DesignTools/Primitives/MeasureToolObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/MeasureToolObject3D.cs @@ -47,7 +47,7 @@ using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.DesignTools { - [MarkDownDescription("Drag the spheres to the locations you would like to measure the distance between.")] + [MarkDownDescription("Drag the spheres to the locations you would like to measure the distance between. The object on the bed will not print.")] [HideMeterialAndColor] public class MeasureToolObject3D : Object3D, IObject3DControlsProvider, IAlwaysEditorDraw, IEditorButtonProvider { From 4500f0fa8b75becbaf7caacba36ad1ae2d89ff8a Mon Sep 17 00:00:00 2001 From: Lars Brubaker Date: Thu, 13 May 2021 10:38:42 -0700 Subject: [PATCH 2/6] Adding customizable probing bed inset --- MatterControl.Printing/Settings/PrinterSettings.cs | 1 + MatterControl.Printing/Settings/SettingsKey.cs | 1 + .../Settings/SliceSettingsFields.cs | 12 ++++++++++++ .../Settings/SliceSettingsLayouts.cs | 1 + .../PrintLeveling/LevelWizardMesh.cs | 7 ++++++- Submodules/agg-sharp | 2 +- 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/MatterControl.Printing/Settings/PrinterSettings.cs b/MatterControl.Printing/Settings/PrinterSettings.cs index bf0352c70..9363426a1 100644 --- a/MatterControl.Printing/Settings/PrinterSettings.cs +++ b/MatterControl.Printing/Settings/PrinterSettings.cs @@ -165,6 +165,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration SettingsKey.print_center, SettingsKey.print_leveling_probe_start, SettingsKey.print_leveling_required_to_print, + SettingsKey.print_leveling_insets, SettingsKey.print_leveling_solution, SettingsKey.print_time_estimate_multiplier, SettingsKey.printer_name, diff --git a/MatterControl.Printing/Settings/SettingsKey.cs b/MatterControl.Printing/Settings/SettingsKey.cs index d22cbb7b7..accfe2568 100644 --- a/MatterControl.Printing/Settings/SettingsKey.cs +++ b/MatterControl.Printing/Settings/SettingsKey.cs @@ -182,6 +182,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public const string print_leveling_probe_start = nameof(print_leveling_probe_start); public const string print_leveling_required_to_print = nameof(print_leveling_required_to_print); public const string print_leveling_solution = nameof(print_leveling_solution); + public const string print_leveling_insets = nameof(print_leveling_insets); public const string print_time_estimate_multiplier = nameof(print_time_estimate_multiplier); public const string printer_name = nameof(printer_name); public const string probe_has_been_calibrated = nameof(probe_has_been_calibrated); diff --git a/MatterControl.Printing/Settings/SliceSettingsFields.cs b/MatterControl.Printing/Settings/SliceSettingsFields.cs index 2c91406de..7a6dd1d3a 100644 --- a/MatterControl.Printing/Settings/SliceSettingsFields.cs +++ b/MatterControl.Printing/Settings/SliceSettingsFields.cs @@ -1075,6 +1075,18 @@ namespace MatterHackers.MatterControl.SlicerConfiguration RebuildGCodeOnChange = false }, new SliceSettingData() + { + SlicerConfigName = SettingsKey.print_leveling_insets, + PresentationName = "Leveling Insets".Localize(), + HelpText = "The inset amount for each side of the bed.\n- As a % of the width or depth\n- Ordered: Left, Front, Right, Back\n- NOTE: The probe offset is added on top of this".Localize(), + DataEditType = DataEditTypes.BOUNDS, + Units = "%".Localize(), + ShowAsOverride = true, + ShowIfSet = "!has_hardware_leveling", + RebuildGCodeOnChange = false, + DefaultValue = "10,10,10,10" + }, + new SliceSettingData() { SlicerConfigName = SettingsKey.leveling_sample_points, PresentationName = "Sample Points".Localize(), diff --git a/MatterControl.Printing/Settings/SliceSettingsLayouts.cs b/MatterControl.Printing/Settings/SliceSettingsLayouts.cs index 696f434df..0eecf38ff 100644 --- a/MatterControl.Printing/Settings/SliceSettingsLayouts.cs +++ b/MatterControl.Printing/Settings/SliceSettingsLayouts.cs @@ -292,6 +292,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration ("Leveling", new[] { SettingsKey.print_leveling_solution, + SettingsKey.print_leveling_insets, SettingsKey.leveling_sample_points, SettingsKey.print_leveling_required_to_print, }), diff --git a/MatterControlLib/ConfigurationPage/PrintLeveling/LevelWizardMesh.cs b/MatterControlLib/ConfigurationPage/PrintLeveling/LevelWizardMesh.cs index 50ef5a78b..8f3c87aa6 100644 --- a/MatterControlLib/ConfigurationPage/PrintLeveling/LevelWizardMesh.cs +++ b/MatterControlLib/ConfigurationPage/PrintLeveling/LevelWizardMesh.cs @@ -29,6 +29,7 @@ either expressed or implied, of the FreeBSD Project. using System; using System.Collections.Generic; +using MatterHackers.Agg; using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.MeshVisualizer; using MatterHackers.VectorMath; @@ -53,7 +54,11 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling { AxisAlignedBoundingBox aabb = printer.Bed.Aabb; - aabb.Expand(aabb.XSize * -.1, aabb.YSize * -.1, 0); + var insets = printer.Settings.GetValue(SettingsKey.print_leveling_insets); + aabb.MinXYZ.X += aabb.XSize * insets[0] / 100.0; + aabb.MinXYZ.Y += aabb.YSize * insets[1] / 100.0; + aabb.MaxXYZ.X -= aabb.XSize * insets[2] / 100.0; + aabb.MaxXYZ.Y -= aabb.YSize * insets[3] / 100.0; if (printer.Settings.GetValue(SettingsKey.bed_shape) == BedShape.Circular) { diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 4c0f9c8ca..ef102435a 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 4c0f9c8cabf149ce6b4d70515b2a38c04483a72d +Subproject commit ef102435a4a6250caf7599fb6a889089b46a19b7 From 4ef7ecfeb7f924b625a662b2788c6d3301e1c134 Mon Sep 17 00:00:00 2001 From: Lars Brubaker Date: Thu, 13 May 2021 12:19:42 -0700 Subject: [PATCH 3/6] Made fit to bounds scale with new inline controls --- .../ApplicationView/SceneOperations.cs | 8 +- .../Braille/BrailleCardObject3D.cs | 2 +- .../DesignApps/Parts/ImageCoinObject3D.cs | 2 +- .../Parts/RibbonWithNameObject3D.cs | 2 +- .../ScaleControls/ScaleController.cs | 48 ++- .../Obsolete/FitToBoundsObject3D.cs | 2 +- .../Operations/FitToBoundsObject3D_2.cs | 8 +- .../Operations/FitToBoundsObject3D_3.cs | 289 +++++++++++++ .../DesignTools/Operations/ScaleObject3D.cs | 2 +- .../DesignTools/Operations/ScaleObject3D_2.cs | 13 +- .../DesignTools/Operations/ScaleObject3D_3.cs | 386 ++++++++++++++++++ .../UIFields/EnumDisplayField.cs | 5 +- .../MatterControl/InteractiveSceneTests.cs | 46 +-- 13 files changed, 758 insertions(+), 55 deletions(-) create mode 100644 MatterControlLib/DesignTools/Operations/FitToBoundsObject3D_3.cs create mode 100644 MatterControlLib/DesignTools/Operations/ScaleObject3D_3.cs diff --git a/MatterControlLib/ApplicationView/SceneOperations.cs b/MatterControlLib/ApplicationView/SceneOperations.cs index e0c4f34e1..06c0c3f43 100644 --- a/MatterControlLib/ApplicationView/SceneOperations.cs +++ b/MatterControlLib/ApplicationView/SceneOperations.cs @@ -591,11 +591,11 @@ namespace MatterHackers.MatterControl return new SceneOperation("Scale") { OperationType = typeof(IObject3D), - ResultType = typeof(ScaleObject3D_2), + ResultType = typeof(ScaleObject3D_3), TitleResolver = () => "Scale".Localize(), Action = (sceneContext) => { - new ScaleObject3D_2().WrapSelectedItemAndSelect(sceneContext.Scene); + new ScaleObject3D_3().WrapSelectedItemAndSelect(sceneContext.Scene); }, Icon = (invertIcon) => StaticData.Instance.LoadIcon("scale_32x32.png", 16, 16, invertIcon).SetPreMultiply(), HelpTextResolver = () => "*At least 1 part must be selected*".Localize(), @@ -1014,7 +1014,7 @@ namespace MatterHackers.MatterControl return new SceneOperation("Fit to Bounds") { OperationType = typeof(IObject3D), - ResultType = typeof(FitToBoundsObject3D_2), + ResultType = typeof(FitToBoundsObject3D_3), TitleResolver = () => "Fit to Bounds".Localize(), Action = async (sceneContext) => { @@ -1022,7 +1022,7 @@ namespace MatterHackers.MatterControl var selectedItem = scene.SelectedItem; using (new SelectionMaintainer(scene)) { - var fit = await FitToBoundsObject3D_2.Create(selectedItem.Clone()); + var fit = await FitToBoundsObject3D_3.Create(selectedItem.Clone()); fit.MakeNameNonColliding(); scene.UndoBuffer.AddAndDo(new ReplaceCommand(new[] { selectedItem }, new[] { fit })); diff --git a/MatterControlLib/DesignTools/Braille/BrailleCardObject3D.cs b/MatterControlLib/DesignTools/Braille/BrailleCardObject3D.cs index 03e985e9e..6c41cd32b 100644 --- a/MatterControlLib/DesignTools/Braille/BrailleCardObject3D.cs +++ b/MatterControlLib/DesignTools/Braille/BrailleCardObject3D.cs @@ -104,7 +104,7 @@ namespace MatterHackers.MatterControl.DesignTools var scaleRatio = Math.Max(letterObject.XSize() / 17, letterObject.ZSize() / 17); if (scaleRatio > 1) { - letterObject = new ScaleObject3D_2(letterObject, 1.0 / scaleRatio, 1, 1.0 / scaleRatio); + letterObject = new ScaleObject3D_3(letterObject, 1.0 / scaleRatio, 1, 1.0 / scaleRatio); } letterObject = new AlignObject3D(letterObject, FaceAlign.Bottom | FaceAlign.Front, brailleLetter, FaceAlign.Top | FaceAlign.Front, 0, 0, 3.5); letterObject = new SetCenterObject3D(letterObject, brailleLetter.GetCenter(), true, false, false); diff --git a/MatterControlLib/DesignTools/EditorTools/DesignApps/Parts/ImageCoinObject3D.cs b/MatterControlLib/DesignTools/EditorTools/DesignApps/Parts/ImageCoinObject3D.cs index 4331e4e42..afce801f1 100644 --- a/MatterControlLib/DesignTools/EditorTools/DesignApps/Parts/ImageCoinObject3D.cs +++ b/MatterControlLib/DesignTools/EditorTools/DesignApps/Parts/ImageCoinObject3D.cs @@ -188,7 +188,7 @@ namespace MatterHackers.MatterControl.DesignTools IObject3D extrusionObject = imageObject; var loadingScale = 32 / extrusionObject.XSize(); - extrusionObject = new ScaleObject3D_2(extrusionObject, loadingScale, loadingScale, 1 / extrusionObject.ZSize()); + extrusionObject = new ScaleObject3D_3(extrusionObject, loadingScale, loadingScale, 1 / extrusionObject.ZSize()); extrusionObject = PlaceOnBase(logoBase, extrusionObject); this.Children.Add(coinBlank); diff --git a/MatterControlLib/DesignTools/EditorTools/DesignApps/Parts/RibbonWithNameObject3D.cs b/MatterControlLib/DesignTools/EditorTools/DesignApps/Parts/RibbonWithNameObject3D.cs index 76056f7f3..a49c22839 100644 --- a/MatterControlLib/DesignTools/EditorTools/DesignApps/Parts/RibbonWithNameObject3D.cs +++ b/MatterControlLib/DesignTools/EditorTools/DesignApps/Parts/RibbonWithNameObject3D.cs @@ -68,7 +68,7 @@ namespace MatterHackers.MatterControl.DesignTools var textArea = new Vector2(25, 6); double scale = Math.Min(textArea.X / textBounds.XSize, textArea.Y / textBounds.YSize); - nameMesh = new ScaleObject3D_2(nameMesh, scale, scale, 2 / textBounds.ZSize); + nameMesh = new ScaleObject3D_3(nameMesh, scale, scale, 2 / textBounds.ZSize); nameMesh = new AlignObject3D(nameMesh, FaceAlign.Bottom | FaceAlign.Front, cancerRibbonStl, FaceAlign.Top | FaceAlign.Front, 0, 0, -1); nameMesh = new SetCenterObject3D(nameMesh, cancerRibbonStl.GetCenter(), true, false, false); diff --git a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleController.cs b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleController.cs index 515a5eb57..08da59061 100644 --- a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleController.cs +++ b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleController.cs @@ -133,8 +133,7 @@ namespace MatterHackers.Plugins.EditorTools { FinalState = new ScaleStates(InitialState); FinalState.Depth = newDepth; - if (context.GuiSurface.ModifierKeys == Keys.Shift - || (selectedItem is IScaleLocker scaleLocker && scaleLocker.ScaleLocked)) + if (context.GuiSurface.ModifierKeys == Keys.Shift || selectedItem is IScaleLocker) { ScaleProportional(newDepth / InitialState.Depth); } @@ -158,8 +157,7 @@ namespace MatterHackers.Plugins.EditorTools { FinalState = new ScaleStates(InitialState); FinalState.Height = newHeight; - if (context.GuiSurface.ModifierKeys == Keys.Shift - || (selectedItem is IScaleLocker scaleLocker && scaleLocker.ScaleLocked)) + if (context.GuiSurface.ModifierKeys == Keys.Shift || selectedItem is IScaleLocker) { ScaleProportional(newHeight / InitialState.Height); } @@ -171,8 +169,7 @@ namespace MatterHackers.Plugins.EditorTools { FinalState = new ScaleStates(InitialState); FinalState.Width = newWidth; - if (context.GuiSurface.ModifierKeys == Keys.Shift - || (selectedItem is IScaleLocker scaleLocker && scaleLocker.ScaleLocked)) + if (context.GuiSurface.ModifierKeys == Keys.Shift || selectedItem is IScaleLocker) { ScaleProportional(newWidth / InitialState.Width); } @@ -211,8 +208,7 @@ namespace MatterHackers.Plugins.EditorTools FinalState = new ScaleStates(InitialState); FinalState.Width = newWidth; FinalState.Depth = newDepth; - if (context.GuiSurface.ModifierKeys == Keys.Shift - || (selectedItem is IScaleLocker scaleLocker && scaleLocker.ScaleLocked)) + if (context.GuiSurface.ModifierKeys == Keys.Shift || selectedItem is IScaleLocker) { ScaleProportional(newWidth / InitialState.Width); } @@ -245,12 +241,38 @@ namespace MatterHackers.Plugins.EditorTools private void ScaleProportional(double scale) { - FinalState.Width = InitialState.Width * scale; - FinalState.Depth = InitialState.Depth * scale; - FinalState.Height = InitialState.Height * scale; - for (int i = 0; i < FinalState.Diameters.Count; i++) + if (selectedItem is IScaleLocker scaleLocker) { - FinalState.Diameters[i] = InitialState.Diameters[i] * scale; + switch (scaleLocker.LockProportion) + { + case LockProportions.None: + break; + + case LockProportions.X_Y: + if (FinalState.Width != InitialState.Width + || FinalState.Depth != InitialState.Depth) + { + FinalState.Width = InitialState.Width * scale; + FinalState.Depth = InitialState.Depth * scale; + } + break; + + case LockProportions.X_Y_Z: + FinalState.Width = InitialState.Width * scale; + FinalState.Depth = InitialState.Depth * scale; + FinalState.Height = InitialState.Height * scale; + break; + } + } + else + { + FinalState.Width = InitialState.Width * scale; + FinalState.Depth = InitialState.Depth * scale; + FinalState.Height = InitialState.Height * scale; + for (int i = 0; i < FinalState.Diameters.Count; i++) + { + FinalState.Diameters[i] = InitialState.Diameters[i] * scale; + } } } diff --git a/MatterControlLib/DesignTools/Obsolete/FitToBoundsObject3D.cs b/MatterControlLib/DesignTools/Obsolete/FitToBoundsObject3D.cs index 277a38a56..cc338c612 100644 --- a/MatterControlLib/DesignTools/Obsolete/FitToBoundsObject3D.cs +++ b/MatterControlLib/DesignTools/Obsolete/FitToBoundsObject3D.cs @@ -63,7 +63,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations X_Y_Z } - [Obsolete("Not used anymore. Replaced with FitToBoundsObject3D_2", true)] + [Obsolete("Not used anymore. Replaced with FitToBoundsObject3D_3", true)] public class FitToBoundsObject3D : Object3D, ISelectedEditorDraw, IPropertyGridModifier { [Description("Set the shape the part will be fit into.")] diff --git a/MatterControlLib/DesignTools/Operations/FitToBoundsObject3D_2.cs b/MatterControlLib/DesignTools/Operations/FitToBoundsObject3D_2.cs index 45dd0614b..98876b5ea 100644 --- a/MatterControlLib/DesignTools/Operations/FitToBoundsObject3D_2.cs +++ b/MatterControlLib/DesignTools/Operations/FitToBoundsObject3D_2.cs @@ -27,16 +27,19 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +/*********************************************************************/ +/**************************** OBSOLETE! ******************************/ +/************************ USE NEWER VERSION **************************/ +/*********************************************************************/ + using MatterHackers.Agg; using MatterHackers.Agg.UI; using MatterHackers.DataConverters3D; using MatterHackers.Localizations; using MatterHackers.MatterControl.PartPreviewWindow; -using MatterHackers.MeshVisualizer; using MatterHackers.PolygonMesh; using MatterHackers.RenderOpenGl; using MatterHackers.VectorMath; -using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; @@ -45,6 +48,7 @@ using System.Threading.Tasks; namespace MatterHackers.MatterControl.DesignTools.Operations { + [Obsolete("Not used anymore. Replaced with FitToBoundsObject3D_3", true)] public class FitToBoundsObject3D_2 : TransformWrapperObject3D, ISelectedEditorDraw { private Vector3 boundsSize; diff --git a/MatterControlLib/DesignTools/Operations/FitToBoundsObject3D_3.cs b/MatterControlLib/DesignTools/Operations/FitToBoundsObject3D_3.cs new file mode 100644 index 000000000..56471f2f5 --- /dev/null +++ b/MatterControlLib/DesignTools/Operations/FitToBoundsObject3D_3.cs @@ -0,0 +1,289 @@ +/* +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.MatterControl.PartPreviewWindow; +using MatterHackers.PolygonMesh; +using MatterHackers.RenderOpenGl; +using MatterHackers.VectorMath; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Threading.Tasks; + +namespace MatterHackers.MatterControl.DesignTools.Operations +{ + public class FitToBoundsObject3D_3 : TransformWrapperObject3D, ISelectedEditorDraw, IObjectWithWidthAndDepth, IObjectWithHeight + { + private Vector3 boundsSize; + private InvalidateType additonalInvalidate; + + public FitToBoundsObject3D_3() + { + Name = "Fit to Bounds".Localize(); + } + + private IObject3D FitBounds => Children.Last(); + + [EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)] + [Description("Ensure that the part maintains its proportions.")] + public LockProportions LockProportion { get; set; } = LockProportions.X_Y_Z; + + public double Width + { + get => boundsSize.X; + set + { + boundsSize.X = value; + if (this.Children.Count() > 0) + { + Rebuild(); + } + } + } + + public double Depth + { + get => boundsSize.Y; + set + { + boundsSize.Y = value; + if (this.Children.Count() > 0) + { + Rebuild(); + } + } + } + + public double Height + { + get => boundsSize.Z; + set + { + boundsSize.Z = value; + if (this.Children.Count() > 0) + { + Rebuild(); + } + } + } + + [Description("Allows you turn on and off applying the fit to the x axis.")] + public bool StretchX { get; set; } = true; + + [Description("Allows you turn on and off applying the fit to the y axis.")] + public bool StretchY { get; set; } = true; + + [Description("Allows you turn on and off applying the fit to the z axis.")] + public bool StretchZ { get; set; } = true; + + public static async Task Create(IObject3D itemToFit) + { + var fitToBounds = new FitToBoundsObject3D_3(); + using (fitToBounds.RebuildLock()) + { + var startingAabb = itemToFit.GetAxisAlignedBoundingBox(); + itemToFit.Translate(-startingAabb.Center); + + // add the fit item + var scaleItem = new Object3D(); + fitToBounds.Children.Add(scaleItem); + scaleItem.Children.Add(itemToFit); + + // create an object that just represents the bounds in the scene + var fitBounds = new Object3D() + { + Visible = false, + Color = new Color(Color.Red, 100), + Mesh = PlatonicSolids.CreateCube() + }; + // add the item that holds the bounds + fitToBounds.Children.Add(fitBounds); + + fitToBounds.boundsSize.X = startingAabb.XSize; + fitToBounds.boundsSize.Y = startingAabb.YSize; + fitToBounds.boundsSize.Z = startingAabb.ZSize; + await fitToBounds.Rebuild(); + + var finalAabb = fitToBounds.GetAxisAlignedBoundingBox(); + fitToBounds.Translate(startingAabb.Center - finalAabb.Center); + } + + return fitToBounds; + } + + public void DrawEditor(Object3DControlsLayer layer, List transparentMeshes, DrawEventArgs e) + { + var aabb = UntransformedChildren.GetAxisAlignedBoundingBox(); + var center = aabb.Center; + var worldMatrix = this.WorldMatrix(); + + var minXyz = center - new Vector3(Width / 2, Depth / 2, Height / 2); + var maxXyz = center + new Vector3(Width / 2, Depth / 2, Height / 2); + var bounds = new AxisAlignedBoundingBox(minXyz, maxXyz); + layer.World.RenderAabb(bounds, worldMatrix, Color.Red, 1, 1); + } + + public override AxisAlignedBoundingBox GetAxisAlignedBoundingBox(Matrix4X4 matrix) + { + if (Children.Count == 2) + { + AxisAlignedBoundingBox bounds; + using (FitBounds.RebuildLock()) + { + FitBounds.Visible = true; + bounds = base.GetAxisAlignedBoundingBox(matrix); + FitBounds.Visible = false; + } + + return bounds; + } + + return base.GetAxisAlignedBoundingBox(matrix); + } + + public override async void OnInvalidate(InvalidateArgs invalidateType) + { + additonalInvalidate = invalidateType.InvalidateType; + + if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Children) + || invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix) + || invalidateType.InvalidateType.HasFlag(InvalidateType.Mesh)) + && invalidateType.Source != this + && !RebuildLocked) + { + await Rebuild(); + } + else if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties) + && invalidateType.Source == this) + { + await Rebuild(); + } + else if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties) + || invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix) + || invalidateType.InvalidateType.HasFlag(InvalidateType.Mesh) + || invalidateType.InvalidateType.HasFlag(InvalidateType.Children)) + { + base.OnInvalidate(invalidateType); + } + + base.OnInvalidate(invalidateType); + + additonalInvalidate = InvalidateType.None; + } + + public override Task Rebuild() + { + this.DebugDepth("Rebuild"); + using (RebuildLock()) + { + using (new CenterAndHeightMaintainer(this)) + { + AdjustChildSize(null, null); + + UpdateBoundsItem(); + } + } + + Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix | additonalInvalidate)); + return Task.CompletedTask; + } + + private void AdjustChildSize(object sender, EventArgs e) + { + if (Children.Count > 0) + { + var aabb = UntransformedChildren.GetAxisAlignedBoundingBox(); + ItemWithTransform.Matrix = Matrix4X4.Identity; + var scale = Vector3.One; + if (StretchX) + { + scale.X = Width / aabb.XSize; + } + if (StretchY) + { + scale.Y = Depth / aabb.YSize; + } + if (StretchZ) + { + scale.Z = Height / aabb.ZSize; + } + + switch (LockProportion) + { + case LockProportions.None: + break; + + case LockProportions.X_Y: + var minXy = Math.Min(scale.X, scale.Y); + scale.X = minXy; + scale.Y = minXy; + break; + + case LockProportions.X_Y_Z: + var minXyz = Math.Min(Math.Min(scale.X, scale.Y), scale.Z); + scale.X = minXyz; + scale.Y = minXyz; + scale.Z = minXyz; + break; + } + + if (aabb.XSize > 0 && aabb.YSize > 0 && aabb.ZSize > 0) + { + ItemWithTransform.Matrix = Object3DExtensions.ApplyAtPosition(ItemWithTransform.Matrix, aabb.Center, Matrix4X4.CreateScale(scale)); + } + } + } + + private void UpdateBoundsItem() + { + if (Children.Count == 2) + { + var transformAabb = ItemWithTransform.GetAxisAlignedBoundingBox(); + var fitAabb = FitBounds.GetAxisAlignedBoundingBox(); + var fitSize = fitAabb.Size; + if (boundsSize.X != 0 && boundsSize.Y != 0 && boundsSize.Z != 0 + && (fitSize != boundsSize + || fitAabb.Center != transformAabb.Center)) + { + FitBounds.Matrix *= Matrix4X4.CreateScale( + boundsSize.X / fitSize.X, + boundsSize.Y / fitSize.Y, + boundsSize.Z / fitSize.Z); + FitBounds.Matrix *= Matrix4X4.CreateTranslation( + transformAabb.Center - FitBounds.GetAxisAlignedBoundingBox().Center); + } + } + } + } +} \ No newline at end of file diff --git a/MatterControlLib/DesignTools/Operations/ScaleObject3D.cs b/MatterControlLib/DesignTools/Operations/ScaleObject3D.cs index 4adf953ec..6c2cb8ad2 100644 --- a/MatterControlLib/DesignTools/Operations/ScaleObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/ScaleObject3D.cs @@ -47,7 +47,7 @@ using Newtonsoft.Json; namespace MatterHackers.MatterControl.DesignTools.Operations { - [Obsolete("Use ScaleObject3D_2 instead", false)] + [Obsolete("Use ScaleObject3D_3 instead", false)] public class ScaleObject3D : TransformWrapperObject3D, ISelectedEditorDraw, IPropertyGridModifier { public enum ScaleType diff --git a/MatterControlLib/DesignTools/Operations/ScaleObject3D_2.cs b/MatterControlLib/DesignTools/Operations/ScaleObject3D_2.cs index 028fa3694..1461aff5e 100644 --- a/MatterControlLib/DesignTools/Operations/ScaleObject3D_2.cs +++ b/MatterControlLib/DesignTools/Operations/ScaleObject3D_2.cs @@ -27,6 +27,11 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +/*********************************************************************/ +/**************************** OBSOLETE! ******************************/ +/************************ USE NEWER VERSION **************************/ +/*********************************************************************/ + using System; using System.Collections.Generic; using System.ComponentModel; @@ -39,11 +44,7 @@ using Newtonsoft.Json; namespace MatterHackers.MatterControl.DesignTools.Operations { - public interface IScaleLocker - { - bool ScaleLocked { get; } - } - + [Obsolete("Use ScaleObject3D_3 instead", false)] public class ScaleObject3D_2 : TransformWrapperObject3D, IObjectWithHeight, IObjectWithWidthAndDepth, IPropertyGridModifier, IScaleLocker { public enum ScaleTypes @@ -232,7 +233,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations } } - public bool ScaleLocked => LockProportions; + public LockProportions LockProportion => LockProportions ? Operations.LockProportions.X_Y_Z: Operations.LockProportions.None; private void FixIfLockedProportions(int index, double newScale) { diff --git a/MatterControlLib/DesignTools/Operations/ScaleObject3D_3.cs b/MatterControlLib/DesignTools/Operations/ScaleObject3D_3.cs new file mode 100644 index 000000000..ea0aff6e4 --- /dev/null +++ b/MatterControlLib/DesignTools/Operations/ScaleObject3D_3.cs @@ -0,0 +1,386 @@ +/* +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 System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Threading.Tasks; +using MatterHackers.Agg.UI; +using MatterHackers.DataConverters3D; +using MatterHackers.Localizations; +using MatterHackers.VectorMath; +using Newtonsoft.Json; + +namespace MatterHackers.MatterControl.DesignTools.Operations +{ + public enum LockProportions + { + [Description("Scale Freely")] + None, + [Description("Lock the Width & Depth together")] + X_Y, + [Description("Lock the Width, Depth & Height together")] + X_Y_Z + } + + public interface IScaleLocker + { + LockProportions LockProportion { get; } + } + + public class ScaleObject3D_3 : TransformWrapperObject3D, IObjectWithHeight, IObjectWithWidthAndDepth, IPropertyGridModifier, IScaleLocker + { + public enum ScaleTypes + { + Custom, + Inches_to_mm, + mm_to_Inches, + mm_to_cm, + cm_to_mm, + Ultrafuse_316L, + } + + public ScaleObject3D_3() + { + Name = "Scale".Localize(); + } + + public ScaleObject3D_3(IObject3D item, double x = 1, double y = 1, double z = 1) + : this(item, new Vector3(x, y, z)) + { + } + + public ScaleObject3D_3(IObject3D itemToScale, Vector3 scale) + : this() + { + WrapItems(new IObject3D[] { itemToScale }); + + ScaleRatio = scale; + Rebuild(); + } + + public override void WrapSelectedItemAndSelect(InteractiveScene scene) + { + base.WrapSelectedItemAndSelect(scene); + + // use source item as it may be a copy of item by the time we have wrapped it + var aabb = UntransformedChildren.GetAxisAlignedBoundingBox(); + var newCenter = new Vector3(aabb.Center.X, aabb.Center.Y, aabb.MinXYZ.Z); + UntransformedChildren.Translate(-newCenter); + this.Translate(newCenter); + } + + public override void WrapItems(IEnumerable items, UndoBuffer undoBuffer = null) + { + base.WrapItems(items, undoBuffer); + + // use source item as it may be a copy of item by the time we have wrapped it + var aabb = UntransformedChildren.GetAxisAlignedBoundingBox(); + var newCenter = new Vector3(aabb.Center.X, aabb.Center.Y, aabb.MinXYZ.Z); + UntransformedChildren.Translate(-newCenter); + this.Translate(newCenter); + } + + // this is the size we actually serialize + public Vector3 ScaleRatio = Vector3.One; + + public ScaleTypes ScaleType { get; set; } = ScaleTypes.Custom; + + public enum ScaleMethods + { + Direct, + Percentage, + } + + [EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Tabs)] + public ScaleMethods ScaleMethod { get; set; } = ScaleMethods.Direct; + + + [EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)] + [Description("Ensure that the part maintains its proportions.")] + public LockProportions LockProportion { get; set; } = LockProportions.X_Y_Z; + + + [MaxDecimalPlaces(3)] + [JsonIgnore] + public double Width + { + get + { + var children = UntransformedChildren; + if (children == null) + { + return 0; + } + return ScaleRatio.X * UntransformedChildren.GetAxisAlignedBoundingBox().XSize; + } + + set + { + var children = UntransformedChildren; + if (children != null) + { + FixIfLockedProportions(0, value / UntransformedChildren.GetAxisAlignedBoundingBox().XSize); + } + } + } + + [MaxDecimalPlaces(3)] + [JsonIgnore] + public double Depth + { + get + { + var children = UntransformedChildren; + if (children == null) + { + return 0; + } + return ScaleRatio.Y * children.GetAxisAlignedBoundingBox().YSize; + } + + set + { + var children = UntransformedChildren; + if (children != null) + { + FixIfLockedProportions(1, value / children.GetAxisAlignedBoundingBox().YSize); + } + } + } + + [MaxDecimalPlaces(3)] + [JsonIgnore] + public double Height + { + get + { + var children = UntransformedChildren; + if (children == null) + { + return 0; + } + return ScaleRatio.Z * children.GetAxisAlignedBoundingBox().ZSize; + } + + set + { + var children = UntransformedChildren; + if (children != null) + { + FixIfLockedProportions(2, value / children.GetAxisAlignedBoundingBox().ZSize); + } + } + } + + [MaxDecimalPlaces(2)] + [JsonIgnore] + public double WidthPercent + { + get + { + return ScaleRatio.X * 100; + } + + set + { + FixIfLockedProportions(0, value / 100); + } + } + + [MaxDecimalPlaces(2)] + [JsonIgnore] + public double DepthPercent + { + get + { + return ScaleRatio.Y * 100; + } + + set + { + FixIfLockedProportions(1, value / 100); + } + } + + [MaxDecimalPlaces(2)] + [JsonIgnore] + public double HeightPercent + { + get + { + return ScaleRatio.Z * 100; + } + + set + { + FixIfLockedProportions(2, value / 100); + } + } + + private void FixIfLockedProportions(int index, double newScale) + { + if (Math.Abs(newScale - ScaleRatio[index]) > .001) + { + ScaleRatio[index] = newScale; + if (ScaleType != ScaleTypes.Custom) + { + // WIP: switch back to custom scaling (as we are no longer on a fixed scaling) + // needs to: + // - create an undo point for the switch + // - update the properties control to show the right drop down + // - show all the settings + } + + if (LockProportion == LockProportions.X_Y_Z) + { + ScaleRatio[(index + 1) % 3] = ScaleRatio[index]; + ScaleRatio[(index + 2) % 3] = ScaleRatio[index]; + Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues)); + } + else if (LockProportion == LockProportions.X_Y) + { + if (index == 0) + { + ScaleRatio[1] = ScaleRatio[index]; + Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues)); + } + else if(index == 1) + { + ScaleRatio[0] = ScaleRatio[index]; + Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues)); + } + } + + Rebuild(); + } + } + + public async override void OnInvalidate(InvalidateArgs invalidateArgs) + { + if ((invalidateArgs.InvalidateType.HasFlag(InvalidateType.Children) + || invalidateArgs.InvalidateType.HasFlag(InvalidateType.Matrix) + || invalidateArgs.InvalidateType.HasFlag(InvalidateType.Mesh)) + && invalidateArgs.Source != this + && !RebuildLocked) + { + await Rebuild(); + } + else if (invalidateArgs.InvalidateType.HasFlag(InvalidateType.Properties) + && invalidateArgs.Source == this) + { + await Rebuild(); + } + else + { + base.OnInvalidate(invalidateArgs); + } + } + + public override Task Rebuild() + { + this.DebugDepth("Rebuild"); + + using (RebuildLock()) + { + using (new CenterAndHeightMaintainer(this)) + { + // set the matrix for the transform object + ItemWithTransform.Matrix = Matrix4X4.Identity; + ItemWithTransform.Matrix *= Matrix4X4.CreateScale(ScaleRatio); + } + } + + Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix)); + + return Task.CompletedTask; + } + + public void UpdateControls(PublicPropertyChange change) + { + change.SetRowVisible(nameof(Width), () => ScaleType == ScaleTypes.Custom && ScaleMethod == ScaleMethods.Direct); + change.SetRowVisible(nameof(Depth), () => ScaleType == ScaleTypes.Custom && ScaleMethod == ScaleMethods.Direct); + change.SetRowVisible(nameof(Height), () => ScaleType == ScaleTypes.Custom && ScaleMethod == ScaleMethods.Direct); + change.SetRowVisible(nameof(WidthPercent), () => ScaleType == ScaleTypes.Custom && ScaleMethod == ScaleMethods.Percentage); + change.SetRowVisible(nameof(DepthPercent), () => ScaleType == ScaleTypes.Custom && ScaleMethod == ScaleMethods.Percentage); + change.SetRowVisible(nameof(HeightPercent), () => ScaleType == ScaleTypes.Custom && ScaleMethod == ScaleMethods.Percentage); + change.SetRowVisible(nameof(LockProportions), () => ScaleType == ScaleTypes.Custom); + change.SetRowVisible(nameof(ScaleMethod), () => ScaleType == ScaleTypes.Custom); + + if (change.Changed == nameof(ScaleType)) + { + // recalculate the scaling + double scale = 1; + switch (ScaleType) + { + case ScaleTypes.Inches_to_mm: + scale = 25.4; + break; + case ScaleTypes.mm_to_Inches: + scale = .0393; + break; + case ScaleTypes.mm_to_cm: + scale = .1; + break; + case ScaleTypes.cm_to_mm: + scale = 10; + break; + case ScaleTypes.Ultrafuse_316L: + ScaleRatio = new Vector3(1.1982, 1.1982, 1.261); + Rebuild(); + Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues)); + return; + } + + ScaleRatio = new Vector3(scale, scale, scale); + Rebuild(); + Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues)); + } + else if (change.Changed == nameof(LockProportion)) + { + if (LockProportion == LockProportions.X_Y_Z) + { + var maxScale = Math.Max(ScaleRatio.X, Math.Max(ScaleRatio.Y, ScaleRatio.Z)); + ScaleRatio = new Vector3(maxScale, maxScale, maxScale); + Rebuild(); + // make sure we update the controls on screen to reflect the different data type + Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues)); + } + else if (LockProportion == LockProportions.X_Y) + { + var maxScale = Math.Max(ScaleRatio.X, ScaleRatio.Y); + ScaleRatio = new Vector3(maxScale, maxScale, ScaleRatio.Z); + Rebuild(); + // make sure we update the controls on screen to reflect the different data type + Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues)); + } + } + } + } +} \ No newline at end of file diff --git a/MatterControlLib/SlicerConfiguration/UIFields/EnumDisplayField.cs b/MatterControlLib/SlicerConfiguration/UIFields/EnumDisplayField.cs index 44b2d711c..8aeef14e9 100644 --- a/MatterControlLib/SlicerConfiguration/UIFields/EnumDisplayField.cs +++ b/MatterControlLib/SlicerConfiguration/UIFields/EnumDisplayField.cs @@ -100,7 +100,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration break; case EnumDisplayAttribute.PresentationMode.Buttons: - AddButtons(enumItems); + AddButtons(enumItems, enumDescriptions); break; default: @@ -157,7 +157,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration this.Content = menuRow; } - private void AddButtons(IEnumerable<(string Key, string Value)> enumItems) + private void AddButtons(IEnumerable<(string Key, string Value)> enumItems, List descriptions) { var menuRow = new FlowLayoutWidget(); @@ -177,6 +177,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration SelectedBackgroundColor = theme.PrimaryAccentColor, UnselectedBackgroundColor = theme.MinimalShade, BackgroundColor = theme.MinimalShade, + ToolTipText = descriptions[index] }; radioButton.CheckedStateChanged += (s, e) => diff --git a/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs b/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs index 857bae866..fe009601d 100644 --- a/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs @@ -325,11 +325,11 @@ namespace MatterControl.Tests.MatterControl root.Children.Add(cube); Assert.IsTrue(root.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)), .001)); root.Children.Remove(cube); - var fit = await FitToBoundsObject3D_2.Create(cube); + var fit = await FitToBoundsObject3D_3.Create(cube); - fit.SizeX = 50; - fit.SizeY = 20; - fit.SizeZ = 20; + fit.Width = 50; + fit.Depth = 20; + fit.Height = 20; root.Children.Add(fit); var rootAabb = root.GetAxisAlignedBoundingBox(); Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-25, -10, -10), new Vector3(25, 10, 10)), .001)); @@ -339,11 +339,11 @@ namespace MatterControl.Tests.MatterControl { var root = new Object3D(); var cube = await CubeObject3D.Create(20, 20, 20); - var fit = await FitToBoundsObject3D_2.Create(cube); + var fit = await FitToBoundsObject3D_3.Create(cube); - fit.SizeX = 50; - fit.SizeY = 20; - fit.SizeZ = 20; + fit.Width = 50; + fit.Depth = 20; + fit.Height = 20; var pinch = new PinchObject3D_3(); pinch.Children.Add(fit); @@ -384,11 +384,11 @@ namespace MatterControl.Tests.MatterControl { var root = new Object3D(); var cube = await CubeObject3D.Create(20, 20, 20); - var fit = await FitToBoundsObject3D_2.Create(cube); + var fit = await FitToBoundsObject3D_3.Create(cube); - fit.SizeX = 50; - fit.SizeY = 20; - fit.SizeZ = 20; + fit.Width = 50; + fit.Depth = 20; + fit.Height = 20; var translate = new TranslateObject3D(fit, 11, 0, 0); @@ -417,7 +417,7 @@ namespace MatterControl.Tests.MatterControl var undoBuffer = new UndoBuffer(); // add a scale to it (that is not scaled) - var scaleObject = new ScaleObject3D_2(); + var scaleObject = new ScaleObject3D_3(); scaleObject.WrapItems(new IObject3D[] { cube }, undoBuffer); // ensure that the object did not move @@ -440,7 +440,7 @@ namespace MatterControl.Tests.MatterControl var preScaleAabb = root.GetAxisAlignedBoundingBox(); // add a scale to it (that is not scaled) - var scaleObject = new ScaleObject3D_2(cube); + var scaleObject = new ScaleObject3D_3(cube); // ensure that the object did not move Assert.AreEqual(4, root.DescendantsAndSelf().Count()); @@ -465,7 +465,7 @@ namespace MatterControl.Tests.MatterControl var preScaleAabb = root.GetAxisAlignedBoundingBox(); // add a scale to it (that is not scaled) - var scaleObject = new ScaleObject3D_2(cube); + var scaleObject = new ScaleObject3D_3(cube); // ensure that the object did not move Assert.AreEqual(4, root.DescendantsAndSelf().Count()); @@ -525,11 +525,11 @@ namespace MatterControl.Tests.MatterControl var root = new Object3D(); var cube = await CubeObject3D.Create(20, 20, 20); - var fit = await FitToBoundsObject3D_2.Create(cube); + var fit = await FitToBoundsObject3D_3.Create(cube); - fit.SizeX = 10; - fit.SizeY = 10; - fit.SizeZ = 6; + fit.Width = 10; + fit.Depth = 10; + fit.Height = 6; Assert.IsTrue(fit.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-5, -5, -10), new Vector3(5, 5, -4)), .01)); @@ -635,11 +635,11 @@ namespace MatterControl.Tests.MatterControl var root = new Object3D(); var cube = await CubeObject3D.Create(20, 20, 20); - var fit = await FitToBoundsObject3D_2.Create(cube); + var fit = await FitToBoundsObject3D_3.Create(cube); - fit.SizeX = 50; - fit.SizeY = 20; - fit.SizeZ = 20; + fit.Width = 50; + fit.Depth = 20; + fit.Height = 20; Assert.IsTrue(fit.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-25, -10, -10), new Vector3(25, 10, 10)), 1.0)); From 87bd79901a11a67e2244bc761bc29afdcc6f8be5 Mon Sep 17 00:00:00 2001 From: Lars Brubaker Date: Thu, 13 May 2021 18:12:22 -0700 Subject: [PATCH 4/6] Working to correct some null refs --- .../View3D/TrackballTumbleWidgetExtended.cs | 18 ++++++++++++------ Submodules/MatterSlice | 2 +- Submodules/agg-sharp | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/MatterControlLib/PartPreviewWindow/View3D/TrackballTumbleWidgetExtended.cs b/MatterControlLib/PartPreviewWindow/View3D/TrackballTumbleWidgetExtended.cs index 939ea36de..0168eef66 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/TrackballTumbleWidgetExtended.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/TrackballTumbleWidgetExtended.cs @@ -349,14 +349,20 @@ namespace MatterHackers.MatterControl.PartPreviewWindow ZeroVelocity(); } - var rayAtPosition = world.GetRayForLocalBounds(position); - var hitAtPosition = hitPlane.GetClosestIntersection(rayAtPosition); + if (hitPlane != null) + { + var rayAtPosition = world.GetRayForLocalBounds(position); + var hitAtPosition = hitPlane.GetClosestIntersection(rayAtPosition); - var offset = hitAtPosition.HitPosition - mouseDownWorldPosition; - bedCenter += offset; - world.Translate(offset); + if (hitAtPosition != null) + { + var offset = hitAtPosition.HitPosition - mouseDownWorldPosition; + bedCenter += offset; + world.Translate(offset); - Invalidate(); + Invalidate(); + } + } } public void ZeroVelocity() diff --git a/Submodules/MatterSlice b/Submodules/MatterSlice index 16e9e5a2b..a2bfc7651 160000 --- a/Submodules/MatterSlice +++ b/Submodules/MatterSlice @@ -1 +1 @@ -Subproject commit 16e9e5a2b5ff60df9c39d084e7820f346ac48111 +Subproject commit a2bfc7651149af674638c5925789a72acf557e23 diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index ef102435a..d7dec9cc6 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit ef102435a4a6250caf7599fb6a889089b46a19b7 +Subproject commit d7dec9cc62b55e5dd55655fa0456caba9f845252 From 9513fbdcd5bc0d6a6dc4ee04be2b07d39901b0f4 Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Fri, 14 May 2021 07:32:07 -0700 Subject: [PATCH 5/6] fixing issue with threads and gear tools --- Submodules/MatterSlice | 2 +- Submodules/agg-sharp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Submodules/MatterSlice b/Submodules/MatterSlice index a2bfc7651..f308b69e1 160000 --- a/Submodules/MatterSlice +++ b/Submodules/MatterSlice @@ -1 +1 @@ -Subproject commit a2bfc7651149af674638c5925789a72acf557e23 +Subproject commit f308b69e1c9338a35f34a1a254326fe2d66474e2 diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index d7dec9cc6..c125e9a5f 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit d7dec9cc62b55e5dd55655fa0456caba9f845252 +Subproject commit c125e9a5f714c1096622540e3d78069bab906044 From 5a4b681e7d608ce2ab4ac556f2a79268a45943c0 Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Fri, 14 May 2021 07:55:08 -0700 Subject: [PATCH 6/6] Hide the scroll bar on the favorites --- MatterControlLib/PartPreviewWindow/PartTabPage.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/MatterControlLib/PartPreviewWindow/PartTabPage.cs b/MatterControlLib/PartPreviewWindow/PartTabPage.cs index 4b8c88320..a2035160f 100644 --- a/MatterControlLib/PartPreviewWindow/PartTabPage.cs +++ b/MatterControlLib/PartPreviewWindow/PartTabPage.cs @@ -31,6 +31,7 @@ using System; using MatterHackers.Agg; using MatterHackers.Agg.Platform; using MatterHackers.Agg.UI; +using MatterHackers.Localizations; using MatterHackers.MatterControl.CustomWidgets; using MatterHackers.MatterControl.Library; using MatterHackers.VectorMath; @@ -176,6 +177,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow favoritesBar.ScrollArea.VAnchor = VAnchor.Fit; + favoritesBar.VerticalScrollBar.Show = ScrollBar.ShowState.Never; + var expandedImage = StaticData.Instance.LoadIcon("expand.png", 16, 16, theme.InvertIcons); var collapsedImage = StaticData.Instance.LoadIcon("collapse.png", 16, 16, theme.InvertIcons); @@ -185,7 +188,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow VAnchor = VAnchor.Absolute | VAnchor.Bottom, Margin = new BorderDouble(bottom: 3, top: 3), Height = theme.ButtonHeight - 6 * GuiWidget.DeviceScale, - Width = theme.ButtonHeight - 6 * GuiWidget.DeviceScale + Width = theme.ButtonHeight - 6 * GuiWidget.DeviceScale, + ToolTipText = expanded ? "Reduced Width".Localize() : "Expand Width".Localize(), }; expandBarButton.Click += (s, e) => UiThread.RunOnIdle(async () => @@ -201,6 +205,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow favoritesBar.ListContentView.BoundsChanged += UpdateWidth; expandBarButton.SetIcon(expanded ? collapsedImage : expandedImage); expandBarButton.Invalidate(); + expandBarButton.ToolTipText = expanded ? "Reduced Width".Localize() : "Expand Width".Localize(); await favoritesBar.Reload(); UpdateWidth(favoritesBar.ListContentView, null);