/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Brep[] a_Blend = new Brep[] { }; Brep[] o_Wall = new Brep[] { }; Brep BrepItem = null; double o_Distance = 4; List <Brep> OutputLs = new List <Brep>(); if (!DA.GetData(0, ref BrepItem)) { return; } if (!DA.GetData(1, ref o_Distance)) { return; } if (o_Distance < 0) { o_Distance = Math.Abs(o_Distance); this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "面偏移的距离不能为负数"); o_Distance = 0; } OutputLs = Brep.CreateOffsetBrep(BrepItem, o_Distance, true, false, 0.001, out a_Blend, out o_Wall).ToList(); DA.SetDataList(0, OutputLs); }
public override bool Construct(bool append = false) { if (!append) { foreach (var part in Parts) { part.Geometry.Clear(); } } debug = new List <object>(); if (InnerSurface == null || OuterSurface == null) { throw new Exception("Surfaces not defined!"); } // Sort elements around the joint normal var dirs = SortPartsClockwise(); var beams = new Beam[4]; for (int i = 0; i < 4; ++i) { beams[i] = (Parts[i].Element as BeamElement).Beam; } // Get beam planes for each beam var planes = new Plane[4]; for (int i = 0; i < 4; ++i) { planes[i] = beams[i].GetPlane(this.Plane.Origin); } // Construct proper planes for each element for (int i = 0; i < 4; ++i) { int signX = 1, signY = 1, signZ = 1; if (planes[i].ZAxis * dirs[i] < 0) { signZ = -1; } if (planes[i].YAxis * Normal < 0) { signY = -1; } planes[i] = new Plane(planes[i].Origin, planes[i].XAxis * signX * signZ, planes[i].YAxis * signY); } debug.Add(Plane); //debug.Add(planes[1]); //debug.Add(planes[2]); //debug.Add(beams[0].Centreline); //debug.Add(beams[1].Centreline); //debug.Add(beams[2].Centreline); //debug.Add(beams[3].Centreline); // Array of lines that describe the seams between // neighbouring beams. // From = point on inner surface // To = point on outer surface // The first line is to the right of the beam // I.e. the 2 seams for beam[0] are seams[0] and seams[3] var seams = new Line[4]; for (int i = 0; i < 4; ++i) { int ii = (i + 1).Modulus(4); // Create side planes for each seam var p0 = new Plane(planes[i].Origin - planes[i].XAxis * beams[i].Width * 0.5, planes[i].ZAxis, planes[i].YAxis); var p1 = new Plane(planes[ii].Origin + planes[ii].XAxis * beams[ii].Width * 0.5, planes[ii].ZAxis, planes[ii].YAxis); // Find intersection of planes = find seam Line xline; Rhino.Geometry.Intersect.Intersection.PlanePlane(p0, p1, out xline); xline.Transform(Transform.Scale((xline.From + xline.To) * 0.5, 500)); var xlineCrv = xline.ToNurbsCurve(); // Find intersection between surfaces and seam Point3d[] xpts; Curve[] overlapCurves; Rhino.Geometry.Intersect.Intersection.CurveBrep(xlineCrv, InnerSurface, 0.01, out overlapCurves, out xpts); var innerPt = xpts[0]; Rhino.Geometry.Intersect.Intersection.CurveBrep(xlineCrv, OuterSurface, 0.01, out overlapCurves, out xpts); var outerPt = xpts[0]; seams[i] = new Line(innerPt, outerPt); debug.Add(seams[i]); } // Vectors that describe the direction between opposing seams var innerCrosses = new Vector3d[4]; var outerCrosses = new Vector3d[4]; for (int i = 0; i < 4; ++i) { int ii = (i + 2).Modulus(4); outerCrosses[i] = seams[ii].To - seams[i].To; innerCrosses[i] = seams[ii].From - seams[i].From; } debug.Add(new Line(seams[0].To, outerCrosses[0])); debug.Add(new Line(seams[1].To, outerCrosses[1])); debug.Add(new Line(seams[0].From, innerCrosses[0])); debug.Add(new Line(seams[1].From, innerCrosses[1])); var cutterInterval = new Interval(-1000, 1000); /* INTERIOR JOINT SURFACES */ // Construct cutters for (int i = 0; i < 4; ++i) { int ii = (i + 3).Modulus(4); Point3d origin; Vector3d xaxis, yaxis; double d = CutterExtension; double lip = CutterLipWidth; // Handle first seam var pts = new Point3d[8]; var cutter0 = new Brep[4]; // Construct outer surface for first seam origin = seams[i].To; xaxis = seams[i].From - seams[i].To; yaxis = outerCrosses[i]; Plane pOuter0 = new Plane(origin, xaxis, yaxis); var projOuter0 = this.Plane.ProjectAlongVector(xaxis); pts[0] = origin + pOuter0.XAxis * d + pOuter0.YAxis * d; pts[1] = origin + pOuter0.XAxis * d - pOuter0.YAxis * CutterToleranceExtension; pts[2] = origin - pOuter0.XAxis * d - pOuter0.YAxis * CutterToleranceExtension; pts[3] = origin - pOuter0.XAxis * d + pOuter0.YAxis * d; pts[0].Transform(projOuter0); pts[0] = pts[0] - pOuter0.XAxis * lip; pts[1].Transform(projOuter0); pts[1] = pts[1] - pOuter0.XAxis * lip; cutter0[0] = Brep.CreateFromCornerPoints(pts[0], pts[1], pts[2], pts[3], 0.01); // Construct inner surface for first seam origin = seams[i].From; xaxis = seams[i].To - seams[i].From; yaxis = innerCrosses[i]; Plane pInner0 = new Plane(origin, xaxis, yaxis); var projInner0 = this.Plane.ProjectAlongVector(xaxis); pts[4] = origin + pInner0.XAxis * d + pInner0.YAxis * d; pts[5] = origin + pInner0.XAxis * d - pInner0.YAxis * CutterToleranceExtension; pts[6] = origin - pInner0.XAxis * d - pInner0.YAxis * CutterToleranceExtension; pts[7] = origin - pInner0.XAxis * d + pInner0.YAxis * d; pts[4].Transform(projInner0); pts[4] = pts[4] - pInner0.XAxis * lip; pts[5].Transform(projInner0); pts[5] = pts[5] - pInner0.XAxis * lip; cutter0[1] = Brep.CreateFromCornerPoints(pts[4], pts[5], pts[6], pts[7], 0.01); cutter0[2] = Brep.CreateFromCornerPoints(pts[0], pts[1], pts[5], 0.01); cutter0[3] = Brep.CreateFromCornerPoints(pts[5], pts[4], pts[0], 0.01); debug.Add(pts[0]); //debug.Add(pts[1]); //debug.Add(pts[4]); //debug.Add(pts[5]); var cutter0Joined = Brep.JoinBreps(cutter0, 0.01); Parts[i].Geometry.AddRange(cutter0Joined); // Handle second seam var cutter1 = new Brep[4]; // Construct outer surface for second seam origin = seams[ii].To; xaxis = seams[ii].From - seams[ii].To; yaxis = outerCrosses[ii]; Plane pOuter1 = new Plane(origin, xaxis, yaxis); var projOuter1 = this.Plane.ProjectAlongVector(xaxis); pts[0] = origin + pOuter1.XAxis * d + pOuter1.YAxis * d; pts[1] = origin + pOuter1.XAxis * d - pOuter1.YAxis * CutterToleranceExtension; pts[2] = origin - pOuter1.XAxis * d - pOuter1.YAxis * CutterToleranceExtension; pts[3] = origin - pOuter1.XAxis * d + pOuter1.YAxis * d; pts[0].Transform(projOuter1); pts[0] = pts[0] - pOuter1.XAxis * lip; pts[1].Transform(projOuter1); pts[1] = pts[1] - pOuter1.XAxis * lip; cutter1[0] = Brep.CreateFromCornerPoints(pts[0], pts[1], pts[2], pts[3], 0.01); // Construct inner surface for second seam origin = seams[ii].From; xaxis = seams[ii].To - seams[ii].From; yaxis = innerCrosses[ii]; Plane pInner1 = new Plane(origin, xaxis, yaxis); var projInner1 = this.Plane.ProjectAlongVector(xaxis); pts[4] = origin + pInner1.XAxis * d + pInner1.YAxis * d; pts[5] = origin + pInner1.XAxis * d - pInner1.YAxis * CutterToleranceExtension; pts[6] = origin - pInner1.XAxis * d - pInner1.YAxis * CutterToleranceExtension; pts[7] = origin - pInner1.XAxis * d + pInner1.YAxis * d; pts[4].Transform(projInner1); pts[4] = pts[4] - pInner1.XAxis * lip; pts[5].Transform(projInner1); pts[5] = pts[5] - pInner1.XAxis * lip; cutter1[1] = Brep.CreateFromCornerPoints(pts[4], pts[5], pts[6], pts[7], 0.01); //cutter1[2] = Brep.CreateFromCornerPoints(pts[0], pts[1], pts[5], pts[4], 0.01); cutter1[2] = Brep.CreateFromCornerPoints(pts[0], pts[1], pts[5], 0.01); cutter1[3] = Brep.CreateFromCornerPoints(pts[5], pts[4], pts[0], 0.01); var cutter1Joined = Brep.JoinBreps(cutter1, 0.01); Parts[i].Geometry.AddRange(cutter1Joined); } /* PLATE AND DOWELS */ // Create interior plate cutter and dowel positions var endPlanes = new Plane[4]; var dowelPlanes = new Plane[4]; var dowelCutters = new Brep[4]; for (int i = 0; i < 4; ++i) { var dir = dirs[i]; dir.Unitize(); endPlanes[i] = new Plane(this.Plane.Origin + dir * PlateLength, dir); var dowelPt = this.Plane.Origin + dir * DowelPosition; var dp = beams[i].GetPlane(dowelPt); debug.Add(endPlanes[i]); dowelCutters[i] = new Cylinder( new Circle(new Plane(dp.Origin - dp.YAxis * DowelLength * 0.5, dp.YAxis), DowelDiameter * 0.5), DowelLength).ToBrep(true, true); dowelPlanes[i] = dp; } var platePlane0 = new Plane(this.Plane.Origin - this.Plane.ZAxis * PlateThickness * 0.5, this.Plane.XAxis, this.Plane.YAxis); var platePlane1 = new Plane(this.Plane.Origin + this.Plane.ZAxis * PlateThickness * 0.5, this.Plane.XAxis, this.Plane.YAxis); var platePts = new Point3d[4]; for (int i = 0; i < 4; ++i) { int ii = (i + 1).Modulus(4); Rhino.Geometry.Intersect.Intersection.PlanePlanePlane( endPlanes[i], endPlanes[ii], platePlane0, out platePts[i]); } // Create plate outline and cutter var plateOutline = new Polyline() { platePts[0], platePts[1], platePts[2], platePts[3], platePts[0] }.ToNurbsCurve(); var plateSrf = Brep.CreateTrimmedPlane(platePlane0, plateOutline); Brep[] outBlends, outWalls; var plateBrep = Brep.CreateOffsetBrep(plateSrf, PlateThickness, true, true, 0.01, out outBlends, out outWalls)[0]; plateBrep.Flip(); for (int i = 0; i < 4; ++i) { Parts[i].Geometry.Add(plateBrep); Parts[i].Geometry.Add(dowelCutters[i]); debug.Add(dowelCutters[i]); } return(true); }
public override bool Construct(bool append = false) { debug = new List <object>(); var cutterInterval = new Interval(-CutterSize, CutterSize); var beams = Parts.Select(x => (x.Element as BeamElement).Beam).ToArray(); var kplane = beams[2].GetPlane(Parts[2].Parameter); debug.Add(kplane); var dirs = new Vector3d[2]; var planes = new Plane[2]; for (int i = 0; i < 2; ++i) { var d0 = beams[i].Centreline.PointAt(beams[i].Centreline.Domain.Mid) - kplane.Origin; //debug.Add(new Line(kplane.Origin, d0)); planes[i] = beams[i].GetPlane(Parts[i].Parameter); //debug.Add(planes[i]); int signX = 1, signY = 1, signZ = 1; if (planes[i].ZAxis * d0 < 0) { signZ = -1; } if (planes[i].YAxis * kplane.YAxis < 0) { signY = -1; } planes[i] = new Plane(planes[i].Origin, planes[i].XAxis * signX * signZ, planes[i].YAxis * signY); dirs[i] = planes[i].ZAxis; debug.Add(planes[i]); } // dsum is actually the plate insertion direction var dsum = dirs[0] + dirs[1]; dsum.Unitize(); var xside = dsum * kplane.XAxis < 0 ? -1 : 1; // Check the order of the V-beams and flip if necessary. // This is important for getting correct Seam and Outside planes, among other things. if (((dirs[0] * kplane.ZAxis) < (dirs[1] * kplane.ZAxis) && xside > 0) || ((dirs[0] * kplane.ZAxis) > (dirs[1] * kplane.ZAxis) && xside < 0)) { var dirTemp = dirs[0]; dirs[0] = dirs[1]; dirs[1] = dirTemp; var planeTemp = planes[0]; planes[0] = planes[1]; planes[1] = planeTemp; var beamTemp = beams[0]; beams[0] = beams[1]; beams[1] = beamTemp; var partTemp = Parts[0]; Parts[0] = Parts[1]; Parts[1] = partTemp; } debug.Add(new Line(kplane.Origin, dsum * 200.0)); //debug.Add(new Line(kplane.Origin, dirs[0] * 200.0)); //debug.Add(new Line(kplane.Origin, dirs[1] * 200.0)); // Find correct plane axis Vector3d xaxis; double dotx = kplane.XAxis * dsum; double doty = kplane.YAxis * dsum; double width; if (Math.Abs(dotx) > Math.Abs(doty)) { width = beams[2].Width; if (dotx < 0) { xaxis = -kplane.XAxis; } else { xaxis = kplane.XAxis; } } else { width = beams[2].Height; if (doty < 0) { xaxis = -kplane.YAxis; } else { xaxis = kplane.YAxis; } } var yaxis = kplane.YAxis; this.Plane = new Plane(kplane.Origin, xaxis, kplane.ZAxis); // plane0 is the plane on top of the sill beam, where the two V-beams meet var plane0 = new Plane(kplane.Origin + xaxis * width * 0.5, kplane.ZAxis, kplane.YAxis); // planeOffset0 is the safety plane for making cutters with a slight overlap var planeOffset0 = new Plane(plane0.Origin - plane0.ZAxis * 3.0, plane0.XAxis, plane0.YAxis); //debug.Add(plane0); // dowelPlane is the plane on which all the dowel points lie var dowelPlane = new Plane(plane0.Origin + xaxis * DowelPosition, plane0.XAxis, plane0.YAxis); //debug.Add(dowelPlane); // Create sill cutters for (int i = 0; i < 2; ++i) { Point3d xpt; var res = Rhino.Geometry.Intersect.Intersection.CurvePlane(beams[i].Centreline, plane0, 0.01); if (res != null && res.Count > 0) { xpt = res[0].PointA; } else { xpt = plane0.ClosestPoint(planes[i].Origin); } var cutterPlane = new Plane(xpt, plane0.XAxis, plane0.YAxis); var cutterRec = new Rectangle3d(cutterPlane, cutterInterval, cutterInterval); var cutterBrep = Brep.CreatePlanarBreps(new Curve[] { cutterRec.ToNurbsCurve() }, 0.01)[0]; Parts[i].Geometry.Add(cutterBrep); } // END sill cutters // Find the seam between the V-beams // Find all seam and outside planes, including offsets double PlaneOffset = 5.0; var seamPlanes = new Plane[2]; var seamOffsetPlanes = new Plane[2]; var endPlanes = new Plane[2]; var endPts = new Point3d[2]; endPts[0] = planes[0].Origin; endPts[0].Transform(dowelPlane.ProjectAlongVector(planes[0].ZAxis)); endPts[0] = endPts[0] + planes[0].ZAxis * 30.0; endPts[1] = planes[1].Origin; endPts[1].Transform(dowelPlane.ProjectAlongVector(planes[1].ZAxis)); endPts[1] = endPts[1] + planes[1].ZAxis * 30.0; endPlanes[0] = new Plane(endPts[0], planes[0].XAxis, planes[0].YAxis); endPlanes[1] = new Plane(endPts[1], planes[1].XAxis, planes[1].YAxis); //debug.Add(endPlanes[0]); //debug.Add(endPlanes[1]); seamPlanes[0] = new Plane(planes[0].Origin + planes[0].XAxis * beams[0].Width * 0.5, planes[0].ZAxis, planes[0].YAxis); seamPlanes[1] = new Plane(planes[1].Origin - planes[1].XAxis * beams[1].Width * 0.5, planes[1].ZAxis, planes[1].YAxis); var outPlanes = new Plane[2]; var outOffsetPlanes = new Plane[2]; outPlanes[0] = new Plane(planes[0].Origin - planes[0].XAxis * beams[0].Width * 0.5, planes[0].ZAxis, planes[0].YAxis); outPlanes[1] = new Plane(planes[1].Origin + planes[1].XAxis * beams[1].Width * 0.5, planes[1].ZAxis, planes[1].YAxis); int sign = -1; for (int i = 0; i < 2; ++i) { sign += i * 2; seamOffsetPlanes[i] = new Plane(seamPlanes[i].Origin + seamPlanes[i].ZAxis * sign * PlaneOffset, seamPlanes[i].XAxis, seamPlanes[i].YAxis); outOffsetPlanes[i] = new Plane(outPlanes[i].Origin - outPlanes[i].ZAxis * sign * PlaneOffset, outPlanes[i].XAxis, outPlanes[i].YAxis); //debug.Add(seamPlanes[i]); //debug.Add(outPlanes[i]); //debug.Add(seamOffsetPlanes[i]); //debug.Add(outOffsetPlanes[i]); } Plane seamPlane; Rectangle3d seamRec; Brep seamBrep; // Pick method of intersecting the 2 arms beams switch (Mode) { case (-1): // beam0 into the side of beam1 seamRec = new Rectangle3d(seamPlanes[1], cutterInterval, cutterInterval); seamBrep = Brep.CreatePlanarBreps(new Curve[] { seamRec.ToNurbsCurve() }, 0.01)[0]; Parts[0].Geometry.Add(seamBrep); break; case (1): // beam1 into the side of beam0 seamRec = new Rectangle3d(seamPlanes[0], cutterInterval, cutterInterval); seamBrep = Brep.CreatePlanarBreps(new Curve[] { seamRec.ToNurbsCurve() }, 0.01)[0]; Parts[1].Geometry.Add(seamBrep); break; default: // centre split Line seam; Rhino.Geometry.Intersect.Intersection.PlanePlane(seamPlanes[0], seamPlanes[1], out seam); seamPlane = new Plane(seam.From, seam.Direction, dsum); seamRec = new Rectangle3d(seamPlane, cutterInterval, cutterInterval); seamBrep = Brep.CreatePlanarBreps(new Curve[] { seamRec.ToNurbsCurve() }, 0.01)[0]; Parts[0].Geometry.Add(seamBrep); Parts[1].Geometry.Add(seamBrep); break; } // END seam // Find plate plane and figure out geometry var platePlane = new Plane(kplane.Origin, dsum, dirs[0]); platePlane.Origin = platePlane.Origin - platePlane.ZAxis * PlateThickness * 0.5; var sillproj = plane0.ProjectAlongVector(dsum); var pts = new Point3d[9]; var proj0 = platePlane.ProjectAlongVector(planes[0].YAxis); var proj1 = platePlane.ProjectAlongVector(planes[1].YAxis); // Get first arm of plate Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(endPlanes[0], outOffsetPlanes[0], platePlane, out pts[0]); Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(endPlanes[0], seamOffsetPlanes[0], platePlane, out pts[1]); if (SingleInsertionDirection) { pts[1] = pts[0]; pts[1].Transform(seamOffsetPlanes[0].ProjectAlongVector(dsum)); } // Get point on seam Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(seamOffsetPlanes[0], seamOffsetPlanes[1], platePlane, out pts[2]); // Get second arm of plate Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(endPlanes[1], outOffsetPlanes[1], platePlane, out pts[3]); Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(endPlanes[1], seamOffsetPlanes[1], platePlane, out pts[4]); if (SingleInsertionDirection) { pts[4] = pts[3]; pts[4].Transform(seamOffsetPlanes[1].ProjectAlongVector(dsum)); } // Get intersection of first arm and sill Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(outOffsetPlanes[0], planeOffset0, platePlane, out pts[5]); Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(outOffsetPlanes[1], planeOffset0, platePlane, out pts[6]); for (int i = 0; i < 9; ++i) { debug.Add(pts[i]); } // Create outline for arms var plateOutline0 = new Polyline() { pts[0], pts[1], pts[2], pts[4], pts[3], pts[6], pts[5], pts[0] }; //plateOutline0. debug.Add(plateOutline0); var plateSrf0 = Brep.CreateTrimmedPlane(platePlane, plateOutline0.ToNurbsCurve()); Brep[] outBlends, outWalls; var plateBreps = Brep.CreateOffsetBrep(plateSrf0, PlateThickness, true, true, 0.01, out outBlends, out outWalls); if (plateBreps != null && plateBreps.Length > 0) { if (plateBreps[0].SolidOrientation != BrepSolidOrientation.Outward) { plateBreps[0].Flip(); } for (int i = 0; i < 2; ++i) { Parts[i].Geometry.Add(plateBreps[0]); } } //var plateBrep0 = Brep.CreateOffsetBrep(plateSrf0, PlateThickness, true, true, 0.01, out outBlends, out outWalls)[0]; //plateBrep0.Flip(); //for (int i = 0; i < 2; ++i) //{ // Parts[i].Geometry.Add(plateBrep0); //} // Create outline for sill planeOffset0.Origin = plane0.Origin + plane0.ZAxis * 5.0; Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(outPlanes[0], plane0, platePlane, out pts[0]); Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(outPlanes[1], plane0, platePlane, out pts[1]); pts[2] = pts[1] - dsum * PlateDepth; pts[3] = pts[0] - dsum * PlateDepth; pts[0] = pts[0] + dsum * 10.0; pts[1] = pts[1] + dsum * 10.0; var plateOutline1 = new Polyline() { pts[0], pts[1], pts[2], pts[3], pts[0] }; debug.Add(plateOutline1); var plateSrf1 = Brep.CreateTrimmedPlane(platePlane, plateOutline1.ToNurbsCurve()); plateBreps = Brep.CreateOffsetBrep(plateSrf1, PlateThickness, true, true, 0.01, out outBlends, out outWalls); if (plateBreps != null && plateBreps.Length > 0) { if (plateBreps[0].SolidOrientation != BrepSolidOrientation.Outward) { plateBreps[0].Flip(); } this.Beam.Geometry.Add(plateBreps[0]); } //var plateBrep1 = Brep.CreateOffsetBrep(plateSrf1, PlateThickness, true, true, 0.01, out outBlends, out outWalls)[0]; //plateBrep1.Flip(); //this.Beam.Geometry.Add(plateBrep1); // Create dowels var dowelPoints = new Point3d[3]; var dproj0 = dowelPlane.ProjectAlongVector(planes[0].ZAxis); var dproj1 = dowelPlane.ProjectAlongVector(planes[1].ZAxis); dowelPoints[0] = planes[0].PointAt(0, 0, DowelPosition); dowelPoints[0].Transform(dproj0); dowelPoints[1] = planes[1].PointAt(0, 0, DowelPosition); dowelPoints[1].Transform(dproj1); dowelPoints[2] = kplane.Origin; var dowelPlane2 = new Plane(dowelPoints[2] - kplane.YAxis * DowelLength * 0.5, kplane.YAxis); var dowelCyl2 = new Cylinder( new Circle(dowelPlane2, DowelDiameter * 0.5), DowelLength).ToBrep(true, true); this.Beam.Geometry.Add(dowelCyl2); for (int i = 0; i < 2; ++i) { var dowelPlane01 = new Plane(dowelPoints[i] - planes[i].YAxis * DowelLength * 0.5, planes[i].YAxis); var dowelCyl = new Cylinder( new Circle(dowelPlane01, DowelDiameter * 0.5), DowelLength).ToBrep(true, true); Parts[i].Geometry.Add(dowelCyl); } // END plate return(true); }