From 02e01ea21a86bd8d59891fac04d96fab90ef0933 Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Fri, 12 Jun 2020 20:21:52 -0700 Subject: [PATCH 01/12] improving gear 2d --- .../DesignTools/Primitives/Gear2D.cs | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/MatterControlLib/DesignTools/Primitives/Gear2D.cs b/MatterControlLib/DesignTools/Primitives/Gear2D.cs index 69811e413..0c6e0d57c 100644 --- a/MatterControlLib/DesignTools/Primitives/Gear2D.cs +++ b/MatterControlLib/DesignTools/Primitives/Gear2D.cs @@ -64,7 +64,7 @@ namespace MatterHackers.MatterControl.DesignTools private double addendum; - private double angleToothToTooth; + private double AngleToothToTooth => 360.0 / this.ToothCount; private Vector2 center = Vector2.Zero; @@ -320,19 +320,15 @@ namespace MatterHackers.MatterControl.DesignTools // we want to remove any concave corners that are located between two convex corners var cleanedUpCorners = new VertexStorage(); - var previousIndex = corners.Count - 1; - var currentIndex = 0; - for (var i = 0; i < corners.Count; i++) + for (var currentIndex = 0; currentIndex < corners.Count; currentIndex++) { var corner = corners[currentIndex]; - var nextIndex = (i + 1) % corners.Count; + var nextIndex = (currentIndex + 1) % corners.Count; + var previousIndex = (currentIndex + corners.Count - 1) % corners.Count; var isSingleConcave = !isConvex[currentIndex] && isConvex[previousIndex] && isConvex[nextIndex]; var isSingleConvex = isConvex[currentIndex] && !isConvex[previousIndex] && !isConvex[nextIndex]; - previousIndex = currentIndex; - currentIndex = nextIndex; - if (removeSingleConvex && isSingleConvex) { continue; @@ -370,7 +366,6 @@ namespace MatterHackers.MatterControl.DesignTools // Outer Circle this.OuterRadius = this.pitchRadius + this.shiftedAddendum; - this.angleToothToTooth = 360.0 / this.ToothCount; if (InternalToothCount > 0) { @@ -439,7 +434,7 @@ namespace MatterHackers.MatterControl.DesignTools for (var i = 1; i < this.ToothCount; i++) { - var angle = i * this.angleToothToTooth; + var angle = i * this.AngleToothToTooth; var roatationMatrix = Affine.NewRotation(MathHelper.DegreesToRadians(angle)); for (var j = 0; j < cornersCount; j++) { @@ -511,6 +506,8 @@ namespace MatterHackers.MatterControl.DesignTools private IVertexSource CreateExternalGearShape() { var tooth = this.CreateSingleTooth(); + // return tooth.wheel; + // return tooth.tooth; // we could now take the tooth cutout, rotate it tooth count times and union the various slices together into a complete gear. // However, the union operations become more and more complex as the complete gear is built up. @@ -521,14 +518,18 @@ namespace MatterHackers.MatterControl.DesignTools // first we need to find the corner that sits at the center for (var i = 1; i < this.ToothCount; i++) { - var angle = i * this.angleToothToTooth; + var angle = i * this.AngleToothToTooth; var roatationMatrix = Affine.NewRotation(MathHelper.DegreesToRadians(angle)); var rotatedCorner = new VertexSourceApplyTransform(tooth.tooth, roatationMatrix); outlinePaths = new CombinePaths(outlinePaths, rotatedCorner); } + // return outlinePaths; + var gearShape = tooth.wheel.Subtract(outlinePaths); + // return gearShape; + if (this.CenterHoleDiameter > 0) { var radius = this.CenterHoleDiameter / 2; @@ -539,13 +540,13 @@ namespace MatterHackers.MatterControl.DesignTools gearShape = gearShape.Subtract(centerhole) as VertexStorage; } - return gearShape; // .RotateZDegrees(-90); + return gearShape; } private (IVertexSource tooth, IVertexSource wheel) CreateSingleTooth() { // create outer circle sector covering one tooth - var toothSectorPath = new Arc(Vector2.Zero, new Vector2(this.OuterRadius, this.OuterRadius), MathHelper.DegreesToRadians(90), MathHelper.DegreesToRadians(90 - this.angleToothToTooth)) + var toothSectorPath = new Ellipse(Vector2.Zero, this.OuterRadius) { ResolutionScale = 10 }; @@ -557,12 +558,13 @@ namespace MatterHackers.MatterControl.DesignTools private IVertexSource CreateToothCutout() { - var angleToothToTooth = 360.0 / this.ToothCount; - var angleStepSize = this.angleToothToTooth / this.stepsPerToothAngle; + var angleStepSize = this.AngleToothToTooth / this.stepsPerToothAngle; IVertexSource toothCutout = new VertexStorage(); var toothCutterShape = this.CreateToothCutter(); + // return toothCutterShape; + var bounds = toothCutterShape.GetBounds(); var lowerLeftCorner = new Vector2(bounds.Left, bounds.Bottom); @@ -576,10 +578,7 @@ namespace MatterHackers.MatterControl.DesignTools var angle = stepCounter * angleStepSize; var xTranslation = new Vector2(angle * Math.PI / 180 * this.pitchRadius, 0); - var movedLowerLeftCorner = lowerLeftCorner + xTranslation; - movedLowerLeftCorner = Vector2.Rotate(movedLowerLeftCorner, MathHelper.DegreesToRadians(angle)); - - if (movedLowerLeftCorner.Length > this.OuterRadius) + if (Vector2.Rotate(lowerLeftCorner + xTranslation, MathHelper.DegreesToRadians(angle)).Length > this.OuterRadius) { // the cutter is now completely outside the gear and no longer influences the shape of the gear tooth break; @@ -592,7 +591,7 @@ namespace MatterHackers.MatterControl.DesignTools if (xTranslation[0] > 0) { - movedToothCutterShape = toothCutterShape.Translate(new Vector2(-xTranslation[0], xTranslation[1])); + movedToothCutterShape = toothCutterShape.Translate(new Vector2(-xTranslation.X, xTranslation.Y)); movedToothCutterShape = movedToothCutterShape.RotateZDegrees(-angle); toothCutout = toothCutout.Union(movedToothCutterShape); } @@ -602,7 +601,7 @@ namespace MatterHackers.MatterControl.DesignTools toothCutout = this.SmoothConcaveCorners(toothCutout); - return toothCutout.RotateZDegrees(-this.angleToothToTooth / 2); + return toothCutout.RotateZDegrees(-this.AngleToothToTooth / 2); } private IVertexSource CreateToothCutter() From 8e79c5a49deeca328971d15ea7a4e5d1d31735c8 Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Sun, 14 Jun 2020 07:46:03 -0700 Subject: [PATCH 02/12] improving debuging --- .../DesignTools/Primitives/Gear2D.cs | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/MatterControlLib/DesignTools/Primitives/Gear2D.cs b/MatterControlLib/DesignTools/Primitives/Gear2D.cs index 0c6e0d57c..8c6c30beb 100644 --- a/MatterControlLib/DesignTools/Primitives/Gear2D.cs +++ b/MatterControlLib/DesignTools/Primitives/Gear2D.cs @@ -190,6 +190,9 @@ namespace MatterHackers.MatterControl.DesignTools } } + public bool Debug { get; set; } = false; + private List debugData = new List(); + public override IEnumerable Vertices() { IVertexSource shape = null; @@ -209,6 +212,21 @@ namespace MatterHackers.MatterControl.DesignTools break; } + if (Debug && debugData.Count > 0) + { + IVertexSource output = debugData[0]; + var offset = 0.0; + for (int i = 1; i < debugData.Count; i++) + { + offset += debugData[i-1].GetBounds().Height/2 + 2; + offset += debugData[i].GetBounds().Height/2 + 2; + output = new CombinePaths(output, new VertexSourceApplyTransform(debugData[i], Affine.NewTranslation(0, offset))); + offset += debugData[i].GetBounds().Height/2 + 2; + } + + return output.Vertices(); + } + return shape.Vertices(); } @@ -256,15 +274,18 @@ namespace MatterHackers.MatterControl.DesignTools }; var sector = fullSector.Subtract(innerCircle); + debugData.Add(sector); + var cutterTemplate = this.CreateInternalToothCutter(); + debugData.Add(cutterTemplate); var pinion = this.connectedGear; var stepsPerTooth = this.stepsPerToothAngle; var angleStepSize = angleToothToTooth / stepsPerTooth; - var toothShape = sector; var cutter = cutterTemplate.Translate(-this.pitchRadius + this.connectedGear.pitchRadius, 0); - toothShape = toothShape.Subtract(cutter); + var toothShape = sector.Subtract(cutter); + debugData.Add(toothShape); for (var i = 1; i < stepsPerTooth; i++) { @@ -385,7 +406,7 @@ namespace MatterHackers.MatterControl.DesignTools private IVertexSource CreateInternalGearShape() { var singleTooth = this.CreateInternalToothProfile(); - return singleTooth; + debugData.Add(singleTooth); var corners = singleTooth as VertexStorage; From 61c724eb7661beb843fdf09f6d42504df3454320 Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Sun, 14 Jun 2020 10:03:49 -0700 Subject: [PATCH 03/12] continuing to try to understand inner gera --- .../DesignTools/Primitives/Gear2D.cs | 61 +++++++++++-------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/MatterControlLib/DesignTools/Primitives/Gear2D.cs b/MatterControlLib/DesignTools/Primitives/Gear2D.cs index 8c6c30beb..4ede19539 100644 --- a/MatterControlLib/DesignTools/Primitives/Gear2D.cs +++ b/MatterControlLib/DesignTools/Primitives/Gear2D.cs @@ -414,64 +414,73 @@ namespace MatterHackers.MatterControl.DesignTools var centerCornerIndex = 0; var radius = this.pitchRadius + (1 + this.profileShift) * this.addendum + this.Clearance; - var delta = 0.0000001; + var bottomRight = new Vector2(-1000000, -1000000); + var deltaFromBR = double.MaxValue; for (var i = 0; i < corners.Count; i++) { var corner = corners[i]; - if (corner.Y < delta && (corner.X + radius) < delta) + var length = (new Vector2(corner.X, corner.Y) - bottomRight).Length; + if (length < deltaFromBR) { centerCornerIndex = i; - break; + deltaFromBR = length; } } - var outerCorners = new VertexStorage(); + var outerCorner = new VertexStorage(); var command = ShapePath.FlagsAndCommand.MoveTo; - for (var i = 0; i < corners.Count; i++) + for (var i = 0; i < corners.Count - 2; i++) { var corner = corners[(i + centerCornerIndex) % corners.Count]; - if (corner.position.X != 0) - { - outerCorners.Add(corner.position.X, corner.position.Y, command); - command = ShapePath.FlagsAndCommand.LineTo; - } + outerCorner.Add(corner.position.X, corner.position.Y, command); + command = ShapePath.FlagsAndCommand.LineTo; } //outerCorners.ClosePolygon(); - return outerCorners; + debugData.Add(outerCorner); - var reversedOuterCorners = new VertexStorage(); + //var reversedOuterCorners = new VertexStorage(); + //command = ShapePath.FlagsAndCommand.MoveTo; + //foreach (var vertex in new ReversePath(outerCorners).Vertices()) + //{ + // reversedOuterCorners.Add(vertex.position.X, vertex.position.Y, command); + // command = ShapePath.FlagsAndCommand.LineTo; + //} + + //// debugData.Add(reversedOuterCorners); + + //outerCorners = reversedOuterCorners; + + var cornerCount = outerCorner.Count; + var outerCorners = new VertexStorage(); command = ShapePath.FlagsAndCommand.MoveTo; - foreach (var vertex in new ReversePath(outerCorners).Vertices()) - { - reversedOuterCorners.Add(vertex.position.X, vertex.position.Y, command); - command = ShapePath.FlagsAndCommand.LineTo; - } - outerCorners = reversedOuterCorners; - - var cornersCount = outerCorners.Count; - - for (var i = 1; i < this.ToothCount; i++) + for (var i = 0; i < this.ToothCount; i++) { var angle = i * this.AngleToothToTooth; var roatationMatrix = Affine.NewRotation(MathHelper.DegreesToRadians(angle)); - for (var j = 0; j < cornersCount; j++) + for (var j = 0; j < cornerCount; j++) { - var rotatedCorner = roatationMatrix.Transform(outerCorners[j].position); - outerCorners.Add(rotatedCorner.X, rotatedCorner.Y, ShapePath.FlagsAndCommand.LineTo); + var rotatedCorner = roatationMatrix.Transform(outerCorner[j].position); + outerCorners.Add(rotatedCorner.X, rotatedCorner.Y, command); + command = ShapePath.FlagsAndCommand.LineTo; } } outerCorners = this.SmoothConcaveCorners(outerCorners) as VertexStorage; + debugData.Add(outerCorners); + var innerRadius = this.pitchRadius + (1 - this.profileShift) * this.addendum + this.Clearance; var outerRadius = innerRadius + 4 * this.addendum; var outerCircle = new Ellipse(this.center, outerRadius, outerRadius); // return outerCorners; - return outerCircle.Subtract(outerCorners); + var finalShape = outerCircle.Subtract(outerCorners); + //debugData.Add(finalShape); + + return finalShape; } private IVertexSource CreateRackShape() From 103aa75d2d31216f8ba150d44b0ff6afc6d87230 Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Sun, 14 Jun 2020 10:06:49 -0700 Subject: [PATCH 04/12] latest AGG --- Submodules/agg-sharp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 7264ed51f..47ce99c0a 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 7264ed51faa05febd6f3ef49c114c3e5ebbfb901 +Subproject commit 47ce99c0a8dc2a139d5a0e75fe2a586a5c812937 From 2acf49ff876316dab335fee8997f902c0ba436fe Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Mon, 15 Jun 2020 09:05:39 -0700 Subject: [PATCH 05/12] working on inner gear --- .../DesignTools/Primitives/Gear2D.cs | 86 +++++++++++++------ Submodules/agg-sharp | 2 +- 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/MatterControlLib/DesignTools/Primitives/Gear2D.cs b/MatterControlLib/DesignTools/Primitives/Gear2D.cs index 4ede19539..d2c3ef05c 100644 --- a/MatterControlLib/DesignTools/Primitives/Gear2D.cs +++ b/MatterControlLib/DesignTools/Primitives/Gear2D.cs @@ -35,6 +35,8 @@ using MatterHackers.Agg.Transform; using MatterHackers.Agg.VertexSource; using MatterHackers.DataConverters2D; using MatterHackers.VectorMath; +using Polygon = System.Collections.Generic.List; +using Polygons = System.Collections.Generic.List>; namespace MatterHackers.MatterControl.DesignTools { @@ -96,6 +98,21 @@ namespace MatterHackers.MatterControl.DesignTools Rack } + private IntPoint ScalledPoint(double x, double y, double scale) + { + return new IntPoint(x * scale, y * scale); + } + + private Polygon Rectangle(double left, double bottom, double right, double top, double scale) + { + var output = new Polygon(4); + output.Add(ScalledPoint(left, bottom, scale)); + output.Add(ScalledPoint(right, bottom, scale)); + output.Add(ScalledPoint(right, top, scale)); + output.Add(ScalledPoint(left, top, scale)); + return output; + } + public double Backlash { get => _backlash; @@ -195,16 +212,16 @@ namespace MatterHackers.MatterControl.DesignTools public override IEnumerable Vertices() { - IVertexSource shape = null; + Polygons shape = null; switch (GearType) { case GearTypes.External: - shape = CreateExternalGearShape(); + //shape = CreateExternalGearShape(); break; case GearTypes.Internal: - shape = CreateInternalGearShape(); + //shape = CreateInternalGearShape(); break; case GearTypes.Rack: @@ -224,10 +241,18 @@ namespace MatterHackers.MatterControl.DesignTools offset += debugData[i].GetBounds().Height/2 + 2; } - return output.Vertices(); + // return output.Vertices(); } - return shape.Vertices(); + foreach (var poly in shape) + { + var command = ShapePath.FlagsAndCommand.MoveTo; + foreach (var point in poly) + { + yield return new VertexData(command, point.X / 1000.0, point.Y / 1000.0); + command = ShapePath.FlagsAndCommand.MoveTo; + } + } } private IVertexSource CreateInternalToothCutter() @@ -483,32 +508,30 @@ namespace MatterHackers.MatterControl.DesignTools return finalShape; } - private IVertexSource CreateRackShape() + private Polygons CreateRackShape() { - IVertexSource rack = new VertexStorage(); + var rack = new Polygons(); for (var i = 0; i < ToothCount; i++) { var tooth = this.CreateRackTooth(); - tooth = tooth.Translate(0, (0.5 + -ToothCount / 2.0 + i) * this.CircularPitch); - rack = rack.Union(tooth); + tooth = tooth.Translate(0, (0.5 + -ToothCount / 2.0 + i) * this.CircularPitch, 1000); + rack = rack.CreateUnion(tooth); } // creating the bar backing the teeth var rightX = -(this.addendum + this.Clearance); var width = 4 * this.addendum; var halfHeight = ToothCount * this.CircularPitch / 2.0; - var bar = new RoundedRect(rightX - width, -halfHeight, rightX, halfHeight, 0); + var bar = Rectangle(rightX - width, -halfHeight, rightX, halfHeight, 1000); - var rackFinal = rack.Union(bar) as VertexStorage; - rackFinal.Translate(this.addendum * this.profileShift, 0); - return rackFinal; + var rackFinal = rack.CreateUnion(bar); + return rackFinal.Translate(this.addendum * this.profileShift, 0, 1000); } - private IVertexSource CreateRackTooth() + private Polygon CreateRackTooth() { var toothWidth = this.CircularPitch / 2; - var toothDepth = this.addendum + this.Clearance; var sinPressureAngle = Math.Sin(this.PressureAngle * Math.PI / 180); var cosPressureAngle = Math.Cos(this.PressureAngle * Math.PI / 180); @@ -519,16 +542,16 @@ namespace MatterHackers.MatterControl.DesignTools var leftDepth = this.addendum + this.Clearance; - var upperLeftCorner = new Vector2(-leftDepth, toothWidth / 2 - dx + (this.addendum + this.Clearance) * sinPressureAngle); - var upperRightCorner = new Vector2(this.addendum, toothWidth / 2 - dx - this.addendum * sinPressureAngle); - var lowerRightCorner = new Vector2(upperRightCorner[0], -upperRightCorner[1]); - var lowerLeftCorner = new Vector2(upperLeftCorner[0], -upperLeftCorner[1]); + var upperLeftCorner = ScalledPoint(-leftDepth, toothWidth / 2 - dx + (this.addendum + this.Clearance) * sinPressureAngle, 1000); + var upperRightCorner = ScalledPoint(this.addendum, toothWidth / 2 - dx - this.addendum * sinPressureAngle, 1000); + var lowerRightCorner = ScalledPoint(upperRightCorner.X, -upperRightCorner.Y, 1000); + var lowerLeftCorner = ScalledPoint(upperLeftCorner.X, -upperLeftCorner.Y, 1000); - var tooth = new VertexStorage(); - tooth.MoveTo(upperLeftCorner); - tooth.LineTo(upperRightCorner); - tooth.LineTo(lowerRightCorner); - tooth.LineTo(lowerLeftCorner); + var tooth = new Polygon(); + tooth.Add(upperLeftCorner); + tooth.Add(upperRightCorner); + tooth.Add(lowerRightCorner); + tooth.Add(lowerLeftCorner); return tooth; } @@ -718,4 +741,19 @@ public static class Extensions return output; } + + public static Polygons CombinePaths(this Polygons aPolys, Polygons bPolys, ClipType clipType) + { + var clipper = new Clipper(); + + clipper.AddPaths(aPolys, PolyType.ptSubject, true); + clipper.AddPaths(bPolys, PolyType.ptClip, true); + + var outputPolys = new List>(); + clipper.Execute(clipType, outputPolys); + + Clipper.CleanPolygons(outputPolys); + + return outputPolys; + } } \ No newline at end of file diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 47ce99c0a..9424d9b2e 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 47ce99c0a8dc2a139d5a0e75fe2a586a5c812937 +Subproject commit 9424d9b2e03bd19d3c61c29dc44ad395f2838091 From 6021697aecc920948ed86d5557bfe6cb2554b5eb Mon Sep 17 00:00:00 2001 From: Lars Brubaker Date: Mon, 15 Jun 2020 18:46:48 -0700 Subject: [PATCH 06/12] Working more on intpoint version of gear --- .../DesignTools/Primitives/Gear2D.cs | 67 ++++++++++++------- Submodules/agg-sharp | 2 +- 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/MatterControlLib/DesignTools/Primitives/Gear2D.cs b/MatterControlLib/DesignTools/Primitives/Gear2D.cs index d2c3ef05c..e1dc146c2 100644 --- a/MatterControlLib/DesignTools/Primitives/Gear2D.cs +++ b/MatterControlLib/DesignTools/Primitives/Gear2D.cs @@ -29,6 +29,7 @@ either expressed or implied, of the FreeBSD Project. using System; using System.Collections.Generic; +using System.Security.Cryptography; using ClipperLib; using MatterHackers.Agg; using MatterHackers.Agg.Transform; @@ -113,6 +114,18 @@ namespace MatterHackers.MatterControl.DesignTools return output; } + private Polygon Circle(double x, double y, double radius, double scale = 1, int steps = 100) + { + var output = new Polygon(100); + for (int i = 0; i < steps; i++) + { + var angle = 2 * Math.PI * i / steps; + output.Add(new IntPoint(Math.Cos(angle) * radius * scale, Math.Sin(angle) * radius * scale)); + } + + return output; + } + public double Backlash { get => _backlash; @@ -208,7 +221,7 @@ namespace MatterHackers.MatterControl.DesignTools } public bool Debug { get; set; } = false; - private List debugData = new List(); + private List debugData = new List(); public override IEnumerable Vertices() { @@ -217,7 +230,7 @@ namespace MatterHackers.MatterControl.DesignTools switch (GearType) { case GearTypes.External: - //shape = CreateExternalGearShape(); + shape = CreateExternalGearShape(); break; case GearTypes.Internal: @@ -231,31 +244,40 @@ namespace MatterHackers.MatterControl.DesignTools if (Debug && debugData.Count > 0) { - IVertexSource output = debugData[0]; + var output = debugData[0]; var offset = 0.0; for (int i = 1; i < debugData.Count; i++) { - offset += debugData[i-1].GetBounds().Height/2 + 2; - offset += debugData[i].GetBounds().Height/2 + 2; + offset += debugData[i - 1].GetBounds().Height / 2 + 2; + offset += debugData[i].GetBounds().Height / 2 + 2; output = new CombinePaths(output, new VertexSourceApplyTransform(debugData[i], Affine.NewTranslation(0, offset))); - offset += debugData[i].GetBounds().Height/2 + 2; + offset += debugData[i].GetBounds().Height / 2 + 2; } // return output.Vertices(); } - foreach (var poly in shape) + if (shape == null) { - var command = ShapePath.FlagsAndCommand.MoveTo; - foreach (var point in poly) + yield return new VertexData(ShapePath.FlagsAndCommand.MoveTo, 0, 0); + yield return new VertexData(ShapePath.FlagsAndCommand.LineTo, 20, 0); + yield return new VertexData(ShapePath.FlagsAndCommand.LineTo, 0, 20); + } + else + { + foreach (var poly in shape) { - yield return new VertexData(command, point.X / 1000.0, point.Y / 1000.0); - command = ShapePath.FlagsAndCommand.MoveTo; + var command = ShapePath.FlagsAndCommand.MoveTo; + foreach (var point in poly) + { + yield return new VertexData(command, point.X / 1000.0, point.Y / 1000.0); + command = ShapePath.FlagsAndCommand.LineTo; + } } } } - private IVertexSource CreateInternalToothCutter() + private Polygons CreateInternalToothCutter() { // To cut the internal gear teeth, the actual pinion comes close but we need to enlarge it so properly caters for clearance and backlash var pinion = this.connectedGear; @@ -275,7 +297,7 @@ namespace MatterHackers.MatterControl.DesignTools enlargedPinion.CalculateDependants(); var tooth = enlargedPinion.CreateSingleTooth(); - return tooth.tooth.RotateZDegrees(90 + 180 / enlargedPinion.ToothCount); // we need a tooth pointing to the left + return tooth.tooth.Rotate(90 + 180 / enlargedPinion.ToothCount); // we need a tooth pointing to the left } private IVertexSource CreateInternalToothProfile() @@ -544,8 +566,8 @@ namespace MatterHackers.MatterControl.DesignTools var upperLeftCorner = ScalledPoint(-leftDepth, toothWidth / 2 - dx + (this.addendum + this.Clearance) * sinPressureAngle, 1000); var upperRightCorner = ScalledPoint(this.addendum, toothWidth / 2 - dx - this.addendum * sinPressureAngle, 1000); - var lowerRightCorner = ScalledPoint(upperRightCorner.X, -upperRightCorner.Y, 1000); - var lowerLeftCorner = ScalledPoint(upperLeftCorner.X, -upperLeftCorner.Y, 1000); + var lowerRightCorner = ScalledPoint(upperRightCorner.X, -upperRightCorner.Y, 1); + var lowerLeftCorner = ScalledPoint(upperLeftCorner.X, -upperLeftCorner.Y, 1); var tooth = new Polygon(); tooth.Add(upperLeftCorner); @@ -556,7 +578,7 @@ namespace MatterHackers.MatterControl.DesignTools return tooth; } - private IVertexSource CreateExternalGearShape() + private Polygons CreateExternalGearShape() { var tooth = this.CreateSingleTooth(); // return tooth.wheel; @@ -579,7 +601,7 @@ namespace MatterHackers.MatterControl.DesignTools // return outlinePaths; - var gearShape = tooth.wheel.Subtract(outlinePaths); + var gearShape = tooth.wheel.CombinePaths(outlinePaths, ClipType.ctDifference); // return gearShape; @@ -596,20 +618,17 @@ namespace MatterHackers.MatterControl.DesignTools return gearShape; } - private (IVertexSource tooth, IVertexSource wheel) CreateSingleTooth() + private (Polygons tooth, Polygon wheel) CreateSingleTooth() { // create outer circle sector covering one tooth - var toothSectorPath = new Ellipse(Vector2.Zero, this.OuterRadius) - { - ResolutionScale = 10 - }; + var toothSectorPath = Circle(0, 0, this.OuterRadius, 1000); var toothCutOut = CreateToothCutout(); return (toothCutOut, toothSectorPath); } - private IVertexSource CreateToothCutout() + private Polygons CreateToothCutout() { var angleStepSize = this.AngleToothToTooth / this.stepsPerToothAngle; @@ -617,7 +636,7 @@ namespace MatterHackers.MatterControl.DesignTools var toothCutterShape = this.CreateToothCutter(); // return toothCutterShape; - + var bounds = toothCutterShape.GetBounds(); var lowerLeftCorner = new Vector2(bounds.Left, bounds.Bottom); diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 9424d9b2e..d4e0174e7 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 9424d9b2e03bd19d3c61c29dc44ad395f2838091 +Subproject commit d4e0174e762f9825d24b204435f2031e3e06ecc6 From db7964a22ed4497dcbdcbca590efa4be159af198 Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Tue, 16 Jun 2020 15:55:04 -0700 Subject: [PATCH 07/12] continuing migration to IntPoint polygons --- .../DesignTools/Primitives/Gear2D.cs | 143 ++++++++---------- Submodules/agg-sharp | 2 +- 2 files changed, 65 insertions(+), 80 deletions(-) diff --git a/MatterControlLib/DesignTools/Primitives/Gear2D.cs b/MatterControlLib/DesignTools/Primitives/Gear2D.cs index e1dc146c2..4db9500fe 100644 --- a/MatterControlLib/DesignTools/Primitives/Gear2D.cs +++ b/MatterControlLib/DesignTools/Primitives/Gear2D.cs @@ -29,6 +29,7 @@ either expressed or implied, of the FreeBSD Project. using System; using System.Collections.Generic; +using System.Linq; using System.Security.Cryptography; using ClipperLib; using MatterHackers.Agg; @@ -104,6 +105,11 @@ namespace MatterHackers.MatterControl.DesignTools return new IntPoint(x * scale, y * scale); } + private IntPoint ScalledPoint(Vector2 position, double scale) + { + return new IntPoint(position.X * scale, position.Y * scale); + } + private Polygon Rectangle(double left, double bottom, double right, double top, double scale) { var output = new Polygon(4); @@ -244,13 +250,14 @@ namespace MatterHackers.MatterControl.DesignTools if (Debug && debugData.Count > 0) { - var output = debugData[0]; + var output = new Polygons(); + output.AddRange(debugData[0]); var offset = 0.0; for (int i = 1; i < debugData.Count; i++) { offset += debugData[i - 1].GetBounds().Height / 2 + 2; offset += debugData[i].GetBounds().Height / 2 + 2; - output = new CombinePaths(output, new VertexSourceApplyTransform(debugData[i], Affine.NewTranslation(0, offset))); + output.AddRange(debugData[i].Translate(0, offset)); offset += debugData[i].GetBounds().Height / 2 + 2; } @@ -300,30 +307,26 @@ namespace MatterHackers.MatterControl.DesignTools return tooth.tooth.Rotate(90 + 180 / enlargedPinion.ToothCount); // we need a tooth pointing to the left } - private IVertexSource CreateInternalToothProfile() + private Polygon CreateInternalToothProfile() { var radius = this.pitchRadius + (1 - this.profileShift) * this.addendum + this.Clearance; var angleToothToTooth = 360 / this.ToothCount; var sin = Math.Sin(angleToothToTooth / 2 * Math.PI / 180); var cos = Math.Cos(angleToothToTooth / 2 * Math.PI / 180); - var fullSector = new VertexStorage(); + var fullSector = new Polygon(); - fullSector.MoveTo(0, 0); - fullSector.LineTo(-(radius * cos), radius * sin); - fullSector.LineTo(-radius, 0); - fullSector.LineTo(-(radius * cos), -radius * sin); + fullSector.Add(ScalledPoint(0, 0, 1000)); + fullSector.Add(ScalledPoint(-(radius * cos), radius * sin, 1000)); + fullSector.Add(ScalledPoint(-radius, 0, 1000)); + fullSector.Add(ScalledPoint(-(radius * cos), -radius * sin, 1000)); var innerRadius = radius - (2 * this.addendum + this.Clearance); - var innerCircle = new Ellipse(this.center, innerRadius) - { - ResolutionScale = 10 - }; + var innerCircle = Circle(this.center.X, center.Y, innerRadius, 1000); var sector = fullSector.Subtract(innerCircle); debugData.Add(sector); - var cutterTemplate = this.CreateInternalToothCutter(); debugData.Add(cutterTemplate); @@ -339,37 +342,41 @@ namespace MatterHackers.MatterControl.DesignTools var pinionRotationAngle = i * angleStepSize; var pinionCenterRayAngle = -pinionRotationAngle * pinion.ToothCount / this.ToothCount; - cutter = cutterTemplate.RotateZDegrees(pinionRotationAngle); + cutter = cutterTemplate.Rotate(pinionRotationAngle); cutter = cutter.Translate(-this.pitchRadius + this.connectedGear.pitchRadius, 0); - cutter = cutter.RotateZDegrees(pinionCenterRayAngle); + cutter = cutter.Rotate(pinionCenterRayAngle); toothShape = toothShape.Subtract(cutter); - cutter = cutterTemplate.RotateZDegrees(-pinionRotationAngle); + cutter = cutterTemplate.Rotate(-pinionRotationAngle); cutter = cutter.Translate(-this.pitchRadius + this.connectedGear.pitchRadius, 0); - cutter = cutter.RotateZDegrees(-pinionCenterRayAngle); + cutter = cutter.Rotate(-pinionCenterRayAngle); toothShape = toothShape.Subtract(cutter); } - return toothShape; + if (toothShape.Count != 1) + { + return null; + } + + return toothShape[0]; } - private IVertexSource SmoothConcaveCorners(IVertexSource corners) + private Polygon SmoothConcaveCorners(Polygon corners) { // removes single concave corners located between convex corners return this.SmoothCorners(corners, false); // removeSingleConvex } - private IVertexSource SmoothConvexCorners(IVertexSource corners) + private Polygon SmoothConvexCorners(Polygon corners) { // removes single convex corners located between concave corners return this.SmoothCorners(corners, true); // removeSingleConvex } - private IVertexSource SmoothCorners(IVertexSource corners_in, bool removeSingleConvex) + private Polygon SmoothCorners(Polygon corners, bool removeSingleConvex) { - var corners = corners_in as VertexStorage; var isConvex = new List(); var previousCorner = corners[corners.Count - 1]; var currentCorner = corners[0]; @@ -377,8 +384,8 @@ namespace MatterHackers.MatterControl.DesignTools { var nextCorner = corners[(i + 1) % corners.Count]; - var v1 = previousCorner.position - currentCorner.position; - var v2 = nextCorner.position - currentCorner.position; + var v1 = previousCorner - currentCorner; + var v2 = nextCorner - currentCorner; var crossProduct = v1.Cross(v2); isConvex.Add(crossProduct < 0); @@ -387,7 +394,7 @@ namespace MatterHackers.MatterControl.DesignTools } // we want to remove any concave corners that are located between two convex corners - var cleanedUpCorners = new VertexStorage(); + var cleanedUpCorners = new Polygon(); for (var currentIndex = 0; currentIndex < corners.Count; currentIndex++) { var corner = corners[currentIndex]; @@ -407,7 +414,7 @@ namespace MatterHackers.MatterControl.DesignTools continue; } - cleanedUpCorners.Add(corner.X, corner.Y, corner.command); + cleanedUpCorners.Add(corner); } return cleanedUpCorners; @@ -450,12 +457,12 @@ namespace MatterHackers.MatterControl.DesignTools } } - private IVertexSource CreateInternalGearShape() + private Polygons CreateInternalGearShape() { var singleTooth = this.CreateInternalToothProfile(); - debugData.Add(singleTooth); + debugData.Add(new Polygons() { singleTooth }); - var corners = singleTooth as VertexStorage; + var corners = singleTooth; // first we need to find the corner that sits at the center var centerCornerIndex = 0; @@ -474,18 +481,16 @@ namespace MatterHackers.MatterControl.DesignTools } } - var outerCorner = new VertexStorage(); - var command = ShapePath.FlagsAndCommand.MoveTo; + var outerCorner = new Polygon(); for (var i = 0; i < corners.Count - 2; i++) { var corner = corners[(i + centerCornerIndex) % corners.Count]; - outerCorner.Add(corner.position.X, corner.position.Y, command); - command = ShapePath.FlagsAndCommand.LineTo; + outerCorner.Add(corner); } //outerCorners.ClosePolygon(); - debugData.Add(outerCorner); + debugData.Add(new Polygons() { outerCorner }); //var reversedOuterCorners = new VertexStorage(); //command = ShapePath.FlagsAndCommand.MoveTo; @@ -500,28 +505,26 @@ namespace MatterHackers.MatterControl.DesignTools //outerCorners = reversedOuterCorners; var cornerCount = outerCorner.Count; - var outerCorners = new VertexStorage(); - command = ShapePath.FlagsAndCommand.MoveTo; + var outerCorners = new Polygon(); for (var i = 0; i < this.ToothCount; i++) { var angle = i * this.AngleToothToTooth; - var roatationMatrix = Affine.NewRotation(MathHelper.DegreesToRadians(angle)); + var radians = MathHelper.DegreesToRadians(angle); for (var j = 0; j < cornerCount; j++) { - var rotatedCorner = roatationMatrix.Transform(outerCorner[j].position); - outerCorners.Add(rotatedCorner.X, rotatedCorner.Y, command); - command = ShapePath.FlagsAndCommand.LineTo; + var rotatedCorner = outerCorner[j].GetRotated(radians); + outerCorners.Add(rotatedCorner); } } - outerCorners = this.SmoothConcaveCorners(outerCorners) as VertexStorage; + outerCorners = this.SmoothConcaveCorners(outerCorners); - debugData.Add(outerCorners); + debugData.Add(new Polygons() { outerCorners }); var innerRadius = this.pitchRadius + (1 - this.profileShift) * this.addendum + this.Clearance; var outerRadius = innerRadius + 4 * this.addendum; - var outerCircle = new Ellipse(this.center, outerRadius, outerRadius); + var outerCircle = Circle(this.center.X, center.Y, outerRadius, 1000); // return outerCorners; var finalShape = outerCircle.Subtract(outerCorners); @@ -538,7 +541,7 @@ namespace MatterHackers.MatterControl.DesignTools { var tooth = this.CreateRackTooth(); tooth = tooth.Translate(0, (0.5 + -ToothCount / 2.0 + i) * this.CircularPitch, 1000); - rack = rack.CreateUnion(tooth); + rack = rack.Union(tooth); } // creating the bar backing the teeth @@ -547,7 +550,7 @@ namespace MatterHackers.MatterControl.DesignTools var halfHeight = ToothCount * this.CircularPitch / 2.0; var bar = Rectangle(rightX - width, -halfHeight, rightX, halfHeight, 1000); - var rackFinal = rack.CreateUnion(bar); + var rackFinal = rack.Union(bar); return rackFinal.Translate(this.addendum * this.profileShift, 0, 1000); } @@ -594,25 +597,22 @@ namespace MatterHackers.MatterControl.DesignTools for (var i = 1; i < this.ToothCount; i++) { var angle = i * this.AngleToothToTooth; - var roatationMatrix = Affine.NewRotation(MathHelper.DegreesToRadians(angle)); - var rotatedCorner = new VertexSourceApplyTransform(tooth.tooth, roatationMatrix); - outlinePaths = new CombinePaths(outlinePaths, rotatedCorner); + var radians = MathHelper.DegreesToRadians(angle); + var rotatedCorner = tooth.tooth.Rotate(radians); + outlinePaths.AddRange(rotatedCorner); } // return outlinePaths; - var gearShape = tooth.wheel.CombinePaths(outlinePaths, ClipType.ctDifference); + var gearShape = tooth.wheel.Subtract(outlinePaths); // return gearShape; if (this.CenterHoleDiameter > 0) { var radius = this.CenterHoleDiameter / 2; - var centerhole = new Ellipse(0, 0, radius, radius) - { - ResolutionScale = 10 - }; - gearShape = gearShape.Subtract(centerhole) as VertexStorage; + var centerhole = Circle(0, 0, radius, 1000); + gearShape = gearShape.Subtract(centerhole); } return gearShape; @@ -632,7 +632,7 @@ namespace MatterHackers.MatterControl.DesignTools { var angleStepSize = this.AngleToothToTooth / this.stepsPerToothAngle; - IVertexSource toothCutout = new VertexStorage(); + var toothCutout = new Polygons(); var toothCutterShape = this.CreateToothCutter(); // return toothCutterShape; @@ -657,26 +657,26 @@ namespace MatterHackers.MatterControl.DesignTools } // we move in both directions - var movedToothCutterShape = toothCutterShape.Translate(xTranslation); - movedToothCutterShape = movedToothCutterShape.RotateZDegrees(angle); + var movedToothCutterShape = toothCutterShape.Translate(xTranslation.X, xTranslation.Y); + movedToothCutterShape = movedToothCutterShape.Rotate(angle); toothCutout = toothCutout.Union(movedToothCutterShape); if (xTranslation[0] > 0) { - movedToothCutterShape = toothCutterShape.Translate(new Vector2(-xTranslation.X, xTranslation.Y)); - movedToothCutterShape = movedToothCutterShape.RotateZDegrees(-angle); + movedToothCutterShape = toothCutterShape.Translate(-xTranslation.X, xTranslation.Y); + movedToothCutterShape = movedToothCutterShape.Rotate(-angle); toothCutout = toothCutout.Union(movedToothCutterShape); } stepCounter++; } - toothCutout = this.SmoothConcaveCorners(toothCutout); + var toothCutout1 = this.SmoothConcaveCorners(toothCutout[0]); - return toothCutout.RotateZDegrees(-this.AngleToothToTooth / 2); + return toothCutout1.Rotate(-this.AngleToothToTooth / 2); } - private IVertexSource CreateToothCutter() + private Polygon CreateToothCutter() { // we create a trapezoidal cutter as described at http://lcamtuf.coredump.cx/gcnc/ch6/ under the section 'Putting it all together' var toothWidth = this.CircularPitch / 2; @@ -696,8 +696,8 @@ namespace MatterHackers.MatterControl.DesignTools var upperLeftCorner = new Vector2(-upperRightCorner[0], upperRightCorner[1]); var lowerLeftCorner = new Vector2(-lowerRightCorner[0], lowerRightCorner[1]); - var cutterPath = new VertexStorage(); - cutterPath.MoveTo(lowerLeftCorner); + var cutterPath = new Polygon(); + cutterPath.Add(ScalledPoint(lowerLeftCorner, 1000)); cutterPath.LineTo(upperLeftCorner); cutterPath.LineTo(upperRightCorner); cutterPath.LineTo(lowerRightCorner); @@ -760,19 +760,4 @@ public static class Extensions return output; } - - public static Polygons CombinePaths(this Polygons aPolys, Polygons bPolys, ClipType clipType) - { - var clipper = new Clipper(); - - clipper.AddPaths(aPolys, PolyType.ptSubject, true); - clipper.AddPaths(bPolys, PolyType.ptClip, true); - - var outputPolys = new List>(); - clipper.Execute(clipType, outputPolys); - - Clipper.CleanPolygons(outputPolys); - - return outputPolys; - } } \ No newline at end of file diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index d4e0174e7..f23931219 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit d4e0174e762f9825d24b204435f2031e3e06ecc6 +Subproject commit f23931219f0942cbdf2bd0d24b382dc5e223c56c From 96c7f204b6609d9a1f1134e8510cc58d45129f6a Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Tue, 16 Jun 2020 15:55:04 -0700 Subject: [PATCH 08/12] continuing migration to IntPoint polygons --- Submodules/agg-sharp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index f23931219..35a939377 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit f23931219f0942cbdf2bd0d24b382dc5e223c56c +Subproject commit 35a9393771b162da27a660855221d83637aab63b From 42b9a76dbffc0643255a6f10f5c4ae5b5fadf73e Mon Sep 17 00:00:00 2001 From: Lars Brubaker Date: Tue, 16 Jun 2020 17:58:26 -0700 Subject: [PATCH 09/12] more working with polygons --- .../DesignTools/Primitives/Gear2D.cs | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/MatterControlLib/DesignTools/Primitives/Gear2D.cs b/MatterControlLib/DesignTools/Primitives/Gear2D.cs index 4db9500fe..6ae231fba 100644 --- a/MatterControlLib/DesignTools/Primitives/Gear2D.cs +++ b/MatterControlLib/DesignTools/Primitives/Gear2D.cs @@ -30,7 +30,6 @@ either expressed or implied, of the FreeBSD Project. using System; using System.Collections.Generic; using System.Linq; -using System.Security.Cryptography; using ClipperLib; using MatterHackers.Agg; using MatterHackers.Agg.Transform; @@ -252,16 +251,15 @@ namespace MatterHackers.MatterControl.DesignTools { var output = new Polygons(); output.AddRange(debugData[0]); - var offset = 0.0; + var offset = debugData[0].GetBounds().Height + 2000; for (int i = 1; i < debugData.Count; i++) { - offset += debugData[i - 1].GetBounds().Height / 2 + 2; - offset += debugData[i].GetBounds().Height / 2 + 2; + offset += debugData[i-1].GetBounds().Height + 2; output.AddRange(debugData[i].Translate(0, offset)); - offset += debugData[i].GetBounds().Height / 2 + 2; + offset += debugData[i].GetBounds().Height + 2; } - // return output.Vertices(); + shape = output; } if (shape == null) @@ -284,7 +282,7 @@ namespace MatterHackers.MatterControl.DesignTools } } - private Polygons CreateInternalToothCutter() + private Polygon CreateInternalToothCutter() { // To cut the internal gear teeth, the actual pinion comes close but we need to enlarge it so properly caters for clearance and backlash var pinion = this.connectedGear; @@ -328,7 +326,7 @@ namespace MatterHackers.MatterControl.DesignTools debugData.Add(sector); var cutterTemplate = this.CreateInternalToothCutter(); - debugData.Add(cutterTemplate); + debugData.Add(new Polygons() { cutterTemplate }); var pinion = this.connectedGear; var stepsPerTooth = this.stepsPerToothAngle; @@ -584,14 +582,13 @@ namespace MatterHackers.MatterControl.DesignTools private Polygons CreateExternalGearShape() { var tooth = this.CreateSingleTooth(); - // return tooth.wheel; - // return tooth.tooth; + debugData.Add(new Polygons() { tooth.tooth }); // we could now take the tooth cutout, rotate it tooth count times and union the various slices together into a complete gear. // However, the union operations become more and more complex as the complete gear is built up. // So instead we capture the outer path of the tooth and concatenate rotated versions of this path into a complete outer gear path. // Concatenating paths is inexpensive resulting in significantly faster execution. - var outlinePaths = tooth.tooth; + var outlinePaths = new Polygon(); // first we need to find the corner that sits at the center for (var i = 1; i < this.ToothCount; i++) @@ -602,11 +599,11 @@ namespace MatterHackers.MatterControl.DesignTools outlinePaths.AddRange(rotatedCorner); } - // return outlinePaths; + debugData.Add(new Polygons() { outlinePaths }); var gearShape = tooth.wheel.Subtract(outlinePaths); - // return gearShape; + debugData.Add(gearShape); if (this.CenterHoleDiameter > 0) { @@ -618,7 +615,7 @@ namespace MatterHackers.MatterControl.DesignTools return gearShape; } - private (Polygons tooth, Polygon wheel) CreateSingleTooth() + private (Polygon tooth, Polygon wheel) CreateSingleTooth() { // create outer circle sector covering one tooth var toothSectorPath = Circle(0, 0, this.OuterRadius, 1000); @@ -628,14 +625,14 @@ namespace MatterHackers.MatterControl.DesignTools return (toothCutOut, toothSectorPath); } - private Polygons CreateToothCutout() + private Polygon CreateToothCutout() { var angleStepSize = this.AngleToothToTooth / this.stepsPerToothAngle; var toothCutout = new Polygons(); var toothCutterShape = this.CreateToothCutter(); - // return toothCutterShape; + debugData.Add(new Polygons() { toothCutterShape }); var bounds = toothCutterShape.GetBounds(); var lowerLeftCorner = new Vector2(bounds.Left, bounds.Bottom); @@ -648,9 +645,10 @@ namespace MatterHackers.MatterControl.DesignTools while (true) { var angle = stepCounter * angleStepSize; - var xTranslation = new Vector2(angle * Math.PI / 180 * this.pitchRadius, 0); + var radians = MathHelper.DegreesToRadians(angle); + var xTranslation = new Vector2(radians * this.pitchRadius, 0) * 1000; - if (Vector2.Rotate(lowerLeftCorner + xTranslation, MathHelper.DegreesToRadians(angle)).Length > this.OuterRadius) + if (Vector2.Rotate(lowerLeftCorner + xTranslation, radians).Length > this.OuterRadius * 1000) { // the cutter is now completely outside the gear and no longer influences the shape of the gear tooth break; @@ -658,13 +656,13 @@ namespace MatterHackers.MatterControl.DesignTools // we move in both directions var movedToothCutterShape = toothCutterShape.Translate(xTranslation.X, xTranslation.Y); - movedToothCutterShape = movedToothCutterShape.Rotate(angle); + movedToothCutterShape = movedToothCutterShape.Rotate(radians); toothCutout = toothCutout.Union(movedToothCutterShape); if (xTranslation[0] > 0) { movedToothCutterShape = toothCutterShape.Translate(-xTranslation.X, xTranslation.Y); - movedToothCutterShape = movedToothCutterShape.Rotate(-angle); + movedToothCutterShape = movedToothCutterShape.Rotate(-radians); toothCutout = toothCutout.Union(movedToothCutterShape); } @@ -673,7 +671,7 @@ namespace MatterHackers.MatterControl.DesignTools var toothCutout1 = this.SmoothConcaveCorners(toothCutout[0]); - return toothCutout1.Rotate(-this.AngleToothToTooth / 2); + return toothCutout1.Rotate(MathHelper.DegreesToRadians(-this.AngleToothToTooth / 2)); } private Polygon CreateToothCutter() @@ -698,9 +696,9 @@ namespace MatterHackers.MatterControl.DesignTools var cutterPath = new Polygon(); cutterPath.Add(ScalledPoint(lowerLeftCorner, 1000)); - cutterPath.LineTo(upperLeftCorner); - cutterPath.LineTo(upperRightCorner); - cutterPath.LineTo(lowerRightCorner); + cutterPath.Add(ScalledPoint(upperLeftCorner, 1000)); + cutterPath.Add(ScalledPoint(upperRightCorner, 1000)); + cutterPath.Add(ScalledPoint(lowerRightCorner, 1000)); return cutterPath; } From bea5d0da6c0ce1c4ec4294f96a4257c6ab057fac Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Wed, 17 Jun 2020 08:05:05 -0700 Subject: [PATCH 10/12] outer gear working with new system --- .../DesignTools/Primitives/Gear2D.cs | 31 +++++++++++-------- Submodules/agg-sharp | 2 +- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/MatterControlLib/DesignTools/Primitives/Gear2D.cs b/MatterControlLib/DesignTools/Primitives/Gear2D.cs index 6ae231fba..068a01004 100644 --- a/MatterControlLib/DesignTools/Primitives/Gear2D.cs +++ b/MatterControlLib/DesignTools/Primitives/Gear2D.cs @@ -251,12 +251,13 @@ namespace MatterHackers.MatterControl.DesignTools { var output = new Polygons(); output.AddRange(debugData[0]); - var offset = debugData[0].GetBounds().Height + 2000; + var top = debugData[0].GetBounds().Top; for (int i = 1; i < debugData.Count; i++) { - offset += debugData[i-1].GetBounds().Height + 2; - output.AddRange(debugData[i].Translate(0, offset)); - offset += debugData[i].GetBounds().Height + 2; + var offset = top - debugData[i].GetBounds().Bottom + 2000; + var offsetPolys = debugData[i].Translate(0, offset); + output.AddRange(offsetPolys); + top = offsetPolys.GetBounds().Top; } shape = output; @@ -581,27 +582,30 @@ namespace MatterHackers.MatterControl.DesignTools private Polygons CreateExternalGearShape() { - var tooth = this.CreateSingleTooth(); - debugData.Add(new Polygons() { tooth.tooth }); + var toothParts = this.CreateSingleTooth(); // we could now take the tooth cutout, rotate it tooth count times and union the various slices together into a complete gear. // However, the union operations become more and more complex as the complete gear is built up. // So instead we capture the outer path of the tooth and concatenate rotated versions of this path into a complete outer gear path. // Concatenating paths is inexpensive resulting in significantly faster execution. - var outlinePaths = new Polygon(); - // first we need to find the corner that sits at the center - for (var i = 1; i < this.ToothCount; i++) + var tooth = toothParts.tooth; + debugData.Add(new Polygons() { tooth }); + + var gearShape = new Polygons(); + for (var i = 0; i < this.ToothCount; i++) { var angle = i * this.AngleToothToTooth; var radians = MathHelper.DegreesToRadians(angle); - var rotatedCorner = tooth.tooth.Rotate(radians); - outlinePaths.AddRange(rotatedCorner); + var rotatedCorner = tooth.Rotate(radians); + gearShape.Add(rotatedCorner); } - debugData.Add(new Polygons() { outlinePaths }); + gearShape = gearShape.Union(gearShape, PolyFillType.pftNonZero); - var gearShape = tooth.wheel.Subtract(outlinePaths); + debugData.Add(gearShape); + + gearShape = toothParts.wheel.Subtract(gearShape); debugData.Add(gearShape); @@ -610,6 +614,7 @@ namespace MatterHackers.MatterControl.DesignTools var radius = this.CenterHoleDiameter / 2; var centerhole = Circle(0, 0, radius, 1000); gearShape = gearShape.Subtract(centerhole); + debugData.Add(gearShape); } return gearShape; diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 35a939377..a474af0f5 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 35a9393771b162da27a660855221d83637aab63b +Subproject commit a474af0f548ce56ba523d33cd77128743acd0103 From 47f77acbe5490b050e9ac8ef871313b499154ee3 Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Thu, 18 Jun 2020 09:10:40 -0700 Subject: [PATCH 11/12] Getting inner gear to show more debug --- .../DesignTools/Primitives/Gear2D.cs | 118 +++++------------- 1 file changed, 33 insertions(+), 85 deletions(-) diff --git a/MatterControlLib/DesignTools/Primitives/Gear2D.cs b/MatterControlLib/DesignTools/Primitives/Gear2D.cs index 068a01004..bc6c9b9fb 100644 --- a/MatterControlLib/DesignTools/Primitives/Gear2D.cs +++ b/MatterControlLib/DesignTools/Primitives/Gear2D.cs @@ -239,7 +239,7 @@ namespace MatterHackers.MatterControl.DesignTools break; case GearTypes.Internal: - //shape = CreateInternalGearShape(); + shape = CreateInternalGearShape(); break; case GearTypes.Rack: @@ -303,15 +303,15 @@ namespace MatterHackers.MatterControl.DesignTools enlargedPinion.CalculateDependants(); var tooth = enlargedPinion.CreateSingleTooth(); - return tooth.tooth.Rotate(90 + 180 / enlargedPinion.ToothCount); // we need a tooth pointing to the left + return tooth.tooth.Rotate(MathHelper.DegreesToRadians(90 + 180) / enlargedPinion.ToothCount); // we need a tooth pointing to the left } private Polygon CreateInternalToothProfile() { var radius = this.pitchRadius + (1 - this.profileShift) * this.addendum + this.Clearance; - var angleToothToTooth = 360 / this.ToothCount; - var sin = Math.Sin(angleToothToTooth / 2 * Math.PI / 180); - var cos = Math.Cos(angleToothToTooth / 2 * Math.PI / 180); + var toothToToothRadians = MathHelper.Tau / this.ToothCount; + var sin = Math.Sin(toothToToothRadians); + var cos = Math.Cos(toothToToothRadians); var fullSector = new Polygon(); @@ -322,7 +322,6 @@ namespace MatterHackers.MatterControl.DesignTools var innerRadius = radius - (2 * this.addendum + this.Clearance); var innerCircle = Circle(this.center.X, center.Y, innerRadius, 1000); - var sector = fullSector.Subtract(innerCircle); debugData.Add(sector); @@ -331,35 +330,31 @@ namespace MatterHackers.MatterControl.DesignTools var pinion = this.connectedGear; var stepsPerTooth = this.stepsPerToothAngle; - var angleStepSize = angleToothToTooth / stepsPerTooth; - var cutter = cutterTemplate.Translate(-this.pitchRadius + this.connectedGear.pitchRadius, 0); - var toothShape = sector.Subtract(cutter); + var stepSizeRadians = toothToToothRadians / stepsPerTooth; + + var toothShape = sector; + + for (var i = 0; i < stepsPerTooth; i++) + { + var pinionRadians = i * stepSizeRadians; + var pinionCenterRayRadians = -pinionRadians * pinion.ToothCount / this.ToothCount; + + var cutter = cutterTemplate.Rotate(pinionRadians); + cutter = cutter.Translate(-this.pitchRadius + this.connectedGear.pitchRadius, 0, 1000); + cutter = cutter.Rotate(pinionCenterRayRadians); + + toothShape = toothShape.Subtract(cutter); + + cutter = cutterTemplate.Rotate(-pinionRadians); + cutter = cutter.Translate(-this.pitchRadius + this.connectedGear.pitchRadius, 0, 1000); + cutter = cutter.Rotate(-pinionCenterRayRadians); + + toothShape = toothShape.Subtract(cutter); + } + debugData.Add(toothShape); - for (var i = 1; i < stepsPerTooth; i++) - { - var pinionRotationAngle = i * angleStepSize; - var pinionCenterRayAngle = -pinionRotationAngle * pinion.ToothCount / this.ToothCount; - - cutter = cutterTemplate.Rotate(pinionRotationAngle); - cutter = cutter.Translate(-this.pitchRadius + this.connectedGear.pitchRadius, 0); - cutter = cutter.Rotate(pinionCenterRayAngle); - - toothShape = toothShape.Subtract(cutter); - - cutter = cutterTemplate.Rotate(-pinionRotationAngle); - cutter = cutter.Translate(-this.pitchRadius + this.connectedGear.pitchRadius, 0); - cutter = cutter.Rotate(-pinionCenterRayAngle); - - toothShape = toothShape.Subtract(cutter); - } - - if (toothShape.Count != 1) - { - return null; - } - - return toothShape[0]; + return toothShape[toothShape.Count - 1]; } private Polygon SmoothConcaveCorners(Polygon corners) @@ -461,65 +456,18 @@ namespace MatterHackers.MatterControl.DesignTools var singleTooth = this.CreateInternalToothProfile(); debugData.Add(new Polygons() { singleTooth }); - var corners = singleTooth; - - // first we need to find the corner that sits at the center - var centerCornerIndex = 0; - var radius = this.pitchRadius + (1 + this.profileShift) * this.addendum + this.Clearance; - - var bottomRight = new Vector2(-1000000, -1000000); - var deltaFromBR = double.MaxValue; - for (var i = 0; i < corners.Count; i++) - { - var corner = corners[i]; - var length = (new Vector2(corner.X, corner.Y) - bottomRight).Length; - if (length < deltaFromBR) - { - centerCornerIndex = i; - deltaFromBR = length; - } - } - - var outerCorner = new Polygon(); - for (var i = 0; i < corners.Count - 2; i++) - { - var corner = corners[(i + centerCornerIndex) % corners.Count]; - outerCorner.Add(corner); - } - - //outerCorners.ClosePolygon(); - - debugData.Add(new Polygons() { outerCorner }); - - //var reversedOuterCorners = new VertexStorage(); - //command = ShapePath.FlagsAndCommand.MoveTo; - //foreach (var vertex in new ReversePath(outerCorners).Vertices()) - //{ - // reversedOuterCorners.Add(vertex.position.X, vertex.position.Y, command); - // command = ShapePath.FlagsAndCommand.LineTo; - //} - - //// debugData.Add(reversedOuterCorners); - - //outerCorners = reversedOuterCorners; - - var cornerCount = outerCorner.Count; - var outerCorners = new Polygon(); + var outerCorners = new Polygons(); for (var i = 0; i < this.ToothCount; i++) { var angle = i * this.AngleToothToTooth; var radians = MathHelper.DegreesToRadians(angle); - for (var j = 0; j < cornerCount; j++) - { - var rotatedCorner = outerCorner[j].GetRotated(radians); - outerCorners.Add(rotatedCorner); - } + outerCorners.Add(singleTooth.Rotate(radians)); } - outerCorners = this.SmoothConcaveCorners(outerCorners); + outerCorners = outerCorners.Union(outerCorners, PolyFillType.pftNonZero); - debugData.Add(new Polygons() { outerCorners }); + debugData.Add(outerCorners); var innerRadius = this.pitchRadius + (1 - this.profileShift) * this.addendum + this.Clearance; var outerRadius = innerRadius + 4 * this.addendum; @@ -604,7 +552,7 @@ namespace MatterHackers.MatterControl.DesignTools gearShape = gearShape.Union(gearShape, PolyFillType.pftNonZero); debugData.Add(gearShape); - + gearShape = toothParts.wheel.Subtract(gearShape); debugData.Add(gearShape); From fe174269bdd1d1c459e18ffa17c939730b6d52bd Mon Sep 17 00:00:00 2001 From: Lars Brubaker Date: Fri, 19 Jun 2020 11:06:03 -0700 Subject: [PATCH 12/12] allowing socketeer to be disabeld --- .../ApplicationView/ApplicationController.cs | 55 +++++++++++-------- .../ApplicationSettingsPage.cs | 6 ++ .../SettingsManagement/UserSettings.cs | 1 + Submodules/agg-sharp | 2 +- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/MatterControlLib/ApplicationView/ApplicationController.cs b/MatterControlLib/ApplicationView/ApplicationController.cs index 79ccb7870..488717fc6 100644 --- a/MatterControlLib/ApplicationView/ApplicationController.cs +++ b/MatterControlLib/ApplicationView/ApplicationController.cs @@ -813,7 +813,13 @@ namespace MatterHackers.MatterControl var selectedItem = scene.SelectedItem; if (selectedItem != null) { - scene.MakeLowestFaceFlat(selectedItem); + try + { + scene.MakeLowestFaceFlat(selectedItem); + } + catch + { + } } }, IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null, @@ -2107,40 +2113,45 @@ namespace MatterHackers.MatterControl [NamedTypeFace.Liberation_Mono] = TypeFace.LoadFrom(AggContext.StaticData.ReadAllText(Path.Combine("Fonts", "LiberationMono.svg"))) }; + static object locker = new object(); + public static TypeFace GetTypeFace(NamedTypeFace namedTypeFace) { - if (!TypeFaceCache.ContainsKey(namedTypeFace)) + lock (locker) { - TypeFace typeFace = new TypeFace(); - var path = Path.Combine("Fonts", $"{namedTypeFace}.ttf"); - var exists = AggContext.StaticData.FileExists(path); - var stream = exists ? AggContext.StaticData.OpenStream(path) : null; - if (stream != null - && typeFace.LoadTTF(stream)) + if (!TypeFaceCache.ContainsKey(namedTypeFace)) { - TypeFaceCache.Add(namedTypeFace, typeFace); - } - else - { - // try the svg - path = Path.Combine("Fonts", $"{namedTypeFace}.svg"); - exists = AggContext.StaticData.FileExists(path); - typeFace = exists ? TypeFace.LoadFrom(AggContext.StaticData.ReadAllText(path)) : null; - if (typeFace != null) + TypeFace typeFace = new TypeFace(); + var path = Path.Combine("Fonts", $"{namedTypeFace}.ttf"); + var exists = AggContext.StaticData.FileExists(path); + var stream = exists ? AggContext.StaticData.OpenStream(path) : null; + if (stream != null + && typeFace.LoadTTF(stream)) { TypeFaceCache.Add(namedTypeFace, typeFace); } else { - // assign it to the default - TypeFaceCache.Add(namedTypeFace, TypeFaceCache[NamedTypeFace.Liberation_Sans]); + // try the svg + path = Path.Combine("Fonts", $"{namedTypeFace}.svg"); + exists = AggContext.StaticData.FileExists(path); + typeFace = exists ? TypeFace.LoadFrom(AggContext.StaticData.ReadAllText(path)) : null; + if (typeFace != null) + { + TypeFaceCache.Add(namedTypeFace, typeFace); + } + else + { + // assign it to the default + TypeFaceCache.Add(namedTypeFace, TypeFaceCache[NamedTypeFace.Liberation_Sans]); + } } + + stream?.Dispose(); } - stream?.Dispose(); + return TypeFaceCache[namedTypeFace]; } - - return TypeFaceCache[namedTypeFace]; } private static TypeFace titilliumTypeFace = null; diff --git a/MatterControlLib/SettingsManagement/ApplicationSettingsPage.cs b/MatterControlLib/SettingsManagement/ApplicationSettingsPage.cs index 9dba7f1d9..582dbaea2 100644 --- a/MatterControlLib/SettingsManagement/ApplicationSettingsPage.cs +++ b/MatterControlLib/SettingsManagement/ApplicationSettingsPage.cs @@ -387,6 +387,12 @@ namespace MatterHackers.MatterControl true, false); + AddUserBoolToggle(advancedPanel, + "Enable Socketeer Client".Localize(), + UserSettingsKey.ApplicationUseSocketeer, + true, + false); + var openCacheButton = new IconButton(AggContext.StaticData.LoadIcon("fa-link_16.png", 16, 16, theme.InvertIcons), theme) { ToolTipText = "Open Folder".Localize(), diff --git a/MatterControlLib/SettingsManagement/UserSettings.cs b/MatterControlLib/SettingsManagement/UserSettings.cs index d7d04300a..c85ab902b 100644 --- a/MatterControlLib/SettingsManagement/UserSettings.cs +++ b/MatterControlLib/SettingsManagement/UserSettings.cs @@ -18,6 +18,7 @@ namespace MatterHackers.MatterControl public const string AfterPrintFinishedSendTextMessage = nameof(AfterPrintFinishedSendTextMessage); public const string ApplicationDisplayMode = nameof(ApplicationDisplayMode); public const string ApplicationUseHeigResDisplays = nameof(ApplicationUseHeigResDisplays); + public const string ApplicationUseSocketeer = nameof(ApplicationUseSocketeer); public const string ApplicationTextSize = nameof(ApplicationTextSize); public const string ColorPanelExpanded = nameof(ColorPanelExpanded); public const string ConfigurePrinter_CurrentTab = nameof(ConfigurePrinter_CurrentTab); diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index a474af0f5..c1111e039 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit a474af0f548ce56ba523d33cd77128743acd0103 +Subproject commit c1111e0391606ca75ed26a4985a9898f19f10223