Finished (for now) fit to bounds 4

Added wraping to single line text object
This commit is contained in:
MatterHackers 2023-11-19 20:19:46 -08:00
parent e78e59e849
commit ae67d206a2
3 changed files with 90 additions and 83 deletions

View file

@ -36,13 +36,14 @@ using MatterHackers.PolygonMesh;
using MatterHackers.RenderOpenGl; using MatterHackers.RenderOpenGl;
using MatterHackers.VectorMath; using MatterHackers.VectorMath;
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace MatterHackers.MatterControl.DesignTools.Operations namespace MatterHackers.MatterControl.DesignTools.Operations
{ {
public class FitToBoundsObject3D_4 : TransformWrapperObject3D, IEditorDraw public class FitToBoundsObject3D_4 : TransformWrapperObject3D, IEditorDraw, IPropertyGridModifier
{ {
private InvalidateType additonalInvalidate; private InvalidateType additonalInvalidate;
@ -61,6 +62,13 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
Expand Expand
} }
public enum FitAlign
{
Min,
Center,
Max
}
private IObject3D FitBounds => Children.Last(); private IObject3D FitBounds => Children.Last();
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)] [EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)]
@ -76,30 +84,30 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
[MaxDecimalPlaces(3)] [MaxDecimalPlaces(3)]
public DoubleOrExpression Height { get; set; } = 0; public DoubleOrExpression Height { get; set; } = 0;
[SectionStart("X Axis"), DisplayName("Align")] [SectionStart("X Axis"), DisplayName("Stretch")]
[EnumDisplay(IconPaths = new string[] { "424.png", "align_left.png", "align_center_x.png", "align_right.png", "align_origin.png" }, InvertIcons = true)]
public Align XAlign { get; set; } = Align.None;
[DisplayName("Stretch")]
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)] [EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)]
public StretchOption XStretchOption { get; set; } = StretchOption.Expand; public StretchOption XStretchOption { get; set; } = StretchOption.Expand;
[SectionStart("Y Axis"), DisplayName("Align")] [DisplayName("Align")]
[EnumDisplay(IconPaths = new string[] { "424.png", "align_bottom.png", "align_center_y.png", "align_top.png", "align_origin.png" }, InvertIcons = true)] [EnumDisplay(IconPaths = new string[] { "align_left.png", "align_center_x.png", "align_right.png" }, InvertIcons = true)]
public Align YAlign { get; set; } = Align.None; public FitAlign XAlign { get; set; } = FitAlign.Center;
[DisplayName("Stretch")] [SectionStart("Y Axis"), DisplayName("Stretch")]
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)] [EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)]
public StretchOption YStretchOption { get; set; } = StretchOption.Expand; public StretchOption YStretchOption { get; set; } = StretchOption.Expand;
[SectionStart("Z Axis"), DisplayName("Align")] [DisplayName("Align")]
[EnumDisplay(IconPaths = new string[] { "424.png", "align_bottom.png", "align_center_y.png", "align_top.png", "align_origin.png" }, InvertIcons = true)] [EnumDisplay(IconPaths = new string[] { "align_bottom.png", "align_center_y.png", "align_top.png" }, InvertIcons = true)]
public Align ZAlign { get; set; } = Align.None; public FitAlign YAlign { get; set; } = FitAlign.Center;
[DisplayName("Stretch")] [SectionStart("Z Axis"), DisplayName("Stretch")]
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)] [EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)]
public StretchOption ZStretchOption { get; set; } = StretchOption.Expand; public StretchOption ZStretchOption { get; set; } = StretchOption.Expand;
[DisplayName("Align")]
[EnumDisplay(IconPaths = new string[] { "align_bottom.png", "align_center_y.png", "align_top.png" }, InvertIcons = true)]
public FitAlign ZAlign { get; set; } = FitAlign.Center;
public static async Task<FitToBoundsObject3D_4> Create(IObject3D itemToFit) public static async Task<FitToBoundsObject3D_4> Create(IObject3D itemToFit)
{ {
var fitToBounds = new FitToBoundsObject3D_4(); var fitToBounds = new FitToBoundsObject3D_4();
@ -109,7 +117,10 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
itemToFit.Translate(-startingAabb.Center); itemToFit.Translate(-startingAabb.Center);
// add the fit item // add the fit item
var scaleItem = new Object3D(); var scaleItem = new Object3D()
{
Name = "Scale Item - Hold Children"
};
fitToBounds.Children.Add(scaleItem); fitToBounds.Children.Add(scaleItem);
scaleItem.Children.Add(itemToFit); scaleItem.Children.Add(itemToFit);
@ -118,7 +129,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
{ {
Visible = false, Visible = false,
Color = new Color(Color.Red, 100), Color = new Color(Color.Red, 100),
Mesh = PlatonicSolids.CreateCube() Mesh = PlatonicSolids.CreateCube(),
Name = "Fit Bounds - No Children"
}; };
// add the item that holds the bounds // add the item that holds the bounds
fitToBounds.Children.Add(fitBounds); fitToBounds.Children.Add(fitBounds);
@ -137,36 +149,15 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
AxisAlignedBoundingBox CalcBounds() AxisAlignedBoundingBox CalcBounds()
{ {
var aabb = UntransformedChildren.GetAxisAlignedBoundingBox(); var aabb = FitBounds.GetAxisAlignedBoundingBox();
var center = aabb.Center; var center = aabb.Center;
var constraint = new Vector3(Width.Value(this), Depth.Value(this), Height.Value(this)); var width = Width.Value(this);
var aligns = new Align[] { XAlign, YAlign, ZAlign }; var depth = Depth.Value(this);
var height = Height.Value(this);
var minXyz = Vector3.Zero;
var maxXyz = Vector3.Zero;
for (int i = 0; i < 3; i++)
{
switch (aligns[i])
{
case Align.Center:
case Align.None:
minXyz[i] = center[i] - constraint[i] / 2;
maxXyz[i] = center[i] + constraint[i] / 2;
break;
case Align.Min:
minXyz[i] = aabb.MinXYZ[i];
maxXyz[i] = minXyz[i] + constraint[i];
break;
case Align.Max:
maxXyz[i] = aabb.MaxXYZ[i];
minXyz[i] = maxXyz[i] - constraint[i];
break;
}
}
var minXyz = center - new Vector3(width / 2, depth / 2, height / 2);
var maxXyz = center + new Vector3(width / 2, depth / 2, height / 2);
return new AxisAlignedBoundingBox(minXyz, maxXyz); return new AxisAlignedBoundingBox(minXyz, maxXyz);
} }
@ -319,41 +310,55 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
var fitAabb = FitBounds.GetAxisAlignedBoundingBox(); var fitAabb = FitBounds.GetAxisAlignedBoundingBox();
var fitSize = fitAabb.Size; var fitSize = fitAabb.Size;
var boundsSize = new Vector3(Width.Value(this), Depth.Value(this), Height.Value(this)); var boundsSize = new Vector3(Width.Value(this), Depth.Value(this), Height.Value(this));
if (boundsSize.X != 0 && boundsSize.Y != 0 && boundsSize.Z != 0 FitBounds.Matrix *= Matrix4X4.CreateScale(
&& (fitSize != boundsSize boundsSize.X / fitSize.X,
|| fitAabb.Center != transformAabb.Center)) boundsSize.Y / fitSize.Y,
boundsSize.Z / fitSize.Z);
Vector3 offset = Vector3.Zero;
FitAlign[] align = { XAlign, YAlign, ZAlign };
for (int i = 0; i < 3; i++)
{ {
FitBounds.Matrix *= Matrix4X4.CreateScale( switch (align[i])
boundsSize.X / fitSize.X,
boundsSize.Y / fitSize.Y,
boundsSize.Z / fitSize.Z);
Vector3 offset = Vector3.Zero;
Align[] align = { XAlign, YAlign, ZAlign };
for (int i = 0; i < 3; i++)
{ {
switch (align[i]) case FitAlign.Min:
{ offset[i] = transformAabb.MinXYZ[i] - fitAabb.MinXYZ[i];
case Align.None: break;
break;
case Align.Min: case FitAlign.Center:
offset[i] = transformAabb.MinXYZ[i] - fitAabb.MinXYZ[i]; offset[i] = transformAabb.Center[i] - fitAabb.Center[i];
break; break;
case Align.Center: case FitAlign.Max:
offset[i] = transformAabb.Center[i] - fitAabb.Center[i]; offset[i] = transformAabb.MaxXYZ[i] - fitAabb.MaxXYZ[i];
break; break;
case Align.Max:
offset[i] = transformAabb.MaxXYZ[i] - fitAabb.MaxXYZ[i];
break;
}
} }
FitBounds.Matrix *= Matrix4X4.CreateTranslation(offset);
} }
FitBounds.Matrix *= Matrix4X4.CreateTranslation(offset);
}
}
private Dictionary<string, bool> changeSet = new Dictionary<string, bool>();
public void UpdateControls(PublicPropertyChange change)
{
changeSet.Clear();
changeSet.Add(nameof(XAlign), XStretchOption == StretchOption.Inside);
changeSet.Add(nameof(YAlign), YStretchOption == StretchOption.Inside);
changeSet.Add(nameof(ZAlign), ZStretchOption == StretchOption.Inside);
// first turn on all the settings we want to see
foreach (var kvp in changeSet.Where(c => c.Value))
{
change.SetRowVisible(kvp.Key, () => kvp.Value);
}
// then turn off all the settings we want to hide
foreach (var kvp in changeSet.Where(c => !c.Value))
{
change.SetRowVisible(kvp.Key, () => kvp.Value);
} }
} }
} }

