public List <Brep> Compute() { globalBaseCrvLi = new List <Curve>(); // global parameter globalTowerCrvLi = new List <Curve>(); // global parameter globalPtCrvLi = new List <Point3d>(); double[] p = c2.DivideByCount(numDiv, true); List <Point3d> ptLi = new List <Point3d>(); // points on the site boundary for (int i = 0; i < p.Length; i++) { Point3d pts = c2.PointAt(p[i]); ptLi.Add(pts); globalPtCrvLi.Add(pts); } // GENERATE NORMALS FROM THE POINT - SCALE=SETBACK DISTANCE List <LineCurve> lineLi = new List <LineCurve>(); for (int i = 0; i < ptLi.Count; i++) { Point3d P = Point3d.Unset; Point3d Q = Point3d.Unset; if (i == 0) { P = ptLi[ptLi.Count - 1]; Q = ptLi[0]; } else { P = ptLi[i - 1]; Q = ptLi[i]; } double sc = 1 / P.DistanceTo(Q); double sc2 = OFFSET_INP; double dx = P.X - (Q.Y - P.Y) * sc; double dy = P.Y + (Q.X - P.X) * sc; Point3d u = new Point3d(dx, dy, 0); double dx2 = P.X - (Q.Y - P.Y) * sc * sc2; double dy2 = P.Y + (Q.X - P.X) * sc * sc2; double ex2 = P.X + (Q.Y - P.Y) * sc * sc2; double ey2 = P.Y - (Q.X - P.X) * sc * sc2; Point3d u2 = new Point3d(dx2, dy2, 0); Point3d v2 = new Point3d(ex2, ey2, 0); Rhino.Geometry.PointContainment contU = c2.Contains(u, Plane.WorldXY, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance); if (contU.ToString() == "Inside") { LineCurve linePu = new LineCurve(P, u2); lineLi.Add(linePu); } else { LineCurve linePu = new LineCurve(P, v2); lineLi.Add(linePu); } } // FIND INTX - NORMAL x SETBACK CURVE; REMOVE OTHER NORMALS List <LineCurve> fLineLi = new List <LineCurve>(); for (int i = 0; i < lineLi.Count; i++) { double t = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; var evt = Rhino.Geometry.Intersect.Intersection.CurveCurve(OFFSET_CRV, lineLi[i], t, t); try { Point3d A = lineLi[i].PointAtStart; Point3d pA = evt[0].PointA; LineCurve line = new LineCurve(A, pA); fLineLi.Add(line); } catch (Exception) { } } // JOIN ADJACENT NORMAL SEGMENTS TO FORM POLYGONS // 1st point is point on site, 2nd = normal @ setback dist List <PolylineCurve> polyCrvLi = new List <PolylineCurve>(); for (int i = 0; i < lineLi.Count; i++) { if (i == 0) { LineCurve A = lineLi[lineLi.Count - 1]; LineCurve B = lineLi[0]; Point3d a0 = A.PointAtStart; Point3d a1 = A.PointAtEnd; Point3d b0 = B.PointAtStart; Point3d b1 = B.PointAtEnd; Point3d[] pts = { a0, b0, b1, a1, a0 }; PolylineCurve poly = new PolylineCurve(pts); double ar2 = AreaMassProperties.Compute(poly).Area; if (ar2 > minTowerAr) { polyCrvLi.Add(poly); } //polyCrvLi.Add(poly); } else { LineCurve A = lineLi[i - 1]; LineCurve B = lineLi[i]; Point3d a0 = A.PointAtStart; Point3d a1 = A.PointAtEnd; Point3d b0 = B.PointAtStart; Point3d b1 = B.PointAtEnd; Point3d[] pts = { a0, b0, b1, a1, a0 }; PolylineCurve poly = new PolylineCurve(pts); double ar2 = AreaMassProperties.Compute(poly).Area; if (ar2 > minTowerAr) { polyCrvLi.Add(poly); } //polyCrvLi.Add(poly); } } double baseExtrHt = 0.0; double spineHt = 0.0; List <Brep> fbrepLi = new List <Brep>(); try { // BASE PROCESSES= EXTRUSION & COPY double c2Area = AreaMassProperties.Compute(c2).Area; double offsetArea = AreaMassProperties.Compute(OFFSET_CRV).Area; double flrAr = c2Area - offsetArea; int numFlrs2 = (int)(SITE_AR * baseFsr / flrAr) + 1; baseExtrHt = numFlrs2 * flrHt; for (int i = 0; i < numFlrs2; i++) { Curve c2_copy = c2.DuplicateCurve(); Rhino.Geometry.Transform xform = Rhino.Geometry.Transform.Translation(0, 0, spineHt); c2_copy.Transform(xform); Curve OFFSET_CRV_copy = OFFSET_CRV.DuplicateCurve(); OFFSET_CRV_copy.Transform(xform); spineHt += flrHt; globalBaseCrvLi.Add(c2_copy); globalBaseCrvLi.Add(OFFSET_CRV_copy); } // base extrusions Extrusion outerExtr = Rhino.Geometry.Extrusion.Create(c2, baseExtrHt, true); var t0 = outerExtr.GetBoundingBox(true); if (t0.Max.Z <= 0) { outerExtr = Rhino.Geometry.Extrusion.Create(c2, baseExtrHt, true); } Brep outerBrep = outerExtr.ToBrep(); Extrusion innerExtr = Rhino.Geometry.Extrusion.Create(OFFSET_CRV, -baseExtrHt, true); var t1 = innerExtr.GetBoundingBox(true); if (t1.Max.Z <= 0) { innerExtr = Rhino.Geometry.Extrusion.Create(OFFSET_CRV, baseExtrHt, true); } Brep innerBrep = innerExtr.ToBrep(); Brep[] netBrepArr = Brep.CreateBooleanDifference(outerBrep, innerBrep, 0.01); Brep netBrep = netBrepArr[0]; fbrepLi.Add(netBrep); } catch (Exception) { } // Tower POLY FOR THE TOWERS List <Curve> towerPolyLi = new List <Curve>(); List <PolylineCurve> fPolyLi = new List <PolylineCurve>(); int numSel = numTowers; double cumuArPoly = 0.0; for (int i = 0; i < numSel; i++) { int idx = rnd.Next(polyCrvLi.Count); fPolyLi.Add(polyCrvLi[idx]); cumuArPoly += AreaMassProperties.Compute(polyCrvLi[idx]).Area; } // Tower POLY EXTRUSION double towerHtReq = SITE_AR * towerFsr / cumuArPoly; for (int i = 0; i < fPolyLi.Count; i++) { PolylineCurve crv = fPolyLi[i]; Extrusion extr0 = Extrusion.Create(crv, -towerHtReq * flrHt, true); var t0 = extr0.GetBoundingBox(true); if (t0.Max.Z <= 0) { extr0 = Extrusion.Create(crv, towerHtReq * flrHt, true); } Brep brep = extr0.ToBrep(); Transform xform = Rhino.Geometry.Transform.Translation(0, 0, baseExtrHt); brep.Transform(xform); fbrepLi.Add(brep); } // Tower POLY FLOOR COPIES // spineHt initialized above & updated from base curve copies int numFlrs = (int)(SITE_AR * towerFsr / cumuArPoly) + 1; for (int i = 0; i < numFlrs; i++) { for (int j = 0; j < fPolyLi.Count; j++) { Curve crv = fPolyLi[j].DuplicateCurve(); Rhino.Geometry.Transform xform = Rhino.Geometry.Transform.Translation(0, 0, spineHt); crv.Transform(xform); globalTowerCrvLi.Add(crv); } spineHt += flrHt; } return(fbrepLi); }
protected override void SolveInstance(IGH_DataAccess DA) { Curve site_ = null; double setback = double.NaN; double OFFSET_INP = double.NaN; double baseFsr = double.NaN; double towerFsr = double.NaN; int numDiv = 10; int numTowers = 7; double flrHt = double.NaN; double minSiteAr = double.NaN; double minTowerAr = double.NaN; if (!DA.GetData(0, ref site_)) { return; } if (!DA.GetData(1, ref setback)) { return; } if (!DA.GetData(2, ref OFFSET_INP)) { return; } if (!DA.GetData(3, ref numDiv)) { return; } if (!DA.GetData(4, ref numTowers)) { return; } if (!DA.GetData(5, ref flrHt)) { return; } if (!DA.GetData(6, ref baseFsr)) { return; } if (!DA.GetData(7, ref towerFsr)) { return; } if (!DA.GetData(8, ref minSiteAr)) { return; } if (!DA.GetData(9, ref minTowerAr)) { return; } Curve site = Rhino.Geometry.Curve.ProjectToPlane(site_, Plane.WorldXY); //CHECKS FOR THE SITE-SETBACK AND MIN SITE AREA1 double siteAr = AreaMassProperties.Compute(site).Area; SITE_AR = AreaMassProperties.Compute(site).Area; Point3d site_cen = AreaMassProperties.Compute(site).Centroid; if (siteAr < minSiteAr) { return; // area restraint } Curve[] site_setback_crv = site.Offset(site_cen, Vector3d.ZAxis, setback, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, CurveOffsetCornerStyle.Sharp); if (site_setback_crv.Length != 1) { return; // rational offset restraint } //OFFSET FROM THE SITE BOUNDARY Curve c2 = site_setback_crv[0].DuplicateCurve(); // duplicate of setback curve : outer boundary of building Curve[] c2Offs; Point3d cen = AreaMassProperties.Compute(c2).Centroid; Rhino.Geometry.PointContainment cont = site.Contains(cen, Plane.WorldXY, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance); if (cont.ToString() == "Inside") { c2Offs = c2.Offset(cen, Vector3d.ZAxis, OFFSET_INP, 0.01, CurveOffsetCornerStyle.Sharp); } else { c2Offs = c2.Offset(cen, Vector3d.ZAxis, -OFFSET_INP, 0.01, CurveOffsetCornerStyle.Sharp); } DA.SetData(4, cont); // ---------------------------------------------- Curve OFFSET_CRV = c2Offs[0]; //inner boundary of building if (c2Offs.Length != 1) { return; } DA.SetData(0, OFFSET_CRV); Polyline outer_crv; Polyline inner_crv; bool t0 = c2.TryGetPolyline(out outer_crv); bool t1 = OFFSET_CRV.TryGetPolyline(out inner_crv); List <Brep> fbrepLi = new List <Brep>(); if (t0 == true && SITE_AR > minSiteAr) { debugMsg += "in poly solver"; List <Point3d> outerPtLi = new List <Point3d>(); IEnumerator <Point3d> outerPts = outer_crv.GetEnumerator(); while (outerPts.MoveNext()) { outerPtLi.Add(outerPts.Current); } List <Point3d> innerPtLi = new List <Point3d>(); IEnumerator <Point3d> innerPts = inner_crv.GetEnumerator(); while (innerPts.MoveNext()) { innerPtLi.Add(innerPts.Current); } PolylineCurve outerPoly = new PolylineCurve(outerPtLi); double t = (double)(1.00 / numDiv); if (t < 1.0 && t > 0.005) { int numDivisionPts = (int)numDiv; fbrepLi = SolveForPolyLineCrv(outerPtLi, innerPtLi, numDivisionPts, numTowers, flrHt, OFFSET_INP, baseFsr, towerFsr, minTowerAr); } } else { if (SITE_AR > minSiteAr) { fbrepLi = SolveForSmoothCrv(c2, OFFSET_CRV, numDiv, numTowers, flrHt, OFFSET_INP, baseFsr, towerFsr, minTowerAr); } } DA.SetDataList(4, debugMsg); // ---------------------------------------------- DA.SetDataList(5, fbrepLi); // ---------------------------------------------- DA.SetDataList(1, globalBaseCrvLi); DA.SetDataList(2, globalTowerCrvLi); }
protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> sites = new List <Curve>(); double fsr = double.NaN; double setback = double.NaN; double flrHt = double.NaN; double minAr = double.NaN; double slendernessRatio = double.NaN; if (!DA.GetDataList(0, sites)) { return; } if (!DA.GetData(1, ref setback)) { return; } if (!DA.GetData(2, ref fsr)) { return; } if (!DA.GetData(3, ref flrHt)) { return; } if (!DA.GetData(4, ref minAr)) { return; } if (!DA.GetData(5, ref slendernessRatio)) { return; } List <Extrusion> massLi = new List <Extrusion>(); List <List <Curve> > listFlrCrvLi = new List <List <Curve> >(); List <Curve> flrCrvLi = new List <Curve>(); string msg = ""; msg += "\nfsr: " + fsr.ToString(); msg += "\nsetback: " + setback.ToString(); string MSG = "Debug BLOCK:\n"; for (int i = 0; i < sites.Count; i++) { //OFFSET FROM THE SITE BOUNDARY Curve c1 = sites[i].DuplicateCurve(); Curve c2 = Rhino.Geometry.Curve.ProjectToPlane(c1, Plane.WorldXY); Curve[] c2Offs; Point3d cen = AreaMassProperties.Compute(c2).Centroid; Rhino.Geometry.PointContainment cont = sites[i].Contains(cen, Plane.WorldXY, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance); if (cont.ToString() == "Inside") { c2Offs = c2.Offset(cen, Vector3d.ZAxis, setback, 0.01, CurveOffsetCornerStyle.Sharp); } else { c2Offs = c2.Offset(cen, Vector3d.ZAxis, -setback, 0.01, CurveOffsetCornerStyle.Sharp); } try { if (c2Offs.Length == 1) { Curve OFFSET_CRV_ = c2Offs[0]; Curve OFFSET_CRV = Curve.ProjectToPlane(OFFSET_CRV_, Plane.WorldXY); double arSite = Rhino.Geometry.AreaMassProperties.Compute(sites[i]).Area; double arOffset = AreaMassProperties.Compute(OFFSET_CRV).Area; // 1 floor double num_flrs = fsr * arSite / arOffset; double ht = num_flrs * flrHt; double gotSlendernessRatio = ht / arOffset; if (gotSlendernessRatio < slendernessRatio) { msg += "\nExceeded slenderness ratio"; } else if (arOffset <= minAr) { msg += "\nar site: " + arSite.ToString() + "\nar offset: " + arOffset.ToString() + "\nht: " + ht.ToString(); } else { Vector3d vec = new Vector3d(0, 0, ht); Curve c3 = Rhino.Geometry.Curve.ProjectToPlane(OFFSET_CRV, Plane.WorldXY); Extrusion mass = Rhino.Geometry.Extrusion.Create(c3, ht, true); var B = mass.GetBoundingBox(true); MSG += "Z = " + B.Max.Z.ToString() + ", " + B.Min.Z.ToString(); if (B.Max.Z <= 0.01) { mass = Extrusion.Create(c3, -ht, true); } massLi.Add(mass); for (int j = 0; j < num_flrs; j++) { Rhino.Geometry.Transform xform = Rhino.Geometry.Transform.Translation(0, 0, j * flrHt); Curve c4 = c3.DuplicateCurve(); c4.Transform(xform); flrCrvLi.Add(c4); } } } } catch (Exception) { } //listFlrCrvLi.Add(flrCrvLi); } DA.SetDataList(0, massLi); DA.SetDataList(1, flrCrvLi); // DA.SetData(2, msg); // DA.SetData(3, MSG); }