Working on new circular fit to bounds

refactoring Transform Wrapper Object
This commit is contained in:
Lars Brubaker 2019-02-08 13:05:04 -08:00
parent e96f7c0fdf
commit d0430bed92
9 changed files with 136 additions and 109 deletions

View file

@ -42,7 +42,7 @@ using System.Threading.Tasks;
namespace MatterHackers.MatterControl.DesignTools.Operations
{
public class FitToBoundsObject3D_2 : TransformWrapperObject3D, IEditorDraw
public class FitToBoundsObject3D_2 : TransformWrapperObject3D, IEditorDraw, IPropertyGridModifier
{
private Vector3 boundsSize;
@ -60,6 +60,72 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
private IObject3D FitBounds => Children.Last();
#region // editable properties
[Description("Set the shape the part will be fit into.")]
public FitType FitType { get; set; } = FitType.Box;
[Description("Set the rules for how to maintain the part while scaling.")]
public MaintainRatio MaintainRatio { get; set; } = MaintainRatio.X_Y;
[Description("Normally the part is expanded to the cylinders. This will try to center the weight of the part in the cylinder.")]
public bool AlternateCentering { get; set; } = false;
[DisplayName("Width")]
public double SizeX
{
get => boundsSize.X;
set
{
boundsSize.X = value;
if (this.Children.Count() > 0)
{
Rebuild();
}
}
}
[DisplayName("Depth")]
public double SizeY
{
get => boundsSize.Y;
set
{
boundsSize.Y = value;
if (this.Children.Count() > 0)
{
Rebuild();
}
}
}
public double Diameter { get; set; }
[DisplayName("Height")]
public double SizeZ
{
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;
#endregion // editable properties
public static async Task<FitToBoundsObject3D_2> Create(IObject3D itemToFit)
{
var fitToBounds = new FitToBoundsObject3D_2();
@ -97,21 +163,41 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
&& layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
{
var aabb = SourceItems.GetAxisAlignedBoundingBox();
var aabb = UntransformedChildren.GetAxisAlignedBoundingBox();
if (FitType == FitType.Box)
{
var center = aabb.Center;
var worldMatrix = this.WorldMatrix();
var center = aabb.Center;
var worldMatrix = this.WorldMatrix();
var minXyz = center - new Vector3(SizeX / 2, SizeY / 2, SizeZ / 2);
var maxXyz = center + new Vector3(SizeX / 2, SizeY / 2, SizeZ / 2);
var bounds = new AxisAlignedBoundingBox(minXyz, maxXyz);
//var leftW = Vector3Ex.Transform(, worldMatrix);
var right = Vector3Ex.Transform(center + new Vector3(SizeX / 2, 0, 0), worldMatrix);
// layer.World.Render3DLine(left, right, Agg.Color.Red);
layer.World.RenderAabb(bounds, worldMatrix, Agg.Color.Red, 1, 1);
var minXyz = center - new Vector3(SizeX / 2, SizeY / 2, SizeZ / 2);
var maxXyz = center + new Vector3(SizeX / 2, SizeY / 2, SizeZ / 2);
var bounds = new AxisAlignedBoundingBox(minXyz, maxXyz);
//var leftW = Vector3Ex.Transform(, worldMatrix);
var right = Vector3Ex.Transform(center + new Vector3(SizeX / 2, 0, 0), worldMatrix);
// layer.World.Render3DLine(left, right, Agg.Color.Red);
layer.World.RenderAabb(bounds, worldMatrix, Agg.Color.Red, 1, 1);
}
else
{
layer.World.RenderCylinderOutline(this.WorldMatrix(), aabb.Center, Diameter, aabb.ZSize, 30, Color.Red, 1, 1);
}
}
}
public void UpdateControls(PublicPropertyChange change)
{
// turn on/off the stuff for cylinder
change.SetRowVisible(nameof(Diameter), () => FitType == FitType.Cylinder);
change.SetRowVisible(nameof(AlternateCentering), () => FitType == FitType.Cylinder);
// turn on/off the stuff for box
change.SetRowVisible(nameof(SizeX), () => FitType == FitType.Box);
change.SetRowVisible(nameof(SizeY), () => FitType == FitType.Box);
change.SetRowVisible(nameof(MaintainRatio), () => FitType == FitType.Box);
change.SetRowVisible(nameof(StretchX), () => FitType == FitType.Box);
change.SetRowVisible(nameof(StretchY), () => FitType == FitType.Box);
}
public override AxisAlignedBoundingBox GetAxisAlignedBoundingBox(Matrix4X4 matrix)
{
if (Children.Count == 2)
@ -188,8 +274,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
{
if (Children.Count > 0)
{
var aabb = SourceItems.GetAxisAlignedBoundingBox();
TransformItem.Matrix = Matrix4X4.Identity;
var aabb = UntransformedChildren.GetAxisAlignedBoundingBox();
ItemWithTransform.Matrix = Matrix4X4.Identity;
var scale = Vector3.One;
if (StretchX)
{
@ -223,7 +309,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
break;
}
TransformItem.Matrix = Object3DExtensions.ApplyAtPosition(TransformItem.Matrix, aabb.Center, Matrix4X4.CreateScale(scale));
ItemWithTransform.Matrix = Object3DExtensions.ApplyAtPosition(ItemWithTransform.Matrix, aabb.Center, Matrix4X4.CreateScale(scale));
}
}
@ -231,7 +317,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
{
if (Children.Count == 2)
{
var transformAabb = TransformItem.GetAxisAlignedBoundingBox();
var transformAabb = ItemWithTransform.GetAxisAlignedBoundingBox();
var fitAabb = FitBounds.GetAxisAlignedBoundingBox();
var fitSize = fitAabb.Size;
if (boundsSize.X != 0 && boundsSize.Y != 0 && boundsSize.Z != 0
@ -243,68 +329,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
boundsSize.Y / fitSize.Y,
boundsSize.Z / fitSize.Z);
FitBounds.Matrix *= Matrix4X4.CreateTranslation(
transformAabb.Center
- FitBounds.GetAxisAlignedBoundingBox().Center);
transformAabb.Center - FitBounds.GetAxisAlignedBoundingBox().Center);
}
}
}
#region // editable properties
[Description("Set the rules for how to maintain the part while scaling.")]
public MaintainRatio MaintainRatio { get; set; } = MaintainRatio.X_Y;
[DisplayName("Width")]
public double SizeX
{
get => boundsSize.X;
set
{
boundsSize.X = value;
if (this.Children.Count() > 0)
{
Rebuild();
}
}
}
[DisplayName("Depth")]
public double SizeY
{
get => boundsSize.Y;
set
{
boundsSize.Y = value;
if (this.Children.Count() > 0)
{
Rebuild();
}
}
}
[DisplayName("Height")]
public double SizeZ
{
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;
#endregion // editable properties
}
}

View file

@ -76,8 +76,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
{
base.WrapItems(items, undoBuffer);
// use source item as the wrape may have cloned it
var aabb = SourceItems.GetAxisAlignedBoundingBox();
// use source item as the wraper may have cloned it
var aabb = UntransformedChildren.GetAxisAlignedBoundingBox();
this.RotateAbout.Origin = aabb.Center;
}
@ -135,7 +135,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
using (RebuildLock())
{
// set the matrix for the inner object
TransformItem.Matrix = RotationMatrix;
ItemWithTransform.Matrix = RotationMatrix;
}
Invalidate(InvalidateType.Matrix);

View file

@ -70,9 +70,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
base.WrapItems(items, undoBuffer);
// use source item as it may be a copy of item by the time we have wrapped it
var aabb = SourceItems.GetAxisAlignedBoundingBox();
var aabb = UntransformedChildren.GetAxisAlignedBoundingBox();
var newCenter = new Vector3(aabb.Center.X, aabb.Center.Y, aabb.MinXYZ.Z);
SourceItems.Translate(-newCenter);
UntransformedChildren.Translate(-newCenter);
this.Translate(newCenter);
}
@ -93,7 +93,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
return ScaleRatio.X * 100;
}
return ScaleRatio.X * SourceItems.GetAxisAlignedBoundingBox().XSize;
return ScaleRatio.X * UntransformedChildren.GetAxisAlignedBoundingBox().XSize;
}
set
@ -104,7 +104,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
else
{
ScaleRatio.X = value / SourceItems.GetAxisAlignedBoundingBox().XSize;
ScaleRatio.X = value / UntransformedChildren.GetAxisAlignedBoundingBox().XSize;
}
}
}
@ -120,7 +120,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
return ScaleRatio.Y * 100;
}
return ScaleRatio.Y * SourceItems.GetAxisAlignedBoundingBox().YSize;
return ScaleRatio.Y * UntransformedChildren.GetAxisAlignedBoundingBox().YSize;
}
set
@ -131,7 +131,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
else
{
ScaleRatio.Y = value / SourceItems.GetAxisAlignedBoundingBox().YSize;
ScaleRatio.Y = value / UntransformedChildren.GetAxisAlignedBoundingBox().YSize;
}
}
}
@ -147,7 +147,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
return ScaleRatio.Z * 100;
}
return ScaleRatio.Z * SourceItems.GetAxisAlignedBoundingBox().ZSize;
return ScaleRatio.Z * UntransformedChildren.GetAxisAlignedBoundingBox().ZSize;
}
set
@ -158,7 +158,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
else
{
ScaleRatio.Z = value / SourceItems.GetAxisAlignedBoundingBox().ZSize;
ScaleRatio.Z = value / UntransformedChildren.GetAxisAlignedBoundingBox().ZSize;
}
}
}
@ -213,10 +213,10 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
using (RebuildLock())
{
// set the matrix for the transform object
TransformItem.Matrix = Matrix4X4.Identity;
TransformItem.Matrix *= Matrix4X4.CreateTranslation(-ScaleAbout);
TransformItem.Matrix *= Matrix4X4.CreateScale(ScaleRatio);
TransformItem.Matrix *= Matrix4X4.CreateTranslation(ScaleAbout);
ItemWithTransform.Matrix = Matrix4X4.Identity;
ItemWithTransform.Matrix *= Matrix4X4.CreateTranslation(-ScaleAbout);
ItemWithTransform.Matrix *= Matrix4X4.CreateScale(ScaleRatio);
ItemWithTransform.Matrix *= Matrix4X4.CreateTranslation(ScaleAbout);
}
Invalidate(InvalidateType.Matrix);