View file

@ -105,12 +105,6 @@ namespace MatterHackers.MatterControl.DesignTools
[DisplayName("Text")] [DisplayName("Text")]
public StringOrExpression MultiLineText { get; set; } = "MultiLine\nText"; public StringOrExpression MultiLineText { get; set; } = "MultiLine\nText";
[Description("Leave 0 for no wrapping")]
public DoubleOrExpression WrappingWidth { get; set; } = 0;
[Description("The number of spaces to add after wrapping a line. Very useful for bullet points.")]
public IntOrExpression WrappingIndent { get; set; } = 0;
[Slider(1, 48, snapDistance: 1)] [Slider(1, 48, snapDistance: 1)]
public DoubleOrExpression PointSize { get; set; } = 24; public DoubleOrExpression PointSize { get; set; } = 24;
@ -125,6 +119,14 @@ namespace MatterHackers.MatterControl.DesignTools
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)] [EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)]
public OutputDimensions Output { get; set; } = OutputDimensions.Output3D; public OutputDimensions Output { get; set; } = OutputDimensions.Output3D;
public bool WrapLines { get; set; } = false;
[Description("The width to wrap at in mm")]
public DoubleOrExpression WrappingWidth { get; set; } = 200;
[Description("The number of spaces to add after wrapping a line. Very useful for bullet points.")]
public IntOrExpression WrappingIndent { get; set; } = 0;
public override bool CanApply => true; public override bool CanApply => true;
public override IVertexSource GetVertexSource() public override IVertexSource GetVertexSource()
@ -203,10 +205,10 @@ namespace MatterHackers.MatterControl.DesignTools
var pointSize = PointSize.Value(this); var pointSize = PointSize.Value(this);
if (MultiLine && wrappingWidth > 0) if (WrapLines && wrappingWidth > 0)
{ {
var wrapper = new EnglishTextWrapping(pointSize); var wrapper = new EnglishTextWrapping(pointSize);
textToWrite = wrapper.InsertCRs(textToWrite, wrappingWidth, wrappingIndent); textToWrite = wrapper.InsertCRs(textToWrite, wrappingWidth, MultiLine ? wrappingIndent : 0);
} }
if (string.IsNullOrWhiteSpace(textToWrite)) if (string.IsNullOrWhiteSpace(textToWrite))
@ -351,8 +353,8 @@ namespace MatterHackers.MatterControl.DesignTools
change.SetRowVisible(nameof(Alignment), () => MultiLine); change.SetRowVisible(nameof(Alignment), () => MultiLine);
change.SetRowVisible(nameof(NameToWrite), () => !MultiLine); change.SetRowVisible(nameof(NameToWrite), () => !MultiLine);
change.SetRowVisible(nameof(Height), () => Output == OutputDimensions.Output3D); change.SetRowVisible(nameof(Height), () => Output == OutputDimensions.Output3D);
change.SetRowVisible(nameof(WrappingWidth), () => MultiLine); change.SetRowVisible(nameof(WrappingWidth), () => WrapLines);
change.SetRowVisible(nameof(WrappingIndent), () => MultiLine); change.SetRowVisible(nameof(WrappingIndent), () => MultiLine && WrapLines);
if (change.PropertyChanged == nameof(Output)) if (change.PropertyChanged == nameof(Output))
{ {
refreshToolBar = true; refreshToolBar = true;

@ -1 +1 @@
Subproject commit 35f4dca6e1635d328eaae0df6ab23bc8a300bad2 Subproject commit f7bda6246e751c44143ddb557f4742f5274015bb