/// <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) { int sides = 3; int iter = 3; int length = 5; if (!DA.GetData(0, ref sides)) { return; } if (!DA.GetData(1, ref iter)) { return; } if (!DA.GetData(2, ref length)) { return; } if (sides <= 2) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Number of sides must be greater than 2."); return; } if (iter < 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Number of iterations must be equal to or greater than 0."); return; } if (length <= 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Length of side must be a natural number."); return; } Double l = length; Double s = sides; List <Point3d> VerticesOut = new List <Point3d>(); List <LineCurve> CurvesOut = new List <LineCurve>(); List <Point3d> points = new List <Point3d>(); List <LineCurve> segments = new List <LineCurve>(); // making the initial polygon Point3d p0 = new Point3d(l / (2 * (Math.Cos(Math.PI * (s - 2) / (2 * s)))), 0, 0); points.Add(p0); for (var i = 0; i < s - 1; i++) { Point3d p1 = new Point3d(p0); p1.Transform(Transform.Rotation(2 * (i + 1) * (Math.PI * (s - 2)) / ((s - 2) * s), new Vector3d(0, 0, 1), new Point3d(0, 0, 0))); points.Add(p1); } VerticesOut = points; for (var i = 0; i < s; i++) { if (i != s - 1) { LineCurve pl = new LineCurve(points[i], points[i + 1]); segments.Add(pl); } else { LineCurve pl = new LineCurve(points[i], points[0]); segments.Add(pl); } } for (var i = 0; i < iter; i++) { List <LineCurve> frag = new List <LineCurve>(); for (var j = 0; j < segments.Count; j++) { Point3d[] p; segments[j].DivideByCount(3, true, out p); for (var k = 0; k < 2; k++) { points.Insert(j * 3 + k + 1, p[k + 1]); } for (var m = 0; m < 3; m++) { if (m + 1 + 3 * j == points.Count) { LineCurve pll = new LineCurve(points[m + 3 * j], points[0]); frag.Add(pll); } else { LineCurve pll = new LineCurve(points[m + 3 * j], points[m + 3 * j + 1]); frag.Add(pll); } } } int a = 0; int w = 0; LineCurve copie = new LineCurve(); for (var n = 0; n < frag.Count; n++) { if (n % 3 == 1) { a = a + 1; frag[n].Transform(Transform.Rotation(-Math.PI * ((s - 2) / s), new Vector3d(0, 0, 1), points[n + a + w - 1])); Point3d[] o; frag[n].DivideByCount(1, true, out o); Point3d np = new Point3d(o[1]); points.Insert(n + a + w, np); if (s > 3) { for (var zz = 0; zz < s - 3; zz++) { if (zz == 0) { LineCurve copy = new LineCurve(frag[n]); copie = copy; } Vector3d translation = new Vector3d(points[n + a + w - 1] - points[n + a + w]); copie.Transform(Transform.Translation(translation)); copie.Transform(Transform.Rotation(-Math.PI * ((s - 2) / s), new Vector3d(0, 0, 1), points[n + a + w])); Point3d[] yy; copie.DivideByCount(1, true, out yy); Point3d nps = new Point3d(yy[1]); points.Insert(n + a + w + 1, nps); w = w + 1; } } } } List <LineCurve> finall = new List <LineCurve>(); for (var q = 0; q < points.Count; q++) { if (q == points.Count - 1) { LineCurve plll = new LineCurve(points[q], points[0]); finall.Add(plll); } else { LineCurve plll = new LineCurve(points[q], points[q + 1]); finall.Add(plll); } } segments = finall; } CurvesOut = segments; VerticesOut = points; DA.SetDataList(0, CurvesOut); DA.SetDataList(1, VerticesOut); }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { double tolerance = doc.ModelAbsoluteTolerance; List <Curve> curves = new List <Curve>(); //Select surface GetObject gs = new Rhino.Input.Custom.GetObject(); gs.SetCommandPrompt("Surface to orient on"); gs.GeometryFilter = Rhino.DocObjects.ObjectType.Surface; gs.SubObjectSelect = true; gs.DeselectAllBeforePostSelect = true; gs.OneByOnePostSelect = true; gs.Get(); if (gs.CommandResult() != Result.Success) { return(gs.CommandResult()); } Rhino.DocObjects.ObjRef objref_Surface = gs.Object(0); Rhino.DocObjects.RhinoObject obj = objref_Surface.Object(); if (obj == null) { return(Result.Failure); } surface = objref_Surface.Surface(); if (surface == null) { return(Result.Failure); } obj.Select(false); //Select Line(s) GetObject gl = new GetObject(); gl.SetCommandPrompt("Select one or two line(s)"); gl.GeometryFilter = Rhino.DocObjects.ObjectType.Curve; gl.DeselectAllBeforePostSelect = true; gl.OneByOnePostSelect = true; gl.GetMultiple(1, 0); for (int i = 0; i < gl.ObjectCount; i++) { Rhino.DocObjects.ObjRef objref_Line = gl.Object(i); curve = objref_Line.Curve(); Curve curveRe = curve.Rebuild(60, 3, true); curves.Add(curveRe); } List <Guid> cir_guid_list = new List <Guid>(); if (curves.Count > 1) { Curve curve2 = curves[0]; Curve curve3 = curves[1]; if (curve2.IsClosed || curve3.IsClosed) { Rhino.UI.Dialogs.ShowMessage("Please only select open curves for two line pave.", "Warning!"); return(Result.Failure); } while (true) { cir_guid_list = new List <Guid>(); var tweenCurves = Curve.CreateTweenCurvesWithSampling(curve2, curve3, 1, 30, tolerance); Curve tCurve = tweenCurves[0]; //3 point circle Point3d po1 = curve2.PointAtStart; Point3d po2 = curve3.PointAtStart; LineCurve line1 = new LineCurve(po1, po2); double[] param = line1.DivideByCount(2, false); double param1 = param[0]; double param2 = param[0]; double param3 = param[0]; Curve curve1 = line1; while (true) { Circle outCircle = Circle.TryFitCircleTTT(curve1, curve2, curve3, param1, param2, param3); //circle normal to surface Point3d outCircleCenter = outCircle.Center; double outCircleRadius = outCircle.Radius; double u, v; surface.ClosestPoint(outCircleCenter, out u, out v); var direction = surface.NormalAt(u, v); Point3d surfCenter = surface.PointAt(u, v); Plane pl1 = new Plane(surfCenter, direction); Circle circle = new Circle(pl1, surfCenter, outCircleRadius - offSetStone); Circle circleDist = new Circle(pl1, surfCenter, outCircleRadius + stoneDist); Guid cir_guid = doc.Objects.AddCircle(circle); cir_guid_list.Add(cir_guid); //Cut tween curve at latest circle center Point3d pointOnCurve; Point3d pointOnCircle; Curve circleDistCurve = circleDist.ToNurbsCurve(); tCurve.Domain = new Interval(0, tCurve.GetLength()); Curve[] splitCurves = tCurve.Split(outCircleRadius); if (splitCurves is null) { break; } tCurve = splitCurves[splitCurves.Length - 1]; tCurve.ClosestPoints(circleDistCurve, out pointOnCurve, out pointOnCircle); //Cut tween curve at latest circle border double curveSplitParam; tCurve.Domain = new Interval(0, tCurve.GetLength()); tCurve.ClosestPoint(pointOnCurve, out curveSplitParam); splitCurves = tCurve.Split(curveSplitParam); if (splitCurves is null) { break; } tCurve = splitCurves[splitCurves.Length - 1]; //New parameter at curve1 double circleParam; circleDistCurve.ClosestPoint(pointOnCircle, out circleParam); param1 = circleParam; curve1 = circleDistCurve; //New parameter at curves[0] double paramCurve0New; curve2.ClosestPoint(pointOnCircle, out paramCurve0New); Point3d pointCurve0New = curve2.PointAt(paramCurve0New); double distNewPoints0 = pointOnCircle.DistanceTo(pointCurve0New); param2 = paramCurve0New + distNewPoints0; //New parameter at curves[1] double paramCurve1New; curve3.ClosestPoint(pointOnCircle, out paramCurve1New); Point3d pointCurve1New = curve3.PointAt(paramCurve1New); double distNewPoints1 = pointOnCircle.DistanceTo(pointCurve1New); param3 = paramCurve1New + distNewPoints1; } doc.Views.Redraw(); //Options var go = new GetOption(); go.SetCommandPrompt("Set options."); var stoneOff = new Rhino.Input.Custom.OptionDouble(offSetStone); var distStone = new Rhino.Input.Custom.OptionDouble(stoneDist); var boolOption = new Rhino.Input.Custom.OptionToggle(false, "Off", "On"); go.AddOptionDouble("Offset", ref stoneOff); go.AddOptionDouble("Distance", ref distStone); go.AddOptionToggle("Reverse", ref boolOption); go.AcceptNothing(true); var res = go.Get(); if (res == GetResult.Nothing) { break; } if (res == GetResult.Cancel) { break; } foreach (var gui in cir_guid_list) { var gu = doc.Objects.Find(gui); doc.Objects.Delete(gu); } offSetStone = stoneOff.CurrentValue; stoneDist = distStone.CurrentValue; optionBool = boolOption.CurrentValue; if (optionBool == true) { curve2.Reverse(); curve2 = curve2.Rebuild(60, 3, false); curve3.Reverse(); curve3 = curve3.Rebuild(60, 3, false); optionBool = false; } } } else { while (true) { cir_guid_list = new List <Guid>(); List <Point3d> points = new List <Point3d>(); double length = (diamStone / 2) + offSetStone; double crv_length = curve.GetLength(); Point3d point = curve.PointAtLength(length); points.Add(point); while (true) { length += diamStone + offSetStone; if (length > crv_length) { break; } point = curve.PointAtLength(length); points.Add(point); } foreach (var poi in points) { double u, v; surface.ClosestPoint(poi, out u, out v); var direction = surface.NormalAt(u, v); double x = direction.X; double y = direction.Y; double z = direction.Z; Vector3d vt1 = new Vector3d(x, y, z); Plane pl1 = new Plane(poi, vt1); Circle circle = new Circle(pl1, poi, diamStone / 2); Guid cir_guid = doc.Objects.AddCircle(circle); cir_guid_list.Add(cir_guid); } doc.Views.Redraw(); //Options var go = new GetOption(); go.SetCommandPrompt("Set options."); var stoneDiam = new Rhino.Input.Custom.OptionDouble(diamStone); var stoneOff = new Rhino.Input.Custom.OptionDouble(offSetStone); var boolOption = new Rhino.Input.Custom.OptionToggle(false, "Off", "On"); go.AddOptionDouble("StoneDiam", ref stoneDiam); go.AddOptionDouble("Offset", ref stoneOff); go.AddOptionToggle("Reverse", ref boolOption); go.AcceptNothing(true); var res = go.Get(); if (res == GetResult.Nothing) { break; } if (res == GetResult.Cancel) { break; } foreach (var gui in cir_guid_list) { var gu = doc.Objects.Find(gui); doc.Objects.Delete(gu); } diamStone = stoneDiam.CurrentValue; offSetStone = stoneOff.CurrentValue; optionBool = boolOption.CurrentValue; if (optionBool == true) { curve.Reverse(); } } } doc.Views.Redraw(); doc.Groups.Add(cir_guid_list); return(Result.Success); }
//HATCH FILL REGION - infills a planar region with a hatching pattern public void Filler(List <double> infDens, List <double> infRot) { double tolerance = 0.001; //double overlaptol = 0.0; double crossSecHyp = Math.Sqrt(Math.Pow(crossSec, 2) * 2); curveInfill = new List <Curve> [planarBreps.Count]; //Create List of Infill Curves for each Planar Region for (int u = 0; u < planarBreps.Count; u++) { //Rotate Plane for Filling double rotationRad = infRot[u] * 0.0174532925; Plane plane = Plane.WorldXY; plane.Rotate(rotationRad, Plane.WorldXY.ZAxis); //Create Bounding Box Box bbox = new Box(); planarBreps[u].GetBoundingBox(plane, out bbox); //Get Corners Point3d[] cornerPts = bbox.GetCorners(); //Draw Parallel Lines LineCurve baseLine = new LineCurve(cornerPts[0], cornerPts[1]); LineCurve baseLine2 = new LineCurve(cornerPts[3], cornerPts[2]); //int nPts = (int)Math.Round((baseLine.Line.Length/crossSec),0); Point3d[] basePts = new Point3d[0]; Point3d[] basePts2 = new Point3d[0]; double length = baseLine.Line.Length; double floatdivisions = length / crossSec; double density = infDens[u]; int divisions = (int)Math.Round((floatdivisions * density)); //Divide Lines by Fill Density ratio baseLine.DivideByCount(divisions, true, out basePts); baseLine2.DivideByCount(divisions, true, out basePts2); if (divisions == 0) { curveInfill[u] = new List <Curve>(); return; } Curve[][] intCurve = new Curve[basePts.Length][]; List <Curve> intCurves = new List <Curve>(); for (int i = 0; i < basePts.Length; i++) { LineCurve intLine = new LineCurve(basePts[i], basePts2[i]); Point3d[] intPts = new Point3d[0]; BrepFace r_Infill = planarBreps[u].Faces[0]; Curve[] int_Curve = new Curve[0]; //Intersect Curves with Regions Intersection.CurveBrepFace(intLine, r_Infill, tolerance, out int_Curve, out intPts); intCurve[i] = int_Curve; //Convert resulting Curves into LineCurves for (int j = 0; j < int_Curve.Length; j++) { LineCurve line = new LineCurve(int_Curve[j].PointAtStart, int_Curve[j].PointAtEnd); intCurve[i][j] = line; //intCurves[j].Add(int_Curve[j]); intCurves.Add(line); } } //Rotate Array List <Curve>[] int_Curves = RotatetoListArray(intCurve); List <Curve> joinLines = new List <Curve>(); List <Curve> p_lines = new List <Curve>(); for (int l = 0; l < int_Curves.Length; l++) { for (int k = 1; k < int_Curves[l].Count; k += 2) { int_Curves[l][k].Reverse(); } } //Create a list of points for all connected lines in the infill. Do this for each seperate string of segments for (int l = 0; l < int_Curves.Length; l++) { List <Point3d> plinePts = new List <Point3d>(); if (int_Curves[l].Count > 0) { plinePts.Add(int_Curves[l][0].PointAtStart); for (int k = 1; k < int_Curves[l].Count; k++) { plinePts.Add(int_Curves[l][k - 1].PointAtEnd); plinePts.Add(int_Curves[l][k].PointAtStart); plinePts.Add(int_Curves[l][k].PointAtEnd); } PolylineCurve plCurve = new PolylineCurve(plinePts); Curve curve = plCurve.ToNurbsCurve(); p_lines.Add(curve); } } List <Curve> curve_s = p_lines; curveInfill[u] = p_lines; } }