public ICollection <DesignBody> CreateSolid(Part mainPart) { var bands = new List <ICollection <Body> >(); var cutters = new List <Body[]>(); double newScale = 0.094; double cutterHeight = 0.01 / newScale; double cutterWidth = 0.0005 / newScale; bool swap = false; for (int i = 0; i < iSteps; i++) { var band = new List <Body>(); //if (i == 4) { // DesignCurve.Create(Window.ActiveWindow.Scene as Part, CurveSegment.Create(points[i][0], points[i][1])); // DesignCurve.Create(Window.ActiveWindow.Scene as Part, CurveSegment.Create(points[i + iSteps / 2][jSteps / 2], points[i + iSteps / 2][jSteps / 2 + 1])); //} for (int j = 0; j < jSteps; j++) { // Main ring Point p00 = points[i][j]; Point p01 = points[i][j + 1]; Point p10 = points[i + 1][j]; Point p11 = points[i + 1][j + 1]; Body b0, b1; if ((p00 - p11).Magnitude < (p10 - p01).Magnitude) { b0 = ShapeHelper.CreatePolygon(new Point[] { p00, p01, p11 }, 0); b1 = ShapeHelper.CreatePolygon(new Point[] { p00, p11, p10 }, 0); } else { b0 = ShapeHelper.CreatePolygon(new Point[] { p01, p10, p00 }, 0); b1 = ShapeHelper.CreatePolygon(new Point[] { p01, p11, p10 }, 0); } // Tabs /* Male Female Male * ---p00last-------p00--------p01-------p10next--- v+ * | | | | * | pn0 | | pn1 | * | | | | * ---p10last-------p10--------p11-------p11next--- * */ Point pn0 = (new Point[] { points[i - 1][j], points[i - 1][j + 1] }).Average(); Point pn1 = (new Point[] { points[i + 2][j], points[i + 2][j + 1] }).Average(); Direction normal0 = Vector.Cross(p01 - pn0, p00 - pn0).Direction; Direction normal1 = Vector.Cross(p10 - pn1, p11 - pn1).Direction; Body tab0 = Tabs.CreateCircularTab(p01, p00, -normal0, tabAngles[i][j], swap); Body tab1 = Tabs.CreateCircularTab(p10, p11, -normal1, tabAngles[i + 1][j], !swap); DesignBody annotateMe = DesignBody.Create(mainPart, "annotatme", (swap ? tab0 : tab1).Copy()); NoteHelper.AnnotateFace(mainPart, annotateMe.Faces.First(), string.Format("{0},{1}", i, j), 0.02, null); annotateMe.Delete(); //DesignBody.Create(Window.ActiveWindow.Scene as Part, "test", b0.Copy()); //DesignBody.Create(Window.ActiveWindow.Scene as Part, "test", b1.Copy()); //DesignBody.Create(Window.ActiveWindow.Scene as Part, "test", tab0.Copy()); //DesignBody.Create(Window.ActiveWindow.Scene as Part, "test", tab1.Copy()); try { b0.Unite(new Body[] { b1, tab0, tab1 }); } catch { DesignBody.Create(Window.ActiveWindow.Scene as Part, "test", b0.Copy()); DesignBody.Create(Window.ActiveWindow.Scene as Part, "test", b1.Copy()); DesignBody.Create(Window.ActiveWindow.Scene as Part, "test", tab0.Copy()); DesignBody.Create(Window.ActiveWindow.Scene as Part, "test", tab1.Copy()); return(null); } // Debug.Assert(b0.Shells.Count == 1); band.Add(b0); swap = !swap; } bands.Add(band.TryUnionBodies()); // Cutters Point p0ThisSide0 = points[i][0]; Point p0ThisSide1 = points[i][1]; Point p0OtherSide0 = points[i + iSteps / 2][jSteps / 2]; Point p0OtherSide1 = points[i + iSteps / 2][1 + jSteps / 2]; Point p1ThisSide0 = points[i + 1][0]; Point p1ThisSide1 = points[i + 1][1]; Point p1OtherSide0 = points[i + 1 + iSteps / 2][jSteps / 2]; Point p1OtherSide1 = points[i + 1 + iSteps / 2][1 + jSteps / 2]; Point p0 = CurveSegment.Create(p0ThisSide0, p0ThisSide1).GetInBetweenPoint( CurveSegment.Create(p0OtherSide0, p0OtherSide1 )); Point p1 = CurveSegment.Create(p1ThisSide0, p1ThisSide1).GetInBetweenPoint( CurveSegment.Create(p1OtherSide0, p1OtherSide1 )); //Point p0 = CurveSegment.Create(p0ThisSide0, p0ThisSide1).IntersectCurve( // CurveSegment.Create(p0OtherSide0, p0OtherSide1 //)).First().Point; //Point p1 = CurveSegment.Create(p1ThisSide0, p1ThisSide1).IntersectCurve( // CurveSegment.Create(p1OtherSide0, p1OtherSide1 //)).First().Point; Direction n0 = (p0OtherSide1 - p0OtherSide0).Direction; Direction n1 = (p1OtherSide1 - p1OtherSide0).Direction; Direction d0 = (p0ThisSide1 - p0ThisSide0).Direction; Direction d1 = (p1ThisSide1 - p1ThisSide0).Direction; var profiles = new List <ICollection <ITrimmedCurve> >(); profiles.Add(p0.GetRectanglePointsAround(d0 * cutterHeight, n0 * cutterWidth).GetProfile()); profiles.Add(p1.GetRectanglePointsAround(d1 * cutterHeight, n1 * cutterWidth).GetProfile()); Body cutterA = Body.LoftProfiles(profiles, false, true); profiles = new List <ICollection <ITrimmedCurve> >(); profiles.Add(p0.GetRectanglePointsAround(n0 * cutterHeight, d0 * cutterWidth).GetProfile()); profiles.Add(p1.GetRectanglePointsAround(n1 * cutterHeight, d1 * cutterWidth).GetProfile()); Body cutterB = Body.LoftProfiles(profiles, false, true); cutters.Add(new Body[] { cutterA, cutterB }); } var designBands = new List <DesignBody>(); Layer cutterLayer = NoteHelper.CreateOrGetLayer(mainPart.Document, "Cutters", System.Drawing.Color.DarkViolet); Matrix scaleMatrix = Matrix.CreateScale(scale, Point.Origin); for (int i = 0; i < bands.Count; i++) { int whichCutter = i % 2; Part part = Part.Create(mainPart, string.Format("Band {0:00}", i)); Component.Create(mainPart, part); int ii = i; if (whichCutter == 0) { ii = i + iSteps / 2; } List <Body> mergedCutters = new Body[] { cutters[(ii + iSteps - 1) % iSteps][whichCutter].Copy(), cutters[ii % iSteps][whichCutter].Copy(), cutters[(ii + 1) % iSteps][whichCutter].Copy() }.TryUnionBodies().ToList(); Debug.Assert(mergedCutters.Count == 1, "Couldn't merge cutters"); double nominalRadius = 0.02; double innerRadius = (nominalRadius - cutterWidth / 2) / newScale; double outerRadius = (nominalRadius + cutterWidth / 2) / newScale; var edgeRounds = new List <KeyValuePair <Edge, EdgeRound> >(); foreach (Edge edge in mergedCutters[0].Edges) { if (edge.Length > cutterHeight * 1.1 || edge.Length < cutterHeight * 0.9) { continue; } double angle = edge.GetAngle(); if (Math.Abs(angle) > Math.PI / 4 || angle == 0) { continue; } edgeRounds.Add(new KeyValuePair <Edge, EdgeRound>(edge, new FixedRadiusRound(angle > 0 ? outerRadius : innerRadius))); } mergedCutters[0].RoundEdges(edgeRounds); mergedCutters.Add(cutters[(ii - 1 + iSteps / 2) % iSteps][1 - whichCutter].Copy()); mergedCutters.Add(cutters[(ii + 1 + iSteps / 2) % iSteps][1 - whichCutter].Copy()); HSBColor hsbColor = new HSBColor(0, 100, 200); hsbColor.H = (float)((double)i / bands.Count * 360); var cutBand = new List <Body>(); foreach (Body body in bands[i]) { foreach (Body cutterBody in mergedCutters) { body.Imprint(cutterBody); foreach (Face face in body.Faces) { if (!IsSpanningBody(face, cutterBody)) { continue; } body.DeleteFaces(new Face[] { face }, RepairAction.None); // DesignBody designBody = DesignBody.Create(part, "Cutter", cutterBody.Copy()); // designBody.SetColor(null, hsbColor.Color); } } cutBand.AddRange(body.SeparatePieces()); } cutBand = cutBand.TryUnionBodies().ToList(); //foreach (Body body in bands[i]) { foreach (Body body in cutBand) { body.Transform(scaleMatrix); DesignBody designBody = DesignBody.Create(part, "Band", body); designBody.SetColor(null, hsbColor.Color); designBands.Add(designBody); } //foreach (Body body in mergedCutters) { // DesignBody designBody = DesignBody.Create(part, "Cutter", body); // designBody.Layer = cutterLayer; // hsbColor.H += 180 * whichCutter; // designBody.SetColor(null, hsbColor.Color); //// designBands[i].Shape.Imprint(designBody.Shape); //} } Trace.WriteLine("vParameters"); for (int j = 0; j < jSteps; j++) { for (int i = 0; i < iSteps; i++) { Trace.Write(vParameters[i][j] + " "); } Trace.WriteLine(""); } Trace.WriteLine("tabAngles"); for (int j = 0; j < jSteps; j++) { for (int i = 0; i < iSteps; i++) { Trace.Write(tabAngles[i][j] + " "); } Trace.WriteLine(""); } return(designBands); }