From 564e5e7bf1b9068a78e2172ce2015bc652287127 Mon Sep 17 00:00:00 2001 From: Lars Brubaker Date: Fri, 25 Jan 2019 16:46:23 -0800 Subject: [PATCH] Moved array and combine objects to new source pattern reverted align object to only align children have new combine 2 object to preserve old files --- .../ApplicationView/ApplicationController.cs | 4 +- .../DesignTools/Operations/AlignObject3D.cs | 73 +++++------ .../Operations/ArrayAdvancedObject3D.cs | 5 +- .../Operations/ArrayLinearObject3D.cs | 35 +++--- .../Operations/ArrayRadialObject3D.cs | 5 +- .../Operations/Object3DExtensions.cs | 2 +- .../Operations/OperationSourceObject3D.cs | 102 +++++++++------ .../PartPreviewWindow/Object3DTreeBuilder.cs | 9 ++ .../View3D/Actions/CombineObject3D.cs | 119 +++++++++++++++++- Submodules/agg-sharp | 2 +- .../MatterControl/InteractiveSceneTests.cs | 12 +- 11 files changed, 253 insertions(+), 115 deletions(-) diff --git a/MatterControlLib/ApplicationView/ApplicationController.cs b/MatterControlLib/ApplicationView/ApplicationController.cs index 024a3592e..ef35d7214 100644 --- a/MatterControlLib/ApplicationView/ApplicationController.cs +++ b/MatterControlLib/ApplicationView/ApplicationController.cs @@ -675,9 +675,9 @@ namespace MatterHackers.MatterControl new SceneSelectionSeparator(), new SceneSelectionOperation() { - OperationType = typeof(CombineObject3D), + OperationType = typeof(CombineObject3D_2), TitleResolver = () => "Combine".Localize(), - Action = (sceneContext) => new CombineObject3D().WrapSelectedItemAndSelect(sceneContext.Scene), + Action = (sceneContext) => new CombineObject3D_2().WrapSelectedItemAndSelect(sceneContext.Scene), Icon = AggContext.StaticData.LoadIcon("combine.png").SetPreMultiply(), IsEnabled = (scene) => { diff --git a/MatterControlLib/DesignTools/Operations/AlignObject3D.cs b/MatterControlLib/DesignTools/Operations/AlignObject3D.cs index f196dd39f..c2a625081 100644 --- a/MatterControlLib/DesignTools/Operations/AlignObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/AlignObject3D.cs @@ -94,6 +94,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations { // We need to serialize this so we can remove the arrange and get back to the objects before arranging public List OriginalChildrenBounds = new List(); + private SelectedChildren _anchorObjectSelector = new SelectedChildren(); public AlignObject3D() { @@ -154,7 +155,34 @@ namespace MatterHackers.MatterControl.DesignTools.Operations [ShowAsList] [DisplayName("Primary")] - public SelectedChildren AnchorObjectSelector { get; set; } = new SelectedChildren(); + public SelectedChildren AnchorObjectSelector + { + get + { + if (Children.Count > 0) + { + if (_anchorObjectSelector.Count != 1) + { + _anchorObjectSelector.Clear(); + _anchorObjectSelector.Add(Children.First().ID); + } + + if (!this.Children.Any(c => c.ID == _anchorObjectSelector[0])) + { + // we don't have an id of any of our current children + _anchorObjectSelector.Clear(); + _anchorObjectSelector.Add(Children.First().ID); + } + } + else + { + _anchorObjectSelector.Clear(); + } + + return _anchorObjectSelector; + } + set => _anchorObjectSelector = value; + } public bool Advanced { get; set; } = false; @@ -215,36 +243,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations { get { - if (AnchorObjectSelector.Count == 1) - { - var anchorChild = this.Children.Where(c => c.ID == AnchorObjectSelector[0]).FirstOrDefault(); - - if (anchorChild != null) - { - return anchorChild; - } - - // try to update the item if possible - var id = AnchorObjectSelector[0]; - - // check if we can set it to something better - var anchorItem = this.Descendants().Where(i => i.ID == id).FirstOrDefault(); - if (anchorItem != null) - { - // we found the item, try to walk up it to find the last object that has a mesh (probably walking up the mesh wrapper chain) - var parentThatIsChildeOfThis = anchorItem.Parents().Where(i => i.Parent == this).FirstOrDefault(); - if (parentThatIsChildeOfThis != null) - { - OriginalChildrenBounds.Clear(); - AnchorObjectSelector.Clear(); - AnchorObjectSelector.Add(parentThatIsChildeOfThis.ID); - - return parentThatIsChildeOfThis; - } - } - } - - return null; + return this.Children.Where(c => c.ID == AnchorObjectSelector[0]).FirstOrDefault(); } } @@ -254,9 +253,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations get { int index = 0; - foreach(var child in this.Children) - { - if(child == AnchorObject) + foreach (var child in this.Children) + { + if (child == AnchorObject) { return index; } @@ -330,12 +329,6 @@ namespace MatterHackers.MatterControl.DesignTools.Operations using (RebuildLock()) { - var xxx = this.Parents().FirstOrDefault(); - if(xxx != null) - { - xxx.ResetMeshWrapperMeshes(Object3DPropertyFlags.All, CancellationToken.None); - } - var aabb = this.GetAxisAlignedBoundingBox(); // TODO: check if the has code for the children diff --git a/MatterControlLib/DesignTools/Operations/ArrayAdvancedObject3D.cs b/MatterControlLib/DesignTools/Operations/ArrayAdvancedObject3D.cs index d619b2f0f..639ad29d8 100644 --- a/MatterControlLib/DesignTools/Operations/ArrayAdvancedObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/ArrayAdvancedObject3D.cs @@ -82,10 +82,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations public override async Task Rebuild() { - //let the Operation Source base rebuild first - await base.Rebuild(); - var rebuildLock = this.RebuildLock(); + SourceContainer.Visible = true; await ApplicationController.Instance.Tasks.Execute( "Advanced Array".Localize(), @@ -123,6 +121,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations lastChild = next; } }); + SourceContainer.Visible = false; rebuildLock.Dispose(); return Task.CompletedTask; }); diff --git a/MatterControlLib/DesignTools/Operations/ArrayLinearObject3D.cs b/MatterControlLib/DesignTools/Operations/ArrayLinearObject3D.cs index ffa104194..52cb33040 100644 --- a/MatterControlLib/DesignTools/Operations/ArrayLinearObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/ArrayLinearObject3D.cs @@ -27,12 +27,12 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ -using MatterHackers.Agg.UI; using MatterHackers.DataConverters3D; using MatterHackers.Localizations; using MatterHackers.MatterControl.DesignTools.EditableTypes; using MatterHackers.VectorMath; using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -75,10 +75,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations public override async Task Rebuild() { - //let the Operation Source base rebuild first - await base.Rebuild(); - var rebuildLock = this.RebuildLock(); + SourceContainer.Visible = true; await ApplicationController.Instance.Tasks.Execute( "Linear Array".Localize(), @@ -87,24 +85,27 @@ namespace MatterHackers.MatterControl.DesignTools.Operations { this.DebugDepth("Rebuild"); - var sourceContainer = SourceContainer; + var newChildren = new List(); - this.Children.Modify(list => + newChildren.Add(SourceContainer); + + var arrayItem = SourceContainer.Children.First(); + + // add in all the array items + for (int i = 0; i < Math.Max(Count, 1); i++) + { + var next = arrayItem.Clone(); + next.Matrix = arrayItem.Matrix * Matrix4X4.CreateTranslation(Direction.Normal.GetNormal() * Distance * i); + newChildren.Add(next); + } + + Children.Modify(list => { list.Clear(); - // add back in the sourceContainer - list.Add(sourceContainer); - // get the source item - var sourceItem = sourceContainer.Children.First(); - - for (int i = 0; i < Math.Max(Count, 1); i++) - { - var next = sourceItem.Clone(); - next.Matrix = sourceItem.Matrix * Matrix4X4.CreateTranslation(Direction.Normal.GetNormal() * Distance * i); - list.Add(next); - } + list.AddRange(newChildren); }); + SourceContainer.Visible = false; rebuildLock.Dispose(); return Task.CompletedTask; }); diff --git a/MatterControlLib/DesignTools/Operations/ArrayRadialObject3D.cs b/MatterControlLib/DesignTools/Operations/ArrayRadialObject3D.cs index 027ce5f80..d072a390c 100644 --- a/MatterControlLib/DesignTools/Operations/ArrayRadialObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/ArrayRadialObject3D.cs @@ -98,10 +98,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations Axis.Origin = this.GetAxisAlignedBoundingBox().Center - new Vector3(-30, 0, 0); } - //let the Operation Source base rebuild first - await base.Rebuild(); - var rebuildLock = this.RebuildLock(); + SourceContainer.Visible = true; await ApplicationController.Instance.Tasks.Execute( "Radial Array".Localize(), @@ -150,6 +148,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations list.Add(next); } }); + SourceContainer.Visible = false; rebuildLock.Dispose(); return Task.CompletedTask; }); diff --git a/MatterControlLib/DesignTools/Operations/Object3DExtensions.cs b/MatterControlLib/DesignTools/Operations/Object3DExtensions.cs index 8b768bd86..0e2ca783b 100644 --- a/MatterControlLib/DesignTools/Operations/Object3DExtensions.cs +++ b/MatterControlLib/DesignTools/Operations/Object3DExtensions.cs @@ -232,7 +232,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations public static IObject3D Plus(this IObject3D a, IObject3D b) { - var combine = new CombineObject3D(); + var combine = new CombineObject3D_2(); combine.Children.Add(a.Clone()); combine.Children.Add(b.Clone()); diff --git a/MatterControlLib/DesignTools/Operations/OperationSourceObject3D.cs b/MatterControlLib/DesignTools/Operations/OperationSourceObject3D.cs index 1f32634c8..b7495c498 100644 --- a/MatterControlLib/DesignTools/Operations/OperationSourceObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/OperationSourceObject3D.cs @@ -27,24 +27,18 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using MatterHackers.Agg.UI; using MatterHackers.DataConverters3D; +using MatterHackers.DataConverters3D.UndoCommands; using MatterHackers.Localizations; +using MatterHackers.MatterControl.PartPreviewWindow; using Newtonsoft.Json; namespace MatterHackers.MatterControl.DesignTools.Operations { - public class OperationSourceObject3D : Object3D - { - public OperationSourceObject3D() - { - Visible = false; - Name = "Source".Localize(); - } - } - public class OperationSourceContainerObject3D : Object3D { [JsonIgnore] @@ -66,12 +60,12 @@ namespace MatterHackers.MatterControl.DesignTools.Operations { foreach (var child in thisChildren) { - thisChildren.Remove(child); sourceChildren.Add(child); } }); // and then add the source container to this + thisChildren.Clear(); thisChildren.Add(sourceContainer); }); } @@ -112,37 +106,6 @@ namespace MatterHackers.MatterControl.DesignTools.Operations base.Flatten(undoBuffer); } - public override async Task Rebuild() - { - var rebuildLock = this.RebuildLock(); - - await ApplicationController.Instance.Tasks.Execute( - "Linear Array".Localize(), - null, - (reporter, cancellationToken) => - { - IObject3D sourceContainer = this.Children.FirstOrDefault(c => c is OperationSourceObject3D); - if (sourceContainer == null) - { - sourceContainer = new OperationSourceObject3D(); - - // Move first child to sourceContainer - var firstChild = this.Children.First(); - this.Children.Remove(firstChild); - sourceContainer.Children.Add(firstChild); - } - - this.Children.Modify(list => - { - list.Clear(); - list.Add(sourceContainer); - }); - - rebuildLock.Dispose(); - return Task.CompletedTask; - }); - } - public override void Remove(UndoBuffer undoBuffer) { using (this.RebuildLock()) @@ -164,5 +127,62 @@ namespace MatterHackers.MatterControl.DesignTools.Operations base.Remove(undoBuffer); } + + public void RemoveAllButSource() + { + var sourceContainer = SourceContainer; + this.Children.Modify(list => + { + list.Clear(); + list.Add(sourceContainer); + }); + } + + public void WrapSelectedItemAndSelect(InteractiveScene scene) + { + using (RebuildLock()) + { + var selectedItems = scene.GetSelectedItems(); + + if (selectedItems.Count > 0) + { + // clear the selected item + scene.SelectedItem = null; + + using (RebuildLock()) + { + var clonedItemsToAdd = new List(selectedItems.Select((i) => i.Clone())); + + Children.Modify((list) => + { + list.Clear(); + + foreach (var child in clonedItemsToAdd) + { + list.Add(child); + } + }); + } + + scene.UndoBuffer.AddAndDo( + new ReplaceCommand( + new List(selectedItems), + new List { this })); + + // and select this + scene.SelectedItem = this; + } + } + + Invalidate(new InvalidateArgs(this, InvalidateType.Properties, null)); + } + } + + public class OperationSourceObject3D : Object3D + { + public OperationSourceObject3D() + { + Name = "Source".Localize(); + } } } \ No newline at end of file diff --git a/MatterControlLib/PartPreviewWindow/Object3DTreeBuilder.cs b/MatterControlLib/PartPreviewWindow/Object3DTreeBuilder.cs index e83fad99a..2568837a7 100644 --- a/MatterControlLib/PartPreviewWindow/Object3DTreeBuilder.cs +++ b/MatterControlLib/PartPreviewWindow/Object3DTreeBuilder.cs @@ -172,6 +172,15 @@ namespace MatterHackers.MatterControl.PartPreviewWindow Source = item }; + case OperationSourceContainerObject3D operationSourceContainerObject3D: + return new ObjectView() + { + Children = item.Children.OfType().ToList(), + Name = operationSourceContainerObject3D.Name, + Source = item + }; + + default: return new ObjectView(item); } diff --git a/MatterControlLib/PartPreviewWindow/View3D/Actions/CombineObject3D.cs b/MatterControlLib/PartPreviewWindow/View3D/Actions/CombineObject3D.cs index 9c514a3d0..fa090dbde 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/Actions/CombineObject3D.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/Actions/CombineObject3D.cs @@ -37,10 +37,12 @@ using MatterHackers.Agg.UI; using MatterHackers.DataConverters3D; using MatterHackers.Localizations; using MatterHackers.MatterControl.DesignTools; +using MatterHackers.MatterControl.DesignTools.Operations; using MatterHackers.PolygonMesh; namespace MatterHackers.MatterControl.PartPreviewWindow.View3D { + [Obsolete("Use CombineObject3D_2 instead", false)] public class CombineObject3D : MeshWrapperObject3D { public CombineObject3D() @@ -65,6 +67,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D await Rebuild(); invalidateType = new InvalidateArgs(this, InvalidateType.Content, invalidateType.UndoBuffer); } + + base.OnInvalidate(invalidateType); } public override Task Rebuild() @@ -133,7 +137,120 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D { first.Mesh = result; } - item.Visible = false; + + percentCompleted += amountPerOperation; + progressStatus.Progress0To1 = percentCompleted; + reporter?.Report(progressStatus); + } + } + } + } + + public class CombineObject3D_2 : OperationSourceContainerObject3D + { + public CombineObject3D_2() + { + Name = "Combine"; + } + + 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, invalidateType.UndoBuffer); + } + else if (invalidateType.InvalidateType == InvalidateType.Properties + && invalidateType.Source == this) + { + await Rebuild(); + invalidateType = new InvalidateArgs(this, InvalidateType.Content, invalidateType.UndoBuffer); + } + + base.OnInvalidate(invalidateType); + } + + public override Task Rebuild() + { + this.DebugDepth("Rebuild"); + + var rebuildLocks = this.RebuilLockAll(); + + // spin up a task to remove holes from the objects in the group + return ApplicationController.Instance.Tasks.Execute( + "Combine".Localize(), + null, + (reporter, cancellationToken) => + { + var progressStatus = new ProgressStatus(); + reporter.Report(progressStatus); + + try + { + Combine(cancellationToken, reporter); + } + catch + { + } + + rebuildLocks.Dispose(); + return Task.CompletedTask; + }); + } + + public void Combine() + { + Combine(CancellationToken.None, null); + } + + public void Combine(CancellationToken cancellationToken, IProgress reporter) + { + SourceContainer.Visible = true; + RemoveAllButSource(); + + var participants = SourceContainer.VisibleMeshes(); + if (participants.Count() < 2) + { + if(participants.Count() == 1) + { + var newMesh = new Object3D(); + newMesh.CopyProperties(participants.First(), Object3DPropertyFlags.All); + this.Children.Add(newMesh); + } + return; + } + + var first = participants.First(); + + var totalOperations = participants.Count() - 1; + double amountPerOperation = 1.0 / totalOperations; + double percentCompleted = 0; + + ProgressStatus progressStatus = new ProgressStatus(); + foreach (var item in participants) + { + if (item != first) + { + var resultMesh = BooleanProcessing.Do(item.Mesh, item.WorldMatrix(), + first.Mesh, first.WorldMatrix(), + 0, + reporter, amountPerOperation, percentCompleted, progressStatus, cancellationToken); + + var inverse = first.WorldMatrix(); + inverse.Invert(); + resultMesh.Transform(inverse); + var resultsItem = new Object3D() + { + Mesh = resultMesh + }; + resultsItem.CopyProperties(first, Object3DPropertyFlags.All); + this.Children.Add(resultsItem); + + SourceContainer.Visible = false; percentCompleted += amountPerOperation; progressStatus.Progress0To1 = percentCompleted; diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index e71579066..51e401c16 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit e71579066f1806eab705145f894e99bdedfa6653 +Subproject commit 51e401c161849a721854774c9e081b6db1edb972 diff --git a/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs b/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs index 3b588d5ad..32c14b671 100644 --- a/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/InteractiveSceneTests.cs @@ -67,7 +67,7 @@ namespace MatterControl.Tests.MatterControl 0, -10, -10, 20, 10, 10), .001)); - var union = new CombineObject3D(); + var union = new CombineObject3D_2(); union.Children.Add(cubeA); union.Children.Add(offsetCubeB); root.Children.Add(union); @@ -92,7 +92,7 @@ namespace MatterControl.Tests.MatterControl var cubeA = new CubeObject3D(20, 20, 20); var cubeB = new CubeObject3D(20, 20, 20); - var union = new CombineObject3D(); + var union = new CombineObject3D_2(); union.Children.Add(cubeA); union.Children.Add(cubeB); root.Children.Add(union); @@ -122,7 +122,7 @@ namespace MatterControl.Tests.MatterControl var cubeB = new CubeObject3D(20, 20, 20); var offsetCubeB = new TranslateObject3D(cubeB, 10); - var combine = new CombineObject3D(); + var combine = new CombineObject3D_2(); combine.Children.Add(cubeA); combine.Children.Add(offsetCubeB); root.Children.Add(combine); @@ -161,7 +161,7 @@ namespace MatterControl.Tests.MatterControl Name = "cubeB" }; - var combine = new CombineObject3D(); + var combine = new CombineObject3D_2(); combine.Children.Add(cubeA); combine.Children.Add(cubeB); root.Children.Add(combine); @@ -194,7 +194,7 @@ namespace MatterControl.Tests.MatterControl var cubeB = new CubeObject3D(20, 20, 20); var offsetCubeB = new TranslateObject3D(cubeB, 10); - var combine = new CombineObject3D(); + var combine = new CombineObject3D_2(); combine.Children.Add(cubeA); combine.Children.Add(offsetCubeB); root.Children.Add(combine); @@ -247,7 +247,7 @@ namespace MatterControl.Tests.MatterControl group.Children.Add(cubeA); group.Children.Add(offsetCubeB); - var union = new CombineObject3D(); + var union = new CombineObject3D_2(); union.Children.Add(group); root.Children.Add(union);