Made fit to bounds scale with new inline controls
This commit is contained in:
parent
4500f0fa8b
commit
4ef7ecfeb7
13 changed files with 758 additions and 55 deletions
|
|
@ -591,11 +591,11 @@ namespace MatterHackers.MatterControl
|
|||
return new SceneOperation("Scale")
|
||||
{
|
||||
OperationType = typeof(IObject3D),
|
||||
ResultType = typeof(ScaleObject3D_2),
|
||||
ResultType = typeof(ScaleObject3D_3),
|
||||
TitleResolver = () => "Scale".Localize(),
|
||||
Action = (sceneContext) =>
|
||||
{
|
||||
new ScaleObject3D_2().WrapSelectedItemAndSelect(sceneContext.Scene);
|
||||
new ScaleObject3D_3().WrapSelectedItemAndSelect(sceneContext.Scene);
|
||||
},
|
||||
Icon = (invertIcon) => StaticData.Instance.LoadIcon("scale_32x32.png", 16, 16, invertIcon).SetPreMultiply(),
|
||||
HelpTextResolver = () => "*At least 1 part must be selected*".Localize(),
|
||||
|
|
@ -1014,7 +1014,7 @@ namespace MatterHackers.MatterControl
|
|||
return new SceneOperation("Fit to Bounds")
|
||||
{
|
||||
OperationType = typeof(IObject3D),
|
||||
ResultType = typeof(FitToBoundsObject3D_2),
|
||||
ResultType = typeof(FitToBoundsObject3D_3),
|
||||
TitleResolver = () => "Fit to Bounds".Localize(),
|
||||
Action = async (sceneContext) =>
|
||||
{
|
||||
|
|
@ -1022,7 +1022,7 @@ namespace MatterHackers.MatterControl
|
|||
var selectedItem = scene.SelectedItem;
|
||||
using (new SelectionMaintainer(scene))
|
||||
{
|
||||
var fit = await FitToBoundsObject3D_2.Create(selectedItem.Clone());
|
||||
var fit = await FitToBoundsObject3D_3.Create(selectedItem.Clone());
|
||||
fit.MakeNameNonColliding();
|
||||
|
||||
scene.UndoBuffer.AddAndDo(new ReplaceCommand(new[] { selectedItem }, new[] { fit }));
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
var scaleRatio = Math.Max(letterObject.XSize() / 17, letterObject.ZSize() / 17);
|
||||
if (scaleRatio > 1)
|
||||
{
|
||||
letterObject = new ScaleObject3D_2(letterObject, 1.0 / scaleRatio, 1, 1.0 / scaleRatio);
|
||||
letterObject = new ScaleObject3D_3(letterObject, 1.0 / scaleRatio, 1, 1.0 / scaleRatio);
|
||||
}
|
||||
letterObject = new AlignObject3D(letterObject, FaceAlign.Bottom | FaceAlign.Front, brailleLetter, FaceAlign.Top | FaceAlign.Front, 0, 0, 3.5);
|
||||
letterObject = new SetCenterObject3D(letterObject, brailleLetter.GetCenter(), true, false, false);
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
IObject3D extrusionObject = imageObject;
|
||||
|
||||
var loadingScale = 32 / extrusionObject.XSize();
|
||||
extrusionObject = new ScaleObject3D_2(extrusionObject, loadingScale, loadingScale, 1 / extrusionObject.ZSize());
|
||||
extrusionObject = new ScaleObject3D_3(extrusionObject, loadingScale, loadingScale, 1 / extrusionObject.ZSize());
|
||||
extrusionObject = PlaceOnBase(logoBase, extrusionObject);
|
||||
|
||||
this.Children.Add(coinBlank);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
var textArea = new Vector2(25, 6);
|
||||
|
||||
double scale = Math.Min(textArea.X / textBounds.XSize, textArea.Y / textBounds.YSize);
|
||||
nameMesh = new ScaleObject3D_2(nameMesh, scale, scale, 2 / textBounds.ZSize);
|
||||
nameMesh = new ScaleObject3D_3(nameMesh, scale, scale, 2 / textBounds.ZSize);
|
||||
nameMesh = new AlignObject3D(nameMesh, FaceAlign.Bottom | FaceAlign.Front, cancerRibbonStl, FaceAlign.Top | FaceAlign.Front, 0, 0, -1);
|
||||
nameMesh = new SetCenterObject3D(nameMesh, cancerRibbonStl.GetCenter(), true, false, false);
|
||||
|
||||
|
|
|
|||
|
|
@ -133,8 +133,7 @@ namespace MatterHackers.Plugins.EditorTools
|
|||
{
|
||||
FinalState = new ScaleStates(InitialState);
|
||||
FinalState.Depth = newDepth;
|
||||
if (context.GuiSurface.ModifierKeys == Keys.Shift
|
||||
|| (selectedItem is IScaleLocker scaleLocker && scaleLocker.ScaleLocked))
|
||||
if (context.GuiSurface.ModifierKeys == Keys.Shift || selectedItem is IScaleLocker)
|
||||
{
|
||||
ScaleProportional(newDepth / InitialState.Depth);
|
||||
}
|
||||
|
|
@ -158,8 +157,7 @@ namespace MatterHackers.Plugins.EditorTools
|
|||
{
|
||||
FinalState = new ScaleStates(InitialState);
|
||||
FinalState.Height = newHeight;
|
||||
if (context.GuiSurface.ModifierKeys == Keys.Shift
|
||||
|| (selectedItem is IScaleLocker scaleLocker && scaleLocker.ScaleLocked))
|
||||
if (context.GuiSurface.ModifierKeys == Keys.Shift || selectedItem is IScaleLocker)
|
||||
{
|
||||
ScaleProportional(newHeight / InitialState.Height);
|
||||
}
|
||||
|
|
@ -171,8 +169,7 @@ namespace MatterHackers.Plugins.EditorTools
|
|||
{
|
||||
FinalState = new ScaleStates(InitialState);
|
||||
FinalState.Width = newWidth;
|
||||
if (context.GuiSurface.ModifierKeys == Keys.Shift
|
||||
|| (selectedItem is IScaleLocker scaleLocker && scaleLocker.ScaleLocked))
|
||||
if (context.GuiSurface.ModifierKeys == Keys.Shift || selectedItem is IScaleLocker)
|
||||
{
|
||||
ScaleProportional(newWidth / InitialState.Width);
|
||||
}
|
||||
|
|
@ -211,8 +208,7 @@ namespace MatterHackers.Plugins.EditorTools
|
|||
FinalState = new ScaleStates(InitialState);
|
||||
FinalState.Width = newWidth;
|
||||
FinalState.Depth = newDepth;
|
||||
if (context.GuiSurface.ModifierKeys == Keys.Shift
|
||||
|| (selectedItem is IScaleLocker scaleLocker && scaleLocker.ScaleLocked))
|
||||
if (context.GuiSurface.ModifierKeys == Keys.Shift || selectedItem is IScaleLocker)
|
||||
{
|
||||
ScaleProportional(newWidth / InitialState.Width);
|
||||
}
|
||||
|
|
@ -245,12 +241,38 @@ namespace MatterHackers.Plugins.EditorTools
|
|||
|
||||
private void ScaleProportional(double scale)
|
||||
{
|
||||
FinalState.Width = InitialState.Width * scale;
|
||||
FinalState.Depth = InitialState.Depth * scale;
|
||||
FinalState.Height = InitialState.Height * scale;
|
||||
for (int i = 0; i < FinalState.Diameters.Count; i++)
|
||||
if (selectedItem is IScaleLocker scaleLocker)
|
||||
{
|
||||
FinalState.Diameters[i] = InitialState.Diameters[i] * scale;
|
||||
switch (scaleLocker.LockProportion)
|
||||
{
|
||||
case LockProportions.None:
|
||||
break;
|
||||
|
||||
case LockProportions.X_Y:
|
||||
if (FinalState.Width != InitialState.Width
|
||||
|| FinalState.Depth != InitialState.Depth)
|
||||
{
|
||||
FinalState.Width = InitialState.Width * scale;
|
||||
FinalState.Depth = InitialState.Depth * scale;
|
||||
}
|
||||
break;
|
||||
|
||||
case LockProportions.X_Y_Z:
|
||||
FinalState.Width = InitialState.Width * scale;
|
||||
FinalState.Depth = InitialState.Depth * scale;
|
||||
FinalState.Height = InitialState.Height * scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FinalState.Width = InitialState.Width * scale;
|
||||
FinalState.Depth = InitialState.Depth * scale;
|
||||
FinalState.Height = InitialState.Height * scale;
|
||||
for (int i = 0; i < FinalState.Diameters.Count; i++)
|
||||
{
|
||||
FinalState.Diameters[i] = InitialState.Diameters[i] * scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
X_Y_Z
|
||||
}
|
||||
|
||||
[Obsolete("Not used anymore. Replaced with FitToBoundsObject3D_2", true)]
|
||||
[Obsolete("Not used anymore. Replaced with FitToBoundsObject3D_3", true)]
|
||||
public class FitToBoundsObject3D : Object3D, ISelectedEditorDraw, IPropertyGridModifier
|
||||
{
|
||||
[Description("Set the shape the part will be fit into.")]
|
||||
|
|
|
|||
|
|
@ -27,16 +27,19 @@ of the authors and should not be interpreted as representing official policies,
|
|||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
/*********************************************************************/
|
||||
/**************************** OBSOLETE! ******************************/
|
||||
/************************ USE NEWER VERSION **************************/
|
||||
/*********************************************************************/
|
||||
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||
using MatterHackers.MeshVisualizer;
|
||||
using MatterHackers.PolygonMesh;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
using MatterHackers.VectorMath;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
|
@ -45,6 +48,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
{
|
||||
[Obsolete("Not used anymore. Replaced with FitToBoundsObject3D_3", true)]
|
||||
public class FitToBoundsObject3D_2 : TransformWrapperObject3D, ISelectedEditorDraw
|
||||
{
|
||||
private Vector3 boundsSize;
|
||||
|
|
|
|||
289
MatterControlLib/DesignTools/Operations/FitToBoundsObject3D_3.cs
Normal file
289
MatterControlLib/DesignTools/Operations/FitToBoundsObject3D_3.cs
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
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 MatterHackers.Agg;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||
using MatterHackers.PolygonMesh;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
using MatterHackers.VectorMath;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
{
|
||||
public class FitToBoundsObject3D_3 : TransformWrapperObject3D, ISelectedEditorDraw, IObjectWithWidthAndDepth, IObjectWithHeight
|
||||
{
|
||||
private Vector3 boundsSize;
|
||||
private InvalidateType additonalInvalidate;
|
||||
|
||||
public FitToBoundsObject3D_3()
|
||||
{
|
||||
Name = "Fit to Bounds".Localize();
|
||||
}
|
||||
|
||||
private IObject3D FitBounds => Children.Last();
|
||||
|
||||
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)]
|
||||
[Description("Ensure that the part maintains its proportions.")]
|
||||
public LockProportions LockProportion { get; set; } = LockProportions.X_Y_Z;
|
||||
|
||||
public double Width
|
||||
{
|
||||
get => boundsSize.X;
|
||||
set
|
||||
{
|
||||
boundsSize.X = value;
|
||||
if (this.Children.Count() > 0)
|
||||
{
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double Depth
|
||||
{
|
||||
get => boundsSize.Y;
|
||||
set
|
||||
{
|
||||
boundsSize.Y = value;
|
||||
if (this.Children.Count() > 0)
|
||||
{
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double Height
|
||||
{
|
||||
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;
|
||||
|
||||
public static async Task<FitToBoundsObject3D_3> Create(IObject3D itemToFit)
|
||||
{
|
||||
var fitToBounds = new FitToBoundsObject3D_3();
|
||||
using (fitToBounds.RebuildLock())
|
||||
{
|
||||
var startingAabb = itemToFit.GetAxisAlignedBoundingBox();
|
||||
itemToFit.Translate(-startingAabb.Center);
|
||||
|
||||
// add the fit item
|
||||
var scaleItem = new Object3D();
|
||||
fitToBounds.Children.Add(scaleItem);
|
||||
scaleItem.Children.Add(itemToFit);
|
||||
|
||||
// create an object that just represents the bounds in the scene
|
||||
var fitBounds = new Object3D()
|
||||
{
|
||||
Visible = false,
|
||||
Color = new Color(Color.Red, 100),
|
||||
Mesh = PlatonicSolids.CreateCube()
|
||||
};
|
||||
// add the item that holds the bounds
|
||||
fitToBounds.Children.Add(fitBounds);
|
||||
|
||||
fitToBounds.boundsSize.X = startingAabb.XSize;
|
||||
fitToBounds.boundsSize.Y = startingAabb.YSize;
|
||||
fitToBounds.boundsSize.Z = startingAabb.ZSize;
|
||||
await fitToBounds.Rebuild();
|
||||
|
||||
var finalAabb = fitToBounds.GetAxisAlignedBoundingBox();
|
||||
fitToBounds.Translate(startingAabb.Center - finalAabb.Center);
|
||||
}
|
||||
|
||||
return fitToBounds;
|
||||
}
|
||||
|
||||
public void DrawEditor(Object3DControlsLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e)
|
||||
{
|
||||
var aabb = UntransformedChildren.GetAxisAlignedBoundingBox();
|
||||
var center = aabb.Center;
|
||||
var worldMatrix = this.WorldMatrix();
|
||||
|
||||
var minXyz = center - new Vector3(Width / 2, Depth / 2, Height / 2);
|
||||
var maxXyz = center + new Vector3(Width / 2, Depth / 2, Height / 2);
|
||||
var bounds = new AxisAlignedBoundingBox(minXyz, maxXyz);
|
||||
layer.World.RenderAabb(bounds, worldMatrix, Color.Red, 1, 1);
|
||||
}
|
||||
|
||||
public override AxisAlignedBoundingBox GetAxisAlignedBoundingBox(Matrix4X4 matrix)
|
||||
{
|
||||
if (Children.Count == 2)
|
||||
{
|
||||
AxisAlignedBoundingBox bounds;
|
||||
using (FitBounds.RebuildLock())
|
||||
{
|
||||
FitBounds.Visible = true;
|
||||
bounds = base.GetAxisAlignedBoundingBox(matrix);
|
||||
FitBounds.Visible = false;
|
||||
}
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
return base.GetAxisAlignedBoundingBox(matrix);
|
||||
}
|
||||
|
||||
public override async void OnInvalidate(InvalidateArgs invalidateType)
|
||||
{
|
||||
additonalInvalidate = invalidateType.InvalidateType;
|
||||
|
||||
if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Children)
|
||||
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix)
|
||||
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Mesh))
|
||||
&& invalidateType.Source != this
|
||||
&& !RebuildLocked)
|
||||
{
|
||||
await Rebuild();
|
||||
}
|
||||
else if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties)
|
||||
&& invalidateType.Source == this)
|
||||
{
|
||||
await Rebuild();
|
||||
}
|
||||
else if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties)
|
||||
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix)
|
||||
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Mesh)
|
||||
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Children))
|
||||
{
|
||||
base.OnInvalidate(invalidateType);
|
||||
}
|
||||
|
||||
base.OnInvalidate(invalidateType);
|
||||
|
||||
additonalInvalidate = InvalidateType.None;
|
||||
}
|
||||
|
||||
public override Task Rebuild()
|
||||
{
|
||||
this.DebugDepth("Rebuild");
|
||||
using (RebuildLock())
|
||||
{
|
||||
using (new CenterAndHeightMaintainer(this))
|
||||
{
|
||||
AdjustChildSize(null, null);
|
||||
|
||||
UpdateBoundsItem();
|
||||
}
|
||||
}
|
||||
|
||||
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix | additonalInvalidate));
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void AdjustChildSize(object sender, EventArgs e)
|
||||
{
|
||||
if (Children.Count > 0)
|
||||
{
|
||||
var aabb = UntransformedChildren.GetAxisAlignedBoundingBox();
|
||||
ItemWithTransform.Matrix = Matrix4X4.Identity;
|
||||
var scale = Vector3.One;
|
||||
if (StretchX)
|
||||
{
|
||||
scale.X = Width / aabb.XSize;
|
||||
}
|
||||
if (StretchY)
|
||||
{
|
||||
scale.Y = Depth / aabb.YSize;
|
||||
}
|
||||
if (StretchZ)
|
||||
{
|
||||
scale.Z = Height / aabb.ZSize;
|
||||
}
|
||||
|
||||
switch (LockProportion)
|
||||
{
|
||||
case LockProportions.None:
|
||||
break;
|
||||
|
||||
case LockProportions.X_Y:
|
||||
var minXy = Math.Min(scale.X, scale.Y);
|
||||
scale.X = minXy;
|
||||
scale.Y = minXy;
|
||||
break;
|
||||
|
||||
case LockProportions.X_Y_Z:
|
||||
var minXyz = Math.Min(Math.Min(scale.X, scale.Y), scale.Z);
|
||||
scale.X = minXyz;
|
||||
scale.Y = minXyz;
|
||||
scale.Z = minXyz;
|
||||
break;
|
||||
}
|
||||
|
||||
if (aabb.XSize > 0 && aabb.YSize > 0 && aabb.ZSize > 0)
|
||||
{
|
||||
ItemWithTransform.Matrix = Object3DExtensions.ApplyAtPosition(ItemWithTransform.Matrix, aabb.Center, Matrix4X4.CreateScale(scale));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBoundsItem()
|
||||
{
|
||||
if (Children.Count == 2)
|
||||
{
|
||||
var transformAabb = ItemWithTransform.GetAxisAlignedBoundingBox();
|
||||
var fitAabb = FitBounds.GetAxisAlignedBoundingBox();
|
||||
var fitSize = fitAabb.Size;
|
||||
if (boundsSize.X != 0 && boundsSize.Y != 0 && boundsSize.Z != 0
|
||||
&& (fitSize != boundsSize
|
||||
|| fitAabb.Center != transformAabb.Center))
|
||||
{
|
||||
FitBounds.Matrix *= Matrix4X4.CreateScale(
|
||||
boundsSize.X / fitSize.X,
|
||||
boundsSize.Y / fitSize.Y,
|
||||
boundsSize.Z / fitSize.Z);
|
||||
FitBounds.Matrix *= Matrix4X4.CreateTranslation(
|
||||
transformAabb.Center - FitBounds.GetAxisAlignedBoundingBox().Center);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@ using Newtonsoft.Json;
|
|||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
{
|
||||
[Obsolete("Use ScaleObject3D_2 instead", false)]
|
||||
[Obsolete("Use ScaleObject3D_3 instead", false)]
|
||||
public class ScaleObject3D : TransformWrapperObject3D, ISelectedEditorDraw, IPropertyGridModifier
|
||||
{
|
||||
public enum ScaleType
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@ of the authors and should not be interpreted as representing official policies,
|
|||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
/*********************************************************************/
|
||||
/**************************** OBSOLETE! ******************************/
|
||||
/************************ USE NEWER VERSION **************************/
|
||||
/*********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
|
@ -39,11 +44,7 @@ using Newtonsoft.Json;
|
|||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
{
|
||||
public interface IScaleLocker
|
||||
{
|
||||
bool ScaleLocked { get; }
|
||||
}
|
||||
|
||||
[Obsolete("Use ScaleObject3D_3 instead", false)]
|
||||
public class ScaleObject3D_2 : TransformWrapperObject3D, IObjectWithHeight, IObjectWithWidthAndDepth, IPropertyGridModifier, IScaleLocker
|
||||
{
|
||||
public enum ScaleTypes
|
||||
|
|
@ -232,7 +233,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
}
|
||||
}
|
||||
|
||||
public bool ScaleLocked => LockProportions;
|
||||
public LockProportions LockProportion => LockProportions ? Operations.LockProportions.X_Y_Z: Operations.LockProportions.None;
|
||||
|
||||
private void FixIfLockedProportions(int index, double newScale)
|
||||
{
|
||||
|
|
|
|||
386
MatterControlLib/DesignTools/Operations/ScaleObject3D_3.cs
Normal file
386
MatterControlLib/DesignTools/Operations/ScaleObject3D_3.cs
Normal file
|
|
@ -0,0 +1,386 @@
|
|||
/*
|
||||
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 System.Threading.Tasks;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.VectorMath;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
{
|
||||
public enum LockProportions
|
||||
{
|
||||
[Description("Scale Freely")]
|
||||
None,
|
||||
[Description("Lock the Width & Depth together")]
|
||||
X_Y,
|
||||
[Description("Lock the Width, Depth & Height together")]
|
||||
X_Y_Z
|
||||
}
|
||||
|
||||
public interface IScaleLocker
|
||||
{
|
||||
LockProportions LockProportion { get; }
|
||||
}
|
||||
|
||||
public class ScaleObject3D_3 : TransformWrapperObject3D, IObjectWithHeight, IObjectWithWidthAndDepth, IPropertyGridModifier, IScaleLocker
|
||||
{
|
||||
public enum ScaleTypes
|
||||
{
|
||||
Custom,
|
||||
Inches_to_mm,
|
||||
mm_to_Inches,
|
||||
mm_to_cm,
|
||||
cm_to_mm,
|
||||
Ultrafuse_316L,
|
||||
}
|
||||
|
||||
public ScaleObject3D_3()
|
||||
{
|
||||
Name = "Scale".Localize();
|
||||
}
|
||||
|
||||
public ScaleObject3D_3(IObject3D item, double x = 1, double y = 1, double z = 1)
|
||||
: this(item, new Vector3(x, y, z))
|
||||
{
|
||||
}
|
||||
|
||||
public ScaleObject3D_3(IObject3D itemToScale, Vector3 scale)
|
||||
: this()
|
||||
{
|
||||
WrapItems(new IObject3D[] { itemToScale });
|
||||
|
||||
ScaleRatio = scale;
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
public override void WrapSelectedItemAndSelect(InteractiveScene scene)
|
||||
{
|
||||
base.WrapSelectedItemAndSelect(scene);
|
||||
|
||||
// use source item as it may be a copy of item by the time we have wrapped it
|
||||
var aabb = UntransformedChildren.GetAxisAlignedBoundingBox();
|
||||
var newCenter = new Vector3(aabb.Center.X, aabb.Center.Y, aabb.MinXYZ.Z);
|
||||
UntransformedChildren.Translate(-newCenter);
|
||||
this.Translate(newCenter);
|
||||
}
|
||||
|
||||
public override void WrapItems(IEnumerable<IObject3D> items, UndoBuffer undoBuffer = null)
|
||||
{
|
||||
base.WrapItems(items, undoBuffer);
|
||||
|
||||
// use source item as it may be a copy of item by the time we have wrapped it
|
||||
var aabb = UntransformedChildren.GetAxisAlignedBoundingBox();
|
||||
var newCenter = new Vector3(aabb.Center.X, aabb.Center.Y, aabb.MinXYZ.Z);
|
||||
UntransformedChildren.Translate(-newCenter);
|
||||
this.Translate(newCenter);
|
||||
}
|
||||
|
||||
// this is the size we actually serialize
|
||||
public Vector3 ScaleRatio = Vector3.One;
|
||||
|
||||
public ScaleTypes ScaleType { get; set; } = ScaleTypes.Custom;
|
||||
|
||||
public enum ScaleMethods
|
||||
{
|
||||
Direct,
|
||||
Percentage,
|
||||
}
|
||||
|
||||
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Tabs)]
|
||||
public ScaleMethods ScaleMethod { get; set; } = ScaleMethods.Direct;
|
||||
|
||||
|
||||
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)]
|
||||
[Description("Ensure that the part maintains its proportions.")]
|
||||
public LockProportions LockProportion { get; set; } = LockProportions.X_Y_Z;
|
||||
|
||||
|
||||
[MaxDecimalPlaces(3)]
|
||||
[JsonIgnore]
|
||||
public double Width
|
||||
{
|
||||
get
|
||||
{
|
||||
var children = UntransformedChildren;
|
||||
if (children == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return ScaleRatio.X * UntransformedChildren.GetAxisAlignedBoundingBox().XSize;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
var children = UntransformedChildren;
|
||||
if (children != null)
|
||||
{
|
||||
FixIfLockedProportions(0, value / UntransformedChildren.GetAxisAlignedBoundingBox().XSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MaxDecimalPlaces(3)]
|
||||
[JsonIgnore]
|
||||
public double Depth
|
||||
{
|
||||
get
|
||||
{
|
||||
var children = UntransformedChildren;
|
||||
if (children == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return ScaleRatio.Y * children.GetAxisAlignedBoundingBox().YSize;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
var children = UntransformedChildren;
|
||||
if (children != null)
|
||||
{
|
||||
FixIfLockedProportions(1, value / children.GetAxisAlignedBoundingBox().YSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MaxDecimalPlaces(3)]
|
||||
[JsonIgnore]
|
||||
public double Height
|
||||
{
|
||||
get
|
||||
{
|
||||
var children = UntransformedChildren;
|
||||
if (children == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return ScaleRatio.Z * children.GetAxisAlignedBoundingBox().ZSize;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
var children = UntransformedChildren;
|
||||
if (children != null)
|
||||
{
|
||||
FixIfLockedProportions(2, value / children.GetAxisAlignedBoundingBox().ZSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MaxDecimalPlaces(2)]
|
||||
[JsonIgnore]
|
||||
public double WidthPercent
|
||||
{
|
||||
get
|
||||
{
|
||||
return ScaleRatio.X * 100;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
FixIfLockedProportions(0, value / 100);
|
||||
}
|
||||
}
|
||||
|
||||
[MaxDecimalPlaces(2)]
|
||||
[JsonIgnore]
|
||||
public double DepthPercent
|
||||
{
|
||||
get
|
||||
{
|
||||
return ScaleRatio.Y * 100;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
FixIfLockedProportions(1, value / 100);
|
||||
}
|
||||
}
|
||||
|
||||
[MaxDecimalPlaces(2)]
|
||||
[JsonIgnore]
|
||||
public double HeightPercent
|
||||
{
|
||||
get
|
||||
{
|
||||
return ScaleRatio.Z * 100;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
FixIfLockedProportions(2, value / 100);
|
||||
}
|
||||
}
|
||||
|
||||
private void FixIfLockedProportions(int index, double newScale)
|
||||
{
|
||||
if (Math.Abs(newScale - ScaleRatio[index]) > .001)
|
||||
{
|
||||
ScaleRatio[index] = newScale;
|
||||
if (ScaleType != ScaleTypes.Custom)
|
||||
{
|
||||
// WIP: switch back to custom scaling (as we are no longer on a fixed scaling)
|
||||
// needs to:
|
||||
// - create an undo point for the switch
|
||||
// - update the properties control to show the right drop down
|
||||
// - show all the settings
|
||||
}
|
||||
|
||||
if (LockProportion == LockProportions.X_Y_Z)
|
||||
{
|
||||
ScaleRatio[(index + 1) % 3] = ScaleRatio[index];
|
||||
ScaleRatio[(index + 2) % 3] = ScaleRatio[index];
|
||||
Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues));
|
||||
}
|
||||
else if (LockProportion == LockProportions.X_Y)
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
ScaleRatio[1] = ScaleRatio[index];
|
||||
Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues));
|
||||
}
|
||||
else if(index == 1)
|
||||
{
|
||||
ScaleRatio[0] = ScaleRatio[index];
|
||||
Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues));
|
||||
}
|
||||
}
|
||||
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
public async override void OnInvalidate(InvalidateArgs invalidateArgs)
|
||||
{
|
||||
if ((invalidateArgs.InvalidateType.HasFlag(InvalidateType.Children)
|
||||
|| invalidateArgs.InvalidateType.HasFlag(InvalidateType.Matrix)
|
||||
|| invalidateArgs.InvalidateType.HasFlag(InvalidateType.Mesh))
|
||||
&& invalidateArgs.Source != this
|
||||
&& !RebuildLocked)
|
||||
{
|
||||
await Rebuild();
|
||||
}
|
||||
else if (invalidateArgs.InvalidateType.HasFlag(InvalidateType.Properties)
|
||||
&& invalidateArgs.Source == this)
|
||||
{
|
||||
await Rebuild();
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnInvalidate(invalidateArgs);
|
||||
}
|
||||
}
|
||||
|
||||
public override Task Rebuild()
|
||||
{
|
||||
this.DebugDepth("Rebuild");
|
||||
|
||||
using (RebuildLock())
|
||||
{
|
||||
using (new CenterAndHeightMaintainer(this))
|
||||
{
|
||||
// set the matrix for the transform object
|
||||
ItemWithTransform.Matrix = Matrix4X4.Identity;
|
||||
ItemWithTransform.Matrix *= Matrix4X4.CreateScale(ScaleRatio);
|
||||
}
|
||||
}
|
||||
|
||||
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void UpdateControls(PublicPropertyChange change)
|
||||
{
|
||||
change.SetRowVisible(nameof(Width), () => ScaleType == ScaleTypes.Custom && ScaleMethod == ScaleMethods.Direct);
|
||||
change.SetRowVisible(nameof(Depth), () => ScaleType == ScaleTypes.Custom && ScaleMethod == ScaleMethods.Direct);
|
||||
change.SetRowVisible(nameof(Height), () => ScaleType == ScaleTypes.Custom && ScaleMethod == ScaleMethods.Direct);
|
||||
change.SetRowVisible(nameof(WidthPercent), () => ScaleType == ScaleTypes.Custom && ScaleMethod == ScaleMethods.Percentage);
|
||||
change.SetRowVisible(nameof(DepthPercent), () => ScaleType == ScaleTypes.Custom && ScaleMethod == ScaleMethods.Percentage);
|
||||
change.SetRowVisible(nameof(HeightPercent), () => ScaleType == ScaleTypes.Custom && ScaleMethod == ScaleMethods.Percentage);
|
||||
change.SetRowVisible(nameof(LockProportions), () => ScaleType == ScaleTypes.Custom);
|
||||
change.SetRowVisible(nameof(ScaleMethod), () => ScaleType == ScaleTypes.Custom);
|
||||
|
||||
if (change.Changed == nameof(ScaleType))
|
||||
{
|
||||
// recalculate the scaling
|
||||
double scale = 1;
|
||||
switch (ScaleType)
|
||||
{
|
||||
case ScaleTypes.Inches_to_mm:
|
||||
scale = 25.4;
|
||||
break;
|
||||
case ScaleTypes.mm_to_Inches:
|
||||
scale = .0393;
|
||||
break;
|
||||
case ScaleTypes.mm_to_cm:
|
||||
scale = .1;
|
||||
break;
|
||||
case ScaleTypes.cm_to_mm:
|
||||
scale = 10;
|
||||
break;
|
||||
case ScaleTypes.Ultrafuse_316L:
|
||||
ScaleRatio = new Vector3(1.1982, 1.1982, 1.261);
|
||||
Rebuild();
|
||||
Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues));
|
||||
return;
|
||||
}
|
||||
|
||||
ScaleRatio = new Vector3(scale, scale, scale);
|
||||
Rebuild();
|
||||
Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues));
|
||||
}
|
||||
else if (change.Changed == nameof(LockProportion))
|
||||
{
|
||||
if (LockProportion == LockProportions.X_Y_Z)
|
||||
{
|
||||
var maxScale = Math.Max(ScaleRatio.X, Math.Max(ScaleRatio.Y, ScaleRatio.Z));
|
||||
ScaleRatio = new Vector3(maxScale, maxScale, maxScale);
|
||||
Rebuild();
|
||||
// make sure we update the controls on screen to reflect the different data type
|
||||
Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues));
|
||||
}
|
||||
else if (LockProportion == LockProportions.X_Y)
|
||||
{
|
||||
var maxScale = Math.Max(ScaleRatio.X, ScaleRatio.Y);
|
||||
ScaleRatio = new Vector3(maxScale, maxScale, ScaleRatio.Z);
|
||||
Rebuild();
|
||||
// make sure we update the controls on screen to reflect the different data type
|
||||
Invalidate(new InvalidateArgs(null, InvalidateType.DisplayValues));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -100,7 +100,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
break;
|
||||
|
||||
case EnumDisplayAttribute.PresentationMode.Buttons:
|
||||
AddButtons(enumItems);
|
||||
AddButtons(enumItems, enumDescriptions);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -157,7 +157,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
this.Content = menuRow;
|
||||
}
|
||||
|
||||
private void AddButtons(IEnumerable<(string Key, string Value)> enumItems)
|
||||
private void AddButtons(IEnumerable<(string Key, string Value)> enumItems, List<string> descriptions)
|
||||
{
|
||||
var menuRow = new FlowLayoutWidget();
|
||||
|
||||
|
|
@ -177,6 +177,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
SelectedBackgroundColor = theme.PrimaryAccentColor,
|
||||
UnselectedBackgroundColor = theme.MinimalShade,
|
||||
BackgroundColor = theme.MinimalShade,
|
||||
ToolTipText = descriptions[index]
|
||||
};
|
||||
|
||||
radioButton.CheckedStateChanged += (s, e) =>
|
||||
|
|
|
|||
|
|
@ -325,11 +325,11 @@ namespace MatterControl.Tests.MatterControl
|
|||
root.Children.Add(cube);
|
||||
Assert.IsTrue(root.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)), .001));
|
||||
root.Children.Remove(cube);
|
||||
var fit = await FitToBoundsObject3D_2.Create(cube);
|
||||
var fit = await FitToBoundsObject3D_3.Create(cube);
|
||||
|
||||
fit.SizeX = 50;
|
||||
fit.SizeY = 20;
|
||||
fit.SizeZ = 20;
|
||||
fit.Width = 50;
|
||||
fit.Depth = 20;
|
||||
fit.Height = 20;
|
||||
root.Children.Add(fit);
|
||||
var rootAabb = root.GetAxisAlignedBoundingBox();
|
||||
Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-25, -10, -10), new Vector3(25, 10, 10)), .001));
|
||||
|
|
@ -339,11 +339,11 @@ namespace MatterControl.Tests.MatterControl
|
|||
{
|
||||
var root = new Object3D();
|
||||
var cube = await CubeObject3D.Create(20, 20, 20);
|
||||
var fit = await FitToBoundsObject3D_2.Create(cube);
|
||||
var fit = await FitToBoundsObject3D_3.Create(cube);
|
||||
|
||||
fit.SizeX = 50;
|
||||
fit.SizeY = 20;
|
||||
fit.SizeZ = 20;
|
||||
fit.Width = 50;
|
||||
fit.Depth = 20;
|
||||
fit.Height = 20;
|
||||
|
||||
var pinch = new PinchObject3D_3();
|
||||
pinch.Children.Add(fit);
|
||||
|
|
@ -384,11 +384,11 @@ namespace MatterControl.Tests.MatterControl
|
|||
{
|
||||
var root = new Object3D();
|
||||
var cube = await CubeObject3D.Create(20, 20, 20);
|
||||
var fit = await FitToBoundsObject3D_2.Create(cube);
|
||||
var fit = await FitToBoundsObject3D_3.Create(cube);
|
||||
|
||||
fit.SizeX = 50;
|
||||
fit.SizeY = 20;
|
||||
fit.SizeZ = 20;
|
||||
fit.Width = 50;
|
||||
fit.Depth = 20;
|
||||
fit.Height = 20;
|
||||
|
||||
var translate = new TranslateObject3D(fit, 11, 0, 0);
|
||||
|
||||
|
|
@ -417,7 +417,7 @@ namespace MatterControl.Tests.MatterControl
|
|||
var undoBuffer = new UndoBuffer();
|
||||
|
||||
// add a scale to it (that is not scaled)
|
||||
var scaleObject = new ScaleObject3D_2();
|
||||
var scaleObject = new ScaleObject3D_3();
|
||||
scaleObject.WrapItems(new IObject3D[] { cube }, undoBuffer);
|
||||
|
||||
// ensure that the object did not move
|
||||
|
|
@ -440,7 +440,7 @@ namespace MatterControl.Tests.MatterControl
|
|||
var preScaleAabb = root.GetAxisAlignedBoundingBox();
|
||||
|
||||
// add a scale to it (that is not scaled)
|
||||
var scaleObject = new ScaleObject3D_2(cube);
|
||||
var scaleObject = new ScaleObject3D_3(cube);
|
||||
|
||||
// ensure that the object did not move
|
||||
Assert.AreEqual(4, root.DescendantsAndSelf().Count());
|
||||
|
|
@ -465,7 +465,7 @@ namespace MatterControl.Tests.MatterControl
|
|||
var preScaleAabb = root.GetAxisAlignedBoundingBox();
|
||||
|
||||
// add a scale to it (that is not scaled)
|
||||
var scaleObject = new ScaleObject3D_2(cube);
|
||||
var scaleObject = new ScaleObject3D_3(cube);
|
||||
|
||||
// ensure that the object did not move
|
||||
Assert.AreEqual(4, root.DescendantsAndSelf().Count());
|
||||
|
|
@ -525,11 +525,11 @@ namespace MatterControl.Tests.MatterControl
|
|||
|
||||
var root = new Object3D();
|
||||
var cube = await CubeObject3D.Create(20, 20, 20);
|
||||
var fit = await FitToBoundsObject3D_2.Create(cube);
|
||||
var fit = await FitToBoundsObject3D_3.Create(cube);
|
||||
|
||||
fit.SizeX = 10;
|
||||
fit.SizeY = 10;
|
||||
fit.SizeZ = 6;
|
||||
fit.Width = 10;
|
||||
fit.Depth = 10;
|
||||
fit.Height = 6;
|
||||
|
||||
Assert.IsTrue(fit.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-5, -5, -10), new Vector3(5, 5, -4)), .01));
|
||||
|
||||
|
|
@ -635,11 +635,11 @@ namespace MatterControl.Tests.MatterControl
|
|||
|
||||
var root = new Object3D();
|
||||
var cube = await CubeObject3D.Create(20, 20, 20);
|
||||
var fit = await FitToBoundsObject3D_2.Create(cube);
|
||||
var fit = await FitToBoundsObject3D_3.Create(cube);
|
||||
|
||||
fit.SizeX = 50;
|
||||
fit.SizeY = 20;
|
||||
fit.SizeZ = 20;
|
||||
fit.Width = 50;
|
||||
fit.Depth = 20;
|
||||
fit.Height = 20;
|
||||
|
||||
Assert.IsTrue(fit.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-25, -10, -10), new Vector3(25, 10, 10)), 1.0));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue