diff --git a/MatterControlLib/ApplicationView/ApplicationController.cs b/MatterControlLib/ApplicationView/ApplicationController.cs index d1d9a08fc..90ce75021 100644 --- a/MatterControlLib/ApplicationView/ApplicationController.cs +++ b/MatterControlLib/ApplicationView/ApplicationController.cs @@ -786,12 +786,13 @@ namespace MatterHackers.MatterControl { var scene = sceneContext.Scene; var selectedItem = scene.SelectedItem; - scene.SelectedItem = null; - var fit = FitToBoundsObject3D_2.Create(selectedItem.Clone()); - fit.MakeNameNonColliding(); + using (new SelectionMaintainer(scene)) + { + var fit = FitToBoundsObject3D_2.Create(selectedItem.Clone()); + fit.MakeNameNonColliding(); - scene.UndoBuffer.AddAndDo(new ReplaceCommand(new[] { selectedItem }, new[] { fit })); - scene.SelectedItem = fit; + scene.UndoBuffer.AddAndDo(new ReplaceCommand(new[] { selectedItem }, new[] { fit })); + } }, Icon = AggContext.StaticData.LoadIcon("fit.png", 16, 16, theme.InvertIcons), IsEnabled = (scene) => scene.SelectedItem != null && !(scene.SelectedItem is SelectionGroupObject3D), @@ -1149,11 +1150,11 @@ namespace MatterHackers.MatterControl ResultType = typeof(TranslateObject3D), Operation = (sceneItem, scene) => { - var selectedItem = scene.SelectedItem; - scene.SelectedItem = null; - var scale = new TranslateObject3D(); - scale.WrapItem(selectedItem, scene.UndoBuffer); - scene.SelectedItem = scale; + using (new SelectionMaintainer(scene)) + { + var scale = new TranslateObject3D(); + scale.WrapItem(sceneItem, scene.UndoBuffer); + } return Task.CompletedTask; }, @@ -1169,11 +1170,11 @@ namespace MatterHackers.MatterControl ResultType = typeof(RotateObject3D_2), Operation = (sceneItem, scene) => { - var selectedItem = scene.SelectedItem; - scene.SelectedItem = null; - var rotate = new RotateObject3D_2(); - rotate.WrapItem(selectedItem, scene.UndoBuffer); - scene.SelectedItem = rotate; + using (new SelectionMaintainer(scene)) + { + var rotate = new RotateObject3D_2(); + rotate.WrapItem(sceneItem, scene.UndoBuffer); + } return Task.CompletedTask; }, @@ -1261,10 +1262,10 @@ namespace MatterHackers.MatterControl OperationID = "Mirror", Title = "Mirror".Localize(), MappedTypes = new List { typeof(IObject3D) }, - ResultType = typeof(MirrorObject3D), + ResultType = typeof(MirrorObject3D_2), Operation = (sceneItem, scene) => { - var mirror = new MirrorObject3D(); + var mirror = new MirrorObject3D_2(); mirror.WrapSelectedItemAndSelect(scene); return Task.CompletedTask; diff --git a/MatterControlLib/DesignTools/Operations/MirrorObject3D.cs b/MatterControlLib/DesignTools/Obsolete/MirrorObject3D.cs similarity index 100% rename from MatterControlLib/DesignTools/Operations/MirrorObject3D.cs rename to MatterControlLib/DesignTools/Obsolete/MirrorObject3D.cs diff --git a/MatterControlLib/DesignTools/Operations/CurveObject3D_2.cs b/MatterControlLib/DesignTools/Operations/CurveObject3D_2.cs index 143da777c..27883b9c7 100644 --- a/MatterControlLib/DesignTools/Operations/CurveObject3D_2.cs +++ b/MatterControlLib/DesignTools/Operations/CurveObject3D_2.cs @@ -110,6 +110,7 @@ namespace MatterHackers.MatterControl.DesignTools public override Task Rebuild() { this.DebugDepth("Rebuild"); + bool propertyUpdated = Diameter == double.MinValue; if (StartPercent < 0 || StartPercent > 100) diff --git a/MatterControlLib/DesignTools/Operations/MirrorObject3D_2.cs b/MatterControlLib/DesignTools/Operations/MirrorObject3D_2.cs new file mode 100644 index 000000000..de84d8522 --- /dev/null +++ b/MatterControlLib/DesignTools/Operations/MirrorObject3D_2.cs @@ -0,0 +1,134 @@ +/* +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.Threading; +using System.Threading.Tasks; +using MatterHackers.DataConverters3D; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.DesignTools.Operations; +using MatterHackers.MatterControl.PartPreviewWindow.View3D; +using MatterHackers.PolygonMesh; +using MatterHackers.VectorMath; + +namespace MatterHackers.MatterControl.DesignTools +{ + public class MirrorObject3D_2 : OperationSourceContainerObject3D + { + public MirrorObject3D_2() + { + Name = "Mirror".Localize(); + } + + public enum MirrorAxis { X_Axis, Y_Axis, Z_Axis }; + + public MirrorAxis MirrorOn { get; set; } = MirrorAxis.X_Axis; + + public override async void OnInvalidate(InvalidateArgs invalidateType) + { + if ((invalidateType.InvalidateType == InvalidateType.Content + || invalidateType.InvalidateType == InvalidateType.Matrix + || invalidateType.InvalidateType == InvalidateType.Mesh) + && invalidateType.Source != this + && !RebuildLocked) + { + await Rebuild(); + invalidateType = new InvalidateArgs(this, InvalidateType.Content); + } + else if (invalidateType.InvalidateType == InvalidateType.Properties + && invalidateType.Source == this) + { + await Rebuild(); + invalidateType = new InvalidateArgs(this, InvalidateType.Content); + } + + base.OnInvalidate(invalidateType); + } + + public override Task Rebuild() + { + this.DebugDepth("Rebuild"); + + var rebuildLock = this.RebuildLock(); + + return ApplicationController.Instance.Tasks.Execute( + "Mirror".Localize(), + null, + (reporter, cancellationToken) => + { + SourceContainer.Visible = true; + RemoveAllButSource(); + + var oldMatrix = this.Matrix; + this.Matrix = Matrix4X4.Identity; + + var mirrorMatrix = Matrix4X4.Identity; + switch (MirrorOn) + { + case MirrorAxis.X_Axis: + mirrorMatrix = this.ApplyAtBoundsCenter(Matrix4X4.CreateScale(-1, 1, 1)); + break; + + case MirrorAxis.Y_Axis: + mirrorMatrix = this.ApplyAtBoundsCenter(Matrix4X4.CreateScale(1, -1, 1)); + break; + + case MirrorAxis.Z_Axis: + mirrorMatrix = this.ApplyAtBoundsCenter(Matrix4X4.CreateScale(1, 1, -1)); + break; + } + + foreach (var sourceItem in SourceContainer.VisibleMeshes()) + { + var originalMesh = sourceItem.Mesh; + var transformedMesh = originalMesh.Copy(CancellationToken.None); + + var sourceToThisMatrix = sourceItem.WorldMatrix(this); + + // move it to us then mirror then move it back + transformedMesh.Transform(sourceToThisMatrix * mirrorMatrix * sourceToThisMatrix.Inverted); + + transformedMesh.ReverseFaces(); + + var newMesh = new Object3D() + { + Mesh = transformedMesh + }; + newMesh.CopyWorldProperties(sourceItem, this, Object3DPropertyFlags.All); + this.Children.Add(newMesh); + } + + this.Matrix = oldMatrix; + SourceContainer.Visible = false; + rebuildLock.Dispose(); + return Task.CompletedTask; + }); + } + } +} \ No newline at end of file diff --git a/MatterControlLib/DesignTools/Operations/OperationSourceObject3D.cs b/MatterControlLib/DesignTools/Operations/OperationSourceObject3D.cs index 3c86b9865..0faade512 100644 --- a/MatterControlLib/DesignTools/Operations/OperationSourceObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/OperationSourceObject3D.cs @@ -208,11 +208,13 @@ namespace MatterHackers.MatterControl.DesignTools.Operations new List { this })); await this.Rebuild(); - - // and select this - scene.SelectedItem = this; } } + + // and select this + scene.SelectedItem = this; + + this.Invalidate(new InvalidateArgs(this, InvalidateType.Content)); } } diff --git a/MatterControlLib/DesignTools/Primitives/TextObject3D.cs b/MatterControlLib/DesignTools/Primitives/TextObject3D.cs index cb89495dd..10c0ec6ef 100644 --- a/MatterControlLib/DesignTools/Primitives/TextObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/TextObject3D.cs @@ -110,9 +110,14 @@ namespace MatterHackers.MatterControl.DesignTools public override Task Rebuild() { - return Task.Run((System.Action)(() => - { - using (RebuildLock()) + this.DebugDepth("Rebuild"); + + var rebuildLock = RebuildLock(); + + return ApplicationController.Instance.Tasks.Execute( + "Mirror".Localize(), + null, + (reporter, cancellationToken) => { var aabb = (this).GetAxisAlignedBoundingBox(); @@ -146,8 +151,10 @@ namespace MatterHackers.MatterControl.DesignTools // If the part was already created and at a height, maintain the height. PlatingHelper.PlaceMeshAtHeight(this, (double)aabb.MinXYZ.Z); } - } - })); + + rebuildLock.Dispose(); + return Task.CompletedTask; + }); } } } \ No newline at end of file diff --git a/Submodules/MatterSlice b/Submodules/MatterSlice index 6255d2b5e..87ca9b3af 160000 --- a/Submodules/MatterSlice +++ b/Submodules/MatterSlice @@ -1 +1 @@ -Subproject commit 6255d2b5e0e17930db124efa20473710ebd369f7 +Subproject commit 87ca9b3afa0fa4f0effe7eba4930c0497d2daaa0 diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 045286c0b..0b872ee19 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 045286c0b438e8af0fc102b53202bd8ca61d60a1 +Subproject commit 0b872ee19fd448a5f459982dcef5e7559405abfe