Added new fit to bounds
This should allow use objects like card holder alignment made aabb rendering more generic Added editor draw to objects
This commit is contained in:
parent
78f73597c5
commit
bf18085e89
9 changed files with 215 additions and 68 deletions
|
|
@ -40,6 +40,7 @@ using MatterHackers.MatterControl.DataStorage;
|
|||
using MatterHackers.MatterControl.PrinterCommunication;
|
||||
using MatterHackers.MatterControl.PrintQueue;
|
||||
using MatterHackers.MatterControl.SlicerConfiguration;
|
||||
using MatterHackers.MatterControl.DesignTools.Operations;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
|
|
@ -458,6 +459,23 @@ namespace MatterHackers.MatterControl
|
|||
Icon = AggContext.StaticData.LoadIcon("array_advanced.png").SetPreMultiply(),
|
||||
IsEnabled = (scene) => scene.HasSelection && !(scene.SelectedItem is SelectionGroup),
|
||||
},
|
||||
new SceneSelectionOperation()
|
||||
{
|
||||
TitleResolver = () => "Fit to Bounds".Localize(),
|
||||
Action = (scene) =>
|
||||
{
|
||||
var selectedItem = scene.SelectedItem;
|
||||
scene.SelectedItem = null;
|
||||
var fit = FitToBounds.Create(selectedItem.Clone());
|
||||
fit.MakeNameNonColliding();
|
||||
|
||||
scene.UndoBuffer.AddAndDo(new ReplaceCommand(new List<IObject3D> { selectedItem }, new List<IObject3D> { fit }));
|
||||
|
||||
scene.SelectedItem = fit;
|
||||
},
|
||||
//Icon = AggContext.StaticData.LoadIcon("array_linear.png").SetPreMultiply(),
|
||||
IsEnabled = (scene) => scene.HasSelection && !(scene.SelectedItem is SelectionGroup),
|
||||
},
|
||||
#if DEBUG // keep this work in progress to the editor for now
|
||||
new SceneSelectionSeparator(),
|
||||
new SceneSelectionOperation()
|
||||
|
|
|
|||
|
|
@ -27,52 +27,14 @@ of the authors and should not be interpreted as representing official policies,
|
|||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.VectorMath;
|
||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
namespace MatterHackers.MatterControl.DesignTools
|
||||
{
|
||||
public class ScaleObject3D : Object3D, IRebuildable
|
||||
public interface IEditorDraw
|
||||
{
|
||||
public ScaleObject3D()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanRemove => true;
|
||||
public override bool CanBake => true;
|
||||
|
||||
public override void Remove()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Rebuild(UndoBuffer undoBuffer)
|
||||
{
|
||||
var aabb = this.GetAxisAlignedBoundingBox();
|
||||
|
||||
// TODO: check if the has code for the children
|
||||
//if (ChildrenBounds.Count == 0)
|
||||
{
|
||||
this.Children.Modify(list =>
|
||||
{
|
||||
foreach (var child in list)
|
||||
{
|
||||
//ChildrenBounds.Add(child.GetAxisAlignedBoundingBox());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.Children.Modify(list =>
|
||||
{
|
||||
// var firstBounds = ChildrenBounds[0];
|
||||
int i = 0;
|
||||
foreach (var child in list)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
});
|
||||
}
|
||||
void DrawEditor(object sender, DrawEventArgs e);
|
||||
}
|
||||
}
|
||||
|
|
@ -41,7 +41,6 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
{
|
||||
Name = "Linear Array".Localize();
|
||||
}
|
||||
|
||||
|
||||
public override bool CanBake => true;
|
||||
public override bool CanRemove => true;
|
||||
|
|
|
|||
155
DesignTools/Operations/FitToBounds.cs
Normal file
155
DesignTools/Operations/FitToBounds.cs
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
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.Drawing;
|
||||
using System.Linq;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||
using MatterHackers.MeshVisualizer;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
using MatterHackers.RenderOpenGl.OpenGl;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools.Operations
|
||||
{
|
||||
public enum MaintainRatio { None, X_Y, X_Y_Z }
|
||||
|
||||
public class FitToBounds : Object3D, IRebuildable, IEditorDraw
|
||||
{
|
||||
public double Width { get; set; }
|
||||
public double Depth { get; set; }
|
||||
public double Height { get; set; }
|
||||
|
||||
public MaintainRatio MaintainRatio { get; set; } = MaintainRatio.X_Y;
|
||||
public bool StretchX { get; set; } = true;
|
||||
public bool StretchY { get; set; } = true;
|
||||
public bool StretchZ { get; set; } = true;
|
||||
|
||||
IObject3D ScaleItem => Children.First();
|
||||
IObject3D ItemToScale => Children.First().Children.First();
|
||||
|
||||
public FitToBounds()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnInvalidate()
|
||||
{
|
||||
// If the child bounds changed than adjust the scale control
|
||||
base.OnInvalidate();
|
||||
}
|
||||
|
||||
public static FitToBounds Create(IObject3D itemToFit)
|
||||
{
|
||||
FitToBounds fitToBounds = new FitToBounds();
|
||||
var aabb = itemToFit.GetAxisAlignedBoundingBox();
|
||||
|
||||
fitToBounds.Width = aabb.XSize;
|
||||
fitToBounds.Depth = aabb.YSize;
|
||||
fitToBounds.Height = aabb.ZSize;
|
||||
|
||||
var scaleItem = new Object3D();
|
||||
fitToBounds.Children.Add(scaleItem);
|
||||
scaleItem.Children.Add(itemToFit);
|
||||
|
||||
return fitToBounds;
|
||||
}
|
||||
|
||||
public void Rebuild(UndoBuffer undoBuffer)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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, Matrix4X4.CreateScale(scale), aabb.Center);
|
||||
}
|
||||
|
||||
public void DrawEditor(object sender, DrawEventArgs e)
|
||||
{
|
||||
if (sender is InteractionLayer layer
|
||||
&& layer.Scene.SelectedItem == this)
|
||||
{
|
||||
var aabb = ItemToScale.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);
|
||||
// GLHelper.Render3DLine(layer.World, left, right, Agg.Color.Red);
|
||||
layer.World.RenderAabb(bounds, worldMatrix, Agg.Color.Red, 1);
|
||||
// turn the lighting back on
|
||||
GL.Enable(EnableCap.Lighting);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -78,6 +78,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
var aabb = this.GetAxisAlignedBoundingBox();
|
||||
|
||||
Mesh = PlatonicSolids.CreateCube(Width, Depth, Height);
|
||||
|
||||
if (aabb.ZSize > 0)
|
||||
{
|
||||
// If the part was already created and at a height, maintain the height.
|
||||
|
|
|
|||
|
|
@ -77,6 +77,15 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
HAnchor = HAnchor.Stretch
|
||||
};
|
||||
|
||||
if(item is IEditorDraw editorDraw)
|
||||
{
|
||||
view3DWidget.InteractionLayer.DrawGlOpaqueContent += editorDraw.DrawEditor;
|
||||
mainContainer.Closed += (s, e) =>
|
||||
{
|
||||
view3DWidget.InteractionLayer.DrawGlOpaqueContent -= editorDraw.DrawEditor;
|
||||
};
|
||||
}
|
||||
|
||||
if (this.item != null)
|
||||
{
|
||||
ModifyObject(view3DWidget, mainContainer, theme);
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@
|
|||
<Compile Include="DesignTools\Attributes\IconsAttribute.cs" />
|
||||
<Compile Include="DesignTools\Attributes\WebPageLinkAttribute.cs" />
|
||||
<Compile Include="DesignTools\ImageAsset.cs" />
|
||||
<Compile Include="DesignTools\Interfaces\IEditorDraw.cs" />
|
||||
<Compile Include="DesignTools\Interfaces\IPropertyGridModifier.cs" />
|
||||
<Compile Include="DesignTools\Interfaces\IRebuildable.cs" />
|
||||
<Compile Include="DesignTools\Operations\ArrangeObject3D.cs" />
|
||||
|
|
@ -99,11 +100,11 @@
|
|||
<Compile Include="DesignTools\Operations\ArrayLinearObject3D.cs" />
|
||||
<Compile Include="DesignTools\Operations\ArrayRadialObject3D.cs" />
|
||||
<Compile Include="DesignTools\Operations\BendObject3D.cs" />
|
||||
<Compile Include="DesignTools\Operations\FitToBounds.cs" />
|
||||
<Compile Include="DesignTools\Operations\Object3DExtensions.cs" />
|
||||
<Compile Include="DesignTools\Operations\Align.cs" />
|
||||
<Compile Include="DesignTools\Operations\Rotate.cs" />
|
||||
<Compile Include="DesignTools\Operations\Scale.cs" />
|
||||
<Compile Include="DesignTools\Operations\ScaleObject3D.cs" />
|
||||
<Compile Include="DesignTools\Operations\SmoothPath.cs" />
|
||||
<Compile Include="DesignTools\Primitives\BaseObject3D.cs" />
|
||||
<Compile Include="DesignTools\Primitives\RingObject3D.cs" />
|
||||
|
|
|
|||
|
|
@ -63,6 +63,26 @@ namespace MatterHackers.MeshVisualizer
|
|||
|
||||
public static class MaterialRendering
|
||||
{
|
||||
public static void RenderAabb(this WorldView world, AxisAlignedBoundingBox bounds, Matrix4X4 matrix, Color color, double width)
|
||||
{
|
||||
GLHelper.PrepareFor3DLineRender(true);
|
||||
|
||||
Frustum frustum = world.GetClippingFrustum();
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Vector3 bottomStartPosition = Vector3.Transform(bounds.GetBottomCorner(i), matrix);
|
||||
Vector3 bottomEndPosition = Vector3.Transform(bounds.GetBottomCorner((i + 1) % 4), matrix);
|
||||
Vector3 topStartPosition = Vector3.Transform(bounds.GetTopCorner(i), matrix);
|
||||
Vector3 topEndPosition = Vector3.Transform(bounds.GetTopCorner((i + 1) % 4), matrix);
|
||||
|
||||
GLHelper.Render3DLineNoPrep(frustum, world, bottomStartPosition, bottomEndPosition, color, width);
|
||||
GLHelper.Render3DLineNoPrep(frustum, world, topStartPosition, topEndPosition, color, width);
|
||||
GLHelper.Render3DLineNoPrep(frustum, world, topStartPosition, bottomStartPosition, color, width);
|
||||
}
|
||||
|
||||
GL.Enable(EnableCap.Lighting);
|
||||
}
|
||||
|
||||
public static Color Color(int materialIndex)
|
||||
{
|
||||
return ColorF.FromHSL(Math.Max(materialIndex, 0) / 10.0, .99, .49).ToColor();
|
||||
|
|
@ -521,9 +541,7 @@ namespace MatterHackers.MeshVisualizer
|
|||
if (totalVertices > maxVerticesToRenderOutline
|
||||
&& scene.DebugItem == null)
|
||||
{
|
||||
GLHelper.PrepareFor3DLineRender(true);
|
||||
RenderAABB(frustum, object3D.GetAxisAlignedBoundingBox(Matrix4X4.Identity), Matrix4X4.Identity, selectionColor, selectionHighlightWidth);
|
||||
GL.Enable(EnableCap.Lighting);
|
||||
World.RenderAabb(object3D.GetAxisAlignedBoundingBox(Matrix4X4.Identity), Matrix4X4.Identity, selectionColor, selectionHighlightWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -538,8 +556,7 @@ namespace MatterHackers.MeshVisualizer
|
|||
|
||||
var aabb = object3D.GetAxisAlignedBoundingBox(Matrix4X4.Identity);
|
||||
|
||||
GLHelper.PrepareFor3DLineRender(true);
|
||||
RenderAABB(frustum, aabb, Matrix4X4.Identity, debugBorderColor, 1);
|
||||
World.RenderAabb(aabb, Matrix4X4.Identity, debugBorderColor, 1);
|
||||
|
||||
if (item.mesh != null)
|
||||
{
|
||||
|
|
@ -656,12 +673,12 @@ namespace MatterHackers.MeshVisualizer
|
|||
|
||||
if(!renderedAnything)
|
||||
{
|
||||
RenderAABB(frustum, renderData.Mesh.GetAxisAlignedBoundingBox(), renderData.WorldMatrix(), selectionColor, selectionHighlightWidth);
|
||||
World.RenderAabb(renderData.Mesh.GetAxisAlignedBoundingBox(), renderData.WorldMatrix(), selectionColor, selectionHighlightWidth);
|
||||
}
|
||||
}
|
||||
else // just render the bounding box
|
||||
{
|
||||
RenderAABB(frustum, renderData.Mesh.GetAxisAlignedBoundingBox(), renderData.WorldMatrix(), selectionColor, selectionHighlightWidth);
|
||||
World.RenderAabb(renderData.Mesh.GetAxisAlignedBoundingBox(), renderData.WorldMatrix(), selectionColor, selectionHighlightWidth);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -676,21 +693,6 @@ namespace MatterHackers.MeshVisualizer
|
|||
return 2.0f * t * (1.0f - t) + 0.5;
|
||||
}
|
||||
|
||||
void RenderAABB(Frustum frustum, AxisAlignedBoundingBox bounds, Matrix4X4 matrix, Color color, double width)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Vector3 bottomStartPosition = Vector3.Transform(bounds.GetBottomCorner(i), matrix);
|
||||
Vector3 bottomEndPosition = Vector3.Transform(bounds.GetBottomCorner((i + 1) % 4), matrix);
|
||||
Vector3 topStartPosition = Vector3.Transform(bounds.GetTopCorner(i), matrix);
|
||||
Vector3 topEndPosition = Vector3.Transform(bounds.GetTopCorner((i + 1) % 4), matrix);
|
||||
|
||||
GLHelper.Render3DLineNoPrep(frustum, World, bottomStartPosition, bottomEndPosition, color, width);
|
||||
GLHelper.Render3DLineNoPrep(frustum, World, topStartPosition, topEndPosition, color, width);
|
||||
GLHelper.Render3DLineNoPrep(frustum, World, topStartPosition, bottomStartPosition, color, width);
|
||||
}
|
||||
}
|
||||
|
||||
public enum EditorType { Printer, Part }
|
||||
|
||||
public EditorType EditorMode { get; set; } = EditorType.Part;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit a20e22e4c02539f81a657db103e1589f2326ebdd
|
||||
Subproject commit 11517c9302bd8ad6161de3192168d47ec8e03d5a
|
||||
Loading…
Add table
Add a link
Reference in a new issue