Added a Translate command
Made Rotate and FitToBounds Apply and Remove refactoring
This commit is contained in:
parent
0783f975a8
commit
72ce9b86de
8 changed files with 331 additions and 211 deletions
|
|
@ -1,282 +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.ComponentModel;
|
||||
using System.Linq;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||
using MatterHackers.MeshVisualizer;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
using MatterHackers.RenderOpenGl.OpenGl;
|
||||
using MatterHackers.VectorMath;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
{
|
||||
public enum FitType { Box, Cylinder }
|
||||
|
||||
public enum MaintainRatio { None, X_Y, X_Y_Z }
|
||||
|
||||
[Obsolete("Not used anymore. Replaced with FitToBoundsObject3D_2", true)]
|
||||
public class FitToBoundsObject3D : Object3D, IEditorDraw, IPropertyGridModifier
|
||||
{
|
||||
[Description("Set the shape the part will be fit into.")]
|
||||
public FitType FitType { get; set; } = FitType.Box;
|
||||
|
||||
public double Width { get; set; }
|
||||
public double Depth { get; set; }
|
||||
public double Diameter { get; set; }
|
||||
public double Height { get; set; }
|
||||
|
||||
[Description("Set the rules for how to maintain the part while scaling.")]
|
||||
public MaintainRatio MaintainRatio { get; set; } = MaintainRatio.X_Y;
|
||||
[Description("Allows you turn turn on and off applying the fit to the x axis.")]
|
||||
public bool StretchX { get; set; } = true;
|
||||
[Description("Allows you turn turn on and off applying the fit to the y axis.")]
|
||||
public bool StretchY { get; set; } = true;
|
||||
[Description("Allows you turn turn on and off applying the fit to the z axis.")]
|
||||
public bool StretchZ { get; set; } = true;
|
||||
|
||||
IObject3D ScaleItem => Children.First();
|
||||
[JsonIgnore]
|
||||
public IObject3D ItemToScale => Children.First().Children.First();
|
||||
|
||||
public FitToBoundsObject3D()
|
||||
{
|
||||
Name = "Fit to Bounds".Localize();
|
||||
}
|
||||
|
||||
public override void Apply(UndoBuffer undoBuffer)
|
||||
{
|
||||
using (RebuildLock())
|
||||
{
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
Invalidate(new InvalidateArgs(this, InvalidateType.Content));
|
||||
}
|
||||
|
||||
public override void Remove(UndoBuffer undoBuffer)
|
||||
{
|
||||
using (RebuildLock())
|
||||
{
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
|
||||
Invalidate(new InvalidateArgs(this, InvalidateType.Content));
|
||||
}
|
||||
|
||||
public override void OnInvalidate(InvalidateArgs invalidateType)
|
||||
{
|
||||
if ((invalidateType.InvalidateType == InvalidateType.Content
|
||||
|| invalidateType.InvalidateType == InvalidateType.Matrix
|
||||
|| invalidateType.InvalidateType == InvalidateType.Mesh)
|
||||
&& invalidateType.Source != this
|
||||
&& !RebuildLocked)
|
||||
{
|
||||
Rebuild(null);
|
||||
}
|
||||
else if (invalidateType.InvalidateType == InvalidateType.Properties
|
||||
&& invalidateType.Source == this)
|
||||
{
|
||||
Rebuild(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnInvalidate(invalidateType);
|
||||
}
|
||||
}
|
||||
|
||||
public static FitToBoundsObject3D Create(IObject3D itemToFit)
|
||||
{
|
||||
FitToBoundsObject3D fitToBounds = new FitToBoundsObject3D();
|
||||
var aabb = itemToFit.GetAxisAlignedBoundingBox();
|
||||
|
||||
fitToBounds.Width = aabb.XSize;
|
||||
fitToBounds.Depth = aabb.YSize;
|
||||
fitToBounds.Height = aabb.ZSize;
|
||||
|
||||
fitToBounds.Diameter = aabb.XSize;
|
||||
|
||||
var scaleItem = new Object3D();
|
||||
fitToBounds.Children.Add(scaleItem);
|
||||
scaleItem.Children.Add(itemToFit);
|
||||
|
||||
return fitToBounds;
|
||||
}
|
||||
|
||||
public void Rebuild(UndoBuffer undoBuffer)
|
||||
{
|
||||
this.DebugDepth("Rebuild");
|
||||
using (RebuildLock())
|
||||
{
|
||||
var aabb = this.GetAxisAlignedBoundingBox();
|
||||
|
||||
AdjustChildSize(null, null);
|
||||
|
||||
if (aabb.ZSize > 0)
|
||||
{
|
||||
// If the part was already created and at a height, maintain the height.
|
||||
PlatingHelper.PlaceMeshAtHeight(this, aabb.minXYZ.Z);
|
||||
}
|
||||
}
|
||||
|
||||
base.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix));
|
||||
}
|
||||
|
||||
public override AxisAlignedBoundingBox GetAxisAlignedBoundingBox(Matrix4X4 matrix)
|
||||
{
|
||||
var aabb = base.GetAxisAlignedBoundingBox(matrix);
|
||||
var size = aabb.Size;
|
||||
|
||||
if (StretchX)
|
||||
{
|
||||
size.X = Width;
|
||||
}
|
||||
if (StretchY)
|
||||
{
|
||||
size.Y = Depth;
|
||||
}
|
||||
if (StretchZ)
|
||||
{
|
||||
size.Z = Height;
|
||||
}
|
||||
|
||||
var half = size / 2;
|
||||
return new AxisAlignedBoundingBox(aabb.Center - half, aabb.Center + half);
|
||||
}
|
||||
|
||||
private void AdjustChildSize(object sender, EventArgs e)
|
||||
{
|
||||
var aabb = ItemToScale.GetAxisAlignedBoundingBox();
|
||||
ScaleItem.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 (MaintainRatio)
|
||||
{
|
||||
case MaintainRatio.None:
|
||||
break;
|
||||
case MaintainRatio.X_Y:
|
||||
var minXy = Math.Min(scale.X, scale.Y);
|
||||
scale.X = minXy;
|
||||
scale.Y = minXy;
|
||||
break;
|
||||
case MaintainRatio.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;
|
||||
}
|
||||
|
||||
ScaleItem.Matrix = Object3DExtensions.ApplyAtPosition(ScaleItem.Matrix, aabb.Center, Matrix4X4.CreateScale(scale));
|
||||
}
|
||||
|
||||
public void DrawEditor(object sender, DrawEventArgs e)
|
||||
{
|
||||
if (sender is InteractionLayer layer
|
||||
&& layer.Scene.SelectedItem != null
|
||||
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
|
||||
{
|
||||
var aabb = ItemToScale.GetAxisAlignedBoundingBox();
|
||||
|
||||
if (FitType == FitType.Box)
|
||||
{
|
||||
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);
|
||||
//var leftW = Vector3.Transform(, worldMatrix);
|
||||
var right = Vector3.Transform(center + new Vector3(Width / 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, Height, 30, Color.Red, 1, 1);
|
||||
}
|
||||
// turn the lighting back on
|
||||
GL.Enable(EnableCap.Lighting);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateControls(PPEContext context)
|
||||
{
|
||||
context.GetEditRow(nameof(Diameter)).Visible = FitType != FitType.Box;
|
||||
|
||||
context.GetEditRow(nameof(Width)).Visible = FitType == FitType.Box;
|
||||
context.GetEditRow(nameof(Depth)).Visible = FitType == FitType.Box;
|
||||
context.GetEditRow(nameof(MaintainRatio)).Visible = FitType == FitType.Box;
|
||||
context.GetEditRow(nameof(StretchX)).Visible = FitType == FitType.Box;
|
||||
context.GetEditRow(nameof(StretchY)).Visible = FitType == FitType.Box;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -27,9 +27,6 @@ of the authors and should not be interpreted as representing official policies,
|
|||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.DataConverters3D;
|
||||
|
|
@ -38,22 +35,182 @@ using MatterHackers.MatterControl.PartPreviewWindow;
|
|||
using MatterHackers.MeshVisualizer;
|
||||
using MatterHackers.PolygonMesh;
|
||||
using MatterHackers.VectorMath;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
{
|
||||
public class FitToBoundsObject3D_2 : TransformWrapperObject3D, IEditorDraw
|
||||
{
|
||||
Vector3 boundsSize;
|
||||
public double Width
|
||||
private Vector3 boundsSize;
|
||||
|
||||
private AxisAlignedBoundingBox cacheAabb;
|
||||
|
||||
private Vector3 cacheBounds;
|
||||
|
||||
private Matrix4X4 cacheMatrix;
|
||||
|
||||
public FitToBoundsObject3D_2()
|
||||
{
|
||||
get => boundsSize.X;
|
||||
set
|
||||
Name = "Fit to Bounds".Localize();
|
||||
}
|
||||
|
||||
public override bool CanApply => true;
|
||||
public override bool CanRemove => true;
|
||||
private IObject3D FitBounds => Children.Last();
|
||||
|
||||
public static FitToBoundsObject3D_2 Create(IObject3D itemToFit)
|
||||
{
|
||||
var fitToBounds = new FitToBoundsObject3D_2();
|
||||
var aabb = itemToFit.GetAxisAlignedBoundingBox();
|
||||
|
||||
var bounds = new Object3D()
|
||||
{
|
||||
boundsSize.X = value;
|
||||
UpdateBoundsItem();
|
||||
Visible = false,
|
||||
Color = new Color(Color.Red, 100),
|
||||
Mesh = PlatonicSolids.CreateCube()
|
||||
};
|
||||
|
||||
// add all the children
|
||||
var scaleItem = new Object3D();
|
||||
fitToBounds.Children.Add(scaleItem);
|
||||
scaleItem.Children.Add(itemToFit);
|
||||
fitToBounds.Children.Add(bounds);
|
||||
|
||||
fitToBounds.SizeX = aabb.XSize;
|
||||
fitToBounds.SizeY = aabb.YSize;
|
||||
fitToBounds.SizeZ = aabb.ZSize;
|
||||
|
||||
return fitToBounds;
|
||||
}
|
||||
|
||||
public void DrawEditor(object sender, DrawEventArgs e)
|
||||
{
|
||||
if (sender is InteractionLayer layer
|
||||
&& layer.Scene.SelectedItem != null
|
||||
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
|
||||
{
|
||||
var aabb = SourceItem.GetAxisAlignedBoundingBox();
|
||||
|
||||
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 = Vector3.Transform(, worldMatrix);
|
||||
var right = Vector3.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);
|
||||
}
|
||||
}
|
||||
|
||||
public override AxisAlignedBoundingBox GetAxisAlignedBoundingBox(Matrix4X4 matrix)
|
||||
{
|
||||
if (Children.Count == 2)
|
||||
{
|
||||
if (cacheMatrix != matrix
|
||||
|| cacheBounds != boundsSize)
|
||||
{
|
||||
using (FitBounds.RebuildLock())
|
||||
{
|
||||
FitBounds.Visible = true;
|
||||
cacheAabb = base.GetAxisAlignedBoundingBox(matrix);
|
||||
FitBounds.Visible = false;
|
||||
}
|
||||
cacheMatrix = matrix;
|
||||
cacheBounds = boundsSize;
|
||||
}
|
||||
|
||||
return cacheAabb;
|
||||
}
|
||||
|
||||
return base.GetAxisAlignedBoundingBox(matrix);
|
||||
}
|
||||
|
||||
public override void OnInvalidate(InvalidateArgs invalidateType)
|
||||
{
|
||||
if ((invalidateType.InvalidateType == InvalidateType.Content
|
||||
|| invalidateType.InvalidateType == InvalidateType.Matrix
|
||||
|| invalidateType.InvalidateType == InvalidateType.Mesh)
|
||||
&& invalidateType.Source != this
|
||||
&& !RebuildLocked)
|
||||
{
|
||||
Rebuild(null);
|
||||
}
|
||||
else if (invalidateType.InvalidateType == InvalidateType.Properties
|
||||
&& invalidateType.Source == this)
|
||||
{
|
||||
Rebuild(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnInvalidate(invalidateType);
|
||||
}
|
||||
}
|
||||
|
||||
public void Rebuild(UndoBuffer undoBuffer)
|
||||
{
|
||||
this.DebugDepth("Rebuild");
|
||||
using (RebuildLock())
|
||||
{
|
||||
UpdateBoundsItem();
|
||||
|
||||
var aabb = this.GetAxisAlignedBoundingBox();
|
||||
|
||||
AdjustChildSize(null, null);
|
||||
|
||||
if (aabb.ZSize > 0)
|
||||
{
|
||||
// If the part was already created and at a height, maintain the height.
|
||||
PlatingHelper.PlaceMeshAtHeight(this, aabb.minXYZ.Z);
|
||||
}
|
||||
}
|
||||
|
||||
base.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix));
|
||||
}
|
||||
|
||||
private void AdjustChildSize(object sender, EventArgs e)
|
||||
{
|
||||
var aabb = SourceItem.GetAxisAlignedBoundingBox();
|
||||
TransformItem.Matrix = Matrix4X4.Identity;
|
||||
var scale = Vector3.One;
|
||||
if (StretchX)
|
||||
{
|
||||
scale.X = SizeX / aabb.XSize;
|
||||
}
|
||||
if (StretchY)
|
||||
{
|
||||
scale.Y = SizeY / aabb.YSize;
|
||||
}
|
||||
if (StretchZ)
|
||||
{
|
||||
scale.Z = SizeZ / aabb.ZSize;
|
||||
}
|
||||
|
||||
switch (MaintainRatio)
|
||||
{
|
||||
case MaintainRatio.None:
|
||||
break;
|
||||
|
||||
case MaintainRatio.X_Y:
|
||||
var minXy = Math.Min(scale.X, scale.Y);
|
||||
scale.X = minXy;
|
||||
scale.Y = minXy;
|
||||
break;
|
||||
|
||||
case MaintainRatio.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;
|
||||
}
|
||||
|
||||
TransformItem.Matrix = Object3DExtensions.ApplyAtPosition(TransformItem.Matrix, aabb.Center, Matrix4X4.CreateScale(scale));
|
||||
}
|
||||
|
||||
private void UpdateBoundsItem()
|
||||
{
|
||||
if (Children.Count == 2)
|
||||
|
|
@ -76,7 +233,24 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
}
|
||||
}
|
||||
|
||||
public double Depth
|
||||
#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;
|
||||
UpdateBoundsItem();
|
||||
}
|
||||
}
|
||||
|
||||
[DisplayName("Depth")]
|
||||
public double SizeY
|
||||
{
|
||||
get => boundsSize.Y;
|
||||
set
|
||||
|
|
@ -85,7 +259,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
UpdateBoundsItem();
|
||||
}
|
||||
}
|
||||
public double Height
|
||||
|
||||
[DisplayName("Height")]
|
||||
public double SizeZ
|
||||
{
|
||||
get => boundsSize.Z;
|
||||
set
|
||||
|
|
@ -95,172 +271,15 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
}
|
||||
}
|
||||
|
||||
private IObject3D FitBounds => Children.Last();
|
||||
|
||||
[Description("Set the rules for how to maintain the part while scaling.")]
|
||||
public MaintainRatio MaintainRatio { get; set; } = MaintainRatio.X_Y;
|
||||
[Description("Allows you turn turn on and off applying the fit to the x axis.")]
|
||||
public bool StretchX { get; set; } = true;
|
||||
|
||||
[Description("Allows you turn turn on and off applying the fit to the y axis.")]
|
||||
public bool StretchY { get; set; } = true;
|
||||
|
||||
[Description("Allows you turn turn on and off applying the fit to the z axis.")]
|
||||
public bool StretchZ { get; set; } = true;
|
||||
|
||||
public FitToBoundsObject3D_2()
|
||||
{
|
||||
Name = "Fit to Bounds".Localize();
|
||||
}
|
||||
|
||||
public override void OnInvalidate(InvalidateArgs invalidateType)
|
||||
{
|
||||
if ((invalidateType.InvalidateType == InvalidateType.Content
|
||||
|| invalidateType.InvalidateType == InvalidateType.Matrix
|
||||
|| invalidateType.InvalidateType == InvalidateType.Mesh)
|
||||
&& invalidateType.Source != this
|
||||
&& !RebuildLocked)
|
||||
{
|
||||
Rebuild(null);
|
||||
}
|
||||
else if (invalidateType.InvalidateType == InvalidateType.Properties
|
||||
&& invalidateType.Source == this)
|
||||
{
|
||||
Rebuild(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnInvalidate(invalidateType);
|
||||
}
|
||||
}
|
||||
|
||||
public static FitToBoundsObject3D_2 Create(IObject3D itemToFit)
|
||||
{
|
||||
var fitToBounds = new FitToBoundsObject3D_2();
|
||||
var aabb = itemToFit.GetAxisAlignedBoundingBox();
|
||||
|
||||
var bounds = new Object3D()
|
||||
{
|
||||
Visible = false,
|
||||
Color = new Color(Color.Red, 100),
|
||||
Mesh = PlatonicSolids.CreateCube()
|
||||
};
|
||||
|
||||
// add all the children
|
||||
var scaleItem = new Object3D();
|
||||
fitToBounds.Children.Add(scaleItem);
|
||||
scaleItem.Children.Add(itemToFit);
|
||||
fitToBounds.Children.Add(bounds);
|
||||
|
||||
fitToBounds.Width = aabb.XSize;
|
||||
fitToBounds.Depth = aabb.YSize;
|
||||
fitToBounds.Height = aabb.ZSize;
|
||||
|
||||
return fitToBounds;
|
||||
}
|
||||
|
||||
public void Rebuild(UndoBuffer undoBuffer)
|
||||
{
|
||||
this.DebugDepth("Rebuild");
|
||||
using (RebuildLock())
|
||||
{
|
||||
UpdateBoundsItem();
|
||||
|
||||
var aabb = this.GetAxisAlignedBoundingBox();
|
||||
|
||||
AdjustChildSize(null, null);
|
||||
|
||||
if (aabb.ZSize > 0)
|
||||
{
|
||||
// If the part was already created and at a height, maintain the height.
|
||||
PlatingHelper.PlaceMeshAtHeight(this, aabb.minXYZ.Z);
|
||||
}
|
||||
}
|
||||
|
||||
base.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix));
|
||||
}
|
||||
|
||||
Matrix4X4 cacheMatrix;
|
||||
Vector3 cacheBounds;
|
||||
AxisAlignedBoundingBox cacheAabb;
|
||||
public override AxisAlignedBoundingBox GetAxisAlignedBoundingBox(Matrix4X4 matrix)
|
||||
{
|
||||
if (Children.Count == 2)
|
||||
{
|
||||
if (cacheMatrix != matrix
|
||||
|| cacheBounds != boundsSize)
|
||||
{
|
||||
using (FitBounds.RebuildLock())
|
||||
{
|
||||
FitBounds.Visible = true;
|
||||
cacheAabb = base.GetAxisAlignedBoundingBox(matrix);
|
||||
FitBounds.Visible = false;
|
||||
}
|
||||
cacheMatrix = matrix;
|
||||
cacheBounds = boundsSize;
|
||||
}
|
||||
|
||||
return cacheAabb;
|
||||
}
|
||||
|
||||
return base.GetAxisAlignedBoundingBox(matrix);
|
||||
}
|
||||
|
||||
private void AdjustChildSize(object sender, EventArgs e)
|
||||
{
|
||||
var aabb = SourceItem.GetAxisAlignedBoundingBox();
|
||||
TransformItem.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 (MaintainRatio)
|
||||
{
|
||||
case MaintainRatio.None:
|
||||
break;
|
||||
case MaintainRatio.X_Y:
|
||||
var minXy = Math.Min(scale.X, scale.Y);
|
||||
scale.X = minXy;
|
||||
scale.Y = minXy;
|
||||
break;
|
||||
case MaintainRatio.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;
|
||||
}
|
||||
|
||||
TransformItem.Matrix = Object3DExtensions.ApplyAtPosition(TransformItem.Matrix, aabb.Center, Matrix4X4.CreateScale(scale));
|
||||
}
|
||||
|
||||
public void DrawEditor(object sender, DrawEventArgs e)
|
||||
{
|
||||
if (sender is InteractionLayer layer
|
||||
&& layer.Scene.SelectedItem != null
|
||||
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
|
||||
{
|
||||
var aabb = SourceItem.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);
|
||||
//var leftW = Vector3.Transform(, worldMatrix);
|
||||
var right = Vector3.Transform(center + new Vector3(Width / 2, 0, 0), worldMatrix);
|
||||
// layer.World.Render3DLine(left, right, Agg.Color.Red);
|
||||
layer.World.RenderAabb(bounds, worldMatrix, Agg.Color.Red, 1, 1);
|
||||
}
|
||||
}
|
||||
#endregion // editable properties
|
||||
}
|
||||
}
|
||||
|
|
@ -1,118 +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 MatterHackers.Agg.UI;
|
||||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.VectorMath;
|
||||
using Newtonsoft.Json;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
{
|
||||
public class RotateObject3D : Object3D
|
||||
{
|
||||
[DisplayName("X")]
|
||||
[Description("Rotate about the X axis")]
|
||||
public double RotationXDegrees { get; set; }
|
||||
[DisplayName("Y")]
|
||||
[Description("Rotate about the Y axis")]
|
||||
public double RotationYDegrees { get; set; }
|
||||
[DisplayName("Z")]
|
||||
[Description("Rotate about the Z axis")]
|
||||
public double RotationZDegrees { get; set; }
|
||||
|
||||
public RotateObject3D()
|
||||
{
|
||||
Name = "Rotate".Localize();
|
||||
}
|
||||
|
||||
public RotateObject3D(IObject3D item, double xRadians = 0, double yRadians = 0, double zRadians = 0, string name = "")
|
||||
{
|
||||
RotationXDegrees = MathHelper.RadiansToDegrees(xRadians);
|
||||
RotationYDegrees = MathHelper.RadiansToDegrees(yRadians);
|
||||
RotationZDegrees = MathHelper.RadiansToDegrees(zRadians);
|
||||
Children.Add(item.Clone());
|
||||
|
||||
Rebuild(null);
|
||||
}
|
||||
|
||||
public RotateObject3D(IObject3D item, Vector3 translation, string name = "")
|
||||
: this(item, translation.X, translation.Y, translation.Z, name)
|
||||
{
|
||||
}
|
||||
|
||||
private void Rebuild(UndoBuffer undoBuffer)
|
||||
{
|
||||
this.DebugDepth("Rebuild");
|
||||
|
||||
using (RebuildLock())
|
||||
{
|
||||
var startingAabb = this.GetAxisAlignedBoundingBox();
|
||||
|
||||
// remove whatever rotation has been applied (they go in reverse order)
|
||||
Matrix = Matrix4X4.Identity;
|
||||
|
||||
// add the current rotation
|
||||
Matrix = this.ApplyAtPosition(startingAabb.Center, Matrix4X4.CreateRotationX(MathHelper.DegreesToRadians(RotationXDegrees)));
|
||||
Matrix = this.ApplyAtPosition(startingAabb.Center, Matrix4X4.CreateRotationY(MathHelper.DegreesToRadians(RotationYDegrees)));
|
||||
Matrix = this.ApplyAtPosition(startingAabb.Center, Matrix4X4.CreateRotationZ(MathHelper.DegreesToRadians(RotationZDegrees)));
|
||||
|
||||
if (startingAabb.ZSize > 0)
|
||||
{
|
||||
// If the part was already created and at a height, maintain the height.
|
||||
PlatingHelper.PlaceMeshAtHeight(this, startingAabb.minXYZ.Z);
|
||||
}
|
||||
}
|
||||
|
||||
Invalidate(new InvalidateArgs(this, InvalidateType.Matrix, null));
|
||||
}
|
||||
|
||||
public override void OnInvalidate(InvalidateArgs invalidateType)
|
||||
{
|
||||
if ((invalidateType.InvalidateType == InvalidateType.Content
|
||||
|| invalidateType.InvalidateType == InvalidateType.Matrix
|
||||
|| invalidateType.InvalidateType == InvalidateType.Mesh)
|
||||
&& invalidateType.Source != this
|
||||
&& !RebuildLocked)
|
||||
{
|
||||
Rebuild(null);
|
||||
}
|
||||
else if (invalidateType.InvalidateType == InvalidateType.Properties
|
||||
&& invalidateType.Source == this)
|
||||
{
|
||||
Rebuild(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnInvalidate(invalidateType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,30 +30,25 @@ 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.MatterControl.PartPreviewWindow;
|
||||
using MatterHackers.MeshVisualizer;
|
||||
using MatterHackers.RenderOpenGl.OpenGl;
|
||||
using MatterHackers.VectorMath;
|
||||
using Newtonsoft.Json;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using MatterHackers.MatterControl.DesignTools.EditableTypes;
|
||||
using System;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
{
|
||||
public class RotateObject3D_2 : TransformWrapperObject3D, IEditorDraw
|
||||
{
|
||||
public DirectionAxis RotateAbout { get; set; } = new DirectionAxis() { Origin = Vector3.NegativeInfinity, Normal = Vector3.UnitZ };
|
||||
[DisplayName("Angle")]
|
||||
public double AngleDegrees { get; set; } = 0;
|
||||
|
||||
public RotateObject3D_2()
|
||||
{
|
||||
Name = "Rotate".Localize();
|
||||
}
|
||||
|
||||
public RotateObject3D_2(IObject3D item, double xRadians = 0, double yRadians = 0, double zRadians = 0, string name = "")
|
||||
: this()
|
||||
{
|
||||
Children.Add(item.Clone());
|
||||
|
||||
|
|
@ -65,6 +60,15 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
{
|
||||
}
|
||||
|
||||
public override bool CanApply => true;
|
||||
public override bool CanRemove => true;
|
||||
|
||||
#region // editable properties
|
||||
public DirectionAxis RotateAbout { get; set; } = new DirectionAxis() { Origin = Vector3.NegativeInfinity, Normal = Vector3.UnitZ };
|
||||
[DisplayName("Angle")]
|
||||
public double AngleDegrees { get; set; } = 0;
|
||||
#endregion
|
||||
|
||||
[JsonIgnore]
|
||||
public Matrix4X4 RotationMatrix
|
||||
{
|
||||
|
|
@ -79,17 +83,28 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
}
|
||||
}
|
||||
|
||||
private void Rebuild(UndoBuffer undoBuffer)
|
||||
public static RotateObject3D_2 Create(IObject3D itemToRotate)
|
||||
{
|
||||
this.DebugDepth("Rebuild");
|
||||
var rotate = new RotateObject3D_2();
|
||||
var aabb = itemToRotate.GetAxisAlignedBoundingBox();
|
||||
|
||||
using (RebuildLock())
|
||||
rotate.RotateAbout.Origin = aabb.Center;
|
||||
|
||||
var rotateItem = new Object3D();
|
||||
rotate.Children.Add(rotateItem);
|
||||
rotateItem.Children.Add(itemToRotate);
|
||||
|
||||
return rotate;
|
||||
}
|
||||
|
||||
public void DrawEditor(object sender, DrawEventArgs e)
|
||||
{
|
||||
if (sender is InteractionLayer layer
|
||||
&& layer.Scene.SelectedItem != null
|
||||
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
|
||||
{
|
||||
// set the matrix for the inner object
|
||||
TransformItem.Matrix = RotationMatrix;
|
||||
layer.World.RenderDirectionAxis(RotateAbout, this.WorldMatrix(), 30);
|
||||
}
|
||||
|
||||
Invalidate(new InvalidateArgs(this, InvalidateType.Matrix, null));
|
||||
}
|
||||
|
||||
public override void OnInvalidate(InvalidateArgs invalidateType)
|
||||
|
|
@ -126,28 +141,17 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
}
|
||||
}
|
||||
|
||||
public void DrawEditor(object sender, DrawEventArgs e)
|
||||
private void Rebuild(UndoBuffer undoBuffer)
|
||||
{
|
||||
if (sender is InteractionLayer layer
|
||||
&& layer.Scene.SelectedItem != null
|
||||
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
|
||||
this.DebugDepth("Rebuild");
|
||||
|
||||
using (RebuildLock())
|
||||
{
|
||||
layer.World.RenderDirectionAxis(RotateAbout, this.WorldMatrix(), 30);
|
||||
// set the matrix for the inner object
|
||||
TransformItem.Matrix = RotationMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
public static RotateObject3D_2 Create(IObject3D itemToRotate)
|
||||
{
|
||||
var rotate = new RotateObject3D_2();
|
||||
var aabb = itemToRotate.GetAxisAlignedBoundingBox();
|
||||
|
||||
rotate.RotateAbout.Origin = aabb.Center;
|
||||
|
||||
var rotateItem = new Object3D();
|
||||
rotate.Children.Add(rotateItem);
|
||||
rotateItem.Children.Add(itemToRotate);
|
||||
|
||||
return rotate;
|
||||
Invalidate(new InvalidateArgs(this, InvalidateType.Matrix, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -27,15 +27,19 @@ 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.VectorMath;
|
||||
using System.Linq;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
{
|
||||
public class TranslateObject3D : Object3D
|
||||
public class TranslateObject3D : TransformWrapperObject3D
|
||||
{
|
||||
public TranslateObject3D()
|
||||
{
|
||||
Name = "Translate".Localize();
|
||||
}
|
||||
|
||||
public TranslateObject3D(IObject3D item, double x = 0, double y = 0, double z = 0)
|
||||
|
|
@ -43,10 +47,84 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
{
|
||||
}
|
||||
|
||||
public TranslateObject3D(IObject3D item, Vector3 translation)
|
||||
public TranslateObject3D(IObject3D itemToTranslate, Vector3 translation)
|
||||
: this()
|
||||
{
|
||||
Matrix *= Matrix4X4.CreateTranslation(translation);
|
||||
Children.Add(item.Clone());
|
||||
var translate = this;
|
||||
var aabb = itemToTranslate.GetAxisAlignedBoundingBox();
|
||||
|
||||
var translateItem = new Object3D();
|
||||
translate.Children.Add(translateItem);
|
||||
translateItem.Children.Add(itemToTranslate);
|
||||
}
|
||||
|
||||
public override bool CanApply => true;
|
||||
|
||||
public override bool CanRemove => true;
|
||||
|
||||
public static TranslateObject3D Create(IObject3D itemToTranslate)
|
||||
{
|
||||
var translate = new TranslateObject3D();
|
||||
var aabb = itemToTranslate.GetAxisAlignedBoundingBox();
|
||||
|
||||
var translateItem = new Object3D();
|
||||
translate.Children.Add(translateItem);
|
||||
translateItem.Children.Add(itemToTranslate);
|
||||
|
||||
return translate;
|
||||
}
|
||||
|
||||
#region // editable properties
|
||||
|
||||
public Vector3 Translation { get; set; } = Vector3.Zero;
|
||||
|
||||
#endregion // editable properties
|
||||
|
||||
public override void OnInvalidate(InvalidateArgs invalidateType)
|
||||
{
|
||||
if ((invalidateType.InvalidateType == InvalidateType.Content
|
||||
|| invalidateType.InvalidateType == InvalidateType.Matrix
|
||||
|| invalidateType.InvalidateType == InvalidateType.Mesh)
|
||||
&& invalidateType.Source != this
|
||||
&& !RebuildLocked)
|
||||
{
|
||||
Rebuild(null);
|
||||
}
|
||||
else if (invalidateType.InvalidateType == InvalidateType.Color)
|
||||
{
|
||||
var sourceItem = OperationSourceObject3D.GetOrCreateSourceContainer(this).Children.FirstOrDefault();
|
||||
foreach (var item in Children)
|
||||
{
|
||||
if (item != sourceItem)
|
||||
{
|
||||
item.Color = sourceItem.Color;
|
||||
}
|
||||
}
|
||||
|
||||
base.OnInvalidate(invalidateType);
|
||||
}
|
||||
else if (invalidateType.InvalidateType == InvalidateType.Properties
|
||||
&& invalidateType.Source == this)
|
||||
{
|
||||
Rebuild(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnInvalidate(invalidateType);
|
||||
}
|
||||
}
|
||||
|
||||
private void Rebuild(UndoBuffer undoBuffer)
|
||||
{
|
||||
this.DebugDepth("Rebuild");
|
||||
|
||||
using (RebuildLock())
|
||||
{
|
||||
// set the matrix for the inner object
|
||||
TransformItem.Matrix = Matrix4X4.CreateTranslation(Translation);
|
||||
}
|
||||
|
||||
Invalidate(new InvalidateArgs(this, InvalidateType.Matrix, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue