diff --git a/ApplicationView/ApplicationController.cs b/ApplicationView/ApplicationController.cs index 059144a1e..74c9376e8 100644 --- a/ApplicationView/ApplicationController.cs +++ b/ApplicationView/ApplicationController.cs @@ -348,11 +348,11 @@ namespace MatterHackers.MatterControl new SceneSelectionSeparator(), new SceneSelectionOperation() { - TitleResolver = () => "Arrange".Localize(), + TitleResolver = () => "Align".Localize(), Action = (scene) => { - scene.AddSelectionAsChildren(new Arrange3D()); - if(scene.SelectedItem is Arrange3D arange) + scene.AddSelectionAsChildren(new Align3D()); + if(scene.SelectedItem is Align3D arange) { arange.Rebuild(null); } diff --git a/DesignTools/Operations/Align.cs b/DesignTools/Operations/Align3D.cs similarity index 58% rename from DesignTools/Operations/Align.cs rename to DesignTools/Operations/Align3D.cs index 85c37e1b5..72211f7d5 100644 --- a/DesignTools/Operations/Align.cs +++ b/DesignTools/Operations/Align3D.cs @@ -28,13 +28,20 @@ either expressed or implied, of the FreeBSD Project. */ using System; +using System.Collections.Generic; +using System.ComponentModel; using MatterHackers.Agg.Transform; +using MatterHackers.Agg.UI; using MatterHackers.Agg.VertexSource; using MatterHackers.DataConverters3D; using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.DesignTools.Operations { + using Aabb = AxisAlignedBoundingBox; + + public enum Align { None, Min, Center, Max } + public enum Alignment { X, Y, Z, negX, negY, negZ }; [Flags] @@ -74,109 +81,6 @@ namespace MatterHackers.MatterControl.DesignTools.Operations Top = 0x20, }; - public class Align : Object3D - { - public Align() - { - } - - public Align(IObject3D objectToAlign, Face boundingFacesToAlign, IObject3D objectToAlignTo, Face boundingFacesToAlignTo, double offsetX = 0, double offsetY = 0, double offsetZ = 0, string name = "") - : this(objectToAlign, boundingFacesToAlign, GetPositionToAlignTo(objectToAlignTo, boundingFacesToAlignTo, new Vector3(offsetX, offsetY, offsetZ)), name) - { - if (objectToAlign == objectToAlignTo) - { - throw new Exception("You cannot align an object to itself."); - } - } - - public Align(IObject3D objectToAlign, Face boundingFacesToAlign, double positionToAlignToX = 0, double positionToAlignToY = 0, double positionToAlignToZ = 0, string name = "") - : this(objectToAlign, boundingFacesToAlign, new Vector3(positionToAlignToX, positionToAlignToY, positionToAlignToZ), name) - { - } - - public Align(IObject3D objectToAlign, Face boundingFacesToAlign, Vector3 positionToAlignTo, double offsetX, double offsetY, double offsetZ, string name = "") - : this(objectToAlign, boundingFacesToAlign, positionToAlignTo + new Vector3(offsetX, offsetY, offsetZ), name) - { - } - - public Align(IObject3D item, Face boundingFacesToAlign, Vector3 positionToAlignTo, string name = "") - { - AxisAlignedBoundingBox bounds = item.GetAxisAlignedBoundingBox(); - - if (IsSet(boundingFacesToAlign, Face.Left, Face.Right)) - { - positionToAlignTo.X = positionToAlignTo.X - bounds.minXYZ.X; - } - if (IsSet(boundingFacesToAlign, Face.Right, Face.Left)) - { - positionToAlignTo.X = positionToAlignTo.X - bounds.minXYZ.X - (bounds.maxXYZ.X - bounds.minXYZ.X); - } - if (IsSet(boundingFacesToAlign, Face.Front, Face.Back)) - { - positionToAlignTo.Y = positionToAlignTo.Y - bounds.minXYZ.Y; - } - if (IsSet(boundingFacesToAlign, Face.Back, Face.Front)) - { - positionToAlignTo.Y = positionToAlignTo.Y - bounds.minXYZ.Y - (bounds.maxXYZ.Y - bounds.minXYZ.Y); - } - if (IsSet(boundingFacesToAlign, Face.Bottom, Face.Top)) - { - positionToAlignTo.Z = positionToAlignTo.Z - bounds.minXYZ.Z; - } - if (IsSet(boundingFacesToAlign, Face.Top, Face.Bottom)) - { - positionToAlignTo.Z = positionToAlignTo.Z - bounds.minXYZ.Z - (bounds.maxXYZ.Z - bounds.minXYZ.Z); - } - - Matrix *= Matrix4X4.CreateTranslation(positionToAlignTo); - Children.Add(item.Clone()); - } - - public static Vector3 GetPositionToAlignTo(IObject3D objectToAlignTo, Face boundingFacesToAlignTo, Vector3 extraOffset) - { - Vector3 positionToAlignTo = new Vector3(); - if (IsSet(boundingFacesToAlignTo, Face.Left, Face.Right)) - { - positionToAlignTo.X = objectToAlignTo.GetAxisAlignedBoundingBox().minXYZ.X; - } - if (IsSet(boundingFacesToAlignTo, Face.Right, Face.Left)) - { - positionToAlignTo.X = objectToAlignTo.GetAxisAlignedBoundingBox().maxXYZ.X; - } - if (IsSet(boundingFacesToAlignTo, Face.Front, Face.Back)) - { - positionToAlignTo.Y = objectToAlignTo.GetAxisAlignedBoundingBox().minXYZ.Y; - } - if (IsSet(boundingFacesToAlignTo, Face.Back, Face.Front)) - { - positionToAlignTo.Y = objectToAlignTo.GetAxisAlignedBoundingBox().maxXYZ.Y; - } - if (IsSet(boundingFacesToAlignTo, Face.Bottom, Face.Top)) - { - positionToAlignTo.Z = objectToAlignTo.GetAxisAlignedBoundingBox().minXYZ.Z; - } - if (IsSet(boundingFacesToAlignTo, Face.Top, Face.Bottom)) - { - positionToAlignTo.Z = objectToAlignTo.GetAxisAlignedBoundingBox().maxXYZ.Z; - } - return positionToAlignTo + extraOffset; - } - - private static bool IsSet(Face variableToCheck, Face faceToCheckFor, Face faceToAssertNot) - { - if ((variableToCheck & faceToCheckFor) != 0) - { - if ((variableToCheck & faceToAssertNot) != 0) - { - throw new Exception("You cannot have both " + faceToCheckFor.ToString() + " and " + faceToAssertNot.ToString() + " set when calling Align. The are mutually exclusive."); - } - return true; - } - - return false; - } - } - public class Align2D : VertexSourceApplyTransform { public Align2D() @@ -264,4 +168,292 @@ namespace MatterHackers.MatterControl.DesignTools.Operations return false; } } + + public class Align3D : Object3D, IRebuildable, IPropertyGridModifier + { + // We need to serialize this so we can remove the arrange and get back to the objects before arranging + public List OriginalChildrenBounds = new List(); + + public Align3D() + { + Name = "Align"; + } + + public Align3D(IObject3D objectToAlign, Face boundingFacesToAlign, IObject3D objectToAlignTo, Face boundingFacesToAlignTo, double offsetX = 0, double offsetY = 0, double offsetZ = 0, string name = "") + : this(objectToAlign, boundingFacesToAlign, GetPositionToAlignTo(objectToAlignTo, boundingFacesToAlignTo, new Vector3(offsetX, offsetY, offsetZ)), name) + { + if (objectToAlign == objectToAlignTo) + { + throw new Exception("You cannot align an object to itself."); + } + } + + public Align3D(IObject3D objectToAlign, Face boundingFacesToAlign, double positionToAlignToX = 0, double positionToAlignToY = 0, double positionToAlignToZ = 0, string name = "") + : this(objectToAlign, boundingFacesToAlign, new Vector3(positionToAlignToX, positionToAlignToY, positionToAlignToZ), name) + { + } + + public Align3D(IObject3D objectToAlign, Face boundingFacesToAlign, Vector3 positionToAlignTo, double offsetX, double offsetY, double offsetZ, string name = "") + : this(objectToAlign, boundingFacesToAlign, positionToAlignTo + new Vector3(offsetX, offsetY, offsetZ), name) + { + } + + public Align3D(IObject3D item, Face boundingFacesToAlign, Vector3 positionToAlignTo, string name = "") + { + AxisAlignedBoundingBox bounds = item.GetAxisAlignedBoundingBox(); + + if (IsSet(boundingFacesToAlign, Face.Left, Face.Right)) + { + positionToAlignTo.X = positionToAlignTo.X - bounds.minXYZ.X; + } + if (IsSet(boundingFacesToAlign, Face.Right, Face.Left)) + { + positionToAlignTo.X = positionToAlignTo.X - bounds.minXYZ.X - (bounds.maxXYZ.X - bounds.minXYZ.X); + } + if (IsSet(boundingFacesToAlign, Face.Front, Face.Back)) + { + positionToAlignTo.Y = positionToAlignTo.Y - bounds.minXYZ.Y; + } + if (IsSet(boundingFacesToAlign, Face.Back, Face.Front)) + { + positionToAlignTo.Y = positionToAlignTo.Y - bounds.minXYZ.Y - (bounds.maxXYZ.Y - bounds.minXYZ.Y); + } + if (IsSet(boundingFacesToAlign, Face.Bottom, Face.Top)) + { + positionToAlignTo.Z = positionToAlignTo.Z - bounds.minXYZ.Z; + } + if (IsSet(boundingFacesToAlign, Face.Top, Face.Bottom)) + { + positionToAlignTo.Z = positionToAlignTo.Z - bounds.minXYZ.Z - (bounds.maxXYZ.Z - bounds.minXYZ.Z); + } + + Matrix *= Matrix4X4.CreateTranslation(positionToAlignTo); + Children.Add(item.Clone()); + } + + [DisplayName("X")] + [Icons(new string[] { "424.png", "align_left.png", "align_center_x.png", "align_right.png" })] + public Align XAlign { get; set; } = Align.None; + + [DisplayName("Start X")] + [Icons(new string[] { "424.png", "align_to_left.png", "align_to_center_x.png", "align_to_right.png" })] + public Align XAlignTo { get; set; } = Align.None; + + [DisplayName("Offset X")] + public double XOffset { get; set; } = 0; + + [DisplayName("Y")] + [Icons(new string[] { "424.png", "align_bottom.png", "align_center_y.png", "align_top.png" })] + public Align YAlign { get; set; } = Align.None; + + [DisplayName("Start Y")] + [Icons(new string[] { "424.png", "align_to_bottom.png", "align_to_center_y.png", "align_to_top.png" })] + public Align YAlignTo { get; set; } = Align.None; + + [DisplayName("Offset Y")] + public double YOffset { get; set; } = 0; + + [DisplayName("Z")] + [Icons(new string[] { "424.png", "align_bottom.png", "align_center_y.png", "align_top.png" })] + public Align ZAlign { get; set; } = Align.None; + + [DisplayName("Start Z")] + [Icons(new string[] { "424.png", "align_to_bottom.png", "align_to_center_y.png", "align_to_top.png" })] + public Align ZAlignTo { get; set; } = Align.None; + + [DisplayName("Offset Z")] + public double ZOffset { get; set; } = 0; + + public bool Advanced { get; set; } = false; + + public override bool CanBake => true; + + public override bool CanRemove => true; + + private List CurrentChildrenBounds + { + get + { + List currentChildrenBounds = new List(); + this.Children.Modify(list => + { + foreach (var child in list) + { + currentChildrenBounds.Add(child.GetAxisAlignedBoundingBox()); + } + }); + + return currentChildrenBounds; + } + } + + public static Vector3 GetPositionToAlignTo(IObject3D objectToAlignTo, Face boundingFacesToAlignTo, Vector3 extraOffset) + { + Vector3 positionToAlignTo = new Vector3(); + if (IsSet(boundingFacesToAlignTo, Face.Left, Face.Right)) + { + positionToAlignTo.X = objectToAlignTo.GetAxisAlignedBoundingBox().minXYZ.X; + } + if (IsSet(boundingFacesToAlignTo, Face.Right, Face.Left)) + { + positionToAlignTo.X = objectToAlignTo.GetAxisAlignedBoundingBox().maxXYZ.X; + } + if (IsSet(boundingFacesToAlignTo, Face.Front, Face.Back)) + { + positionToAlignTo.Y = objectToAlignTo.GetAxisAlignedBoundingBox().minXYZ.Y; + } + if (IsSet(boundingFacesToAlignTo, Face.Back, Face.Front)) + { + positionToAlignTo.Y = objectToAlignTo.GetAxisAlignedBoundingBox().maxXYZ.Y; + } + if (IsSet(boundingFacesToAlignTo, Face.Bottom, Face.Top)) + { + positionToAlignTo.Z = objectToAlignTo.GetAxisAlignedBoundingBox().minXYZ.Z; + } + if (IsSet(boundingFacesToAlignTo, Face.Top, Face.Bottom)) + { + positionToAlignTo.Z = objectToAlignTo.GetAxisAlignedBoundingBox().maxXYZ.Z; + } + return positionToAlignTo + extraOffset; + } + + public void Rebuild(UndoBuffer undoBuffer) + { + var aabb = this.GetAxisAlignedBoundingBox(); + + // TODO: check if the has code for the children + if (OriginalChildrenBounds.Count == 0) + { + this.Children.Modify(list => + { + foreach (var child in list) + { + OriginalChildrenBounds.Add(child.GetAxisAlignedBoundingBox()); + } + }); + } + + var currentChildrenBounds = CurrentChildrenBounds; + this.Children.Modify(list => + { + var firstBounds = currentChildrenBounds[0]; + int i = 0; + foreach (var child in list) + { + if (i > 0) + { + if (XAlign == Align.None) + { + // make sure it is where it started + AlignAxis(0, Align.Min, currentChildrenBounds[i].minXYZ.X, 0, child); + } + else + { + AlignAxis(0, XAlign, GetAlignToOffset(currentChildrenBounds, 0, (!Advanced || XAlignTo == Align.None) ? XAlign : XAlignTo), XOffset, child); + } + if (YAlign == Align.None) + { + AlignAxis(1, Align.Min, currentChildrenBounds[i].minXYZ.Y, 0, child); + } + else + { + AlignAxis(1, YAlign, GetAlignToOffset(currentChildrenBounds, 1, (!Advanced || YAlignTo == Align.None) ? YAlign : YAlignTo), YOffset, child); + } + if (ZAlign == Align.None) + { + AlignAxis(2, Align.Min, currentChildrenBounds[i].minXYZ.Z, 0, child); + } + else + { + AlignAxis(2, ZAlign, GetAlignToOffset(currentChildrenBounds, 2, (!Advanced || ZAlignTo == Align.None) ? ZAlign : ZAlignTo), ZOffset, child); + } + } + i++; + } + }); + } + + public override void Remove() + { + // put everything back to where it was before the arange started + if (OriginalChildrenBounds.Count == Children.Count) + { + int i = 0; + foreach (var child in Children) + { + // Where you are minus where you started to get back to where you started + child.Translate(-(child.GetAxisAlignedBoundingBox().minXYZ - OriginalChildrenBounds[i].minXYZ)); + i++; + } + } + + base.Remove(); + } + + public void UpdateControls(PublicPropertyEditor editor) + { + editor.GetEditRow(nameof(XAlignTo)).Visible = Advanced; + editor.GetEditRow(nameof(XOffset)).Visible = Advanced; + editor.GetEditRow(nameof(YAlignTo)).Visible = Advanced; + editor.GetEditRow(nameof(YOffset)).Visible = Advanced; + editor.GetEditRow(nameof(ZAlignTo)).Visible = Advanced; + editor.GetEditRow(nameof(ZOffset)).Visible = Advanced; + } + + private static bool IsSet(Face variableToCheck, Face faceToCheckFor, Face faceToAssertNot) + { + if ((variableToCheck & faceToCheckFor) != 0) + { + if ((variableToCheck & faceToAssertNot) != 0) + { + throw new Exception("You cannot have both " + faceToCheckFor.ToString() + " and " + faceToAssertNot.ToString() + " set when calling Align. The are mutually exclusive."); + } + return true; + } + + return false; + } + + private void AlignAxis(int axis, Align align, double alignTo, double offset, + IObject3D item) + { + var aabb = item.GetAxisAlignedBoundingBox(); + var translate = Vector3.Zero; + + switch (align) + { + case Align.Min: + translate[axis] = alignTo - aabb.minXYZ[axis] + offset; + break; + + case Align.Center: + translate[axis] = alignTo - aabb.Center[axis] + offset; + break; + + case Align.Max: + translate[axis] = alignTo - aabb.maxXYZ[axis] + offset; + break; + } + + item.Translate(translate); + } + + private double GetAlignToOffset(List currentChildrenBounds, int axis, Align alignTo) + { + switch (alignTo) + { + case Align.Min: + return currentChildrenBounds[0].minXYZ[axis]; + + case Align.Center: + return currentChildrenBounds[0].Center[axis]; + + case Align.Max: + return currentChildrenBounds[0].maxXYZ[axis]; + + default: + throw new NotImplementedException(); + } + } + } } \ No newline at end of file diff --git a/DesignTools/Operations/Arrange3D.cs b/DesignTools/Operations/Arrange3D.cs deleted file mode 100644 index 689d86393..000000000 --- a/DesignTools/Operations/Arrange3D.cs +++ /dev/null @@ -1,234 +0,0 @@ -/* -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 MatterHackers.Agg.UI; -using MatterHackers.DataConverters3D; -using MatterHackers.Localizations; -using MatterHackers.VectorMath; - -namespace MatterHackers.MatterControl.DesignTools.Operations -{ - using Aabb = AxisAlignedBoundingBox; - - public class Arrange3D : Object3D, IRebuildable, IPropertyGridModifier - { - // We need to serialize this so we can remove the arrange and get back to the objects before arranging - public List OriginalChildrenBounds = new List(); - List CurrentChildrenBounds - { - get - { - List currentChildrenBounds = new List(); - this.Children.Modify(list => - { - foreach (var child in list) - { - currentChildrenBounds.Add(child.GetAxisAlignedBoundingBox()); - } - }); - - return currentChildrenBounds; - } - } - - public Arrange3D() - { - Name = "Arrange".Localize(); - } - - public enum Align { None, Min, Center, Max } - - public override bool CanBake => true; - - public override bool CanRemove => true; - - [DisplayName("X")] - [Icons(new string[] { "424.png", "align_left.png", "align_center_x.png", "align_right.png" })] - public Align XAlign { get; set; } = Align.None; - - [DisplayName("Start X")] - [Icons(new string[] { "424.png", "align_to_left.png", "align_to_center_x.png", "align_to_right.png" })] - public Align XAlignTo { get; set; } = Align.None; - - [DisplayName("Offset X")] - public double XOffset { get; set; } = 0; - - [DisplayName("Y")] - [Icons(new string[] { "424.png", "align_bottom.png", "align_center_y.png", "align_top.png" })] - public Align YAlign { get; set; } = Align.None; - - [DisplayName("Start Y")] - [Icons(new string[] { "424.png", "align_to_bottom.png", "align_to_center_y.png", "align_to_top.png" })] - public Align YAlignTo { get; set; } = Align.None; - - [DisplayName("Offset Y")] - public double YOffset { get; set; } = 0; - - [DisplayName("Z")] - [Icons(new string[] { "424.png", "align_bottom.png", "align_center_y.png", "align_top.png" })] - public Align ZAlign { get; set; } = Align.None; - - [DisplayName("Start Z")] - [Icons(new string[] { "424.png", "align_to_bottom.png", "align_to_center_y.png", "align_to_top.png" })] - public Align ZAlignTo { get; set; } = Align.None; - - [DisplayName("Offset Z")] - public double ZOffset { get; set; } = 0; - - public bool Advanced { get; set; } = false; - - public void Rebuild(UndoBuffer undoBuffer) - { - var aabb = this.GetAxisAlignedBoundingBox(); - - // TODO: check if the has code for the children - if (OriginalChildrenBounds.Count == 0) - { - this.Children.Modify(list => - { - foreach (var child in list) - { - OriginalChildrenBounds.Add(child.GetAxisAlignedBoundingBox()); - } - }); - } - - var currentChildrenBounds = CurrentChildrenBounds; - this.Children.Modify(list => - { - var firstBounds = currentChildrenBounds[0]; - int i = 0; - foreach (var child in list) - { - if (i > 0) - { - if (XAlign == Align.None) - { - // make sure it is where it started - AlignAxis(0, Align.Min, currentChildrenBounds[i].minXYZ.X, 0, child); - } - else - { - AlignAxis(0, XAlign, GetAlignToOffset(currentChildrenBounds, 0, (!Advanced || XAlignTo == Align.None) ? XAlign : XAlignTo), XOffset, child); - } - if (YAlign == Align.None) - { - AlignAxis(1, Align.Min, currentChildrenBounds[i].minXYZ.Y, 0, child); - } - else - { - AlignAxis(1, YAlign, GetAlignToOffset(currentChildrenBounds, 1, (!Advanced || YAlignTo == Align.None) ? YAlign : YAlignTo), YOffset, child); - } - if (ZAlign == Align.None) - { - AlignAxis(2, Align.Min, currentChildrenBounds[i].minXYZ.Z, 0, child); - } - else - { - AlignAxis(2, ZAlign, GetAlignToOffset(currentChildrenBounds, 2, (!Advanced || ZAlignTo == Align.None) ? ZAlign : ZAlignTo), ZOffset, child); - } - } - i++; - } - }); - } - - public override void Remove() - { - // put everything back to where it was before the arange started - if (OriginalChildrenBounds.Count == Children.Count) - { - int i = 0; - foreach (var child in Children) - { - // Where you are minus where you started to get back to where you started - child.Translate(-(child.GetAxisAlignedBoundingBox().minXYZ - OriginalChildrenBounds[i].minXYZ)); - i++; - } - } - - base.Remove(); - } - - public void UpdateControls(PublicPropertyEditor editor) - { - editor.GetEditRow(nameof(XAlignTo)).Visible = Advanced; - editor.GetEditRow(nameof(XOffset)).Visible = Advanced; - editor.GetEditRow(nameof(YAlignTo)).Visible = Advanced; - editor.GetEditRow(nameof(YOffset)).Visible = Advanced; - editor.GetEditRow(nameof(ZAlignTo)).Visible = Advanced; - editor.GetEditRow(nameof(ZOffset)).Visible = Advanced; - } - - private void AlignAxis(int axis, Align align, double alignTo, double offset, - IObject3D item) - { - var aabb = item.GetAxisAlignedBoundingBox(); - var translate = Vector3.Zero; - - switch (align) - { - case Align.Min: - translate[axis] = alignTo - aabb.minXYZ[axis] + offset; - break; - - case Align.Center: - translate[axis] = alignTo - aabb.Center[axis] + offset; - break; - - case Align.Max: - translate[axis] = alignTo - aabb.maxXYZ[axis] + offset; - break; - } - - item.Translate(translate); - } - - private double GetAlignToOffset(List currentChildrenBounds, int axis, Align alignTo) - { - switch (alignTo) - { - case Align.Min: - return currentChildrenBounds[0].minXYZ[axis]; - - case Align.Center: - return currentChildrenBounds[0].Center[axis]; - - case Align.Max: - return currentChildrenBounds[0].maxXYZ[axis]; - - default: - throw new NotImplementedException(); - } - } - } -} \ No newline at end of file diff --git a/DesignTools/Operations/FitToBounds3D.cs b/DesignTools/Operations/FitToBounds3D.cs index c7e8067f5..e9961b935 100644 --- a/DesignTools/Operations/FitToBounds3D.cs +++ b/DesignTools/Operations/FitToBounds3D.cs @@ -60,6 +60,41 @@ namespace MatterHackers.MatterControl.DesignTools.Operations { } + public override void Bake() + { + // push our matrix into our children + foreach (var child in this.Children) + { + child.Matrix *= this.Matrix; + } + + // push child into children + ItemToScale.Matrix *= ScaleItem.Matrix; + + // add our children to our parent and remove from parent + this.Parent.Children.Modify(list => + { + list.Remove(this); + list.AddRange(ScaleItem.Children); + }); + } + + public override void Remove() + { + // push our matrix into inner children + foreach (var child in ScaleItem.Children) + { + child.Matrix *= this.Matrix; + } + + // add inner children to our parent and remove from parent + this.Parent.Children.Modify(list => + { + list.Remove(this); + list.AddRange(ScaleItem.Children); + }); + } + protected override void OnInvalidate() { // If the child bounds changed than adjust the scale control diff --git a/DesignTools/Operations/Package3D.cs b/DesignTools/Operations/Package3D.cs index 81268d0b6..dca900c97 100644 --- a/DesignTools/Operations/Package3D.cs +++ b/DesignTools/Operations/Package3D.cs @@ -48,7 +48,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations fit.Rebuild(null); } - var align = this.Descendants().FirstOrDefault(); + var align = this.Descendants().FirstOrDefault(); if (align != null) { align.Rebuild(null); diff --git a/MatterControl.csproj b/MatterControl.csproj index 82e4f5a25..e5a6c7e17 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -95,14 +95,13 @@ - + - diff --git a/TextCreator/Braille/BrailleCardObject3D.cs b/TextCreator/Braille/BrailleCardObject3D.cs index 56d904239..c9626d791 100644 --- a/TextCreator/Braille/BrailleCardObject3D.cs +++ b/TextCreator/Braille/BrailleCardObject3D.cs @@ -91,7 +91,7 @@ namespace MatterHackers.MatterControl.DesignTools }; textObject.Rebuild(null); IObject3D letterObject = new Rotate(textObject, -MathHelper.Tau / 4); - letterObject = new Align(letterObject, Face.Bottom | Face.Front, brailleLetter, Face.Top | Face.Front, 0, 0, 3.5); + letterObject = new Align3D(letterObject, Face.Bottom | Face.Front, brailleLetter, Face.Top | Face.Front, 0, 0, 3.5); letterObject = new SetCenter(letterObject, brailleLetter.GetCenter(), true, false, false); this.Children.Add(letterObject); @@ -106,13 +106,13 @@ namespace MatterHackers.MatterControl.DesignTools Matrix = Matrix4X4.CreateRotationX(MathHelper.Tau / 4) }; - basePlate = new Align(basePlate, Face.Bottom | Face.Back, brailleLetter, Face.Bottom | Face.Back); + basePlate = new Align3D(basePlate, Face.Bottom | Face.Back, brailleLetter, Face.Bottom | Face.Back); basePlate = new SetCenter(basePlate, brailleLetter.GetCenter(), true, false, false); this.Children.Add(basePlate); IObject3D underline = new CubeObject3D(basePlate.XSize(), .2, 1); - underline = new Align(underline, Face.Bottom, brailleLetter, Face.Top); - underline = new Align(underline, Face.Back | Face.Left, basePlate, Face.Front | Face.Left, 0, .01); + underline = new Align3D(underline, Face.Bottom, brailleLetter, Face.Top); + underline = new Align3D(underline, Face.Back | Face.Left, basePlate, Face.Front | Face.Left, 0, .01); this.Children.Add(underline); if (aabb.ZSize > 0) diff --git a/TextCreator/Braille/BrailleObject3D.cs b/TextCreator/Braille/BrailleObject3D.cs index df461005e..480b42228 100644 --- a/TextCreator/Braille/BrailleObject3D.cs +++ b/TextCreator/Braille/BrailleObject3D.cs @@ -194,8 +194,8 @@ namespace MatterHackers.MatterControl.DesignTools Mesh = VertexSourceToMesh.Extrude(basePath, BaseHeight) }; - basePlate = new Align(basePlate, Face.Top, textObject, Face.Bottom, 0, 0, .01); - basePlate = new Align(basePlate, Face.Left | Face.Front, + basePlate = new Align3D(basePlate, Face.Top, textObject, Face.Bottom, 0, 0, .01); + basePlate = new Align3D(basePlate, Face.Left | Face.Front, size.Left - padding/2, size.Bottom - padding/2); this.Children.Add(basePlate); @@ -234,7 +234,7 @@ namespace MatterHackers.MatterControl.DesignTools Matrix = Matrix4X4.CreateRotationX(MathHelper.Tau / 4) }; - chainHook = new Align(chainHook, Face.Left | Face.Bottom | Face.Back, basePlate, Face.Right | Face.Bottom | Face.Back, -.01); + chainHook = new Align3D(chainHook, Face.Left | Face.Bottom | Face.Back, basePlate, Face.Right | Face.Bottom | Face.Back, -.01); this.Children.Add(chainHook); }