/// <summary> /// 외곽 사각형 찾기 /// </summary> /// <param name="c"></param> /// <returns></returns> public PolylineCurve OutRect(Curve c) { Point3d Center = CenterPoint(c); center = Center; //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(Center); double MX = 0; double MY = 0; Curve[] components = c.DuplicateSegments(); foreach (Curve d in components) { double CY = d.PointAtStart.Y - Center.Y; double CX = d.PointAtStart.X - Center.X; if (Math.Abs(CY) > MY) { MY = Math.Abs(CY); } if (Math.Abs(CX) > MX) { MX = Math.Abs(CX); } } //Rhino.RhinoApp.WriteLine("MX = " + MX.ToString() + "MY = " + MY.ToString()); if (MX > 1.625f * MY) { //Rhino.RhinoApp.WriteLine("Y확장"); MY = MX / 1.625f; } else if (MX < 1.625f * MY) { MX = MY * 1.625; //Rhino.RhinoApp.WriteLine("X확장"); } //Rhino.RhinoApp.WriteLine("MX = " + MX.ToString() + "MY = " + MY.ToString()); List <Point3d> rectAP = new List <Point3d>(); for (int i = 0; i < 4; i++) { double scale = 1.3; double a = scale; double b = scale; if (i < 2) { a = -scale; } if (i % 3 == 0) { b = -scale; } Point3d tempPoint = new Point3d(Center.X + (a * MX), Center.Y + (b * MY), Center.Z); //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(tempPoint); rectAP.Add(tempPoint); } rectAP.Add(rectAP[0]); PolylineCurve rect = new PolylineCurve(rectAP); //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoints(rectAP); //Rhino.RhinoDoc.ActiveDoc.Objects.AddCurve(rect); return(rect); }
protected override void GroundHogSolveInstance(IGH_DataAccess DA) { // Create holder variables for input parameters var ALL_CONTOURS = new List <Curve>(); // Access and extract data from the input parameters individually if (!DA.GetDataList(0, ALL_CONTOURS)) { return; } // Input Validation int preCullSize = ALL_CONTOURS.Count; ALL_CONTOURS.RemoveAll(item => item == null); if (ALL_CONTOURS.Count == 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "No valid contour curves were provided."); return; } else if (ALL_CONTOURS.Count < preCullSize) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, String.Format("{0} contours were removed because they were null items — perhaps because they are no longer present in the Rhino model.", preCullSize - ALL_CONTOURS.Count)); } // Create holder variables for ouput parameters var fixedContours = new List <Curve>(); var allContours = new List <Curve>(); foreach (var contour in ALL_CONTOURS) { var degree = contour.Degree; if (contour.IsPolyline()) { contour.TryGetPolyline(out Polyline contourPLine); // Convert to Polyline var zValues = GetZValues(new List <Point3d>(contourPLine.ToArray())); if (zValues[0] != zValues[zValues.Count - 1]) { // All are not the same z-index var medianZ = CalculateMean(zValues); var newPoints = new List <Point3d>(); foreach (var point in contourPLine) { var newPoint = point; newPoint.Z = medianZ; newPoints.Add(newPoint); } var fixedPolyline = new PolylineCurve(newPoints); fixedContours.Add(fixedPolyline); allContours.Add(fixedPolyline); } else { allContours.Add(contour); } } else { // TODO: probably shouldn't just assume the curve is nurbs var contourNurbsCurve = contour.ToNurbsCurve(); var pts = new List <Point3d>(); foreach (var ncp in contourNurbsCurve.Points) { pts.Add(ncp.Location); } var zValues = GetZValues(pts); if (zValues[0] != zValues[zValues.Count - 1]) { var medianZ = CalculateMean(zValues); for (var index = 0; index < contourNurbsCurve.Points.Count; index++) { var tempPt = contourNurbsCurve.Points[index].Location; var tempWeight = contourNurbsCurve.Points[index].Weight; tempPt.Z = medianZ; contourNurbsCurve.Points[index] = new ControlPoint(tempPt, tempWeight); } fixedContours.Add(contourNurbsCurve); allContours.Add(contourNurbsCurve); } else { allContours.Add(contour); } } } // Assign variables to output parameters DA.SetDataList(0, allContours); DA.SetDataList(1, fixedContours); }
/// <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) { var curveA = new List <Curve>(); Curve curveB = new PolylineCurve(); var Int_plane = new Plane(); double tol = 0.001; var res = new List <GH_Curve>(); var Ares = new List <GH_Number>(); var comment = new List <string>(); if (!DA.GetDataList(0, curveA)) { return; } if (!DA.GetData(1, ref curveB)) { return; } if (!DA.GetData(2, ref Int_plane)) { return; } // check if curveB is null if (curveB == null) { res.Add(null); Ares.Add(new GH_Number(0.00)); comment.Add("Null curveB"); } for (int i = 0; i < curveA.Count; i++) { if (curveA[i] == null) { res.Add(null); Ares.Add(new GH_Number(0.00)); comment.Add("Null curveA"); } else { RegionContainment status = Curve.PlanarClosedCurveRelationship(curveA[i], curveB, Int_plane, tol); switch (status) { case RegionContainment.Disjoint: res.Add(null); Ares.Add(new GH_Number(0.0)); comment.Add("Disjoint"); break; case RegionContainment.MutualIntersection: var current_intersection = Curve.CreateBooleanIntersection(curveA[i], curveB); // test needed to determine if there is one or more distinct resulting curves if (current_intersection.Length == 0) { res.Add(null); Ares.Add(new GH_Number(0.0)); comment.Add("MutualIntersection, line intersection"); } else if (current_intersection.Length == 1) { res.Add(new GH_Curve(current_intersection[0])); Ares.Add(new GH_Number(AreaMassProperties.Compute(current_intersection[0]).Area)); comment.Add("MutualIntersection, 1 resulting closed curve"); } else { for (int j = 0; j < current_intersection.Length; j++) { res.Add(new GH_Curve(current_intersection[j])); } Ares.Add(new GH_Number(AreaMassProperties.Compute(current_intersection).Area)); comment.Add("MutualIntersection, " + current_intersection.Length.ToString() + " resulting closed curves"); } break; case RegionContainment.AInsideB: if (curveA[i].IsClosed) { res.Add(new GH_Curve(curveA[i])); Ares.Add(new GH_Number(AreaMassProperties.Compute(curveA[i]).Area)); comment.Add("A Inside B, resulting curve is closed"); } else { res.Add(new GH_Curve(curveA[i])); Ares.Add(null); comment.Add("A Inside B, resulting curve is NOT closed"); } break; case RegionContainment.BInsideA: res.Add(new GH_Curve(curveB)); Ares.Add(new GH_Number(AreaMassProperties.Compute(curveB).Area)); comment.Add("B Inside A, resulting curve is closed"); break; } } } DA.SetDataList(0, res); DA.SetDataList(1, Ares); DA.SetDataList(2, comment); }
private bool GetInnerBoundary() { //plot 의 boundary 와 roads 를 사용. var segments = boundary.DuplicateSegments(); double offsetDistance = UnderGroundParkingConsts.Clearance; for (int i = 0; i < segments.Length; i++) { Curve temp = segments[i]; var v = temp.TangentAtStart; v.Rotate(-Math.PI / 2, Vector3d.ZAxis); temp.Translate(v * offsetDistance); segments[i] = temp; } List <Point3d> topoly = new List <Point3d>(); for (int k = 0; k < segments.Length; k++) { int j = (k + 1) % segments.Length; Line li = new Line(segments[k].PointAtStart, segments[k].PointAtEnd); Line lj = new Line(segments[j].PointAtStart, segments[j].PointAtEnd); double paramA; double paramB; var intersect = Rhino.Geometry.Intersect.Intersection.LineLine(li, lj, out paramA, out paramB, 0, false); // 교점이 A 선 위에 있음 bool isparamAonA = paramA >= 0 && paramA <= 1 ? true : false; // 교점이 B 선 위에 있음 bool isparamBonB = paramB >= 0 && paramB <= 1 ? true : false; bool isRightSided = paramA > 1 && paramB > 1 ? true : false; bool isLeftSided = paramA < 0 && paramB < 0 ? true : false; // A 나 B 둘중 한 선의 위에. if (isparamAonA && !isparamBonB || !isparamAonA && isparamBonB) { topoly.Add(li.PointAt(paramA)); //topoly.Add(segments[k].PointAtEnd); //topoly.Add(segments[j].PointAtStart); //k의 endpoint 에서 j의 startpoint로 선 긋는다. } // 두 선 위의 교점에. else if (isparamAonA && isparamBonB) { //교점을 더함 topoly.Add(li.PointAt(paramA)); } //외부에 else { //오른쪽 치우침 if (isRightSided) { topoly.Add(segments[k].PointAtEnd); topoly.Add(segments[j].PointAtStart); } //왼쪽 치우침 else if (isLeftSided) { topoly.Add(segments[k].PointAtEnd); topoly.Add(segments[j].PointAtStart); } //일반 else { topoly.Add(li.PointAt(paramA)); } } } topoly.Add(topoly[0]); var tempcurve = new PolylineCurve(topoly); var rotation = tempcurve.ClosedCurveOrientation(Vector3d.ZAxis); var selfintersection = Rhino.Geometry.Intersect.Intersection.CurveSelf(tempcurve, 0); var parameters = selfintersection.Select(n => n.ParameterA).ToList(); parameters.AddRange(selfintersection.Select(n => n.ParameterB)); var spl = tempcurve.Split(parameters); var f = CommonFunc.NewJoin(spl); var merged = f.Where(n => n.ClosedCurveOrientation(Vector3d.ZAxis) == rotation).ToList(); if (merged.Count == 0) { return(false); } merged = merged.OrderByDescending(n => n.GetArea()).ToList(); innerBoundary = merged[0]; return(true); }
/// <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) { #region updateInputs //if (!cap && this.Params.Input.Count ==7) //{ // this.Params.Input[5].RemoveAllSources(); // this.Params.UnregisterInputParameter(this.Params.Input[5]); // this.Params.Input[6].RemoveAllSources(); // this.Params.UnregisterInputParameter(this.Params.Input[6]); // Params.OnParametersChanged(); //} //if (cap && this.Params.Input.Count == 5) //{ // this.Params.RegisterInputParam(new Param_Colour // { // Name = "MinColor", // NickName = "MinColor", // Description = "MinColor", // Access = GH_ParamAccess.item, // Optional = true // }); // this.Params.RegisterInputParam(new Param_Colour // { // Name = "MaxColor", // NickName = "MaxColor", // Description = "MinColor", // Access = GH_ParamAccess.item, // Optional = true // }); // Params.OnParametersChanged(); //} #endregion updateInputs //bool caps = DA.Fetch<bool>("Cap"); Color?maxColor = DA.Fetch <Color?>(i_inputSelecterMax); Color?minColor = DA.Fetch <Color?>(i_inputSelectorMin); var allResults = DA.FetchTree <GH_Number>("Results"); var grids = DA.FetchList <Grid>("Grids"); //var gradientRange = DA.Fetch<string>("GradientRange"); //int maxCount = DA.Fetch<int>("MaxCount"); int maxCount = 200; //var inStepSize = DA.Fetch<int>("StepSize"); //var inSteps = DA.Fetch<int>("Steps"); InputSelector inputSelector = DA.Fetch <InputSelector>("_Section Type"); double globalMin = double.MaxValue; double globalMax = double.MinValue; for (int g = 0; g < grids.Count; g++) { globalMin = Math.Min(globalMin, ((List <GH_Number>)allResults.get_Branch(g)).Select(r => r.Value).Min()); globalMax = Math.Max(globalMax, ((List <GH_Number>)allResults.get_Branch(g)).Select(r => r.Value).Max()); } if (inputSelector == null) { inputSelector = new InputSelector(10, globalMin, globalMax); } if (allResults.Branches.Count != grids.Count) { throw new Exception("Grid count doesnt match results"); } //var colorDomain = Misc.AutoDomain(gradientRange, allResults); //Rhino.RhinoApp.WriteLine($"{range} -> {domain[0]} to {domain[1]}"); GH_GradientControl gc; try { gc = (GH_GradientControl)Params.Input[i_inputGradient].Sources[0].Attributes.GetTopLevel.DocObject; } catch (System.ArgumentOutOfRangeException) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Remember to add a gradient component in grasshopper!"); gc = null; } GradientParser gp = new GradientParser(gc) { //Cap = caps, AboveMax = maxColor == default(Color) ? null : maxColor, BelowMin = minColor == default(Color) ? null : minColor, //Min = domain[0], //Max = domain[1], Reverse = Params.Input[i_inputGradient].Reverse }; IDictionary <string, Color> colorDescriptions = new Dictionary <string, Color>(); IDictionary <string, int> colorPaths = new Dictionary <string, int>(); #region coloredMesh var outMeshes = new List <Mesh>(); for (int i = 0; i < grids.Count; i++) { //AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Mesh vertices: {grids[i].SimMesh.Vertices.Count}, colors = {gp.GetColors(allResults.Branches[i].Select(p => p.Value).ToArray()).Length} f"); outMeshes.Add(grids[i].GetColoredMesh(gp.GetColors(allResults.Branches[i].Select(p => p.Value).ToArray()))); Mesh m = grids[i].SimMesh; Point3d[] points = grids[i].SimPoints.ToArray(); outMeshes[outMeshes.Count - 1].Translate(0, 0, Units.ConvertFromMeter(0.001)); } DA.SetDataList(0, outMeshes); #endregion coloredMesh #region layeredMesh if (grids[0].UseCenters == true) { return; } //Outputs GH_Structure <GH_Mesh> oLayeredMeshes = new GH_Structure <GH_Mesh>(); List <GH_Mesh> previewMeshes = new List <GH_Mesh>(); List <GH_Plane> outPlanes = new List <GH_Plane>(); GH_Structure <GH_Curve> outCurves = new GH_Structure <GH_Curve>(); GH_Structure <GH_String> outValues = new GH_Structure <GH_String>(); GH_Structure <GH_Colour> outColors = new GH_Structure <GH_Colour>(); const double SCALAR = 1; // don't change. if (((GH_Structure <GH_Number>)gc.Params.Input[1].VolatileData)[0][0].Value == 1) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "The gradient connected has 1 as max. Is that on purpose? Check the inputs of your gradient component." + $"\nI suggest you set your max somewhere around {globalMax:0.0}"); } for (int g = 0; g < grids.Count; g++) { //GH_Structure<GH_Curve> curves = new GH_Structure<GH_Curve>(); Grid grid = grids[g]; Mesh inputMesh = grids[g].SimMesh.DuplicateMesh(); //Mesh meshToCut = grids[g].SimMesh; List <double> results = ((List <GH_Number>)allResults.get_Branch(g)).Select(r => r.Value).ToList(); if (grids[g].UseCenters == true) { results = RTreeSolver.FindClosestWeightedValues(grids[g], results, true).ToList(); // ADD CONVERSION TODO: } inputMesh.Normals.ComputeNormals(); Vector3f normal = inputMesh.FaceNormals[0]; Plane basePlane = new Plane(inputMesh.Vertices[0], normal); Transform ProjectToBase = Transform.PlanarProjection(basePlane); Plane cuttingPlane = new Plane(basePlane); Mesh meshToCut = CreateMeshToBeCut(SCALAR, inputMesh, results, cuttingPlane); previewMeshes.Add(new GH_Mesh(inputMesh)); MeshingParameters mp = new MeshingParameters(0); List <Mesh> layeredMeshesThisGrid = new List <Mesh>(); double valueForSmallAreas = double.MinValue; double resultsMin = results.Min(); foreach (var item in inputSelector) { if (resultsMin >= item) { valueForSmallAreas = item; break; } } //Color col = gp.GetColors(new List<double>() { inputSelector.Min.Value })[0]; Color col = gp.GetColors(new List <double>() { gp.BelowMin.HasValue&& inputSelector.Min.Value <= gp.Min ? resultsMin > gp.Min ? valueForSmallAreas : double.MinValue : inputSelector.Min.Value })[0]; Polyline[] outlinePolylines = inputMesh.GetNakedEdges(); PolylineCurve[] curvesFromOutline = new PolylineCurve[outlinePolylines.Length]; for (int i = 0; i < outlinePolylines.Length; i++) { curvesFromOutline[i] = new PolylineCurve(outlinePolylines[i]); curvesFromOutline[i].Transform(ProjectToBase); } Mesh meshFromCurves = GetMeshFromCurves(curvesFromOutline, mp, in col); GH_Path startPath = new GH_Path(g, -1); oLayeredMeshes.Append(new GH_Mesh(meshFromCurves), startPath); string lessThanKey = gp.BelowMin.HasValue && inputSelector.Min.Value < gp.Min ? $"<{gp.Min:0.0}" : $"<{inputSelector.Min.Value:0.0}"; if (!colorDescriptions.ContainsKey(lessThanKey) && inputSelector.First() < gp.Min) { colorDescriptions.Add(lessThanKey, col); colorPaths.Add(lessThanKey, -1); } ////outColors.Append(new GH_Colour(col), startPath); ////outValues.Append(new GH_Number(double.MinValue), startPath); //Mesh[] meshesFromCurves = GetMeshesFromCurves(curvesFromOutline, mp, in col); //oLayeredMeshes.AppendRange(meshesFromCurves.Select(m => new GH_Mesh(m)), new GH_Path(g, -1)); int cuttingCount = 0; double previousValue = 0; foreach (double currentValue in inputSelector) { if (cuttingCount > maxCount) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Too many steps... I reached {maxCount} and then stopped"); break; } if (gp.BelowMin.HasValue && currentValue < gp.Min) { continue; } if (currentValue > results.Max()) { break; } // Create planes Vector3f moveUpVector = normal * (float)((currentValue - previousValue) * SCALAR); Transform t = Transform.Translation(moveUpVector); GH_Path path = new GH_Path(g, cuttingCount); cuttingPlane.Transform(t); outPlanes.Add(new GH_Plane(cuttingPlane)); // Create boundary intersected curves Curve[] intersectedCurves = GetIntersectedCurves(inputMesh, cuttingPlane); if (intersectedCurves != null) { outCurves.AppendRange(intersectedCurves.Select(c => new GH_Curve(c.DuplicateCurve())), path); foreach (var curve in intersectedCurves) { curve.Transform(ProjectToBase); } // Create meshes col = gp.GetColors(new List <double>() { currentValue })[0]; meshFromCurves = GetMeshFromCurves(intersectedCurves, mp, in col); meshFromCurves.Transform(Transform.Translation(0, 0, (cuttingCount + 1) * Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance * 12.0)); if (meshFromCurves != null) { //oLayeredMeshes.AppendRange(meshesFromCurves.Select(m => new GH_Mesh(m)), path); oLayeredMeshes.Append(new GH_Mesh(meshFromCurves), path); string key = currentValue >= gp.Max.Value ? $">{currentValue:0.0}" : $"{currentValue:0.0}"; if (!colorDescriptions.ContainsKey(key)) { colorDescriptions.Add(key, col); colorPaths.Add(key, cuttingCount); } } if (currentValue >= gp.Max.Value) { break; } } previousValue = currentValue; cuttingCount++; } } foreach (KeyValuePair <string, Color> valuePair in colorDescriptions) { GH_Path path = new GH_Path(colorPaths[valuePair.Key]); outColors.Append(new GH_Colour(valuePair.Value), path); outValues.Append(new GH_String(valuePair.Key), path); } DA.SetDataTree(1, oLayeredMeshes); DA.SetDataTree(2, outCurves); DA.SetDataList("Planes", outPlanes); DA.SetDataList("TempMeshes", previewMeshes); DA.SetDataTree(6, outValues); DA.SetDataTree(5, outColors); #endregion layeredMesh }
protected override void SolveInstance(IGH_DataAccess DA) { int year = 2017; //int tasks = 1; //if (this.mt) tasks = Environment.ProcessorCount; int tasks = Environment.ProcessorCount; ParallelOptions paropts = new ParallelOptions { MaxDegreeOfParallelism = tasks }; //ParallelOptions paropts_1cpu = new ParallelOptions { MaxDegreeOfParallelism = 1 }; ////////////////////////////////////////////////////////////////////////////////////////// /// INPUTS int reclvl = 0; if (!DA.GetData(0, ref reclvl)) { return; } bool drawviewfactors = false; if (!DA.GetData(1, ref drawviewfactors)) { drawviewfactors = false; } bool drawcumskymatrix = false; if (!DA.GetData(2, ref drawcumskymatrix)) { drawcumskymatrix = false; } bool draw_sunpath = true; if (!DA.GetData(3, ref draw_sunpath)) { draw_sunpath = true; } bool draw_solarvec = true; if (!DA.GetData(4, ref draw_solarvec)) { draw_solarvec = true; } List <int> hoy = new List <int>(); if (!DA.GetDataList(5, hoy)) { return; } List <double> loc = new List <double>(); if (!DA.GetDataList(6, loc)) { return; } double longitude = loc[0]; double latitude = loc[1]; List <double> dni = new List <double>(); List <double> dhi = new List <double>(); DA.GetDataList(7, dni); DA.GetDataList(8, dhi); double domesize = 1.2; if (!DA.GetData(9, ref domesize)) { domesize = 1.2; } List <Mesh> context = new List <Mesh>(); DA.GetDataList(10, context); Point3d sp = new Point3d(); if (!DA.GetData(11, ref sp)) { return; } int timezone = 0; DA.GetData(12, ref timezone); ////////////////////////////////////////////////////////////////////////////////////////// /// size of skydome Point3d anchor = sp; Point3d bb_furthest_point; // max distance to furthest corner of context double bb_max_distance = double.MinValue; if (context.Count > 0) { Mesh context_joined = new Mesh(); foreach (Mesh msh in context) { context_joined.Append(msh); } BoundingBox bb_context = context_joined.GetBoundingBox(false); if (bb_context.IsDegenerate(-1.0) == 4) { bb_furthest_point = new Point3d(sp.X + 1.0, sp.Y + 1.0, sp.Z + 1.0); } else { Point3d[] _pts = bb_context.GetCorners(); int _p_index = 0; for (int i = 0; i < _pts.Length; i++) { double _d = sp.DistanceTo(_pts[i]); if (_d > bb_max_distance) { bb_max_distance = _d; _p_index = i; } } bb_furthest_point = _pts[_p_index]; } } else { bb_furthest_point = new Point3d(sp.X + 1.0, sp.Y + 1.0, sp.Z + 1.0); } Vector3d vec_sp = bb_furthest_point - sp; vec_sp = Vector3d.Multiply(vec_sp, domesize); double vec_sp_len = vec_sp.Length; ////////////////////////////////////////////////////////////////////////////////////////// /// SKYDOME /// View factors and/or Cumulative SkyMatrix SkyDome dome = new SkyDome(reclvl); // create 2 meshes, one with obstructed views (make it black transparent), and one unobstructed (regular GH_Mesh color) Mesh meshObstructed = new Mesh(); foreach (double[] p in dome.VertexVectorsSphere) { Vector3d vec = new Vector3d(p[0], p[1], p[2]); vec = Vector3d.Multiply(vec_sp_len, vec); meshObstructed.Vertices.Add(vec + sp); } foreach (int[] f in dome.Faces) { meshObstructed.Faces.AddFace(f[0], f[1], f[2]); } meshObstructed.UnifyNormals(); if (drawviewfactors) { List <Vector3d> vec_sky_list = new List <Vector3d>(); List <int> vec_int = new List <int>(); for (int i = 0; i < meshObstructed.Vertices.Count; i++) { Vector3d testvec = meshObstructed.Vertices[i] - sp; if (testvec.Z >= 0.0) { vec_sky_list.Add(testvec); vec_int.Add(i); } } Color[] colors = new Color[meshObstructed.Vertices.Count]; for (int i = 0; i < meshObstructed.Vertices.Count; i++) { colors[i] = Color.FromArgb(100, 255, 255, 255); //alpha not working } meshObstructed.VertexColors.SetColors(colors); Vector3d[] vec_sky = vec_sky_list.ToArray(); bool[] shadow = new bool[vec_sky_list.Count]; if (context.Count > 0) { CShadow.CalcShadowMT(sp, new Vector3d(0, 0, 1), 0.001, vec_sky, context.ToArray(), ref shadow, paropts); } int j = 0; foreach (int i in vec_int) { Color c = new Color(); if (shadow[j]) { // Custom material, DisplayMaterial (rhinostyle) rendering material. and make in override DrawViewportMesh c = Color.FromArgb(100, 0, 0, 0); //alpha not working meshObstructed.VertexColors.SetColor(i, c); _vectorsObstructed.Add(i); } j++; } } else if (drawcumskymatrix) { // https://www.sciencedirect.com/science/article/pii/S0038092X04001161 // http://alexandria.tue.nl/openaccess/635611/p1153final.pdf // Solarmodel.dll needs new function to compute cumulative sky view matrix (requires obstruction check from drawviewfactors // 1. calc perez diffuse for each hour. use that value (hor, circum, dome) and assign it to each mesh face // 2. DNI is computed directly onto SP // 3. visualize colored dome for diff only. // 4. add text to sensorpoint, stating annual irradiation (DNI plus diff) // // cumskymatrix seperate component!! coz it can be re-used for several sensor points // matrix inversion as in robinson stone to compute irradiation on all sensor points with refl.? // // needs a separate component that uses cumskymatrix on a number of SPs and visualizes that analysis surface. //... or use this component, output the sensorpoints, give it to a surface and make surface evaluate with the points, and recolor that surface if (dni.Count == 8760 && dhi.Count == 8760) // only continue, if solar irradiance time series are provided { //Rhino.RhinoApp.WriteLine("Leggo!"); //Context.cWeatherdata weather; //weather.DHI = dhi; //weather.DNI = dni; //weather.Snow = new List<double>(); //double[] beta = new double[1] { beta_in }; //double[] psi = new double[1] { psi_in }; //Sensorpoints.p3d[] coord = new Sensorpoints.p3d[1]; //dummy variables. will not be used in this simplified simulation //coord[0].X = 0; //coord[0].Y = 0; //coord[0].Z = 0; //Sensorpoints.v3d[] normal = new Sensorpoints.v3d[1]; //dummy variables. will not be used in this simplified simulation //normal[0].X = 0; //normal[0].Y = 1; //normal[0].Z = 0; //double[] albedo = new double[8760]; //for (int t = 0; t < 8760; t++) //{ // albedo[t] = albedo1; //} //Console.WriteLine("Calculating irradiation..."); //Sensorpoints p = new Sensorpoints(beta, psi, coord, normal, reclvl); //p.SetSimpleSkyMT(beta, paropts); //p.SetSimpleGroundReflectionMT(beta, albedo, weather, sunvectors.ToArray(), paropts); //p.CalcIrradiationMT(weather, sunvectors.ToArray(), paropts); // hold on... i need a new function in SolarModel for CumSkyMatrix } else { Rhino.RhinoApp.WriteLine("No data for Direct Normal Irradiance and Diffuse Horizontal Irradiance provided... Please provide 8760 time series for each."); } } if (drawviewfactors || drawcumskymatrix) { //_colouredMesh.Add(meshObstructed); _viewFactors = meshObstructed; } ////////////////////////////////////////////////////////////////////////////////////////// /// Solar Vectors List <Sphere> spheres = new List <Sphere>(); double fontsize = vec_sp_len / 50.0; List <SunVector> sunvectors_list; SunVector.Create8760SunVectors(out sunvectors_list, longitude, latitude, year); //shifting list of sunvectors according to timezone, so it matches weather file data SunVector.ShiftSunVectorsByTimezone(ref sunvectors_list, timezone); int count = 0; if (draw_solarvec) { foreach (int h in hoy) { Vector3d vec = new Vector3d(sunvectors_list[h].udtCoordXYZ.x, sunvectors_list[h].udtCoordXYZ.y, sunvectors_list[h].udtCoordXYZ.z); vec = Vector3d.Multiply(vec_sp_len, vec); Point3d solarpoint = new Point3d(Point3d.Add(sp, vec)); Line ln = new Line(sp, solarpoint); ln.Flip(); _solar_vectors.Add(ln); if (sunvectors_list[h].udtCoordXYZ.z < 0) { _night_time.Add(true); } else { _night_time.Add(false); } int year_now = sunvectors_list[h].udtTime.iYear; int month_now = sunvectors_list[h].udtTime.iMonth; int day_now = sunvectors_list[h].udtTime.iDay; double hour_now = sunvectors_list[h].udtTime.dHours; string hour_now2 = Convert.ToString(hour_now); if (hour_now < 10) { hour_now2 = "0" + Convert.ToString(hour_now); } string strval = Convert.ToString(year_now) + "/ " + Convert.ToString(month_now) + "/ " + Convert.ToString(day_now) + "/ " + hour_now2 + ":00"; Plane pl = new Plane(ln.From, new Vector3d(-1, 0, 0)); //Plane pl = new Plane(ln.From, vec); var te = Rhino.RhinoDoc.ActiveDoc.Objects.AddText(strval, pl, fontsize, "Baskerville", false, false); Rhino.DocObjects.TextObject txt = Rhino.RhinoDoc.ActiveDoc.Objects.Find(te) as Rhino.DocObjects.TextObject; _txt.Add(new List <Curve>()); if (txt != null) { var tt = txt.Geometry as Rhino.Geometry.TextEntity; Curve[] A = tt.Explode(); foreach (Curve crv in A) { _txt[count].Add(crv); } } count++; Rhino.RhinoDoc.ActiveDoc.Objects.Delete(te, true); Sphere sph = new Sphere(ln.From, vec_sp_len / 30.0); spheres.Add(sph); } } ////////////////////////////////////////////////////////////////////////////////////////// /// SUN PATH /// !!! wierd sun paths at extreme longitudes -> time shift... +/- UCT // draw solar paths: curves that connect each month, but for the same hour if (draw_sunpath) { for (int hod = 0; hod < 24; hod++) { List <Point3d> pts = new List <Point3d>(); for (int d = 0; d < 365; d++) { int h = hod + 24 * d; Vector3d vec = new Vector3d(sunvectors_list[h].udtCoordXYZ.x, sunvectors_list[h].udtCoordXYZ.y, sunvectors_list[h].udtCoordXYZ.z); vec = Vector3d.Multiply(vec_sp_len, vec); if (vec.Z > 0) { Point3d solarpoint = new Point3d(Point3d.Add(sp, vec)); pts.Add(solarpoint); } } if (pts.Count > 0) { PolylineCurve crv = new PolylineCurve(pts); _sun_paths.Add(crv); } } // draw solar paths; curves that connects each hour, but for the same month int interv = 365 / 12; for (int m = 0; m < 12; m++) { List <Point3d> pts = new List <Point3d>(); for (int hod = 0; hod < 24; hod++) { int h = hod + ((m * interv + interv / 2) * 24); Vector3d vec = new Vector3d(sunvectors_list[h].udtCoordXYZ.x, sunvectors_list[h].udtCoordXYZ.y, sunvectors_list[h].udtCoordXYZ.z); vec = Vector3d.Multiply(vec_sp_len, vec); if (vec.Z > 0) { Point3d solarpoint = new Point3d(Point3d.Add(sp, vec)); pts.Add(solarpoint); } } if (pts.Count > 0) { PolylineCurve crv = new PolylineCurve(pts); _sun_paths.Add(crv); } } } ////////////////////////////////////////////////////////////////////////////////////////// /// OUTPUT DA.SetData(0, _viewFactors); // this mesh needs to be colored according to view factor or cumulative sky matrix DA.SetDataList(1, _solar_vectors); DA.SetDataList(2, _sun_paths); DA.SetDataList(3, spheres); }
private Curve DrawLineRamp(Curve road, Vector3d axis, int onStart, RampScale scale, double offset) { Point3d start; Vector3d vx; Vector3d vy; if (axis == Vector3d.Unset) { axis = Vector3d.XAxis; } Vector3d axisPerp = new Vector3d(axis); axisPerp.Rotate(-Math.PI / 2, Vector3d.ZAxis); Vector3d roadv = road.TangentAtStart; double angleRoadAxis = Vector3d.VectorAngle(roadv, axis, Plane.WorldXY); if (angleRoadAxis < Math.PI * 0.25 || angleRoadAxis > Math.PI * 1.75 || (angleRoadAxis < Math.PI * 1.25 && angleRoadAxis > Math.PI * 0.75)) { //selectperpvector vy = axisPerp; } else { //selectoriginvector vy = axis; } Point3d testPoint = road.PointAtNormalizedLength(0.5); Vector3d dirInside = new Vector3d(roadv); dirInside.Rotate(-Math.PI / 2, Vector3d.ZAxis); Point3d testPointInside = testPoint + dirInside; Point3d testPointY = testPoint + vy; Curve testLine = new LineCurve(testPointInside, testPointY); var testI = Rhino.Geometry.Intersect.Intersection.CurveCurve(testLine, road, 0, 0); if (testI.Count != 0) { vy.Reverse(); } //true if (onStart == 0) { vx = new Vector3d(vy); vx.Rotate(Math.PI / 2, Vector3d.ZAxis); //vx = axis; // road.TangentAtStart; //if (vx == Vector3d.Unset) // vx = road.TangentAtStart; //vy = new Vector3d(vx); //vy.Rotate(-Math.PI / 2, Vector3d.ZAxis); start = road.PointAtStart + road.TangentAtStart * (800 + offset); start = start + vy * 1000; } //false else { vx = new Vector3d(vy); vx.Rotate(-Math.PI / 2, Vector3d.ZAxis); //vx = -axis; //-road.TangentAtStart; //if (vx == -Vector3d.Unset) // vx = -road.TangentAtStart; //vy = new Vector3d(vx); //vy.Rotate(Math.PI / 2, Vector3d.ZAxis); start = road.PointAtEnd + -road.TangentAtStart * (800 + offset); start = start + vy * 1000; } Point3d second = start + vx * UnderGroundParkingConsts.LinearRampWidth[(int)scale]; Point3d third = second + vy * (20000 + UnderGroundParkingConsts.WithinRadius[(int)scale]); Point3d forth = third - vx * UnderGroundParkingConsts.LinearRampWidth[(int)scale]; PolylineCurve plc = new PolylineCurve(new Point3d[] { start, second, third, forth, start }); return(plc); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object can be used to retrieve data from input parameters and /// to store data in output parameters.</param> protected override void SolveInstance(IGH_DataAccess DA) { Curve boundary = new PolylineCurve(); bool shouldInstantiateRooms = false; adjStrList = new List <string>(); List <Line> adjLines = new List <Line>(); bool shouldClearGenes = false; bool springCollAllGenes = false; bool adjustArea = false; DA.GetData("Reset", ref shouldInstantiateRooms); DA.GetData("Boundary", ref boundary); currentInputRooms.Clear(); DA.GetDataList(1, currentInputRooms); if (shouldInstantiateRooms || rooms.Count == 0 || boundaryArea != AreaMassProperties.Compute(boundary).Area || originalInputRooms == null || !RoomListsAreEqual(originalInputRooms, currentInputRooms)) { shouldClearGenes = true; boundaryArea = AreaMassProperties.Compute(boundary).Area; rooms.Clear(); originalInputRooms.Clear(); DA.GetDataList(1, rooms); DA.GetDataList(1, originalInputRooms); } DA.GetData("ProportionThreshold", ref proportionThreshold); DA.GetData("FF Balance", ref Gene.fitnessFunctionBalance); DA.GetDataList("Adjacencies", adjStrList); DA.GetData("SpringCollAllGenes", ref springCollAllGenes); DA.GetData("AdjustArea", ref adjustArea); int[,] adjArray = new int[adjStrList.Count, 2]; for (int i = 0; i < adjStrList.Count; i++) { adjArray[i, 0] = Int32.Parse((adjStrList[i].Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries)[0])); adjArray[i, 1] = Int32.Parse((adjStrList[i].Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries)[1])); } Gene.proportionThreshold = proportionThreshold; Gene.adjacencyList = adjArray; if (shouldClearGenes) { // Adapt the summarized rooms area to the boundary area if it is needed if (adjustArea) { double roomSumArea = 0; foreach (Curve room in rooms) { roomSumArea += AreaMassProperties.Compute(room).Area; } foreach (Curve room in rooms) { room.Transform(Transform.Scale(room.GetBoundingBox(false).Center, Math.Sqrt(boundaryArea / roomSumArea)));// AreaMassProperties.Compute(room).Area; } } shouldClearGenes = false; geneCollection = new GeneCollection(15, boundary); // Let's create some starting genes foreach (Gene gene in geneCollection.genes) { if (Menu_ShuffleRoomsAtFirst) { gene.InstantiateRandomly(rooms); } else { gene.Instantiate(rooms); } } } geneCollection.Iterate(); if (springCollAllGenes) { for (int l = 0; l < geneCollection.genes.Count; l++) { Gene gene = geneCollection.genes[l]; rooms = gene.GetCurves(); rooms = CollisionDetectionMain(rooms, boundary); gene.collection.Clear(); gene.Instantiate(rooms); } } rooms = geneCollection.GetBest(); AdjacentContraction(rooms, adjStrList, boundary, out adjLines); List <GH_Curve> GH_rooms = new List <GH_Curve>(); foreach (Curve c in rooms) { GH_rooms.Add(new GH_Curve(c)); } DA.SetDataList(0, GH_rooms); DA.SetDataList(1, adjLines); }
//채광방향 public static List <Curve> Lighting(Curve roadCenter, Plot plot, double aptAngle) { double d = 0; if (plot.PlotType != PlotTypes.상업지역) { if (plot.LegalMaxF <= 7) { d = 0.25; } else { d = 0.5; } } else { d = 0.25; } Curve basecurve = null; var cp = AreaMassProperties.Compute(plot.Boundary).Centroid; var basev = Vector3d.XAxis; basev.Rotate(aptAngle, Vector3d.ZAxis); var bounding = plot.Boundary.GetBoundingBox(false); basecurve = new LineCurve(cp - basev * bounding.Diagonal.Length / 2, cp + basev * bounding.Diagonal.Length / 2); List <Curve> result = new List <Curve>(); Curve last = roadCenter.DuplicateCurve(); double pheight = 3.3; double fheight = 2.8; int floor = plot.LegalMaxF; List <Curve> debug = new List <Curve>(); for (int i = 0; i < floor; i++) { var height = pheight + fheight * i; var distance = d * (height - pheight); var segments = roadCenter.DuplicateSegments(); for (int j = 0; j < segments.Length; j++) { var ps = segments[j].PointAtStart; var pe = segments[j].PointAtEnd; double ds = 0; double de = 0; basecurve.ClosestPoint(ps, out ds); basecurve.ClosestPoint(pe, out de); Vector3d vs = basecurve.PointAt(ds) - ps; Vector3d ve = basecurve.PointAt(de) - pe; vs.Unitize(); ve.Unitize(); var mp = segments[j].PointAtNormalizedLength(0.5); var ts = mp + vs; var te = mp + ve; if (roadCenter.Contains(ts) == PointContainment.Inside) { segments[j].Translate(vs * distance); } else if (roadCenter.Contains(te) == PointContainment.Inside) { segments[j].Translate(ve * distance); } segments[j].Translate(Vector3d.ZAxis * height); } List <Point3d> topoly = new List <Point3d>(); for (int k = 0; k < segments.Length; k++) { int j = (k + 1) % segments.Length; Line li = new Line(segments[k].PointAtStart, segments[k].PointAtEnd); Line lj = new Line(segments[j].PointAtStart, segments[j].PointAtEnd); double paramA; double paramB; var intersect = Rhino.Geometry.Intersect.Intersection.LineLine(li, lj, out paramA, out paramB, 0, false); topoly.Add(li.PointAt(paramA)); } topoly.Add(topoly[0]); var tempcurve = new PolylineCurve(topoly); var rotation = tempcurve.ClosedCurveOrientation(Vector3d.ZAxis); var selfintersection = Rhino.Geometry.Intersect.Intersection.CurveSelf(tempcurve, 0); var parameters = selfintersection.Select(n => n.ParameterA).ToList(); parameters.AddRange(selfintersection.Select(n => n.ParameterB)); var spl = tempcurve.Split(parameters); var f = NewJoin(spl); var merged = f.Where(n => n.ClosedCurveOrientation(Vector3d.ZAxis) == rotation).ToList(); debug.AddRange(merged); for (int j = merged.Count - 1; j >= 0; j--) { var tc = merged[j].DuplicateCurve(); tc.Translate(Vector3d.ZAxis * -tc.PointAtStart.Z); if (Curve.CreateBooleanDifference(tc, last).Length == 0) { last = tc; result.Add(merged[j]); } } } return(result); }
/// <summary> /// This one does many things, which essentially boil down to translating the geometry + performance measures into a spk instance. /// This instance subsequently gets json-ed out to a file /// </summary> public static System.Dynamic.ExpandoObject translateGeometry(List <System.Object> inputObjects, List <string> guids, String name, IGH_Component component) { dynamic myInstance = new System.Dynamic.ExpandoObject(); myInstance.metadata = new System.Dynamic.ExpandoObject(); myInstance.metadata.verion = "1.0"; myInstance.metadata.type = "Object"; myInstance.metadata.generator = "Instance Export"; // super important - name will link it to the correct group in three js myInstance.metadata.name = name; myInstance.metadata.properties = new List <String>(); foreach (IGH_Param param in component.Params.Input[1].Sources) { var myprop = getPanelNameAndVal(param); if (myprop != null) { myInstance.metadata.properties.Add(myprop); } } myInstance.geometries = new List <System.Object>(); int k = 0; foreach (System.Object myObj in inputObjects) { if (myObj != null) { string myguid = "000"; if (name != "staticGeo") { myguid = guids[k]; } k++; if (myObj is GH_Mesh) { GH_Mesh tempers = (GH_Mesh)myObj; SuperMesh mesh = new SuperMesh(tempers, myguid); myInstance.geometries.Add(mesh); } else if ((myObj is GH_Curve)) { GH_Curve tempers = (GH_Curve)myObj; Curve myCrv = tempers.Value; if (myCrv.Degree == 1) { Polyline tempP; myCrv.TryGetPolyline(out tempP); SuperPolyline polyline = new SuperPolyline(tempP, false, myguid); myInstance.geometries.Add(polyline); } else if ((myCrv.Degree == 2) || (myCrv.Degree == 3)) { bool isClosed = myCrv.IsClosed; int mainSegmentCount = 0, subSegmentCount = 1; double maxAngleRadians = 0, maxChordLengthRatio = 0, maxAspectRatio = 0, tolerance = 0.1, minEdgeLength = 0, maxEdgeLength = 0; bool keepStartPoint = true; PolylineCurve p = myCrv.ToPolyline(mainSegmentCount, subSegmentCount, maxAngleRadians, maxChordLengthRatio, maxAspectRatio, tolerance, minEdgeLength, maxEdgeLength, keepStartPoint); Polyline pp; p.TryGetPolyline(out pp); myInstance.geometries.Add(new SuperPolyline(pp, isClosed, myguid)); } } else if (myObj is Point3d) { GH_Point tempers = (GH_Point)myObj; SuperPoint point = new SuperPoint(tempers, myguid); myInstance.geometries.Add(point); } else if ((myObj is GH_Brep) || (myObj is GH_Surface)) { Mesh[] myMeshes; Brep myFutureBrep = null; GH_Convert.ToBrep(myObj, ref myFutureBrep, GH_Conversion.Primary); if (myFutureBrep != null) { myMeshes = Mesh.CreateFromBrep(myFutureBrep, MeshingParameters.Smooth); if (myMeshes == null || myMeshes.Length == 0) { // TODO throw an error } Mesh brep_mesh = new Mesh(); foreach (Mesh tempmesh in myMeshes) { brep_mesh.Append(tempmesh); } GH_Mesh temporal = new GH_Mesh(brep_mesh); SuperMesh mesh = new SuperMesh(temporal, myguid); myInstance.geometries.Add(mesh); } } else if (myObj is GH_Circle) { GH_Circle myCircle = myObj as GH_Circle; //NurbsCurve mycrv = myCircle.Value.ToNurbsCurve(); NurbsCurve mycrv = NurbsCurve.CreateFromCircle(myCircle.Value); int mainSegmentCount = 30, subSegmentCount = 1; double maxAngleRadians = 0, maxChordLengthRatio = 0, maxAspectRatio = 0, tolerance = 0.1, minEdgeLength = 0, maxEdgeLength = 0; bool keepStartPoint = true; if (mycrv != null) { PolylineCurve p = mycrv.ToPolyline(mainSegmentCount, subSegmentCount, maxAngleRadians, maxChordLengthRatio, maxAspectRatio, tolerance, minEdgeLength, maxEdgeLength, keepStartPoint); Polyline pp; p.TryGetPolyline(out pp); if (pp != null) { myInstance.geometries.Add(new SuperPolyline(pp, true, myguid)); } else { myInstance.geometries.Add("Circle error"); } } else { myInstance.geometries.Add("Circle error 2"); } } else if (myObj is GH_Line) { GH_Line myLine = myObj as GH_Line; myInstance.geometries.Add(new SuperPolyline(myLine, myguid)); } else { myInstance.geometries.Add("error - undefined type"); } } } return(myInstance); }
private IntersectResult Intersect2Curves(Curve a, Curve b) { int clipperPrecision = 100; IntersectResult result = new IntersectResult(); if (Curve.PlanarCurveCollision(a, b, Plane.WorldXY, 0.001f)) { Clipper clipper = new Clipper(); Path subjectA = CurveToPath(a, clipperPrecision); Path subjectB = CurveToPath(b, clipperPrecision); Paths solution = new Paths(); clipper.AddPath(subjectA, PolyType.ptClip, true); clipper.AddPath(subjectB, PolyType.ptSubject, true); clipper.Execute(ClipType.ctIntersection, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero); if (solution.Count > 0) { result.intersect = true; PolylineCurve pl = PathToPolyline(solution[0], clipperPrecision); result.unionCurve = pl; Point3d minPoint = pl.GetBoundingBox(false).Min; Point3d maxPoint = pl.GetBoundingBox(false).Max; if (maxPoint.X - minPoint.X > maxPoint.Y - minPoint.Y) { result.reboundingVector = new Vector2d(0, -(maxPoint.Y - minPoint.Y)); if (AreaMassProperties.Compute(a).Centroid.Y > AreaMassProperties.Compute(b).Centroid.Y) { result.reboundingVector.Y *= -1; } } else { result.reboundingVector = new Vector2d(-(maxPoint.X - minPoint.X), 0); if (AreaMassProperties.Compute(a).Centroid.X > AreaMassProperties.Compute(b).Centroid.X) { result.reboundingVector.X *= -1; } } } } /* Curve[] unionCurveArray = Curve.CreateBooleanIntersection(a, b); * if (unionCurveArray.Length > 0) * { * result.intersect = true; * result.unionCurve = unionCurveArray[0]; * * // Find the smallest dimesion of unionCurve * Point3d minPoint = result.unionCurve.GetBoundingBox(false).Min; * Point3d maxPoint = result.unionCurve.GetBoundingBox(false).Max; * * if (maxPoint.X - minPoint.X > maxPoint.Y - minPoint.Y) * { * result.reboundingVector = new Vector2d(0, -(maxPoint.Y - minPoint.Y)); * if (AreaMassProperties.Compute(a).Centroid.Y > AreaMassProperties.Compute(b).Centroid.Y) * result.reboundingVector.Y *= -1; * } * else * { * result.reboundingVector = new Vector2d(-(maxPoint.X - minPoint.X), 0); * if (AreaMassProperties.Compute(a).Centroid.X > AreaMassProperties.Compute(b).Centroid.X) * result.reboundingVector.X *= -1; * } * * * } * }*/ else { result.intersect = false; result.reboundingVector = Vector2d.Unset; result.unionCurve = null; } return(result); }
public static Curve RatchetPawl(Circle C, int T, double D, int pawlCount, double pRad, double Spring, out Curve SpringPawl) { List <Curve> rachets = new List <Curve>(); List <Curve> paws = new List <Curve>(); List <double> split = new List <double>(); for (int i = 0; i < T; i++) { double ta = (Math.PI * 2 / T) * i; double tb = (Math.PI * 2 / T) * ((i + 1) % T); //teeth build Point3d start = new Circle(C.Plane, C.Radius - D).PointAt(ta); //fillet corner point Vector3d va = C.PointAt(ta) - start; va.Unitize(); Vector3d vb = C.PointAt(tb) - start; vb.Unitize(); Curve lineA = new LineCurve(C.PointAt(ta), start); Curve lineB = new LineCurve(C.PointAt(tb), start); Curve teeth = Curve.CreateFilletCurves(lineA, start + (va * 0.1), lineB, start + (vb * 0.1), 0.2, true, true, true, 0.01, 0.01)[0]; rachets.Add(teeth); //pawl build double t_paw = (double)T / (double)pawlCount; if (i == 0 || i + 1 > paws.Count * t_paw) { ArcCurve innC = new ArcCurve(new Circle(C.Plane, C.Radius - D - pRad)); Point3d pawP = start + (va * (D - 0.2)); double side = Math.Sqrt(Math.Pow(C.Center.DistanceTo(pawP), 2) - Math.Pow(innC.Radius, 2)); ArcCurve tanC = new ArcCurve(new Circle(pawP, side)); //diection var ccx = Rhino.Geometry.Intersect.Intersection.CurveCurve(innC, tanC, 0.1, 0.1); Point3d tanP; if (i == 0) { tanP = ccx[1].PointA; } else { tanP = ccx[0].PointA; } List <double> angle = Trigonometry(C.Center.DistanceTo(pawP), pawP.DistanceTo(tanP), innC.Radius, TrigLaw.SSS, Traingle.Angle); Point3d depthP = pawP + ((Spring / Math.Sin(angle[1])) * Math.Tan(angle[1]) * -va); Vector3d tan2cen = C.Center - tanP; tan2cen.Unitize(); Vector3d springY = Vector3d.CrossProduct(tan2cen, C.Normal); springY.Unitize(); //pawl teeth List <Point3d> points = new List <Point3d> { tanP + (tan2cen * Spring), depthP, pawP, tanP }; PolylineCurve pawl = new PolylineCurve(points); //spring arc ArcCurve springArc = new ArcCurve(new Arc(tanP + (tan2cen * Spring), tanP + (tan2cen * Spring * 1.5) - springY * Spring * 0.5, tanP + (tan2cen * Spring * 2))); Transform xform = Transform.Rotation(-Math.PI / (pawlCount * 3), C.Normal, C.Center); springArc.Transform(xform); ArcCurve extendSpring = new ArcCurve(new Arc(tanP + (tan2cen * Spring), tanP - pawP, springArc.PointAtStart)); ArcCurve clipSpring = new ArcCurve(new Arc(tanP + (tan2cen * Spring) + tan2cen * Spring, tanP - pawP, springArc.PointAtEnd)); clipSpring.Reverse(); //innC intersection Line innRay = new Line(clipSpring.PointAtEnd, clipSpring.PointAtEnd - (tanP - pawP) * 2); Point3d rayStop = Point3d.Unset; double clt; var clx = Rhino.Geometry.Intersect.Intersection.LineCircle(innRay, new Circle(C.Plane, C.Radius - D - pRad), out clt, out rayStop, out clt, out rayStop); LineCurve innSpring = new LineCurve(clipSpring.PointAtEnd, rayStop); paws.Add(Curve.JoinCurves(new List <Curve> { pawl, extendSpring, springArc, clipSpring, innSpring })[0]); //split t values double splitA; double splitB; new ArcCurve(new Circle(C.Plane, C.Radius - D - pRad)).ClosestPoint(rayStop, out splitA); new ArcCurve(new Circle(C.Plane, C.Radius - D - pRad)).ClosestPoint(tanP, out splitB); split.Add(splitA); split.Add(splitB); } } ArcCurve innCircle = new ArcCurve(new Circle(C.Plane, C.Radius - D - pRad)); Curve[] shatter = innCircle.Split(split); for (int i = 0; i < shatter.Length; i += 2) { paws.Add(shatter[i]); } SpringPawl = Curve.JoinCurves(paws)[0]; return(Curve.JoinCurves(rachets)[0]); }
protected override void SolveInstance(IGH_DataAccess DA) { // --- Input var curveOnSurface = default(IOrientableCurve); var thickness = default(double); var offset = default(double); if (!DA.GetData(0, ref curveOnSurface)) { return; } if (!DA.GetData(1, ref thickness)) { return; } if (!DA.GetData(2, ref offset)) { return; } // --- Execute var polyline = default(PolylineCurve); var curve = curveOnSurface.ToCurve(DocumentTolerance()); if (curve.TryGetPolyline(out var points)) { polyline = new PolylineCurve(points); } else { polyline = curve.ToPolyline(DocumentTolerance(), DocumentAngleTolerance(), 0, 0); } var points3d = new List <Point3d>(polyline.PointCount); var mesh = new Mesh(); for (int i = 0; i < polyline.PointCount; i++) { var point2d = polyline.Point(i); curve.ClosestPoint(point2d, out var t); var point = curveOnSurface.PointAt(t); points3d.Add(point); var normal = curveOnSurface.NormalAt(t); var d = 0.5 * thickness; mesh.Vertices.Add(point + (offset + d) * normal); mesh.Vertices.Add(point + (offset - d) * normal); } for (int i = 1; i < polyline.PointCount; i++) { var a = (i - 1) * 2; var b = (i - 1) * 2 + 1; var c = i * 2 + 1; var d = i * 2; mesh.Faces.AddFace(a, b, c, d); } if (Unroll) { var m = mesh.DuplicateMesh(); var p = points3d[0]; var oldA = m.Vertices[0]; var oldB = m.Vertices[1]; var newA = new Point3d(0, offset + 0.5 * thickness, 0); var newB = new Point3d(0, offset - 0.5 * thickness, 0); m.Vertices.SetVertex(0, newA); m.Vertices.SetVertex(1, newB); var outOfPlane = 0.0; for (int i = 1; i < polyline.PointCount; i++) { var t = points3d[i] - points3d[i - 1]; var n = new Vector3d(oldA.X - oldB.X, oldA.Y - oldB.Y, oldA.Z - oldB.Z); var c = i * 2 + 1; var d = i * 2; var oldC = m.Vertices[c]; var oldD = m.Vertices[d]; var oldPlane = new Plane(p, t, n); var newPlane = new Plane(newB + (0.5 * thickness - offset) * (newA - newB) / (newA - newB).Length, Vector3d.CrossProduct(newA - newB, Vector3d.ZAxis), newA - newB); var xf = Transform.PlaneToPlane(oldPlane, newPlane); var newC = new Point3f(oldC.X, oldC.Y, oldC.Z); newC.Transform(xf); outOfPlane = Math.Max(outOfPlane, Math.Abs(newC.Z)); newC.Z = 0; var newD = new Point3f(oldD.X, oldD.Y, oldD.Z); newD.Transform(xf); outOfPlane = Math.Max(outOfPlane, Math.Abs(newD.Z)); newD.Z = 0; m.Vertices.SetVertex(c, newC); m.Vertices.SetVertex(d, newD); oldA = oldD; oldB = oldC; newA = newD; newB = newC; p = points3d[i]; } mesh = m; } // --- Output DA.SetData(0, mesh); }
/// <summary> /// Generate a series of planes on the glulam cross-section. TODO: Re-implement as GlulamOrientation function /// </summary> /// <param name="N">Number of planes to extract.</param> /// <param name="extension">Extension of the centreline curve</param> /// <param name="frames">Output cross-section planes.</param> /// <param name="parameters">Output t-values along centreline curve.</param> /// <param name="interpolation">Type of interpolation to use (default is Linear).</param> public override void GenerateCrossSectionPlanes(int N, out Plane[] frames, out double[] parameters, GlulamData.Interpolation interpolation = GlulamData.Interpolation.LINEAR) { Curve curve = Centreline; double multiplier = RhinoMath.UnitScale(UnitSystem.Millimeters, Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem); //PolylineCurve discrete = curve.ToPolyline(Glulam.Tolerance * 10, Glulam.AngleTolerance, 0.0, 0.0); PolylineCurve discrete = curve.ToPolyline(multiplier * Tolerance, AngleTolerance, multiplier * MininumSegmentLength, curve.GetLength() / MinimumNumSegments); if (discrete == null) { parameters = curve.DivideByCount(N - 1, true).ToArray(); //discrete = new PolylineCurve(new Point3d[] { curve.PointAtStart, curve.PointAtEnd }); } else { if (discrete.TryGetPolyline(out Polyline discrete2)) { N = discrete2.Count; parameters = new double[N]; for (int i = 0; i < N; ++i) { curve.ClosestPoint(discrete2[i], out parameters[i]); } } else { parameters = curve.DivideByCount(N - 1, true).ToArray(); } } //frames = parameters.Select(x => GetPlane(x)).ToArray(); //return; frames = new Plane[parameters.Length]; var vectors = Orientation.GetOrientations(curve, parameters); Plane temp; for (int i = 0; i < parameters.Length; ++i) { temp = Utility.PlaneFromNormalAndYAxis( curve.PointAt(parameters[i]), curve.TangentAt(parameters[i]), vectors[i]); if (temp.IsValid) { frames[i] = temp; } else { throw new Exception(string.Format("Plane is invalid: vector {0} tangent {1}", vectors[i], curve.TangentAt(parameters[i]))); } } return; }
/// <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) { Mesh topoMesh = new Mesh(); DA.GetData <Mesh>("Topography Mesh", ref topoMesh); GH_Structure <IGH_GeometricGoo> featureGoo = new GH_Structure <IGH_GeometricGoo>(); DA.GetDataTree <IGH_GeometricGoo>("Feature Geometry", out featureGoo); ///Reserve one processor for GUI totalMaxConcurrancy = System.Environment.ProcessorCount - 1; ///Tells us how many threads were using //Message = totalMaxConcurrancy + " threads"; ///Get Rtree of points and flat mesh for processing in detailed feature mesh projection Mesh topoFlat = new Mesh(); Point3d[] topoFlatPoints = null; RTree rTree = new RTree(); if (!fast) { topoFlat = topoMesh.DuplicateMesh(); for (int i = 0; i < topoFlat.Vertices.Count; i++) { Point3f v = topoFlat.Vertices[i]; v.Z = 0; topoFlat.Vertices.SetVertex(i, v); } topoFlatPoints = topoFlat.Vertices.ToPoint3dArray(); rTree = RTree.CreateFromPointArray(topoFlatPoints); } ///Create a dictionary that works in parallel var gooTree = new System.Collections.Concurrent.ConcurrentDictionary <GH_Path, List <IGH_GeometricGoo> >(); ///Multi-threading the loop System.Threading.Tasks.Parallel.ForEach(featureGoo.Paths, new System.Threading.Tasks.ParallelOptions { MaxDegreeOfParallelism = totalMaxConcurrancy }, pth => { ///Create containers for translating from GH Goo Point3d pt = new Point3d(); Polyline pLine = null; PolylineCurve pLineCurve = null; Curve curve = null; Mesh mesh = new Mesh(); Surface surface = null; Brep brep = new Brep(); ///Output container list List <IGH_GeometricGoo> gGooList = new List <IGH_GeometricGoo>(); List <IGH_GeometricGoo> fGooList = new List <IGH_GeometricGoo>(); var branchFeatures = featureGoo.get_Branch(pth); BoundingBox branchBox = new BoundingBox(); if (branchFeatures.Count > 0) { foreach (var bGoo in branchFeatures) { ///Get geometry type(s) in branch string geomType = string.Empty; IGH_GeometricGoo fGoo = GH_Convert.ToGeometricGoo(bGoo); if (fGoo != null && fGoo.IsValid) { if (grouped) { ///Need to duplicate geometry or else move vector piles on similar to the following ///https://www.grasshopper3d.com/forum/topics/c-component-refresh-problem fGooList.Add(fGoo.DuplicateGeometry()); branchBox.Union(fGoo.Boundingbox); } geomType = fGoo.TypeName; switch (geomType) { case "Point": fGoo.CastTo <Point3d>(out pt); gGooList.Add(ProjectPointToTopo(topoMesh, pt)); break; case "Line": case "Polyline": fGoo.CastTo <Polyline>(out pLine); if (fast) { gGooList.Add(ProjectPolylineToTopo(topoMesh, pLine)); } else { ///Lock topoMesh so it's not accessed by mutliple threads at once in a "deadlock" ///https://docs.microsoft.com/en-us/dotnet/standard/threading/managed-threading-best-practices lock (topoMesh) { gGooList.AddRange(ProjectCurveToTopo(topoMesh, pLine.ToNurbsCurve())); } } break; case "PolylineCurve": fGoo.CastTo <PolylineCurve>(out pLineCurve); if (fast) { gGooList.Add(ProjectPolylineToTopo(topoMesh, pLineCurve.ToPolyline())); } else { lock (topoMesh) { gGooList.AddRange(ProjectCurveToTopo(topoMesh, pLineCurve.ToNurbsCurve())); } } break; case "Curve": fGoo.CastTo <Curve>(out curve); if (fast) { if (curve.TryGetPolyline(out pLine)) { gGooList.Add(ProjectPolylineToTopo(topoMesh, pLine)); } else { gGooList.AddRange(ProjectCurveToTopo(topoMesh, curve)); } } else { lock (topoMesh) { gGooList.AddRange(ProjectCurveToTopo(topoMesh, curve)); } } break; case "Mesh": fGoo.CastTo <Mesh>(out mesh); if (mesh.IsClosed) { gGooList.Add(ProjectSolidMeshToTopo(topoMesh, mesh)); } else { if (fast) { gGooList.Add(ProjectMeshToTopoFast(topoMesh, mesh)); } else { lock (topoMesh) { gGooList.Add(ProjectMeshToTopoSlow(topoMesh, topoFlat, topoFlatPoints, rTree, mesh)); } } } break; case "Surface": fGoo.CastTo <Surface>(out surface); gGooList.Add(ProjectSurfaceToTopoFast(topoMesh, surface)); break; case "Brep": fGoo.CastTo <Brep>(out brep); gGooList.Add(ProjectBrepToTopo(topoMesh, brep)); break; default: AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Not able to move " + geomType + " geometry to mesh" + ". Geometry must be a Point, Curve, Mesh, Surface or Brep."); break; } } else { } } ///Move objects in branch a minimum distance if grouped selected ///If only one feature in a branch, not need to group if (grouped && gGooList.Count > 1) { ///Get the minimum move vector Point3d lowestPoint = new Point3d(); double minDistance = double.MaxValue; Vector3d minimumVec = new Vector3d(); foreach (var gi in gGooList) { if (gi != null) { Point3d gGooMin = gi.Boundingbox.Min; Vector3d distVector = gGooMin - branchBox.Min; if (distVector.Length < minDistance && distVector.Length > 0 && distVector.IsValid) { lowestPoint = gGooMin; minDistance = distVector.Length; minimumVec = new Vector3d(0, 0, distVector.Z); } } } ///Move orignal feature geometry the minimum move vector if (minDistance != double.MaxValue) { Transform transform = Transform.Translation(minimumVec); for (int f = 0; f < fGooList.Count; f++) { fGooList[f].Transform(transform); } gooTree[pth] = fGooList; } } else { gooTree[pth] = gGooList; } } }); ///End of multi-threaded loop ///Convert dictionary to regular old data tree GH_Structure <IGH_GeometricGoo> gTree = new GH_Structure <IGH_GeometricGoo>(); foreach (KeyValuePair <GH_Path, List <IGH_GeometricGoo> > g in gooTree) { gTree.AppendRange(g.Value, g.Key); } topoFlat.Dispose(); topoMesh.Dispose(); DA.SetDataTree(0, gTree); }
protected override void SolveInstance(IGH_DataAccess DA) { Brep basebrep = new Brep(); double height = 0; bool revers = true; DA.GetData(0, ref basebrep); DA.GetData(1, ref height); DA.GetData(2, ref revers); List <Point3d> ps = new List <Point3d>(); List <BrepEdge> be_list = new List <BrepEdge>(); foreach (BrepTrim btr in basebrep.Loops[0].Trims) { be_list.Add(btr.Edge); } AddFirstEdge(be_list[0], be_list[1]); for (int i = 1; i < be_list.Count - 1; i++) { AddEdge(be_list[i]); } if (revers) { ps.Reverse(); } Vector3d nv = Tools.GetFaceNormal(ps)[0]; nv = new Vector3d(nv.X * height, nv.Y * height, nv.Z * height); List <FD_Vertex> basepolyline = new List <FD_Vertex>(); foreach (Point3d pt in ps) { basepolyline.Add(new FD_Vertex(pt.X, pt.Y, pt.Z)); } ps.Add(ps[0]); PolylineCurve pc = new PolylineCurve(ps); Surface extrusion = Surface.CreateExtrusion(pc, nv); List <Brep> bl = new List <Brep>(); bl.Add(basebrep); bl.Add(extrusion.ToBrep()); Brep step1 = Brep.JoinBreps(bl, 0.1)[0]; basebrep.Translate(nv); bl = new List <Brep>(); bl.Add(basebrep); bl.Add(step1); Brep step2 = Brep.JoinBreps(bl, 0.1)[0]; FD_Cube cube = new FD_Cube(basepolyline, height); DA.SetData(0, cube); DA.SetData(1, step2); bool SamePoint(Point3d p1, Point3d p2) { double dx = Math.Abs(p1.X - p2.X); double dy = Math.Abs(p1.Y - p2.Y); double dz = Math.Abs(p1.Z - p2.Z); if (dx < 0.001 && dy < 0.001 && dz < 0.001) { return(true); } else { return(false); } } void AddEdge(BrepEdge be) { if (SamePoint(ps[ps.Count - 1], be.PointAtStart)) { ps.Add(be.PointAtEnd); } else { ps.Add(be.PointAtStart); } } void AddFirstEdge(BrepEdge be0, BrepEdge be1) { ps.Clear(); if (SamePoint(be0.PointAtEnd, be1.PointAtEnd) || SamePoint(be0.PointAtEnd, be1.PointAtStart)) { ps.Add(be0.PointAtStart); ps.Add(be0.PointAtEnd); } else { ps.Add(be0.PointAtEnd); ps.Add(be0.PointAtStart); } } }
public Polyline[][] GooToOutlines(List <IGH_GeometricGoo> geo_) { geo = new List <IGH_GeometricGoo>(); geo_Original = new List <IGH_GeometricGoo>(); foreach (var goo in geo_) { if (goo != null) { if (goo.IsValid) { geo.Add(goo.DuplicateGeometry()); geo_Original.Add(goo.DuplicateGeometry()); } } } this.n = geo.Count; Polyline[][] outlines = new Polyline[this.n][]; for (int i = 0; i < geo_.Count; i++) { switch (geo_[i].TypeName) { case ("Brep"): case ("Surface"): bool flagBrep = geo_[i].CastTo <Brep>(out Brep b); if (flagBrep) { if (b.IsValid) { outlines[i] = OpenNestUtil.BrepLoops(b); } } break; case ("Mesh"): bool flagMesh = geo_[i].CastTo <Mesh>(out Mesh m); if (flagMesh) { if (m.IsValid) { outlines[i] = OpenNestUtil.MeshLoops(m); } } break; case ("Curve"): bool flagPolyline = geo_[i].CastTo <Curve>(out Curve c); if (flagPolyline) { if (c.IsValid) { bool isPolyline = c.TryGetPolyline(out Polyline polyline); if (isPolyline) { if (polyline.IsValid && polyline.Count > 2 && OpenNestUtil.FastDistance(polyline[0], polyline[polyline.Count - 1]) < 0.01) { outlines[i] = new Polyline[] { polyline }; } } else { PolylineCurve polycurve = c.ToPolyline(20, 1, 0.00, 0.00, 0.00, 0.01, 0.00, 0.00, true); bool notPolyline = polycurve.TryGetPolyline(out Polyline polycurvePolyline); if (!notPolyline) { Rhino.RhinoApp.WriteLine("wrongCurve"); } outlines[i] = new Polyline[] { polycurvePolyline }; } } } break; } } return(outlines); }
private static void GetBuildingLayout(string defPath, string mixPath, Line mainCorridor, Line leftLeg, Line middleLeg, Line rightLeg, double unitDepth, double hallWidth, out List <PolylineCurve> polyUnits, out List <string> unitNames, out List <Line> shearWallLines, out List <Line> lineList, out PolylineCurve boundary, out List <double> percentMix) { var unitList = new List <BuildingUnit>(); var csv = File.ReadAllLines(defPath); for (int i = 1; i < csv.Length; i++) { var lineSplit = csv[i].Split(','); unitList.Add(new BuildingUnit(lineSplit[0], lineSplit[1], Convert.ToDouble(lineSplit[2]), Convert.ToDouble(lineSplit[3]), Convert.ToDouble(lineSplit[4]), Convert.ToDouble(lineSplit[5]))); } BuildingUnitMix desiredUnitMix = new BuildingUnitMix(); csv = File.ReadAllLines(mixPath); for (int i = 1; i < csv.Length; i++) { var lineSplit = csv[i].Split(','); desiredUnitMix.Add(lineSplit[0], Convert.ToDouble(lineSplit[2])); } var corridors = new List <Corridor>(); var mainCorridorObject = new MainCorridor(); var location = CorridorLocation.Main; var corridorLineList = new List <UnitsLine>(); var leftLegObject = new Corridor(); if (leftLeg.Length > unitDepth + hallWidth / 2) { var leftLine2D = CreateLine2D(leftLeg); location = CorridorLocation.LeftLeg; leftLegObject = new Corridor(leftLine2D, unitDepth, hallWidth, location); corridorLineList.AddRange(leftLegObject.GetLines()); } var midLegObject = new Corridor(); if (middleLeg.Length > unitDepth + hallWidth / 2) { var midLine2D = CreateLine2D(middleLeg); location = CorridorLocation.MiddleLeg; midLegObject = new Corridor(midLine2D, unitDepth, hallWidth, location); corridorLineList.AddRange(midLegObject.GetLines()); } var rightLegObject = new Corridor(); if (rightLeg.Length > unitDepth + hallWidth / 2) { var rightLine2D = CreateLine2D(rightLeg); location = CorridorLocation.RightLeg; rightLegObject = new Corridor(rightLine2D, unitDepth, hallWidth, location); corridorLineList.AddRange(rightLegObject.GetLines()); } var mainLine2D = CreateLine2D(mainCorridor); location = CorridorLocation.Main; mainCorridorObject.CenterLine = mainLine2D; mainCorridorObject.UnitDepth = unitDepth; mainCorridorObject.HallWidth = hallWidth; mainCorridorObject.CorridorLocation = location; mainCorridorObject.LeftLeg = leftLegObject; mainCorridorObject.MiddleLeg = midLegObject; mainCorridorObject.RightLeg = rightLegObject; mainCorridorObject.CalculateMainLines(); var currentPercentage = new BuildingUnitMix(); foreach (var kvp in desiredUnitMix) { currentPercentage.Add(kvp.Key, 0); } corridorLineList.AddRange(mainCorridorObject.GetLines()); corridorLineList.OrderBy(x => x.Line.Length); double usedLength = 0; var unitPriority = new List <string>() { "C", "B", "A", "S" }; var totalUnitList = new List <Tuple <string, double> >(); polyUnits = new List <PolylineCurve>(); unitNames = new List <string>(); shearWallLines = new List <Line>(); foreach (var corridorLine in corridorLineList) { var corridorLength = corridorLine.Line.Length; var units = FittingAlgorithm.CreateUnitLine(unitList, desiredUnitMix, corridorLength, ref currentPercentage, unitPriority, ref totalUnitList, ref usedLength); var buildingUnits = new List <BuildingUnit>(); double startLength = 0; var lineVector = corridorLine.Line.Direction; var angle = new Vector2D(1, 0).SignedAngleTo(lineVector); foreach (var unit in units) { var matchingUnit = unitList.Single(x => (x.Type == unit.Item1 && x.Width == unit.Item2)); matchingUnit.Rotation = angle; matchingUnit.Location = corridorLine.Line.StartPoint + startLength * lineVector; var unitPolygon = matchingUnit.GetPolygon(); var unitWallLines = matchingUnit.GetShearWallLines(); foreach (var unitLine in unitWallLines) { shearWallLines.Add(new Line(new Point3d(unitLine.StartPoint.X, unitLine.StartPoint.Y, 0), new Point3d(unitLine.EndPoint.X, unitLine.EndPoint.Y, 0))); } var unitPoints = unitPolygon.ToPolyLine2D().Vertices; var point3dList = new List <Point3d>(); foreach (var vertex in unitPoints) { point3dList.Add(new Point3d(vertex.X, vertex.Y, 0)); } var unitPolyline = new PolylineCurve(point3dList); polyUnits.Add(unitPolyline); unitNames.Add(matchingUnit.Type); buildingUnits.Add(matchingUnit); startLength += matchingUnit.Width; } corridorLine.BuildingUnits = buildingUnits; } lineList = new List <Line>(); foreach (var corridorLine in corridorLineList) { lineList.Add(new Line(new Point3d(corridorLine.Line.StartPoint.X, corridorLine.Line.StartPoint.Y, 0), new Point3d(corridorLine.Line.EndPoint.X, corridorLine.Line.EndPoint.Y, 0))); } var finalPoints = FittingAlgorithm.GetOutlinePoints(unitDepth, hallWidth, mainCorridorObject); var boundaryPointList = new List <Point3d>(); foreach (var point in finalPoints) { boundaryPointList.Add(new Point3d(point.X, point.Y, 0)); } var planBoundary = new PolylineCurve(boundaryPointList); boundary = planBoundary; var percentMixFinal = new List <double> { }; foreach (var buildingMix in currentPercentage) { percentMixFinal.Add(buildingMix.Value); } percentMix = percentMixFinal; }
public static IEnumerable <NXOpen.Line> ToNXLines(this PolylineCurve value) => ToNXLines(value, UnitConverter.RhinoToNXUnitsRatio);
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { var gc = new GetObject(); gc.SetCommandPrompt("Select some FANCY curves"); gc.GeometryFilter = ObjectType.Curve; gc.GetMultiple(1, 0); if (gc.CommandResult() != Result.Success) { return(gc.CommandResult()); } int linecount = 0; int arccount = 0; int circlecount = 0; int polylinecount = 0; //create a collection of curves // var curves = new List<Curve>(gc.ObjectCount); OR var curves = new CurveList(); for (var i = 0; i < gc.ObjectCount; i++) { var curve = gc.Object(i).Curve(); if (null != curve) { curves.Add(curve); } // ADD THE CURVE TO THE CURVES LIST, expanding dynamically through the loop LineCurve line_curve = curve as LineCurve; //check if curve is a line, 'as' is simplest form of casting if (line_curve != null) // so long as the selection is not null, the our curve is a line { linecount++; // then we can increase our linecount } PolylineCurve polyline_curve = curve as PolylineCurve; if (polyline_curve != null) { polylinecount++; } ArcCurve arc_curve = curve as ArcCurve; if (arc_curve != null) { if (arc_curve.IsCircle()) { circlecount++; } else { arccount++; } } curve.Domain = new Interval(0, 1); //this will force all curves to have the Domain from 0 to 1 doc.Objects.AddPoint(curve.PointAtStart); doc.Objects.AddPoint(curve.PointAtEnd); doc.Objects.AddPoint(curve.PointAt(0.75)); //add points along the domain... var format = string.Format("F{0}", doc.DistanceDisplayPrecision); string crvinfo = string.Format("The curve {0} has the length {1} and domain: {2} to {3}. Degree {4}. Points at 0,0.75 and 1 of domain.", i, curve.GetLength().ToString(format), curve.Domain.T0.ToString(format), curve.Domain.T1.ToString(format), curve.Degree.ToString(format)); RhinoApp.WriteLine(crvinfo); } doc.Views.Redraw(); string s = string.Format("{0} line(s), {1} polyline(s), {2} circle(s), {3} arc(s) and {4} curve(s) selected in total", linecount.ToString(), polylinecount.ToString(), circlecount.ToString(), arccount.ToString(), curves.Count.ToString()); RhinoApp.WriteLine(s); return(Result.Success); }
private Curve DrawCurvedRamp(Curve road, Vector3d axis, int onStart, RampScale scale, double beforeRamp, double offset) { Point3d start; Vector3d vx; Vector3d vy; if (axis == Vector3d.Unset) { axis = Vector3d.XAxis; } double afterRamp = 10000 - beforeRamp; Vector3d axisPerp = new Vector3d(axis); axisPerp.Rotate(-Math.PI / 2, Vector3d.ZAxis); Vector3d roadv = road.TangentAtStart; double angleRoadAxis = Vector3d.VectorAngle(roadv, axis, Plane.WorldXY); if (angleRoadAxis < Math.PI * 0.25 || angleRoadAxis > Math.PI * 1.75 || (angleRoadAxis < Math.PI * 1.25 && angleRoadAxis > Math.PI * 0.75)) { //selectperpvector vy = axisPerp; } else { //selectoriginvector vy = axis; } Point3d testPoint = road.PointAtNormalizedLength(0.5); Vector3d dirInside = new Vector3d(roadv); dirInside.Rotate(-Math.PI / 2, Vector3d.ZAxis); Point3d testPointInside = testPoint + dirInside; Point3d testPointY = testPoint + vy; Curve testLine = new LineCurve(testPointInside, testPointY); var testI = Rhino.Geometry.Intersect.Intersection.CurveCurve(testLine, road, 0, 0); if (testI.Count != 0) { vy.Reverse(); } //true if (onStart == 0) { vx = new Vector3d(vy); vx.Rotate(Math.PI / 2, Vector3d.ZAxis); //vx = axis;//road.TangentAtStart; //if (vx == Vector3d.Unset) // vx = road.TangentAtStart; //vy = new Vector3d(vx); //vy.Rotate(-Math.PI / 2, Vector3d.ZAxis); start = road.PointAtStart + vx * (800 + offset); start = start + vy * 1000; } //false else { vx = new Vector3d(vy); vx.Rotate(-Math.PI / 2, Vector3d.ZAxis); //vx = -axis;// - road.TangentAtStart; //if (vx == -Vector3d.Unset) // vx = -road.TangentAtStart; //vy = new Vector3d(vx); //vy.Rotate(Math.PI / 2, Vector3d.ZAxis); start = road.PointAtEnd + vx * (800 + offset); start = start + vy * 1000; } Point3d second = start + vx * UnderGroundParkingConsts.CurveRampWidth[(int)scale]; Point3d third = second + vy * beforeRamp;//(20000 + UnderGroundParkingConsts.WithinRadius[(int)scale]); double innerArcR = UnderGroundParkingConsts.WithinRadius[(int)scale]; double outerArcR = UnderGroundParkingConsts.WithinRadius[(int)scale] + UnderGroundParkingConsts.CurveRampWidth[(int)scale]; Point3d forth = third + vy * innerArcR + vx * innerArcR; // third - vx * UnderGroundParkingConsts.LinearRampWidth[(int)scale]; Point3d fifth = forth + vx * afterRamp; Point3d sixth = fifth + vy * UnderGroundParkingConsts.CurveRampWidth[(int)scale]; Point3d seventh = sixth - vx * afterRamp; Point3d eighth = seventh - vx * outerArcR - vy * outerArcR; Point3d ninth = start; //polyline1 PolylineCurve plc1 = new PolylineCurve(new Point3d[] { start, second, third }); ArcCurve arc1 = new ArcCurve(new Arc(third, vy, forth)); PolylineCurve plc2 = new PolylineCurve(new Point3d[] { forth, fifth, sixth, seventh }); ArcCurve arc2 = new ArcCurve(new Arc(seventh, -vx, eighth)); PolylineCurve plc3 = new PolylineCurve(new Point3d[] { eighth, ninth }); Curve[] curvesToJoin = new Curve[] { plc1, arc1, plc2, arc2, plc3 }; //Rhino.RhinoDoc.ActiveDoc.Objects.Add(Curve.JoinCurves(curvesToJoin)[0]); var joined = Curve.JoinCurves(curvesToJoin); if (joined.Length > 0) { return(joined[0]); } else { return(null); } //return plc; }
public static Dictionary <OSMTag, List <Brep> > BuildingBrepsFromCoords(ref RequestHandler result, bool outputHeighted) { var geometryResult = new Dictionary <OSMTag, List <Brep> >(); var unitScale = RhinoMath.UnitScale(UnitSystem.Meters, RhinoDoc.ActiveDoc.ModelUnitSystem); // OSM conversion assumes meters var tolerance = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; Coord lengthPerDegree = GetDegreesPerAxis(result.MinBounds, result.MaxBounds, unitScale); foreach (var entry in result.FoundData) { geometryResult[entry.Key] = new List <Brep>(); for (int i = entry.Value.Count - 1; i >= 0; i--) { var outlinePoints = new List <Point3d>(); foreach (var coord in entry.Value[i].Coords) { outlinePoints.Add(GetPointFromLatLong(coord, lengthPerDegree, result.MinBounds)); } var outline = new PolylineCurve(outlinePoints); // Creating a polylinecurve from scratch makes invalid geometry if (!outline.IsClosed) { if (outline.IsClosable(ALLOWABLE_CLOSURE)) // Force-close the curve { outline.MakeClosed(ALLOWABLE_CLOSURE); } else // Skip this curve as no valid Brep can be made { entry.Value.RemoveAt(i); continue; } } var height = GetBuildingHeights.ParseHeight(entry.Value[i].Tags, unitScale); if (outputHeighted && height > 0.0) // Output heighted buildings { var toHeight = new Vector3d(0, 0, height); var envelope = Surface.CreateExtrusion(outline, toHeight); var floor = Brep.CreatePlanarBreps(outline, tolerance); outline.Translate(toHeight); var roof = Brep.CreatePlanarBreps(outline, tolerance); var volume = Brep.JoinBreps(new Brep[] { floor[0], envelope.ToBrep(), roof[0] }, tolerance); geometryResult[entry.Key].Add(volume[0]); } else if (!outputHeighted && height == 0.0) // Output unheighted buildings { var builtSurface = Brep.CreatePlanarBreps(outline, tolerance); if (builtSurface != null && builtSurface.Length > 0) { geometryResult[entry.Key].Add(builtSurface[0]); } } else // Item wasn't matched, so should be removed from result so its metadata is not output { entry.Value.RemoveAt(i); } } geometryResult[entry.Key].Reverse(); // We iterated in reverse order, so swap list back to right direction } return(geometryResult); }
public String findLeastDimension(List <RhinoObject> newObjs, Plane plane, String perimeterName, double rotationAngle) { RhinoDoc doc = RhinoDoc.ActiveDoc; double minX = 0; double minY = 0; double minArea = double.MaxValue; Layer layerIndex = doc.Layers.FindName("Default"); RhinoUtilities.SetActiveLayer("temp", System.Drawing.Color.Black); //Copy Objects of current layer to temp layer foreach (var selected_object in newObjs) { selected_object.Attributes.LayerIndex = doc.Layers.Find("temp", false); selected_object.CommitChanges(); } //select objects in the temporart layer and join RhinoApp.RunScript("SelNone", true); RhinoApp.RunScript("SelLayerNumber " + doc.Layers.Find("temp", true), false); //MetrixUtilities.joinCurves(doc.Layers.Find("temp", false)); //plane.Rotate(i, plane.XAxis); //rotateshape with the value of i RhinoObject[] objs = doc.Objects.FindByLayer("temp"); List <Curve> curveList = new List <Curve>(); Curve[] curveArray = null; RhinoObject obj = objs[0]; foreach (RhinoObject objt in objs) { curveList.Add(new ObjRef(objt).Curve()); } curveArray = Curve.JoinCurves(curveList); obj.Attributes.ToString(); ObjRef objR = new ObjRef(obj); Curve curve = objR.Curve(); double curvelength = -1; Curve baseline = null; double angle = 0; foreach (Curve cv in curveList) { if (cv.GetLength() > curvelength) { curvelength = cv.GetLength(); baseline = cv; angle = Math.Atan(baseline.TangentAtStart.Y / baseline.TangentAtStart.X); } } if (curveArray != null) { double maxArea = Double.MinValue; foreach (Curve tempCurve in curveArray) { BoundingBox tempBBox = tempCurve.GetBoundingBox(true); if (tempBBox.Area > maxArea) { curve = tempCurve; } } } BoundingBox boundingBox = curve.GetBoundingBox(Plane.WorldXY); List <Point3d> points = new List <Point3d>(); PolylineCurve polyline_curve = curve as PolylineCurve; double diagnal = 0; bool rectangle = false; Point3d centerC = boundingBox.Center; minArea = boundingBox.Area; minX = boundingBox.Max.X - boundingBox.Min.X; minY = boundingBox.Max.Y - boundingBox.Min.Y; /* * if (polyline_curve != null && polyline_curve.PointCount == 5) * { * for (int j = 0; j < polyline_curve.PointCount; j++) * { * points.Add(polyline_curve.Point(j)); * } * * if(Math.Round(points[0].DistanceTo(points[1])) == Math.Round(points[2].DistanceTo(points[3]))) * { * minX = points[0].DistanceTo(points[1]); * minY = points[1].DistanceTo(points[2]); * rectangle = true; * } * else * { * rectangle = false; * } * }*/ if (rectangle == false) { curve.Rotate(-angle, Plane.WorldXY.ZAxis, baseline.PointAtStart); boundingBox = curve.GetBoundingBox(Plane.WorldXY); if (boundingBox.Area < minArea) { Point3d min = boundingBox.Min; Point3d max = boundingBox.Max; minX = max.X - min.X; minY = max.Y - min.Y; } } RhinoApp.RunScript("-_Rotate " + centerC + " " + rotationAngle, false); //RhinoApp.RunScript("-_Rotate " + boundingBox.Center +" " + 5, false); //Set back the previous default layer RhinoUtilities.SetActiveLayer(perimeterName, System.Drawing.Color.Black); //Copy all object of temp layer back to the previous layer foreach (var selected_object in doc.Objects.FindByLayer("temp")) { selected_object.Attributes.LayerIndex = doc.Layers.FindByFullPath(perimeterName, false); selected_object.CommitChanges(); } doc.Layers.SetCurrentLayerIndex(doc.Layers.FindByFullPath(layerIndex.Name, false), true); //needs to fix the tab issue return(String.Format("{0}#{1}", Math.Max(minX, minY), Math.Min(minX, minY))); //return the minX and minY for the panel }
public Curve DrawCrossSection() { PolylineCurve poly = this.ToPolylines()[0]; return(poly); }
/// <summary> /// Generate a series of planes on the glulam cross-section. TODO: Re-implement as GlulamOrientation function /// </summary> /// <param name="N">Number of planes to extract.</param> /// <param name="extension">Extension of the centreline curve</param> /// <param name="frames">Output cross-section planes.</param> /// <param name="parameters">Output t-values along centreline curve.</param> /// <param name="interpolation">Type of interpolation to use (default is Linear).</param> public override void GenerateCrossSectionPlanes(int N, out Plane[] frames, out double[] parameters, GlulamData.Interpolation interpolation = GlulamData.Interpolation.LINEAR) { Curve curve = Centreline; double multiplier = RhinoMath.UnitScale(Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, UnitSystem.Millimeters); //PolylineCurve discrete = curve.ToPolyline(Glulam.Tolerance * 10, Glulam.AngleTolerance, 0.0, 0.0); PolylineCurve discrete = curve.ToPolyline(multiplier * Tolerance, AngleTolerance, multiplier * MininumSegmentLength, curve.GetLength() / MinimumNumSegments); if (discrete.TryGetPolyline(out Polyline discrete2)) { N = discrete2.Count; parameters = new double[N]; for (int i = 0; i < N; ++i) { curve.ClosestPoint(discrete2[i], out parameters[i]); } } else { parameters = curve.DivideByCount(N - 1, true).ToArray(); } //frames = parameters.Select(x => GetPlane(x)).ToArray(); //return; frames = new Plane[parameters.Length]; var vectors = Orientation.GetOrientations(curve, parameters); Plane temp; for (int i = 0; i < parameters.Length; ++i) { temp = Misc.PlaneFromNormalAndYAxis( curve.PointAt(parameters[i]), curve.TangentAt(parameters[i]), vectors[i]); if (temp.IsValid) { frames[i] = temp; } else { throw new Exception(string.Format("Plane is invalid: vector {0} tangent {1}", vectors[i], curve.TangentAt(parameters[i]))); } // TODO: Make back-up orientation direction in this case. } return; N = Math.Max(N, 2); frames = new Plane[N]; Curve CL; double extension = 0; if (Centreline.IsClosed) { CL = Centreline.DuplicateCurve(); } else { CL = Centreline.Extend(CurveEnd.Both, extension, CurveExtensionStyle.Smooth); } parameters = CL.DivideByCount(N - 1, true); GlulamOrientation TempOrientation = Orientation.Duplicate(); TempOrientation.Remap(Centreline, CL); for (int i = 0; i < N; ++i) { Vector3d v = TempOrientation.GetOrientation(CL, parameters[i]); frames[i] = tas.Core.Util.Misc.PlaneFromNormalAndYAxis(CL.PointAt(parameters[i]), CL.TangentAt(parameters[i]), v); } return; /* * double[] ft = new double[Frames.Count]; * double[] fa = new double[Frames.Count]; * * Plane temp; * for (int i = 0; i < Frames.Count; ++i) * { * CL.PerpendicularFrameAt(Frames[i].Item1, out temp); * ft[i] = Frames[i].Item1; * //fa[i] = Math.Acos(temp.YAxis * Frames[i].Item2.YAxis); * fa[i] = Vector3d.VectorAngle(temp.YAxis, Frames[i].Item2.YAxis, Frames[i].Item2); * } * * for (int i = 1; i < fa.Length; ++i) * { * if (fa[i] - fa[i - 1] > Math.PI) * fa[i] -= Constants.Tau; * else if (fa[i] - fa[i - 1] < -Math.PI) * fa[i] += Constants.Tau; * } * * int res; * int max = ft.Length - 1; * double mu; * * double[] angles = new double[N]; * * if (Frames.Count < 3) * interpolation = GlulamData.Interpolation.LINEAR; * * switch (interpolation) * { * case (GlulamData.Interpolation.HERMITE): // Hermite Interpolation * for (int i = 0; i < N; ++i) * { * if (t[i] < ft[0]) * { * angles[i] = fa[0]; * continue; * } * else if (t[i] > ft.Last()) * { * angles[i] = fa.Last(); * continue; * } * * res = Array.BinarySearch(ft, t[i]); * if (res < 0) * { * res = ~res; * res--; * } * * if (res == 0 && res < max - 1) * { * mu = (t[i] - ft[0]) / (ft[1] - ft[0]); * angles[i] = Interpolation.HermiteInterpolate(fa[0], fa[0], fa[1], fa[2], mu, 0, 0); * } * else if (res > 0 && res < max - 1) * { * mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]); * angles[i] = Interpolation.HermiteInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 2], mu, 0, 0); * * } * else if (res > 0 && res < max) * { * mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]); * angles[i] = Interpolation.HermiteInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 1], mu, 0, 0); * } * else if (res == max) * { * angles[i] = fa[res]; * } * * else * continue; * } * break; * * case (GlulamData.Interpolation.CUBIC): // Cubic Interpolation * for (int i = 0; i < N; ++i) * { * if (t[i] <= ft[0]) * { * angles[i] = fa[0]; * continue; * } * else if (t[i] >= ft.Last()) * { * angles[i] = fa.Last(); * continue; * } * * res = Array.BinarySearch(ft, t[i]); * if (res < 0) * { * res = ~res; * res--; * } * * if (res == 0 && res < max - 1) * { * mu = (t[i] - ft[0]) / (ft[1] - ft[0]); * angles[i] = Interpolation.CubicInterpolate(fa[0], fa[0], fa[1], fa[2], mu); * } * else if (res > 0 && res < max - 1) * { * mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]); * angles[i] = Interpolation.CubicInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 2], mu); * * } * else if (res > 0 && res < max) * { * mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]); * angles[i] = Interpolation.CubicInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 1], mu); * } * else if (res == max) * { * angles[i] = fa[res]; * } * * else * continue; * } * break; * * default: // Default linear interpolation * for (int i = 0; i < N; ++i) * { * res = Array.BinarySearch(ft, t[i]); * if (res < 0) * { * res = ~res; * res--; * } * if (res >= 0 && res < max) * { * if (ft[res + 1] - ft[res] == 0) * mu = 0.5; * else * mu = Math.Min(1.0, Math.Max(0, (t[i] - ft[res]) / (ft[res + 1] - ft[res]))); * angles[i] = Interpolation.Lerp(fa[res], fa[res + 1], mu); * } * else if (res < 0) * angles[i] = fa[0]; * else if (res >= max) * angles[i] = fa[max]; * } * break; * } * * for (int i = 0; i < N; ++i) * { * CL.PerpendicularFrameAt(t[i], out temp); * temp.Transform(Rhino.Geometry.Transform.Rotation(angles[i], temp.ZAxis, temp.Origin)); * planes[i] = temp; * } */ }
public Curve DrawCrossSection(Plane plane) { PolylineCurve poly = this.ToPolylines(plane)[0]; return(poly); }
public static IEnumerable <DB.Curve> ToCurveMany(this PolylineCurve value) => value.ToCurveMany(UnitConverter.ToHostUnits);
/// <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 iterations = 3; List <Point3d> iPoints = new List <Point3d>(); GridVectors = new List <Vector3d>(); roadDensity = 0; double blockWidth = 0; List <Curve> outputCurves = new List <Curve>(); pointCloudStructureList = new List <PointCloudStructure>(); DA.GetDataList(0, iPoints); DA.GetDataList(1, GridVectors); DA.GetData(2, ref GridFirstPoint); DA.GetData(3, ref GridLastPoint); DA.GetData(4, ref boundary); DA.GetData(5, ref roadDensity); DA.GetData(6, ref angle); DA.GetData(7, ref iterations); DA.GetData(8, ref step); // step = blockWidth; // roadDensity = step - 10; gridRes = (int)Math.Sqrt(GridVectors.Count) - 1; pointCloud = new Point3dList(); int sign = 1; Vector3d prevTensor = new Vector3d(0, 1, 0); Point3d nextPt = new Point3d(); Vector3d nextTensor = new Vector3d(); List <Point3d> currPointList = new List <Point3d>(); List <Point3d> prevPointList = new List <Point3d>(); for (int i = 0; i < 1; i++) {///////////////////////////////////////////////////// List <Curve> currCurves = new List <Curve>(); for (int j = 0; j < iPoints.Count; j++) // J ======= iPoints { sign = 1; currPointList.Clear(); prevPointList.Clear(); for (int k = 0; k < 2; k++) { prevPointList = new List <Point3d>(currPointList); currPointList.Clear(); // prevTensor = new Vector3d((i + 1) % 2, (i) % 2, 0); prevTensor = new Vector3d(0, 0, 0); if (GetTensor(iPoints[j], prevTensor) != Vector3d.Unset) { nextPt = iPoints[j] + sign * GetTensor(iPoints[j], prevTensor); currPointList.Add(iPoints[j]); prevTensor = GetTensor(iPoints[j], prevTensor); } int f = 0; while (CheckPt(nextPt) && f < 40) { currPointList.Add(nextPt); pointCloudStructureList.Add(new PointCloudStructure(nextPt, currPointList.Count - 1)); nextTensor = GetTensor(currPointList[currPointList.Count - 1], prevTensor); nextPt = currPointList[currPointList.Count - 1] + sign * nextTensor; f++; prevTensor = nextTensor; } if (pointCloud.Count > 0) { Point3d pt = pointCloud[pointCloud.ClosestIndex(nextPt)]; // if ((pt.DistanceTo(nextPt) <= roadDensity) && f > 0) currPointList.Add(pt); } outputCurves.Add(new PolylineCurve(currPointList)); currCurves.Add(new PolylineCurve(currPointList)); sign = -1; } pointCloud.AddRange(currPointList); pointCloud.AddRange(prevPointList); } /* iPoints.Clear(); * * foreach (PolylineCurve curve in currCurves) * { * if (curve != null && curve.GetLength() > 0.1) * { * // if (curve.DivideEquidistant(blockWidth) != null) * // iPoints.AddRange(new List<Point3d>(curve.DivideEquidistant(blockWidth))); * List<Point3d> points = new List<Point3d>(); * for (int q = 0; q < curve.PointCount; q++) * points.Add(curve.Point(q)); * iPoints.AddRange(points); * } * } */ angle += 90; }////////////////////////////////////////////// Point3dList tempList1 = pointCloud; pointCloud.Clear(); for (int i = 0; i < 1; i++) {///////////////////////////////////////////////////// List <Curve> currCurves = new List <Curve>(); for (int j = 0; j < iPoints.Count; j++) // J ======= iPoints { sign = 1; currPointList.Clear(); prevPointList.Clear(); for (int k = 0; k < 2; k++) { prevPointList = new List <Point3d>(currPointList); currPointList.Clear(); // prevTensor = new Vector3d((i + 1) % 2, (i) % 2, 0); prevTensor = new Vector3d(0, 0, 0); if (GetTensor(iPoints[j], prevTensor) != Vector3d.Unset) { nextPt = iPoints[j] + sign * GetTensor(iPoints[j], prevTensor); currPointList.Add(iPoints[j]); prevTensor = GetTensor(iPoints[j], prevTensor); } int f = 0; while (CheckPt(nextPt) && f < 40) { currPointList.Add(nextPt); pointCloudStructureList.Add(new PointCloudStructure(nextPt, currPointList.Count - 1)); nextTensor = GetTensor(currPointList[currPointList.Count - 1], prevTensor); nextPt = currPointList[currPointList.Count - 1] + sign * nextTensor; f++; prevTensor = nextTensor; } if (pointCloud.Count > 0) { Point3d pt = pointCloud[pointCloud.ClosestIndex(nextPt)]; // if ((pt.DistanceTo(nextPt) <= roadDensity) && f > 0) currPointList.Add(pt); } outputCurves.Add(new PolylineCurve(currPointList)); currCurves.Add(new PolylineCurve(currPointList)); sign = -1; } pointCloud.AddRange(currPointList); pointCloud.AddRange(prevPointList); } iPoints.Clear(); foreach (PolylineCurve curve in currCurves) { if (curve != null && curve.GetLength() > 0.1) { // if (curve.DivideEquidistant(blockWidth) != null) // iPoints.AddRange(new List<Point3d>(curve.DivideEquidistant(blockWidth))); List <Point3d> points = new List <Point3d>(); for (int q = 0; q < curve.PointCount; q++) { points.Add(curve.Point(q)); } iPoints.AddRange(points); } } angle += 90; }////////////////////////////////////////////// Point3dList tempList2 = pointCloud; pointCloud.Clear(); pointCloud.AddRange(tempList1); pointCloud.AddRange(tempList2); for (int i = 0; i < 2; i++) {///////////////////////////////////////////////////// List <Curve> currCurves = new List <Curve>(); for (int j = 0; j < iPoints.Count; j++) // J ======= iPoints { sign = 1; currPointList.Clear(); prevPointList.Clear(); for (int k = 0; k < 2; k++) { prevPointList = new List <Point3d>(currPointList); currPointList.Clear(); // prevTensor = new Vector3d((i + 1) % 2, (i) % 2, 0); prevTensor = new Vector3d(0, 0, 0); if (GetTensor(iPoints[j], prevTensor) != Vector3d.Unset) { nextPt = iPoints[j] + sign * GetTensor(iPoints[j], prevTensor); currPointList.Add(iPoints[j]); prevTensor = GetTensor(iPoints[j], prevTensor); } int f = 0; while (CheckPt(nextPt) && f < 40) { currPointList.Add(nextPt); pointCloudStructureList.Add(new PointCloudStructure(nextPt, currPointList.Count - 1)); nextTensor = GetTensor(currPointList[currPointList.Count - 1], prevTensor); nextPt = currPointList[currPointList.Count - 1] + sign * nextTensor; f++; prevTensor = nextTensor; } if (pointCloud.Count > 0) { Point3d pt = pointCloud[pointCloud.ClosestIndex(nextPt)]; // if ((pt.DistanceTo(nextPt) <= roadDensity) && f > 0) currPointList.Add(pt); } outputCurves.Add(new PolylineCurve(currPointList)); currCurves.Add(new PolylineCurve(currPointList)); sign = -1; } // pointCloud.AddRange(currPointList); //pointCloud.AddRange(prevPointList); } iPoints.Clear(); PolylineCurve curve = currCurves[0] as PolylineCurve; //foreach (PolylineCurve curve in currCurves) // { if (curve != null && curve.GetLength() > 0.1) { // if (curve.DivideEquidistant(blockWidth) != null) // iPoints.AddRange(new List<Point3d>(curve.DivideEquidistant(blockWidth))); List <Point3d> points = new List <Point3d>(); for (int q = 0; q < curve.PointCount; q++) { points.Add(curve.Point(q)); } iPoints.AddRange(points); } // } angle += 90; }////////////////////////////////////////////// DA.SetDataList(0, outputCurves); }
/// <summary> /// Finds the intersection of a mesh and a polyline. /// </summary> /// <param name="mesh">A mesh to intersect.</param> /// <param name="curve">A polyline curves to intersect.</param> /// <param name="faceIds">The indices of the intersecting faces. This out reference is assigned during the call.</param> /// <returns>An array of points: one for each face that was passed by the faceIds out reference.</returns> public static Point3d[] MeshPolyline(Mesh mesh, PolylineCurve curve, out int[] faceIds) { faceIds = null; IntPtr pConstMesh = mesh.ConstPointer(); IntPtr pConstCurve = curve.ConstPointer(); int count = 0; IntPtr rc = UnsafeNativeMethods.ON_Intersect_MeshPolyline1(pConstMesh, pConstCurve, ref count); if (0 == count || IntPtr.Zero == rc) return new Point3d[0]; Point3d[] points = new Point3d[count]; faceIds = new int[count]; UnsafeNativeMethods.ON_Intersect_MeshPolyline_Fill(rc, count, points, faceIds); return points; }
/// <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) { var X2D = new double[2][] { new double[2] { 0, 1 }, new double[2] { 0, 1 } }; X2D = new double[2][] { new double[3] { 0, 0.25, 1 }, new double[3] { 0, 0.5, 1 } }; //var Z2D = new double[9] { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; var Z2D = new double[9] { 1, 2, 3, 4, 2, -3, 1, 2, 3 }; //var Z2D = new double[4] { 1, 2, 3, 4 }; //Z2D = new double[6] { 1, 2, 3, 1, 2, 3 }; Z = Z2D; grid = new Grid(X2D); gp = new IvyCore.Parametric.Point(grid); Zpts = this.ConstructFieldView(grid, Z); var p = new Point3d(); DA.GetData(0, ref p); int n = Math.Min(gp.Dim, 3); for (int i = 0; i < n; i++) { gp[i] = p[i]; } int cellIndex = gp.CellIndex(); var cell = gp.Grid.Cells[cellIndex]; Interpolant interp = cell.GetInterpolant(gp); double zlerp = interp.Lerp(Z); //for (int i = 0; i < LERP.Length; i++) //{ // int index = cell.VerticesIndex[i]; // zlerp += LERP[i] * Z[index]; //} var cellPts = new Point3d[5]; double[] node; node = grid.Nodes[cell.VerticesIndex[0]].Coord; cellPts[0] = new Point3d(node[0], node[1], 0); node = grid.Nodes[cell.VerticesIndex[1]].Coord; cellPts[1] = new Point3d(node[0], node[1], 0); node = grid.Nodes[cell.VerticesIndex[3]].Coord; cellPts[2] = new Point3d(node[0], node[1], 0); node = grid.Nodes[cell.VerticesIndex[2]].Coord; cellPts[3] = new Point3d(node[0], node[1], 0); cellPts[4] = cellPts[0]; var contour = new PolylineCurve(cellPts); p.Z = zlerp; DA.SetData(0, p); DA.SetDataList(1, Zpts); DA.SetData(2, contour); DA.SetData(3, grid.Info()); }