diff --git a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleDiameterControl.cs b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleDiameterControl.cs index c65cfa540..102c0f2a0 100644 --- a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleDiameterControl.cs +++ b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleDiameterControl.cs @@ -344,7 +344,7 @@ namespace MatterHackers.Plugins.EditorTools Vector3 GetEdgePosition(IObject3D item, double angle, ObjectSpace.Placement placement) { var aabb = item.GetAxisAlignedBoundingBox(item.Matrix.Inverted); - var centerPosition = aabb.Center; + var centerPosition = default(Vector3); switch (placement) { case ObjectSpace.Placement.Bottom: diff --git a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleWidthDepthEdgeControl.cs b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleWidthDepthEdgeControl.cs index adaa1fa75..ee8ae0823 100644 --- a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleWidthDepthEdgeControl.cs +++ b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleWidthDepthEdgeControl.cs @@ -559,8 +559,20 @@ namespace MatterHackers.Plugins.EditorTools public static Vector3 GetCenterPosition(IObject3D item, Placement placement) { - var aabb = item.GetAxisAlignedBoundingBox(item.Matrix.Inverted); - var cornerPosition = aabb.Center; + var invertedMatrix = item.Matrix.Inverted; + var aabb = item.GetAxisAlignedBoundingBox(invertedMatrix); + + Vector3 cornerPosition; + var useOriginXy = true; + if (useOriginXy) + { + cornerPosition = Vector3.Zero; + } + else + { + cornerPosition = aabb.Center; + } + switch (placement) { case Placement.Bottom: diff --git a/MatterControlLib/DesignTools/Operations/ArrayLinearObject3D.cs b/MatterControlLib/DesignTools/Operations/ArrayLinearObject3D.cs index 825ce3e55..ab8195eaa 100644 --- a/MatterControlLib/DesignTools/Operations/ArrayLinearObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/ArrayLinearObject3D.cs @@ -60,7 +60,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations var rebuildLock = this.RebuildLock(); SourceContainer.Visible = true; - using (new CenterAndHeightMaintainer(this, CenterAndHeightMaintainer.MaintainFlags.Height)) + using (new CenterAndHeightMaintainer(this, MaintainFlags.Bottom)) { await ApplicationController.Instance.Tasks.Execute( "Linear Array".Localize(), diff --git a/MatterControlLib/DesignTools/Operations/CurveObject3D_3.cs b/MatterControlLib/DesignTools/Operations/CurveObject3D_3.cs index 2578da3d9..421065416 100644 --- a/MatterControlLib/DesignTools/Operations/CurveObject3D_3.cs +++ b/MatterControlLib/DesignTools/Operations/CurveObject3D_3.cs @@ -127,7 +127,7 @@ namespace MatterHackers.MatterControl.DesignTools GL.Enable(EnableCap.Lighting); } - private void DiameterFromAngle() + private double DiameterFromAngle() { var diameter = Diameter.Value(this); var angle = Angle.Value(this); @@ -141,6 +141,8 @@ namespace MatterHackers.MatterControl.DesignTools Diameter = newDiameter; Invalidate(InvalidateType.DisplayValues); } + + return diameter; } @@ -170,9 +172,10 @@ namespace MatterHackers.MatterControl.DesignTools var startPercent = StartPercent.ClampIfNotCalculated(this, 0, 100, ref valuesChanged); var diameter = Diameter.Value(this); - if (diameter == double.MaxValue) + if (diameter == double.MaxValue + || diameter == 0) { - DiameterFromAngle(); + diameter = DiameterFromAngle(); } // keep the unused type synced so we don't change the bend when clicking the tabs @@ -182,15 +185,10 @@ namespace MatterHackers.MatterControl.DesignTools } else { - DiameterFromAngle(); - } - - if (diameter < 1 || diameter > 100000) - { - Diameter = Math.Min(10000000, Math.Max(.1, diameter)); - valuesChanged = true; + diameter = DiameterFromAngle(); } + diameter = Diameter.ClampIfNotCalculated(this, .1, 100000, ref valuesChanged); var minSidesPerRotation = MinSidesPerRotation.ClampIfNotCalculated(this, 3, 360, ref valuesChanged); diff --git a/MatterControlLib/DesignTools/Operations/Image/ImageToPathObject3D_2.cs b/MatterControlLib/DesignTools/Operations/Image/ImageToPathObject3D_2.cs index 18a3f006e..9b669e2c1 100644 --- a/MatterControlLib/DesignTools/Operations/Image/ImageToPathObject3D_2.cs +++ b/MatterControlLib/DesignTools/Operations/Image/ImageToPathObject3D_2.cs @@ -170,6 +170,7 @@ namespace MatterHackers.MatterControl.DesignTools [Slider(0, 150, Easing.EaseType.Quadratic)] [Description("The minimum area each loop needs to be for inclusion")] + [MaxDecimalPlaces(2)] public double MinSurfaceArea {get; set; } = 1; public IVertexSource VertexSource { get; set; } = new VertexStorage(); diff --git a/MatterControlLib/DesignTools/Operations/Path/LinearExtrudeObject3D.cs b/MatterControlLib/DesignTools/Operations/Path/LinearExtrudeObject3D.cs index 391937d29..48902d543 100644 --- a/MatterControlLib/DesignTools/Operations/Path/LinearExtrudeObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/Path/LinearExtrudeObject3D.cs @@ -52,6 +52,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations , IPropertyGridModifier #endif { + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression Height { get; set; } = 5; #if DEBUG diff --git a/MatterControlLib/DesignTools/Operations/Path/RevolveObject3D.cs b/MatterControlLib/DesignTools/Operations/Path/RevolveObject3D.cs index 5e5a0c5b4..115aad09b 100644 --- a/MatterControlLib/DesignTools/Operations/Path/RevolveObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/Path/RevolveObject3D.cs @@ -52,11 +52,14 @@ namespace MatterHackers.MatterControl.DesignTools.Operations public DoubleOrExpression AxisPosition { get; set; } = 0; [MaxDecimalPlaces(2)] + [Slider(3, 360, snapDistance: 1)] public DoubleOrExpression StartingAngle { get; set; } = 0; [MaxDecimalPlaces(2)] + [Slider(3, 360, snapDistance: 1)] public DoubleOrExpression EndingAngle { get; set; } = 45; + [Slider(3, 360, Easing.EaseType.Quadratic, snapDistance: 1)] public IntOrExpression Sides { get; set; } = 30; public override bool CanFlatten => true; diff --git a/MatterControlLib/DesignTools/Operations/RotateObject3D_2.cs b/MatterControlLib/DesignTools/Operations/RotateObject3D_2.cs index 2303c84e7..e6519c7df 100644 --- a/MatterControlLib/DesignTools/Operations/RotateObject3D_2.cs +++ b/MatterControlLib/DesignTools/Operations/RotateObject3D_2.cs @@ -94,6 +94,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations [MaxDecimalPlaces(2)] [DisplayName("Angle")] + [Slider(3, 360, Easing.EaseType.Cubic, snapDistance: 1)] public DoubleOrExpression AngleDegrees { get; set; } = 0; [JsonIgnore] diff --git a/MatterControlLib/DesignTools/Primitives/BaseObject3D.cs b/MatterControlLib/DesignTools/Primitives/BaseObject3D.cs index d6fdbde0d..43a952a11 100644 --- a/MatterControlLib/DesignTools/Primitives/BaseObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/BaseObject3D.cs @@ -83,11 +83,14 @@ namespace MatterHackers.MatterControl.DesignTools public DoubleOrExpression CalculationHeight { get; set; } = .1; [DisplayName("Expand")] + [Slider(1, 100, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression BaseSize { get; set; } = 3; + [Slider(1, 20, Easing.EaseType.Quadratic, snapDistance: .1)] public DoubleOrExpression InfillAmount { get; set; } = 3; [DisplayName("Height")] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression ExtrusionHeight { get; set; } = 5; [DisplayName("")] @@ -231,7 +234,7 @@ namespace MatterHackers.MatterControl.DesignTools null, (reporter, cancellationToken) => { - using (new CenterAndHeightMaintainer(this, CenterAndHeightMaintainer.MaintainFlags.Height)) + using (new CenterAndHeightMaintainer(this, MaintainFlags.Bottom)) { var firstChild = this.Children.FirstOrDefault(); diff --git a/MatterControlLib/DesignTools/Primitives/BoxPathObject3D.cs b/MatterControlLib/DesignTools/Primitives/BoxPathObject3D.cs index 18ad6d1db..d6ab058ea 100644 --- a/MatterControlLib/DesignTools/Primitives/BoxPathObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/BoxPathObject3D.cs @@ -36,6 +36,7 @@ using MatterHackers.Localizations; using MatterHackers.MatterControl.DesignTools.Operations; using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.PolygonMesh; +using MatterHackers.VectorMath; using Newtonsoft.Json; namespace MatterHackers.MatterControl.DesignTools @@ -74,9 +75,11 @@ namespace MatterHackers.MatterControl.DesignTools /// This is the actual serialized with that can use expressions /// [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression Width { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression Depth { get; set; } = 20; public static async Task Create() diff --git a/MatterControlLib/DesignTools/Primitives/ConeObject3D.cs b/MatterControlLib/DesignTools/Primitives/ConeObject3D.cs index 1afe0dc26..61e6221d5 100644 --- a/MatterControlLib/DesignTools/Primitives/ConeObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/ConeObject3D.cs @@ -36,6 +36,7 @@ using MatterHackers.DataConverters3D; using MatterHackers.Localizations; using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.Plugins.EditorTools; +using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.DesignTools { @@ -57,11 +58,14 @@ namespace MatterHackers.MatterControl.DesignTools return item; } + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression Diameter { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression Height { get; set; } = 20; + [Slider(3, 360, Easing.EaseType.Quadratic, snapDistance: 1)] public IntOrExpression Sides { get; set; } = 40; public override async void OnInvalidate(InvalidateArgs invalidateArgs) diff --git a/MatterControlLib/DesignTools/Primitives/CylinderObject3D.cs b/MatterControlLib/DesignTools/Primitives/CylinderObject3D.cs index 3e1c96a50..27c8acc17 100644 --- a/MatterControlLib/DesignTools/Primitives/CylinderObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/CylinderObject3D.cs @@ -120,12 +120,15 @@ namespace MatterHackers.MatterControl.DesignTools [MaxDecimalPlaces(2)] [Description("The width from one side to the opposite side.")] + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression Diameter { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression Height { get; set; } = 20; [Description("The number of segments around the perimeter.")] + [Slider(3, 360, Easing.EaseType.Quadratic, snapDistance: 1)] public IntOrExpression Sides { get; set; } = 40; public bool Advanced { get; set; } = false; @@ -135,12 +138,15 @@ namespace MatterHackers.MatterControl.DesignTools public string EasyModeMessage { get; set; } = "You can switch to Advanced mode to get more cylinder options."; [MaxDecimalPlaces(2)] + [Slider(3, 360, snapDistance: 1)] public DoubleOrExpression StartingAngle { get; set; } = 0; [MaxDecimalPlaces(2)] + [Slider(3, 360, snapDistance: 1)] public DoubleOrExpression EndingAngle { get; set; } = 360; [MaxDecimalPlaces(2)] + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression DiameterTop { get; set; } = 20; public override async void OnInvalidate(InvalidateArgs invalidateArgs) @@ -178,7 +184,7 @@ namespace MatterHackers.MatterControl.DesignTools using (RebuildLock()) { - using (new CenterAndHeightMaintainer(this)) + using (new CenterAndHeightMaintainer(this, MaintainFlags.Origin)) { if (!Advanced) { diff --git a/MatterControlLib/DesignTools/Primitives/HalfCylinderObject3D.cs b/MatterControlLib/DesignTools/Primitives/HalfCylinderObject3D.cs index 4418f3668..b3103f427 100644 --- a/MatterControlLib/DesignTools/Primitives/HalfCylinderObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/HalfCylinderObject3D.cs @@ -57,12 +57,15 @@ namespace MatterHackers.MatterControl.DesignTools } [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression Width { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression Depth { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(3, 360, Easing.EaseType.Quadratic, snapDistance: 1)] public IntOrExpression Sides { get; set; } = 20; public override async void OnInvalidate(InvalidateArgs invalidateArgs) diff --git a/MatterControlLib/DesignTools/Primitives/HalfSphereObject3D.cs b/MatterControlLib/DesignTools/Primitives/HalfSphereObject3D.cs index 2f0db854e..47789aaa8 100644 --- a/MatterControlLib/DesignTools/Primitives/HalfSphereObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/HalfSphereObject3D.cs @@ -70,8 +70,13 @@ namespace MatterHackers.MatterControl.DesignTools return item; } + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression Diameter { get; set; } = 20; + + [Slider(3, 360, Easing.EaseType.Quadratic, snapDistance: 1)] public IntOrExpression LongitudeSides { get; set; } = 40; + + [Slider(3, 180, Easing.EaseType.Quadratic, snapDistance: 1)] public IntOrExpression LatitudeSides { get; set; } = 10; public override async void OnInvalidate(InvalidateArgs invalidateArgs) diff --git a/MatterControlLib/DesignTools/Primitives/HalfWedgeObject3D.cs b/MatterControlLib/DesignTools/Primitives/HalfWedgeObject3D.cs index ac4504ed6..f1a060cb6 100644 --- a/MatterControlLib/DesignTools/Primitives/HalfWedgeObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/HalfWedgeObject3D.cs @@ -56,12 +56,15 @@ namespace MatterHackers.MatterControl.DesignTools } [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression Width { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression Depth { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression Height { get; set; } = 10; public override async void OnInvalidate(InvalidateArgs invalidateArgs) diff --git a/MatterControlLib/DesignTools/Primitives/PyramidObject3D.cs b/MatterControlLib/DesignTools/Primitives/PyramidObject3D.cs index 162a68db5..5a624972f 100644 --- a/MatterControlLib/DesignTools/Primitives/PyramidObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/PyramidObject3D.cs @@ -57,12 +57,15 @@ namespace MatterHackers.MatterControl.DesignTools } [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression Width { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression Depth { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression Height { get; set; } = 20; public override async void OnInvalidate(InvalidateArgs invalidateArgs) diff --git a/MatterControlLib/DesignTools/Primitives/RingObject3D.cs b/MatterControlLib/DesignTools/Primitives/RingObject3D.cs index df361e086..8f23a17d8 100644 --- a/MatterControlLib/DesignTools/Primitives/RingObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/RingObject3D.cs @@ -43,6 +43,13 @@ namespace MatterHackers.MatterControl.DesignTools { public class RingObject3D : PrimitiveObject3D, IPropertyGridModifier, IObject3DControlsProvider { + public enum BevelTypes + { + None, + In, + Out, + } + public RingObject3D() { Name = "Ring".Localize(); @@ -71,14 +78,18 @@ namespace MatterHackers.MatterControl.DesignTools } [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression OuterDiameter { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression InnerDiameter { get; set; } = 15; [MaxDecimalPlaces(2)] + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression Height { get; set; } = 5; + [Slider(3, 360, Easing.EaseType.Quadratic, snapDistance: 1)] public IntOrExpression Sides { get; set; } = 40; public bool Advanced { get; set; } = false; @@ -87,10 +98,18 @@ namespace MatterHackers.MatterControl.DesignTools [DisplayName("")] // clear the display name so this text will be the full width of the editor public string EasyModeMessage { get; set; } = "You can switch to Advanced mode to get more ring options."; + [EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)] + public BevelTypes Bevel { get; set; } = BevelTypes.None; + + [Slider(2, 90, Easing.EaseType.Quadratic, snapDistance: 1)] + public IntOrExpression RoundSegments { get; set; } = 2; + [MaxDecimalPlaces(2)] + [Slider(3, 360, snapDistance: 1)] public DoubleOrExpression StartingAngle { get; set; } = 0; [MaxDecimalPlaces(2)] + [Slider(3, 360, snapDistance: 1)] public DoubleOrExpression EndingAngle { get; set; } = 360; public override async void OnInvalidate(InvalidateArgs invalidateArgs) @@ -121,8 +140,9 @@ namespace MatterHackers.MatterControl.DesignTools var startingAngle = StartingAngle.ClampIfNotCalculated(this, 0, 360 - .01, ref valuesChanged); var endingAngle = EndingAngle.ClampIfNotCalculated(this, startingAngle + .01, 360, ref valuesChanged); var height = Height.Value(this); + var roundSegments = RoundSegments.ClampIfNotCalculated(this, 2, 90, ref valuesChanged); - using (new CenterAndHeightMaintainer(this)) + using (new CenterAndHeightMaintainer(this, MaintainFlags.Origin)) { if (!Advanced) { @@ -133,11 +153,40 @@ namespace MatterHackers.MatterControl.DesignTools innerDiameter = Math.Min(outerDiameter - .1, innerDiameter); var path = new VertexStorage(); - path.MoveTo(outerDiameter / 2, -height / 2); - path.LineTo(outerDiameter / 2, height / 2); - path.LineTo(innerDiameter / 2, height / 2); - path.LineTo(innerDiameter / 2, -height / 2); - path.LineTo(outerDiameter / 2, -height / 2); + var width = (outerDiameter - innerDiameter) / 2; + var r = innerDiameter / 2; + path.MoveTo(r, 0); + path.LineTo(r + width, 0); + var range = 360 / 4.0; + + switch (Bevel) + { + case BevelTypes.None: + path.LineTo(r + width, height); + path.LineTo(r, height); + break; + + case BevelTypes.In: + path.LineTo(r + width, height); + for (int i = 1; i < roundSegments - 1; i++) + { + var angle = range / (roundSegments - 1) * i; + var rad = MathHelper.DegreesToRadians(angle); + path.LineTo(r + width - Math.Sin(rad) * width, Math.Cos(rad) * height); + } + break; + + case BevelTypes.Out: + for (int i = 1; i < roundSegments - 1; i++) + { + var angle = range / (roundSegments - 1) * i; + var rad = MathHelper.DegreesToRadians(angle); + path.LineTo(r + width - Math.Sin(rad) * width, height - Math.Cos(rad) * height); + } + path.LineTo(r, height); + break; + } + var startAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(startingAngle)); var endAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(endingAngle)); @@ -156,6 +205,8 @@ namespace MatterHackers.MatterControl.DesignTools public void UpdateControls(PublicPropertyChange change) { + change.SetRowVisible(nameof(Bevel), () => Advanced); + change.SetRowVisible(nameof(RoundSegments), () => Advanced || Bevel != BevelTypes.None); change.SetRowVisible(nameof(StartingAngle), () => Advanced); change.SetRowVisible(nameof(EndingAngle), () => Advanced); change.SetRowVisible(nameof(EasyModeMessage), () => !Advanced); diff --git a/MatterControlLib/DesignTools/Primitives/SphereObject3D.cs b/MatterControlLib/DesignTools/Primitives/SphereObject3D.cs index 511c3fce7..a63ff1a4b 100644 --- a/MatterControlLib/DesignTools/Primitives/SphereObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/SphereObject3D.cs @@ -76,8 +76,10 @@ namespace MatterHackers.MatterControl.DesignTools } [MaxDecimalPlaces(2)] + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression Diameter { get; set; } = 20; + [Slider(3, 360, Easing.EaseType.Quadratic, snapDistance: 1)] public IntOrExpression Sides { get; set; } = 40; public bool Advanced { get; set; } = false; @@ -87,11 +89,14 @@ namespace MatterHackers.MatterControl.DesignTools public string EasyModeMessage { get; set; } = "You can switch to Advanced mode to get more sphere options."; [MaxDecimalPlaces(2)] + [Slider(3, 360, snapDistance: 1)] public DoubleOrExpression StartingAngle { get; set; } = 0; [MaxDecimalPlaces(2)] + [Slider(3, 360, snapDistance: 1)] public DoubleOrExpression EndingAngle { get; set; } = 360; + [Slider(3, 180, Easing.EaseType.Quadratic, snapDistance: 1)] public IntOrExpression LatitudeSides { get; set; } = 30; public override async void OnInvalidate(InvalidateArgs invalidateArgs) @@ -117,12 +122,12 @@ namespace MatterHackers.MatterControl.DesignTools using (RebuildLock()) { var sides = Sides.ClampIfNotCalculated(this, 3, 360, ref valuesChanged); - var latitudeSides = LatitudeSides.ClampIfNotCalculated(this, 3, 360, ref valuesChanged); + var latitudeSides = LatitudeSides.ClampIfNotCalculated(this, 3, 180, ref valuesChanged); var startingAngle = StartingAngle.ClampIfNotCalculated(this, 0, 360 - .01, ref valuesChanged); var endingAngle = EndingAngle.ClampIfNotCalculated(this, startingAngle + .01, 360, ref valuesChanged); var diameter = Diameter.Value(this); - using (new CenterAndHeightMaintainer(this)) + using (new CenterAndHeightMaintainer(this, MaintainFlags.Origin)) { if (sides != lastSides || latitudeSides != lastLatitudeSides diff --git a/MatterControlLib/DesignTools/Primitives/TextObject3D.cs b/MatterControlLib/DesignTools/Primitives/TextObject3D.cs index 0cb6ebf0b..a646fdd5c 100644 --- a/MatterControlLib/DesignTools/Primitives/TextObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/TextObject3D.cs @@ -67,9 +67,11 @@ namespace MatterHackers.MatterControl.DesignTools [DisplayName("Text")] public StringOrExpression NameToWrite { get; set; } = "Text"; + [Slider(1, 48, snapDistance: 1)] public DoubleOrExpression PointSize { get; set; } = 24; [MaxDecimalPlaces(2)] + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression Height { get; set; } = 5; [Sortable] diff --git a/MatterControlLib/DesignTools/Primitives/TorusObject3D.cs b/MatterControlLib/DesignTools/Primitives/TorusObject3D.cs index 1251f82a9..af714fd4b 100644 --- a/MatterControlLib/DesignTools/Primitives/TorusObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/TorusObject3D.cs @@ -59,11 +59,14 @@ namespace MatterHackers.MatterControl.DesignTools } [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Cubic, snapDistance: .1)] public DoubleOrExpression OuterDiameter { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Cubic, snapDistance: .1)] public DoubleOrExpression InnerDiameter { get; set; } = 10; + [Slider(3, 360, Easing.EaseType.Quadratic, snapDistance: 1)] public IntOrExpression Sides { get; set; } = 40; public bool Advanced { get; set; } = false; @@ -73,14 +76,18 @@ namespace MatterHackers.MatterControl.DesignTools public string EasyModeMessage { get; set; } = "You can switch to Advanced mode to get more torus options."; [MaxDecimalPlaces(2)] + [Slider(3, 360, snapDistance: 1)] public DoubleOrExpression StartingAngle { get; set; } = 0; [MaxDecimalPlaces(2)] + [Slider(3, 360, snapDistance: 1)] public DoubleOrExpression EndingAngle { get; set; } = 360; + [Slider(3, 260, Easing.EaseType.Quadratic, snapDistance: 1)] public IntOrExpression RingSides { get; set; } = 15; [MaxDecimalPlaces(2)] + [Slider(1, 90, snapDistance: 1)] public DoubleOrExpression RingPhaseAngle { get; set; } = 0; public override async void OnInvalidate(InvalidateArgs invalidateArgs) @@ -124,7 +131,7 @@ namespace MatterHackers.MatterControl.DesignTools innerDiameter = Math.Min(outerDiameter - .1, innerDiameter); - using (new CenterAndHeightMaintainer(this)) + using (new CenterAndHeightMaintainer(this, MaintainFlags.Origin)) { var poleRadius = (outerDiameter / 2 - innerDiameter / 2) / 2; var toroidRadius = innerDiameter / 2 + poleRadius; diff --git a/MatterControlLib/DesignTools/Primitives/WedgeObject3D.cs b/MatterControlLib/DesignTools/Primitives/WedgeObject3D.cs index 0a99f92d5..02f012f01 100644 --- a/MatterControlLib/DesignTools/Primitives/WedgeObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/WedgeObject3D.cs @@ -40,7 +40,7 @@ using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.DesignTools { - public class WedgeObject3D : PrimitiveObject3D, IPropertyGridModifier, IObject3DControlsProvider + public class WedgeObject3D : PrimitiveObject3D, IObject3DControlsProvider { public WedgeObject3D() { @@ -59,17 +59,19 @@ namespace MatterHackers.MatterControl.DesignTools } [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression Width { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(1, 400, Easing.EaseType.Quadratic, snapDistance: 1)] public DoubleOrExpression Depth { get; set; } = 20; [MaxDecimalPlaces(2)] + [Slider(1, 400, VectorMath.Easing.EaseType.Quadratic, useSnappingGrid: true)] public DoubleOrExpression Height { get; set; } = 20; - public bool Round { get; set; } = false; - - public IntOrExpression RoundSegments { get; set; } = 15; + [Slider(2, 90, Easing.EaseType.Quadratic, snapDistance: 1)] + public IntOrExpression RoundSegments { get; set; } = 2; public override async void OnInvalidate(InvalidateArgs invalidateArgs) { @@ -92,7 +94,7 @@ namespace MatterHackers.MatterControl.DesignTools this.DebugDepth("Rebuild"); bool valuesChanged = false; - var roundSegments = RoundSegments.ClampIfNotCalculated(this, 3, 360 / 4 - 2, ref valuesChanged); + var roundSegments = RoundSegments.ClampIfNotCalculated(this, 2, 90, ref valuesChanged); if (valuesChanged) { @@ -101,24 +103,23 @@ namespace MatterHackers.MatterControl.DesignTools using (RebuildLock()) { + var height = Height.Value(this); + var width = Width.Value(this); using (new CenterAndHeightMaintainer(this)) { var path = new VertexStorage(); path.MoveTo(0, 0); - path.LineTo(Width.Value(this), 0); + path.LineTo(width, 0); - if (Round) + var range = 360 / 4.0; + for (int i = 1; i < roundSegments - 1; i++) { - var range = 360 / 4.0; - for (int i = 1; i < roundSegments - 1; i++) - { - var angle = range / (roundSegments - 1) * i; - var rad = MathHelper.DegreesToRadians(angle); - path.LineTo(Width.Value(this) - Math.Sin(rad) * Width.Value(this), Height.Value(this) - Math.Cos(rad) * Height.Value(this)); - } + var angle = range / (roundSegments - 1) * i; + var rad = MathHelper.DegreesToRadians(angle); + path.LineTo(width - Math.Sin(rad) * width, height - Math.Cos(rad) * height); } - path.LineTo(0, Height.Value(this)); + path.LineTo(0, height); Mesh = VertexSourceToMesh.Extrude(path, Depth.Value(this)); Mesh.Transform(Matrix4X4.CreateRotationX(MathHelper.Tau / 4)); @@ -130,14 +131,6 @@ namespace MatterHackers.MatterControl.DesignTools return Task.CompletedTask; } - public void UpdateControls(PublicPropertyChange change) - { - if (change.Context.GetEditRow(nameof(RoundSegments)) is GuiWidget segmentsWidget) - { - segmentsWidget.Visible = Round; - } - } - public void AddObject3DControls(Object3DControlsLayer object3DControlsLayer) { object3DControlsLayer.AddHeightControl(this, Width, Depth, Height); diff --git a/MatterControlLib/DesignTools/PublicPropertyEditor.cs b/MatterControlLib/DesignTools/PublicPropertyEditor.cs index 6aba55f74..a0caa6e4c 100644 --- a/MatterControlLib/DesignTools/PublicPropertyEditor.cs +++ b/MatterControlLib/DesignTools/PublicPropertyEditor.cs @@ -845,7 +845,7 @@ namespace MatterHackers.MatterControl.DesignTools // This code only executes when the in scene controls are updating the objects data and the display needs to tack them. if (e.InvalidateType.HasFlag(InvalidateType.DisplayValues)) { - DoubleOrExpression newValue = (DoubleOrExpression)property.Value; + var newValue = (DoubleOrExpression)property.Value; if (newValue.Expression != field.Value) { // we should never be in the situation where there is an '=' as the in scene controls should be disabled @@ -874,26 +874,71 @@ namespace MatterHackers.MatterControl.DesignTools else if (propertyValue is IntOrExpression intExpresion) { // create a string editor - var field = new ExpressionField(theme); + var field = new ExpressionField(theme) + { + Name = property.DisplayName + " Field" + }; field.Initialize(0); - field.SetValue(intExpresion.Expression, false); + if (intExpresion.Expression.Contains("=")) + { + field.SetValue(intExpresion.Expression, false); + } + else // make sure it is formatted + { + var format = "0." + new string('#', 5); + if (property.PropertyInfo.GetCustomAttributes(true).OfType().FirstOrDefault() is MaxDecimalPlacesAttribute decimalPlaces) + { + format = "0." + new string('#', Math.Min(10, decimalPlaces.Number)); + } + + field.SetValue(intExpresion.Value(object3D).ToString(format), false); + } + field.ClearUndoHistory(); RegisterValueChanged(field, - (valueString) => new IntOrExpression(valueString), + (valueString) => + { + intExpresion.Expression = valueString; + return intExpresion; + }, (value) => { return ((IntOrExpression)value).Expression; }); - rowContainer = CreateSettingsRow(property, field.Content, theme, rows); + + rowContainer = CreateSettingsRow(property, + PublicPropertySliderFunctions.GetFieldContentWithSlider(property, context, field, undoBuffer, (valueString) => + { + intExpresion.Expression = valueString; + return intExpresion; + }), + theme, + rows); void RefreshField(object s, InvalidateArgs e) { + // This code only executes when the in scene controls are updating the objects data and the display needs to tack them. if (e.InvalidateType.HasFlag(InvalidateType.DisplayValues)) { - IntOrExpression newValue = (IntOrExpression)property.Value; + var newValue = (IntOrExpression)property.Value; if (newValue.Expression != field.Value) { - field.TextValue = newValue.Value(object3D).ToString(); + // we should never be in the situation where there is an '=' as the in scene controls should be disabled + if (newValue.Expression.StartsWith("=")) + { + field.TextValue = newValue.Expression; + } + else + { + var format = "0." + new string('#', 5); + if (property.PropertyInfo.GetCustomAttributes(true).OfType().FirstOrDefault() is MaxDecimalPlacesAttribute decimalPlaces) + { + format = "0." + new string('#', Math.Min(10, decimalPlaces.Number)); + } + + var rawValue = newValue.Value(object3D); + field.TextValue = rawValue.ToString(format); + } } } } diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index fe92ba117..51adb3d9b 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit fe92ba117fc836f326a6bde3bd4ca95796998e3c +Subproject commit 51adb3d9b5bcd805a53faac324527c6e0121deb2