public class FlatFinComparer : IComparer <FlatFin> { // structure borrowed from online help public int Compare(FlatFin x, FlatFin y) { if (x == null) { if (y == null) // If x is null and y is null, they're equal. { return(0); } else // If x is null and y is not null, y is greater. { return(-1); } } else // If x is not null and y is null, x is greater. { if (y == null) { return(1); } else // and y is not null, compare the lengths of the two strings. { double xl = x.SourceFin.Edge.Length; double yl = y.SourceFin.Edge.Length; if (Accuracy.EqualLengths(xl, yl)) // if lengths are close { return(-x.FlatFace.Rank.CompareTo(y.FlatFace.Rank)); // then use proximity to seed face } else if (xl > yl) { return(1); } else { return(-1); } } } }
private static Body CreateThreadBody(Face cylinderFace, double pitch, double angle, double positionOffset) { double stitchTolerance = Accuracy.LinearResolution * 1E4; double radius, innerRadius, outerRadius; Line axis; CurveSegment innerCurve, outerCurveA, outerCurveB; Matrix trans; Cylinder cylinder = cylinderFace.Geometry as Cylinder; Debug.Assert(cylinder != null); axis = cylinder.Axis; Interval bounds = AxisBounds(cylinderFace, axis); int threadsPerSurface = 2; double threads = bounds.Span / pitch / threadsPerSurface; int threadSurfaceCount = (int)threads + 2; var surfaceBounds = Interval.Create(bounds.Start, bounds.Start + pitch * threadsPerSurface); // var extendedSurfaceBounds = Interval.Create(surfaceBounds.Start - surfaceBounds.Span / threadsPerSurface, surfaceBounds.End + surfaceBounds.Span / threadsPerSurface); CreateUntransformedThreadCurves(cylinderFace, pitch, angle, surfaceBounds, positionOffset, out radius, out axis, out innerCurve, out outerCurveA, out outerCurveB, out trans, out innerRadius, out outerRadius); Body loftBodyA = Body.LoftProfiles(new[] { new[] { outerCurveA }, new[] { innerCurve } }, false, false); Body loftBodyB = Body.LoftProfiles(new[] { new[] { innerCurve }, new[] { outerCurveB } }, false, false); loftBodyA.Stitch(new[] { loftBodyB }, stitchTolerance, null); loftBodyA.Transform(Matrix.CreateTranslation(Direction.DirZ * -pitch * threadsPerSurface / 2)); double threadDepth = outerRadius - innerRadius; double padding = 1.1; double paddedOuterRadius = innerRadius + threadDepth * padding; var copies = new Body[threadSurfaceCount]; for (int i = 0; i < threadSurfaceCount; i++) { copies[i] = loftBodyA.CreateTransformedCopy(Matrix.CreateTranslation(Direction.DirZ * surfaceBounds.Span * (i + 1))); } loftBodyA.Stitch(copies, stitchTolerance, null); double length = bounds.Span; var capA = Body.SweepProfile(Plane.PlaneZX, new[] { Point.Origin, Point.Create(innerRadius, 0, 0), Point.Create(paddedOuterRadius, 0, threadDepth * Math.Tan(angle / 2) * padding), Point.Create(paddedOuterRadius, 0, length - threadDepth * Math.Tan(angle / 2) * padding), Point.Create(innerRadius, 0, length), Point.Create(0, 0, length) }.AsPolygon(), new[] { CurveSegment.Create(Circle.Create(Frame.World, 1)) }); loftBodyA.Imprint(capA); capA.DeleteFaces(capA.Faces .Where(f => f.Edges .Where(e => (e.Geometry is Circle && Accuracy.EqualLengths(((Circle)e.Geometry).Radius, paddedOuterRadius)) ).Count() > 0).ToArray(), RepairAction.None ); loftBodyA.Fuse(new[] { capA }, true, null); while (!loftBodyA.IsManifold) { loftBodyA.DeleteFaces(loftBodyA.Faces.Where(f => f.Edges.Where(e => e.Faces.Count == 1).Count() > 0).ToArray(), RepairAction.None); } // loftBodyA.Faces.Select(f => loftBodyA.CopyFaces(new[] { f })).ToArray().Print(); loftBodyA.Transform(trans); return(loftBodyA); }