// Rh Capture public Base PolylineToSpeckle(PolylineCurve poly, string units = null) { var u = units ?? ModelUnits; RH.Polyline polyline; if (poly.TryGetPolyline(out polyline)) { var intervalToSpeckle = IntervalToSpeckle(poly.Domain); if (polyline.Count == 2) { var polylineToSpeckle = new Line(PointsToFlatArray(polyline), u) { domain = intervalToSpeckle }; polylineToSpeckle.length = polyline.Length; var box = new RH.Box(poly.GetBoundingBox(true)); polylineToSpeckle.bbox = BoxToSpeckle(box, u); return(polylineToSpeckle); } var myPoly = new Polyline(PointsToFlatArray(polyline), u); myPoly.closed = polyline.IsClosed; if (myPoly.closed) { myPoly.value.RemoveRange(myPoly.value.Count - 3, 3); } myPoly.domain = intervalToSpeckle; myPoly.bbox = BoxToSpeckle(new RH.Box(poly.GetBoundingBox(true)), u); myPoly.length = poly.GetLength(); return(myPoly); } return(null); }
public static List <Mesh> DistanceAnalysis(List <Mesh> Analysis, int _SocialDistanceRadius, int Codensity) { if (_SocialDistanceRadius < 1) { _SocialDistanceRadius = 1; } if (Codensity < 1) { Codensity = 1; } Plane plane = Plane.WorldXY; List <Circle> test = new List <Circle>(); foreach (Mesh swMesh in Analysis) { List <LineCurve> boundaryList = new List <LineCurve>(); List <Point3d> boundaryPoints = new List <Point3d>(); Polyline[] meshboundary = swMesh.GetOutlines(plane); MeshVertexList vertexList = swMesh.Vertices; foreach (Polyline meshPline in meshboundary) { PolylineCurve boundary = new PolylineCurve(meshPline); Line[] boundarysegments = meshPline.GetSegments(); boundaryList.AddRange(from Line segment in boundarysegments select new LineCurve(segment)); Point3d[] points; if (boundary.GetLength(1.0) <= 100) { boundary.DivideByCount(4, false, out points); boundaryPoints.AddRange(from Point3d point in points select point); } else { boundary.DivideByLength(100.0, false, out points); boundaryPoints.AddRange(from Point3d point in points select point); } } PointCloud pointCloud = new PointCloud(boundaryPoints); int width = 2; int testRadii = (_SocialDistanceRadius * Codensity) + 100; for (int vertex = 0; vertex < vertexList.Count; vertex++) { Point3d v = vertexList.Point3dAt(vertex); int cP = pointCloud.ClosestPoint(v); Point3d point = pointCloud[cP].Location; int rvalue = 255; int intersectionCount = 0; while (intersectionCount <= 3 && width < testRadii) { Curve walkwidth = (new Circle(point, width)).ToNurbsCurve(); for (int i = 0; i < boundaryList.Count; i++) { if (Curve.PlanarCurveCollision(walkwidth, boundaryList[i], plane, 0.1)) { intersectionCount++; } } width++; } rvalue = intersectionCount >= 3 && ((width / _SocialDistanceRadius) / Codensity) * 255 < 255 ? ((width / _SocialDistanceRadius) / Codensity) * 255 : intersectionCount > 2 && ((width / _SocialDistanceRadius) / Codensity) * 255 >= 255 ? 255 : 255; if (width < testRadii) { } else { rvalue = 0; } swMesh.VertexColors.SetColor(vertex, System.Drawing.Color.FromArgb(rvalue, 70, 100)); } } return(Analysis); }
/// <summary> /// This method works on list-inputs and uses a special-case caching optimisation. As a result the looping logic is explicitly defined. /// </summary> protected override void SolveInstance(IGH_DataAccess DA) { var ptList = new List <GH_Point>(); var meshList = new List <GH_Mesh>(); var tolList = new List <GH_Number>(); var stepList = new List <GH_Integer>(); var flowDirList = new List <GH_Vector>(); if (!DA.GetDataList("Start Points", ptList)) { return; } if (!DA.GetDataList("Mesh", meshList)) { return; } if (!DA.GetDataList("Tolerance", tolList)) { return; } if (!DA.GetDataList("Maximum Steps", stepList)) { return; } if (!DA.GetDataList("Direction", flowDirList)) { return; } int len = Math.Max(Math.Max(Math.Max(ptList.Count, meshList.Count), Math.Max(tolList.Count, stepList.Count)), flowDirList.Count); GH_Curve[] polyFlows = new GH_Curve[len]; GH_Number[] polyLength = new GH_Number[len]; GH_Integer[] polySteps = new GH_Integer[len]; Mesh[,] tMeshCache = new Mesh[meshList.Count, flowDirList.Count]; if (ptList.Count == 0 || meshList.Count == 0 || tolList.Count == 0 || flowDirList.Count == 0 || stepList.Count == 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Empty List! Skipping branch."); DA.SetDataList("Curves", polyFlows); //Add empty nulls to preserve structure DA.SetDataList("Lengths", polyLength); DA.SetDataList("Steps", polySteps); return; } //Todo: Add special case for Many Pts -> 1 Mesh. This allows us to reuse the mesh transform w/o cache. if (ptList.Count > 1 && meshList.Count == 1 && tolList.Count == 1 && flowDirList.Count == 1 && stepList.Count <= ptList.Count) { if (MeshTolVecErrorCheck(meshList[0], tolList[0], flowDirList[0])) { Vector3d flowDir = flowDirList[0].Value; Mesh mesh = meshList[0].Value; double tol = tolList[0].Value; Transform xform = GetReorientation(flowDir); xform.TryGetInverse(out Transform inverseXform); Mesh tMesh = mesh.DuplicateMesh(); tMesh.Transform(xform); Parallel.For(0, ptList.Count, i => { int sidx = Math.Min(i, stepList.Count - 1); if (PointStepErrorCheck(ptList[i], stepList[sidx])) { Point3d pt = ptList[i].Value; //make accessible to steplist? pt.Transform(xform); int steps = stepList[sidx].Value; var polyList = MeshFlow(pt, tMesh, tol, steps); var poly = new PolylineCurve(polyList); poly.Transform(inverseXform); //why is this not polyFlows[i] = new GH_Curve(poly); polyLength[i] = new GH_Number(poly.GetLength()); polySteps[i] = new GH_Integer(polyList.Count); } }); } ///Do special case optimisation here -- no copies! } else { Parallel.For(0, len, i => { //Boilerplate indexing and error check int pidx = Math.Min(i, ptList.Count - 1); int midx = Math.Min(i, meshList.Count - 1); int tidx = Math.Min(i, tolList.Count - 1); int sidx = Math.Min(i, stepList.Count - 1); int fidx = Math.Min(i, flowDirList.Count - 1); if (FullErrorCheck(ptList[pidx], meshList[midx], tolList[tidx], stepList[sidx], flowDirList[fidx])) { Point3d pt = ptList[pidx].Value; Mesh mesh = meshList[midx].Value; double tol = tolList[tidx].Value; int steps = stepList[sidx].Value; Vector3d flowDir = flowDirList[fidx].Value; Transform xform = GetReorientation(flowDir); xform.TryGetInverse(out Transform inverseXform); //rotations are always invertible Mesh tMesh = new Mesh(); bool tryGetMesh = false; lock (tMeshCache) { //see if we haven't already done this one if (tMeshCache[midx, fidx] != null) { tMesh = tMeshCache[midx, fidx]; tryGetMesh = true; } } if (!tryGetMesh) { tMesh = mesh.DuplicateMesh(); tMesh.Transform(xform); lock (tMeshCache) //looks like we haven't, let's put it in { tMeshCache[midx, fidx] = tMesh; } } Point3d tPt = new Point3d(pt); tPt.Transform(xform); List <Point3d> polyList = MeshFlow(tPt, tMesh, tol, steps); PolylineCurve poly = new PolylineCurve(polyList); poly.Transform(inverseXform); polyFlows[i] = new GH_Curve(poly); polyLength[i] = new GH_Number(poly.GetLength()); polySteps[i] = new GH_Integer(polyList.Count); } }); } //Finish up solveInstance by actually outputting geometry! DA.SetDataList("Curves", polyFlows); DA.SetDataList("Lengths", polyLength); DA.SetDataList("Steps", polySteps); }
/// <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; 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); }