diff --git a/MatterControlLib/ApplicationView/ApplicationController.cs b/MatterControlLib/ApplicationView/ApplicationController.cs index edfe15e10..1506d3d6b 100644 --- a/MatterControlLib/ApplicationView/ApplicationController.cs +++ b/MatterControlLib/ApplicationView/ApplicationController.cs @@ -1154,9 +1154,9 @@ namespace MatterHackers.MatterControl { var selectedItem = scene.SelectedItem; scene.SelectedItem = null; - var scale = new RotateObject3D_2(); - scale.WrapItem(selectedItem, scene.UndoBuffer); - scene.SelectedItem = scale; + var rotate = new RotateObject3D_2(); + rotate.WrapItem(selectedItem, scene.UndoBuffer); + scene.SelectedItem = rotate; return Task.CompletedTask; }, diff --git a/MatterControlLib/DesignTools/Operations/RotateObject3D_2.cs b/MatterControlLib/DesignTools/Operations/RotateObject3D_2.cs index 2defa8e69..cd270fcf9 100644 --- a/MatterControlLib/DesignTools/Operations/RotateObject3D_2.cs +++ b/MatterControlLib/DesignTools/Operations/RotateObject3D_2.cs @@ -37,6 +37,7 @@ using MatterHackers.VectorMath; using Newtonsoft.Json; using System.ComponentModel; using System.Linq; +using System.Threading.Tasks; namespace MatterHackers.MatterControl.DesignTools.Operations { @@ -72,7 +73,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations public override bool CanFlatten => true; #region // editable properties - public DirectionAxis RotateAbout { get; set; } = new DirectionAxis() { Origin = Vector3.NegativeInfinity, Normal = Vector3.UnitZ }; + public DirectionAxis RotateAbout { get; set; } = new DirectionAxis() { Origin = Vector3.Zero, Normal = Vector3.UnitZ }; [DisplayName("Angle")] public double AngleDegrees { get; set; } = 0; #endregion @@ -101,31 +102,27 @@ namespace MatterHackers.MatterControl.DesignTools.Operations } } - public override void OnInvalidate(InvalidateArgs invalidateType) + public override void OnInvalidate(InvalidateArgs invalidateArgs) { - if ((invalidateType.InvalidateType == InvalidateType.Content - || invalidateType.InvalidateType == InvalidateType.Matrix - || invalidateType.InvalidateType == InvalidateType.Mesh) - && invalidateType.Source != this + if ((invalidateArgs.InvalidateType == InvalidateType.Content + || invalidateArgs.InvalidateType == InvalidateType.Matrix + || invalidateArgs.InvalidateType == InvalidateType.Mesh) + && invalidateArgs.Source != this && !RebuildLocked) { - Rebuild(null); + Rebuild(); } - else if (invalidateType.InvalidateType == InvalidateType.Properties - && invalidateType.Source == this) + else if (invalidateArgs.InvalidateType == InvalidateType.Properties + && invalidateArgs.Source == this) { - Rebuild(null); - } - else - { - base.OnInvalidate(invalidateType); + Rebuild(); } + + base.OnInvalidate(invalidateArgs); } - private void Rebuild(UndoBuffer undoBuffer) + public override Task Rebuild() { - this.DebugDepth("Rebuild"); - using (RebuildLock()) { // set the matrix for the inner object @@ -133,6 +130,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations } Invalidate(new InvalidateArgs(this, InvalidateType.Matrix, null)); + + return Task.CompletedTask; } } } \ No newline at end of file diff --git a/MatterControlLib/DesignTools/Operations/ScaleObject3D.cs b/MatterControlLib/DesignTools/Operations/ScaleObject3D.cs index f39cb6a86..d46e23f92 100644 --- a/MatterControlLib/DesignTools/Operations/ScaleObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/ScaleObject3D.cs @@ -38,6 +38,7 @@ using Newtonsoft.Json; using System; using System.ComponentModel; using System.Linq; +using System.Threading.Tasks; namespace MatterHackers.MatterControl.DesignTools.Operations { @@ -190,23 +191,19 @@ namespace MatterHackers.MatterControl.DesignTools.Operations && invalidateArgs.Source != this && !RebuildLocked) { - Rebuild(null); + Rebuild(); } else if (invalidateArgs.InvalidateType == InvalidateType.Properties && invalidateArgs.Source == this) { - Rebuild(invalidateArgs.UndoBuffer); - } - else - { - base.OnInvalidate(invalidateArgs); + Rebuild(); } + + base.OnInvalidate(invalidateArgs); } - private void Rebuild(UndoBuffer undoBuffer) + public override Task Rebuild() { - this.DebugDepth("Rebuild"); - using (RebuildLock()) { // set the matrix for the transform object @@ -217,6 +214,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations } Invalidate(new InvalidateArgs(this, InvalidateType.Matrix, null)); + + return Task.CompletedTask; } public void UpdateControls(PublicPropertyChange change) @@ -255,7 +254,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations break; } ScaleRatio = new Vector3(scale, scale, scale); - Rebuild(null); + Rebuild(); } else if(change.Changed == nameof(UsePercentage)) { @@ -268,8 +267,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations { var maxScale = Math.Max(ScaleRatio.X, Math.Max(ScaleRatio.Y, ScaleRatio.Z)); ScaleRatio = new Vector3(maxScale, maxScale, maxScale); - Rebuild(null); - base.OnInvalidate(new InvalidateArgs(this, InvalidateType.Properties)); + Rebuild(); } } else if (change.Changed == nameof(SizeX)) @@ -279,8 +277,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations // scale y and z to match ScaleRatio[1] = ScaleRatio[0]; ScaleRatio[2] = ScaleRatio[0]; - Rebuild(null); - base.OnInvalidate(new InvalidateArgs(this, InvalidateType.Properties)); + Rebuild(); } } else if (change.Changed == nameof(SizeY)) @@ -290,8 +287,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations // scale y and z to match ScaleRatio[0] = ScaleRatio[1]; ScaleRatio[2] = ScaleRatio[1]; - Rebuild(null); - base.OnInvalidate(new InvalidateArgs(this, InvalidateType.Properties)); + Rebuild(); } } else if (change.Changed == nameof(SizeZ)) @@ -301,8 +297,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations // scale y and z to match ScaleRatio[0] = ScaleRatio[2]; ScaleRatio[1] = ScaleRatio[2]; - Rebuild(null); - base.OnInvalidate(new InvalidateArgs(this, InvalidateType.Properties)); + Rebuild(); } } } diff --git a/MatterControlLib/DesignTools/Primitives/TextObject3D.cs b/MatterControlLib/DesignTools/Primitives/TextObject3D.cs index e082119f3..cd09b7acc 100644 --- a/MatterControlLib/DesignTools/Primitives/TextObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/TextObject3D.cs @@ -112,7 +112,6 @@ namespace MatterHackers.MatterControl.DesignTools { return Task.Run((System.Action)(() => { - (this).DebugDepth("Rebuild"); using (RebuildLock()) { var aabb = (this).GetAxisAlignedBoundingBox(); diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 0b9244734..c9136949a 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 0b924473448ea12f9b3f47523d58b9155383fdd5 +Subproject commit c9136949a147eee728294b80aeb752432cf3222d diff --git a/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs b/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs index cc267d97e..3b588d5ad 100644 --- a/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs @@ -449,6 +449,67 @@ namespace MatterControl.Tests.MatterControl } } + [Test, Category("InteractiveScene")] + public void ScaleAndRotateMantainsCorrectAabb() + { + { + // create a simple cube with translation + var root = new Object3D(); + var cube = new CubeObject3D(20, 20, 20); + cube.Matrix = Matrix4X4.CreateTranslation(50, 60, 10); + root.Children.Add(cube); + Assert.AreEqual(2, root.DescendantsAndSelf().Count()); + var preScaleAabb = root.GetAxisAlignedBoundingBox(); + + // add a scale to it (that is not scaled) + var scaleObject = new ScaleObject3D(cube); + + // ensure that the object did not move + Assert.IsTrue(scaleObject.ScaleAbout.Equals(Vector3.Zero), "The objects have been moved to be scalling about 0."); + Assert.AreEqual(4, root.DescendantsAndSelf().Count()); + var postScaleAabb = root.GetAxisAlignedBoundingBox(); + + Assert.IsTrue(preScaleAabb.Equals(postScaleAabb, .001)); + + Assert.AreEqual(cube, scaleObject.SourceItem, "There is no undo buffer, there should not have been a clone"); + + var rotateScaleObject = new RotateObject3D_2(cube); + // ensure that the object did not move + Assert.AreEqual(6, root.DescendantsAndSelf().Count()); + var postRotateScaleAabb = root.GetAxisAlignedBoundingBox(); + + Assert.IsTrue(preScaleAabb.Equals(postRotateScaleAabb, .001)); + + Assert.AreEqual(cube, rotateScaleObject.SourceItem, "There is no undo buffer, there should not have been a clone"); + } + } + + [Test, Category("InteractiveScene")] + public void RotateMantainsCorrectAabb() + { + { + // create a simple cube with translation + var root = new Object3D(); + var cube = new CubeObject3D(20, 20, 20); + cube.Matrix = Matrix4X4.CreateTranslation(50, 60, 10); + root.Children.Add(cube); + Assert.AreEqual(2, root.DescendantsAndSelf().Count()); + var preRotateAabb = root.GetAxisAlignedBoundingBox(); + + // add a rotate to it (that is not rotated) + var rotateObject = new RotateObject3D_2(cube); + + // ensure that the object did not move + Assert.IsTrue(rotateObject.RotateAbout.Origin.Equals(new Vector3(50, 60, 10))); + Assert.AreEqual(4, root.DescendantsAndSelf().Count()); + var postRotateAabb = root.GetAxisAlignedBoundingBox(); + + Assert.IsTrue(preRotateAabb.Equals(postRotateAabb, .001)); + + Assert.AreEqual(cube, rotateObject.SourceItem, "There is no undo buffer, there should not have been a clone"); + } + } + [Test, Category("InteractiveScene")] public void AabbCalculatedCorrectlyForCurvedFitObjects() {