View file

@ -50,20 +50,20 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
public override bool CanFlatten => true;
[JsonIgnore]
public SafeList<IObject3D> SourceItems
public SafeList<IObject3D> UntransformedChildren
{
get
{
if (TransformItem?.Children.Count > 0)
if (ItemWithTransform?.Children.Count > 0)
{
return TransformItem.Children;
return ItemWithTransform.Children;
}
return null;
}
}
protected IObject3D TransformItem
protected IObject3D ItemWithTransform
{
get
{
@ -87,16 +87,16 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
// push child into children
foreach (var item in SourceItems)
foreach (var item in UntransformedChildren)
{
item.Matrix *= TransformItem.Matrix;
item.Matrix *= ItemWithTransform.Matrix;
}
// add our children to our parent and remove from parent
this.Parent.Children.Modify(list =>
{
list.Remove(this);
list.AddRange(TransformItem.Children);
list.AddRange(ItemWithTransform.Children);
});
}
Invalidate(InvalidateType.Children);
@ -107,7 +107,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
using (RebuildLock())
{
// push our matrix into inner children
foreach (var child in TransformItem.Children)
foreach (var child in ItemWithTransform.Children)
{
child.Matrix *= this.Matrix;
}
@ -116,7 +116,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
this.Parent.Children.Modify(list =>
{
list.Remove(this);
list.AddRange(TransformItem.Children);
list.AddRange(ItemWithTransform.Children);
});
}

View file

@ -104,7 +104,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
using (RebuildLock())
{
// set the matrix for the inner object
TransformItem.Matrix = Matrix4X4.CreateTranslation(Translation);
ItemWithTransform.Matrix = Matrix4X4.CreateTranslation(Translation);
}
Invalidate(InvalidateType.Matrix);

View file

@ -142,7 +142,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
case TransformWrapperObject3D transformWrapperObject3D:
return new ObjectView()
{
Children = transformWrapperObject3D.SourceItems,
Children = transformWrapperObject3D.UntransformedChildren,
Name = item.Name,
Source = item
};

@ -1 +1 @@
Subproject commit 99e43459d04563a62fa721a9023d6f4c3e1748a2
Subproject commit 2572ad0b29d45fb647ef4d0d5d4dcc2e38e308e4

@ -1 +1 @@
Subproject commit a0c518cffc3fbfa781e582af0281a458c5e65903
Subproject commit b078d2a5e9d9981734096476de079b285a52efaf

View file

@ -431,7 +431,7 @@ namespace MatterControl.Tests.MatterControl
Assert.IsTrue(preScaleAabb.Equals(postScaleAabb, .001));
Assert.AreNotEqual(cube, scaleObject.SourceItems.First(), "There is an undo buffer, there should have been a clone");
Assert.AreNotEqual(cube, scaleObject.UntransformedChildren.First(), "There is an undo buffer, there should have been a clone");
}
// build cube with scale
@ -454,7 +454,7 @@ namespace MatterControl.Tests.MatterControl
Assert.IsTrue(preScaleAabb.Equals(postScaleAabb, .001));
Assert.AreEqual(cube, scaleObject.SourceItems.First(), "There is no undo buffer, there should not have been a clone");
Assert.AreEqual(cube, scaleObject.UntransformedChildren.First(), "There is no undo buffer, there should not have been a clone");
}
}
@ -480,7 +480,7 @@ namespace MatterControl.Tests.MatterControl
Assert.IsTrue(preScaleAabb.Equals(postScaleAabb, .001));
Assert.AreEqual(cube, scaleObject.SourceItems.First(), "There is no undo buffer, there should not have been a clone");
Assert.AreEqual(cube, scaleObject.UntransformedChildren.First(), "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
@ -489,7 +489,7 @@ namespace MatterControl.Tests.MatterControl
Assert.IsTrue(preScaleAabb.Equals(postRotateScaleAabb, .001));
Assert.AreEqual(cube, rotateScaleObject.SourceItems.First(), "There is no undo buffer, there should not have been a clone");
Assert.AreEqual(cube, rotateScaleObject.UntransformedChildren.First(), "There is no undo buffer, there should not have been a clone");
}
}
@ -515,7 +515,7 @@ namespace MatterControl.Tests.MatterControl
Assert.IsTrue(preRotateAabb.Equals(postRotateAabb, .001));
Assert.AreEqual(cube, rotateObject.SourceItems.First(), "There is no undo buffer, there should not have been a clone");
Assert.AreEqual(cube, rotateObject.UntransformedChildren.First(), "There is no undo buffer, there should not have been a clone");
}
}