/// <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) { List <Line> lines = new List <Line>(); DA.GetDataList(0, lines); PointCloud cloud = new PointCloud(); List <IElement> elements = new List <IElement>(); List <ITopologicVertex> vertices = new List <ITopologicVertex>(); foreach (Line ln in lines) { Point3d p1 = ln.From; Point3d p2 = ln.To; int idx1 = cloud.ClosestPoint(p1); if (idx1 == -1) { cloud.Add(p1); idx1 = 1; vertices.Add(new ITopologicVertex(p1.X, p1.Y, p1.Z, idx1)); } else { if (p1.DistanceTo(cloud[idx1].Location) > 0.01) { cloud.Add(p1); idx1 = cloud.Count; vertices.Add(new ITopologicVertex(p1.X, p1.Y, p1.Z, idx1)); } else { idx1++; } } int idx2 = cloud.ClosestPoint(p2); if (p2.DistanceTo(cloud[idx2].Location) > 0.01) { cloud.Add(p2); idx2 = cloud.Count; vertices.Add(new ITopologicVertex(p2.X, p2.Y, p2.Z, idx2)); } else { idx2++; } elements.Add(new IBarElement(idx1, idx2)); } IMesh mesh = new IMesh(); mesh.AddRangeVertices(vertices); mesh.AddRangeElements(elements); mesh.BuildTopology(); DA.SetData(0, mesh); }
/// <summary> /// Uses CreateBrep then tries to match each vertex to a brepVertex in the PolySurface /// </summary> /// <returns></returns> public Brep CreateBrepMatched() { var cellBrep = CreateBrep(); var cellBPC = new PointCloud(cellBrep.Vertices.Select(x => x.Location)); foreach (var vert in Vertices) { var cellBrVertIndex = cellBPC.ClosestPoint(vert.Point); var dist = vert.Point.DistanceTo(cellBPC[cellBrVertIndex].Location); if (dist > Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) { cellBrep.Vertices.Add(vert.Point, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance); cellBrVertIndex = cellBrep.Vertices.Count - 1; //BakeErrorGeo(new List<GeometryBase> { cellBrep, new Point(vert.Point) }, new List<String> { $"cell_{Id}", $"vert_{vert.Id}" }); //throw new PolyFrameworkException($"Cannot match a CellBrep Vertex to Cell Vertex {vert.Id} for cell {Id}."); } cellBrep.Vertices[cellBrVertIndex].UserDictionary.Set("Id", vert.Id); } cellBrep.UserDictionary.Set("Id", Id); return(cellBrep); }
private static void closeIntersect(Curve innerBounderyCrv, PointCloud startPTsLeft, List <Parkingspace> finalParkingLinesLeft, Point3d crvEnd, out Curve lineOne, out CurveIntersections intersectionsOne) { int indexOne = startPTsLeft.ClosestPoint(crvEnd); lineOne = finalParkingLinesLeft[indexOne].Curves; Vector3d vectorone = lineOne.TangentAtEnd; vectorone.Rotate(RhinoMath.ToRadians(90), new Vector3d(0, 0, 1)); Point3d movedPTone = lineOne.PointAtStart + vectorone; vectorone.Rotate(RhinoMath.ToRadians(180), new Vector3d(0, 0, 1)); Point3d movedPTTwo = lineOne.PointAtStart + vectorone; PointCloud directionPT = new PointCloud(); directionPT.Add(movedPTone); directionPT.Add(movedPTTwo); int indexdir = directionPT.ClosestPoint(crvEnd); if (indexdir == 0) { vectorone.Rotate(RhinoMath.ToRadians(180), new Vector3d(0, 0, 1)); } vectorone = Vector3d.Multiply(vectorone, 10); intersectionsOne = Intersection.CurveCurve(innerBounderyCrv, new Line(lineOne.PointAtEnd, vectorone).ToNurbsCurve(), 0.01, 0.01); }
private SimpleGraph <Point3d> BuildGraph(List <Polyline> Polylines) { List <Polyline> .Enumerator enumerator = new List <Polyline> .Enumerator(); SimpleGraph <Point3d> simpleGraph = new SimpleGraph <Point3d>(null); PointCloud pointCloud = new PointCloud(); pointCloud.Add(Polylines[0][0]); simpleGraph.AddVertex(Polylines[0][0]); int num = 0; try { enumerator = Polylines.GetEnumerator(); while (enumerator.MoveNext()) { Polyline current = enumerator.Current; GraphEdge count = new GraphEdge(); int num1 = pointCloud.ClosestPoint(current[0]); Point3d location = pointCloud[num1].Location; double num2 = location.DistanceTo(current[0]); count.From = num1; if (num2 > Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) { pointCloud.Add(current[0]); simpleGraph.AddVertex(current[0]); count.From = checked (simpleGraph.Count - 1); } num1 = pointCloud.ClosestPoint(current[checked (current.Count - 1)]); count.To = num1; if (pointCloud[num1].Location.DistanceTo(current[checked (current.Count - 1)]) > Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) { pointCloud.Add(current[checked (current.Count - 1)]); simpleGraph.AddVertex(current[checked (current.Count - 1)]); count.To = checked (simpleGraph.Count - 1); } count.Orient(); this.SrtThick[count] = this.Thickness[num]; this.SrtFaces[count] = this.FacesCounts[num]; simpleGraph.Edges.Add(count); num = checked (num + 1); } } finally { ((IDisposable)enumerator).Dispose(); } return(simpleGraph); }
internal static int EvaluatePoint(PointCloud pts, Point3d p, double t) { int idx = pts.ClosestPoint(p); if (idx != -1 && p.DistanceTo(pts[idx].Location) > t) { idx = -1; } return(idx); }
static bool Exists(Point3d point, PointCloud pc) { int index = pc.ClosestPoint(point); if (index == -1) { return(false); } Point3d closest = pc[index].Location; return((closest - point).SquareLength < 0.0001); }
public static Point3d ClosestPoint(List <Point3d> C, Point3d P) { var pc = new PointCloud(C); var index = pc.ClosestPoint(P); if (index != -1) { return(C[index]); } else { return(Point3d.Unset); } }
public Tuple <int, int> ClosestCoords(Point3d point) { PointCloud pointCloud = new PointCloud(); for (int y = 0; y < yLen; y++) { for (int x = 0; x < xLen; x++) { pointCloud.Add(Points[x, y]); } } int i = pointCloud.ClosestPoint(point); return(Tuple.Create(i % xLen, i / xLen)); }
/// <summary> /// /// </summary> /// <param name="m"></param> /// <param name="pts"></param> /// <returns></returns> internal static List <double> GetDistanceField(Mesh m, List <Point3d> pts) { Point3d[] verts = m.Vertices.ToPoint3dArray(); PointCloud ptsc = new PointCloud(pts); double[] vals = new double[verts.Length]; Parallel.For(0, verts.Length, i => { Point3d v = verts[i]; int id = ptsc.ClosestPoint(v); double dist = (v - ptsc[id].Location).Length; vals[i] = dist; }); List <double> casted = vals.ToList <double>(); return(casted); }
private Curve splitend(Curve curve, PointCloud allStartPT, Point3d crvEnd) { //split ends of centerline int ptIndex = allStartPT.ClosestPoint(crvEnd); curve.ClosestPoint(allStartPT.PointAt(ptIndex), out double centerT); Curve[] splitCenterCurves = curve.Split(centerT); Curve splitCenter; if (splitCenterCurves[0].GetLength() < splitCenterCurves[1].GetLength()) { splitCenter = splitCenterCurves[1]; } else { splitCenter = splitCenterCurves[0]; } return(splitCenter); }
/// <summary> /// Culls the PFVertex duplicates based on their position in 3d space /// MAKE SURE TO REMOVE also the corresponding edges /// </summary> /// <param name="pottentialDuplicates"></param> /// <param name="tollerance"></param> /// <returns></returns> public static IList <PFVertex> RemoveDuplicates(IList <PFVertex> pottentialDuplicates, double tollerance) { PointCloud pc = new PointCloud(); List <PFVertex> singulars = new List <PFVertex>(); pc.Add(pottentialDuplicates[0].Point); singulars.Add(pottentialDuplicates[0]); for (int p = 1; p < pottentialDuplicates.Count; p++) { int closeIndex = pc.ClosestPoint(pottentialDuplicates[p].Point); if (pottentialDuplicates[p].Point.DistanceTo(pc[closeIndex].Location) > tollerance) { pc.Add(pottentialDuplicates[p].Point); singulars.Add(pottentialDuplicates[p]); } } return(singulars); }
void SetTypeClosest(IEnumerable <GeometryBase> attractors, double maxDistance) { var points = attractors.Where(a => a is Point).Select(p => (p as Point).Location); var curves = attractors.Where(a => a is Curve).Select(c => (c as Curve)); var pointCloud = new PointCloud(points); foreach (var voxel in GetVoxels().Where(v => v.IsActive)) { Point3d p = voxel.Location.Origin; var closestIndex = pointCloud.ClosestPoint(p); var closestPoint = pointCloud[closestIndex].Location; double minDistance = p.DistanceToSquared(closestPoint); foreach (var curve in curves) { if (curve.ClosestPoint(p, out double t, minDistance)) { minDistance = curve.PointAt(t).DistanceToSquared(p); } } var distance = Sqrt(minDistance); var param = distance / maxDistance; param = Rhino.RhinoMath.Clamp(param, 0.0, 1.0); var typeCount = _typesCount.Max(); var type = (int)(param * typeCount); if (type == typeCount) { type--; } voxel.AttractorDistance = param; voxel.Type = type; } }
protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> C_ = NGonsCore.Clipper.DataAccessHelper.FetchList <Curve>(DA, "Curves"); double T = NGonsCore.Clipper.DataAccessHelper.Fetch <double>(DA, "Tolerance"); List <Point3d> P = NGonsCore.Clipper.DataAccessHelper.FetchList <Point3d>(DA, "Points"); List <Curve> curves = new List <Curve>(); if (P.Count > 0) { for (int i = 0; i < C_.Count; i++) { Curve C = C_[i].DuplicateCurve(); PointCloud cloud = new PointCloud(P); double tol = (T == 0.0) ? C.GetLength() * 0.5 : T; Point3d p0 = cloud.PointAt(cloud.ClosestPoint(C.PointAtStart)); Point3d p1 = cloud.PointAt(cloud.ClosestPoint(C.PointAtEnd)); if (p0.DistanceTo(C.PointAtStart) < tol) { C.SetStartPoint(p0); } if (p1.DistanceTo(C.PointAtEnd) < tol) { C.SetEndPoint(p1); } curves.Add(C); } } else { PointCloud cloud = new PointCloud(); double tol = (T == 0.0) ? 0.01 : T; base.Message = tol.ToString(); //Add start and end point to pointcloud with incrementing nornal if point already exists for (int i = 0; i < C_.Count; i++) { if (i == 0) { cloud.Add(C_[i].PointAtStart, new Vector3d(0, 0, 1)); cloud.Add(C_[i].PointAtEnd, new Vector3d(0, 0, 1)); } else { int cp0 = cloud.ClosestPoint(C_[i].PointAtStart); bool flag0 = cloud.PointAt(cp0).DistanceToSquared(C_[i].PointAtStart) < tol; if (flag0) { cloud[cp0].Normal = new Vector3d(0, 0, cloud[cp0].Normal.Z + 1); } else { cloud.Add(C_[i].PointAtStart, new Vector3d(0, 0, 1)); } int cp1 = cloud.ClosestPoint(C_[i].PointAtEnd); bool flag1 = cloud.PointAt(cp1).DistanceToSquared(C_[i].PointAtEnd) < tol; if (flag1) { cloud[cp1].Normal = new Vector3d(0, 0, cloud[cp1].Normal.Z + 1); } else { cloud.Add(C_[i].PointAtEnd, new Vector3d(0, 0, 1)); } } }//for //List<Curve> curves = new List<Curve>(); for (int i = 0; i < C_.Count; i++) { //Print(cloud[cloud.ClosestPoint(C[i].PointAtStart)].Normal.Z.ToString() + " " + cloud[cloud.ClosestPoint(C[i].PointAtEnd)].Normal.Z.ToString()); int a = cloud.ClosestPoint(C_[i].PointAtStart); int b = cloud.ClosestPoint(C_[i].PointAtEnd); bool flag0 = cloud[a].Normal.Z != 1; bool flag1 = cloud[b].Normal.Z != 1; Curve c = C_[i].DuplicateCurve(); if (flag0) { c.SetStartPoint(cloud[a].Location); } if (flag1) { c.SetEndPoint(cloud[b].Location); } curves.Add(c); } } DA.SetDataList(0, curves); }
protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = DA.Fetch <Mesh>("Mesh"); string v = DA.Fetch <string>("Start"); List <int> o = DA.FetchList <int>("Sequence"); Curve sequenceCrv = DA.Fetch <Curve>("SequenceCrv"); List <Line> customVectors = DA.FetchList <Line>("CustomVectors"); double angleTol = DA.Fetch <double>("Angle"); v = Math.Min(Convert.ToInt32(v), mesh.Ngons.Count - 1).ToString(); if (mesh.Ngons.Count == o.Count) { mesh = mesh.ReoderMeshNgons(o); base.Message = "Sequence"; } else if (sequenceCrv != null) { if (sequenceCrv.IsValid) { mesh = mesh.ReoderMeshNgons(sequenceCrv); List <int> order = Enumerable.Range(0, mesh.Ngons.Count).ToList(); base.Message = "Sequence Curve"; } } else { var ve = NGonsCore.Graphs.UndirectedGraphBfsRhino.MeshBFS(mesh, v); List <int> order = ve.Item1[0]; mesh = mesh.ReoderMeshNgons(ve.Item1[0]); base.Message = "BFS"; DA.SetDataTree(0, GrasshopperUtil.IE2(ve.Item1)); DA.SetDataTree(1, GrasshopperUtil.IE3(ve.Item2)); } DA.SetData(4, mesh); List <int> order_ = Enumerable.Range(0, mesh.Ngons.Count).ToList(); DataTree <int> vertices_ = new DataTree <int>(order_); DataTree <int> edges_ = new DataTree <int>(); for (int i = 0; i < order_.Count - 1; i++) { edges_.Add(order_[i], new GH_Path(i)); edges_.Add(order_[i] + 1, new GH_Path(i)); } int S = mesh.Ngons.Count;//stop //Insertion vectors DataTree <int> N = SequenceNeighbours(mesh, order_, S); //FN = N; //O_ = O; //Edge Vectors int[][] tv = mesh.GetNGonsTopoBoundaries(); int[][] fe = mesh.GetNGonFacesEdges(tv); HashSet <int> e = mesh.GetAllNGonEdges(tv); Dictionary <int, int[]> efDict = mesh.GetFE(e, false); Polyline[] outlines = mesh.GetPolylines(); //Dictionary<int, Vector3d> edgeVectors = new Dictionary<int, Vector3d> (); DataTree <Vector3d> edgeVectors = new DataTree <Vector3d>(); List <Vector3d> faceVectors = new List <Vector3d>(); Dictionary <int, List <GH_Path> > faceEdgeID = new Dictionary <int, List <GH_Path> >(); for (int i = 0; (i < S && i < mesh.Ngons.Count); i++) { ///////////// // Properties ///////////// //Current path and face GH_Path p = new GH_Path(i); int f = order_[i];//O[i]; if (!N.PathExists(p)) { continue; //If no connectio nskip } HashSet <int> fadj = new HashSet <int>(N.Branch(p)); //adjacency list ///////////// // Solution ///////////// //Iterate mesh edges //Get connected faces //Check if they are in adjacency list //The order thoses ids List <int> NotOrderedEdges = new List <int>(); for (int j = 0; j < fe[f].Length; j++) { int[] facePair = efDict[fe[f][j]];//get face pair if (facePair.Length == 1) { continue; //if naked skip } if (fadj.Contains(facePair[0]) || fadj.Contains(facePair[1])) { NotOrderedEdges.Add(j); //if edge face are in fadj } } List <int> orderedEdges = SortIntegers(NotOrderedEdges, fe[f].Length); //Collect lines for Insertion Vector List <Line> el = new List <Line>(); //Line[] lines = outlines[f].GetSegments(); foreach (int j in orderedEdges) { el.Add(outlines[f].SegmentAt(j));//el.Add(M.TopologyEdges.EdgeLine(fe[f][j])); } //Create Insertion Vector Vector3d vec = NGonsCore.VectorUtil.BisectorVector(el, outlines[f].AverageNormal(), false); faceVectors.Add(vec); List <GH_Path> paths = new List <GH_Path>(); foreach (int j in orderedEdges) { //edgeVectors.Add(fe[f][j],vec); edgeVectors.Add(vec, new GH_Path(fe[f][j])); paths.Add(new GH_Path(fe[f][j])); } faceEdgeID.Add(i, paths); //Rhino.RhinoApp.WriteLine(i.ToString() + " " + paths.Count.ToString()); //A = el; //B = vec; //C = outlines[f].AverageNormal(); } DataTree <Vector3d> EV = mesh.insertionVectors(true); DataTree <Line> edges = new DataTree <Line>(); PointCloud cloud = new PointCloud(); //Check angles if vectors are not parallel to mesh edge foreach (GH_Path p in EV.Paths) { Line line = mesh.TopologyEdges.EdgeLine(p.Indices[0]); Plane edgePlane = new Plane(line.PointAt(0.5), mesh.GetMeshEdgePerpDir(p.Indices[0])); cloud.Add(line.PointAt(0.5), new Vector3d(p.Indices[0], 0, 0)); double angledifference = Math.Abs(Vector3d.VectorAngle(line.Direction, edgeVectors.Branch(p)[0], edgePlane) % Math.PI); //Rhino.RhinoApp.WriteLine(angledifference.ToString()); if (angledifference < angleTol || angledifference > (Math.PI - angleTol)) { edges.Add(new Line(line.PointAt(0.5), line.PointAt(0.5) + line.Direction.UnitVector() * line.Length * 0.25), p); edges.Add(new Line(line.PointAt(0.5), line.PointAt(0.5) + edgeVectors.Branch(p)[0].UnitVector() * line.Length * 0.25), p); edgeVectors.Branch(p)[0] = -EV.Branch(p)[0]; } else { } } //Change insertion vectors if (customVectors.Count > 0) { for (int i = 0; i < customVectors.Count; i++) { int edgeID = cloud.ClosestPoint(customVectors[i].From); edgeVectors.Branch(new GH_Path((int)cloud[edgeID].Normal.X))[0] = customVectors[i].Direction; } } //Rhino.RhinoApp.WriteLine (faceEdgeID.Count.ToString()); List <Vector3d> NGonsVectors = new List <Vector3d>() { Vector3d.ZAxis }; for (int i = 1; i < faceEdgeID.Count; i++) { Vector3d vec = Vector3d.Zero; for (int j = 0; j < faceEdgeID[i].Count; j++) { vec += edgeVectors.Branch(faceEdgeID[i][j])[0]; } vec.Unitize(); NGonsVectors.Add(vec); } DA.SetDataList(5, NGonsVectors); //EV = edgeVectors; DA.SetDataTree(2, edgeVectors); DA.SetDataTree(3, edges); //Get current face edges //Take edge only connected in current set }
protected override void SolveInstance(IGH_DataAccess DA) { //Declare Variables Point3d startingPoint = new Point3d(0, 0, 0); List <Point3d> interests = new List <Point3d>(); List <Mesh> obstacles = new List <Mesh>(); double distance = 0; int viewDist = 30; int viewAngle = 180; Mesh obsMesh = new Mesh(); double targetradius = 1.1; double walkingdist = 1; //Attach inputs DA.GetData(0, ref startingPoint); DA.GetDataList(1, interests); DA.GetDataList(2, obstacles); DA.GetData(3, ref distance); DA.GetData(4, ref viewAngle); DA.GetData(5, ref viewDist); // Join obstacles in one Mesh foreach (Mesh mesh in obstacles) { obsMesh.Append(mesh); } //Starting //Create Person Person firstperson = new Person(startingPoint, interests); //While loop (Moving) while (firstperson.TravedledDist < distance) { //Check if ESC is pressed and if true, Abort if (GH_Document.IsEscapeKeyDown()) { GH_Document GHDocument = OnPingDocument(); GHDocument.RequestAbortSolution(); } //Find Target PointCloud interestcloud = new PointCloud(firstperson.Interests); Boolean targetisinterest = true; //Check if any interests are left if (interestcloud.Count < 1) { //If no interest left, move along Y axis firstperson.UpdateTarget(firstperson.Position + new Point3d(0, walkingdist, 0)); targetisinterest = false; break; } while (true) { //Find closets point int intindex = interestcloud.ClosestPoint(firstperson.Position); if (firstperson.Position.DistanceTo(interestcloud[intindex].Location) > viewDist) { //If closets point is not within viewdist, move along Y axis firstperson.UpdateTarget(firstperson.Position + new Point3d(0, walkingdist, 0)); targetisinterest = false; break; } //Check for within fieldview if (viewAngle < Rhino.RhinoMath.ToDegrees(Vector3d.VectorAngle(firstperson.Facing, new Vector3d(interestcloud[intindex].X - firstperson.Position.X, interestcloud[intindex].Y - firstperson.Position.Y, interestcloud[intindex].Z - firstperson.Position.Z)))) { //If the interest is not in view remove interest from interestcloud interestcloud.RemoveAt(intindex); continue; } //Check for view collision Ray3d visibleRay = new Ray3d(firstperson.Position, new Vector3d(interestcloud[intindex].X - firstperson.Position.X, interestcloud[intindex].Y - firstperson.Position.Y, interestcloud[intindex].Z - firstperson.Position.Z)); double RayT = Rhino.Geometry.Intersect.Intersection.MeshRay(obsMesh, visibleRay); if (RayT > 0) { //If there is no direct view remove interest from interestcloud interestcloud.RemoveAt(intindex); continue; } else { firstperson.UpdateTarget(interestcloud[intindex].Location); break; } } //Check if arrived at Target if (firstperson.Position.DistanceTo(firstperson.CurrentTarget) < targetradius & targetisinterest == true) { firstperson.removeinterest(); continue; } //Move in direction Vector3d direction = new Vector3d(firstperson.CurrentTarget.X - firstperson.Position.X, firstperson.CurrentTarget.Y - firstperson.Position.Y, firstperson.CurrentTarget.Z - firstperson.Position.Z); direction.Unitize(); direction = Rhino.Geometry.Vector3d.Multiply(direction, walkingdist); Point3d newpos = firstperson.Position + direction; Boolean update = firstperson.UpdatePos(newpos, direction); DA.SetData(0, firstperson.Position); DA.SetData(1, firstperson.Facing); //System.Timers.Timer timer = new System.Timers.Timer(1000); } DA.SetDataList(2, firstperson.Path); }
public List <List <string> > ShortestWalkStripper(UndirectedWeightedGraph g, Line line, int maxLength, int perimeterEdgeWeight, bool flag, int loops) { //For adjusting odd walks UndirectedWeightedGraph adjustGraph = new UndirectedWeightedGraph(g); //Store paths List <List <string> > allPaths = new List <List <string> >(); //Find shortest path for (int i = 0; i < loops; i++) { if (g.N == 0) { base.Message = "Iterations " + i.ToString(); break; } //1.0 Perimeter weight if (perimeterEdgeWeight != 1) { //How to retrieve edges from a graph if it is represented as adjacency matrix? } //1.1 Split graph into connected subgraphs and pick first one List <UndirectedWeightedGraph> components = g.ConnectedComponents(g); for (int j = 0; j < components.Count; j++) { //Check if this component has one or two elements add them to path and deleter from graph if (components[j].N < 3) { allPaths.Add(components[j].GetVertexNames()); g.DeleteVertices(components[j].GetVertexNames()); components[j].DeleteVertices(components[j].GetVertexNames()); } //If not procede with Walker else { //1.0 Gather all points in that component; vertex name = point index List <string> vnames = components[j].GetVertexNames(); PointCloud componentCloud = new PointCloud(); foreach (var name in vnames) { componentCloud.Add(_pointCloud[Convert.ToInt32(name)].Location, new Vector3d(0, 0, Convert.ToInt32(name))); } //1.1 index of closest nodes to line endpoints; normals are indexes in global _pointCloud int indexA = componentCloud.ClosestPoint(line.From); string startId = ((int)componentCloud[indexA].Normal.Z).ToString(); componentCloud.RemoveAt(indexA); int indexB = componentCloud.ClosestPoint(line.To); string endId = ((int)componentCloud[indexB].Normal.Z).ToString(); //1.2 Shortest Path / Dijkstra List <string> path = components[j].FindPaths(startId, new List <string> { endId })[0]; //1.3 Limit the length if (path.Count > maxLength && maxLength > 1) { path.RemoveRange(0, path.Count - maxLength); } //1.4 Add path to path list allPaths.Add(path); //1.5 Remove edges from the main Graph g.DeleteVertices(path); } } //For } //Combine Odd Walks //2.0 Append very short segments to walks List <List <string> > oddPaths = new List <List <string> >(); List <List <string> > oddPaths2 = new List <List <string> >(); List <List <string> > normalPaths = new List <List <string> >(); for (int i = 0; i < allPaths.Count; i++) { if (allPaths[i].Count == 1) { oddPaths.Add(allPaths[i]); } else { normalPaths.Add(allPaths[i]); } } if (flag) { //2.1 Get neighbour walks by original adjacency map for (int i = 0; i < oddPaths.Count; i++) { Dictionary <string, int> neighbours = adjustGraph.GetAdjacentVertices(oddPaths[i][0], adjustGraph); List <string> _neighbours = new List <string>(neighbours.Keys); for (int j = 0; j < normalPaths.Count; j++) { if (_neighbours.Contains(normalPaths[j].First())) { normalPaths[j].Insert(0, oddPaths[i][0]); break; } else if (_neighbours.Contains(normalPaths[j].Last())) { normalPaths[j].Add(oddPaths[i][0]); break; } else if (j == normalPaths.Count - 1 && true) { oddPaths2.Add(oddPaths[i]); } } } normalPaths.AddRange(oddPaths2); oddWalks = oddPaths2.Count; return(normalPaths); } oddWalks = oddPaths.Count; return(allPaths); }
public static Polyline GetAxis(IEnumerable <Line> lines) { var allPoints = lines.SelectMany(l => new Point3d[] { l.From, l.To }); var pc = new PointCloud(); foreach (var point in allPoints) { if (Exists(point, pc)) { continue; } pc.Add(point); } var nodes = new List <List <Edge> >(Enumerable.Repeat(new List <Edge>(), pc.Count)); var edges = lines.Select(l => { var edge = new Edge() { Start = pc.ClosestPoint(l.From), End = pc.ClosestPoint(l.To), Line = l, Enabled = true }; nodes[edge.Start].Add(edge); nodes[edge.End].Add(edge); return(edge); }).ToList(); while (true) { var toDisable = new List <Edge>(); for (int i = 0; i < nodes.Count; i++) { var node = nodes[i]; int valence = node.Count(e => e.Enabled); if (valence == 1) { var edge = node.First(e => e.Enabled); var j = edge.Start == i ? edge.End : edge.Start; int otherValence = nodes[j].Count(e => e.Enabled); if (otherValence >= 3) { toDisable.Add(edge); } } } if (toDisable.Count == 0) { break; } foreach (var edge in toDisable) { edge.Enabled = false; } } var axes = edges .Where(e => e.Enabled) .Select(e => e.Line.ToNurbsCurve()); var curve = Curve.JoinCurves(axes); Polyline pl = new Polyline(); if (curve.Length > 0) { curve[0].TryGetPolyline(out pl); } else { Line maxLine = Line.Unset; double maxLength = 0; foreach (var line in lines) { double length = line.Direction.SquareLength; if (length > maxLength) { maxLength = length; maxLine = line; } } pl = new Polyline(new Point3d[] { maxLine.From, maxLine.To }); } return(pl); }
public static Mesh CurveMesh(List <Line> lines, List <double> r_, double DivisionDist, int DivisionU, int DivisionV, ref DataTree <Point3d> anchors0, ref DataTree <Point3d> anchors1, ref DataTree <Polyline> outlines, ref Circle[] graphNodes, List <Circle> circleRadius = null) { Tuple <Point3d[], List <string>, List <int>, List <int>, List <int>, DataTree <int> > data = GetGraphData(lines); List <Point3d> TP = data.Item1.ToList(); List <int> U = data.Item3; List <int> V = data.Item4; DataTree <int> VAdj = data.Item6; DataTree <Vector3d> sortedVecs = new DataTree <Vector3d>(); DataTree <Vector3d> sortedBisectors = new DataTree <Vector3d>(); DataTree <Polyline> output = new DataTree <Polyline>(); DataTree <Mesh> outputMesh = new DataTree <Mesh>(); DataTree <Point3d> outputPt = new DataTree <Point3d>(); DataTree <Point3d> outputPtArc = new DataTree <Point3d>(); Mesh joinedMesh = new Mesh(); DataTree <int> sortedIDs = new DataTree <int>(); var polys = new List <Polyline>(); double[] radius = Enumerable.Repeat(1.0, TP.Count).ToArray(); List <double> r = new List <double>(); if (r_.Count == 0) { r.Add(1); } else { r = r_; } if (r.Count < TP.Count) { radius = new double[radius.Length]; for (int i = 0; i < TP.Count; i++) { radius[i] = r[i % r.Count]; } } else { radius = r.ToArray(); // Rhino.RhinoApp.WriteLine("correct"); } PointCloud cloud = new PointCloud(TP); for (int i = 0; i < circleRadius.Count; i++) { int cp = cloud.ClosestPoint(circleRadius[i].Center); if (cloud[cp].Location.DistanceToSquared(circleRadius[i].Center) < 0.01) { //r[cp] = circleRadius[i].Radius; if (circleRadius[i].Plane.ZAxis != Vector3d.ZAxis) { radius[cp] = -circleRadius[i].Radius; } else { radius[cp] = circleRadius[i].Radius; } } } for (int i = 0; i < TP.Count; i++) { //create node vectors and sort them //also sort ids Vector3d[] vec = new Vector3d[VAdj.Branch(i).Count]; int[] nei = VAdj.Branch(i).ToArray(); for (int j = 0; j < VAdj.Branch(i).Count; j++) { Point3d p0 = TP[i]; Point3d p1 = TP[VAdj.Branch(i)[j]]; vec[j] = p1 - p0; vec[j].Unitize(); vec[j] *= Math.Abs(radius[j]); } Array.Sort(vec, nei, new ClockwiseVector3dComparer()); sortedVecs.AddRange(vec, new GH_Path(i)); sortedIDs.AddRange(nei, new GH_Path(i)); //Bisector Vector3d[] bisectors = new Vector3d[VAdj.Branch(i).Count]; if (VAdj.Branch(i).Count > 1) { for (int j = 0; j < VAdj.Branch(i).Count; j++) { Vector3d vec0 = vec[j]; Vector3d vec1 = vec[(j + 1) % VAdj.Branch(i).Count]; Vector3d bisector = new Vector3d(vec1); Vector3d vvec0 = new Vector3d(vec0); Vector3d vvec1 = new Vector3d(vec1); vvec0.Unitize(); vvec1.Unitize(); vvec0.Rotate(-Math.PI * 0.5, Vector3d.ZAxis); double angle = Vector3d.VectorAngle(vec0, vec1, new Plane(TP[i], vec0, vvec0)) * 0.5; // Vector3d cross = Rhino.Geometry.Vector3d.CrossProduct(vvec0, vvec1); // angle = Math.Atan2(cross * Vector3d.ZAxis, vvec0*vvec1); bisector.Rotate(angle, Vector3d.ZAxis); bisector.Unitize(); bisector *= Math.Abs(radius[i]); bisectors[j] = bisector; } sortedBisectors.AddRange(bisectors, new GH_Path(i)); } else { Vector3d vec0 = new Vector3d(vec[0]); Vector3d vec1 = new Vector3d(vec[0]); vec0.Rotate(-Math.PI * 0.5, Vector3d.ZAxis); vec1.Rotate(Math.PI * 0.5, Vector3d.ZAxis); vec0.Unitize(); vec1.Unitize(); vec0 *= Math.Abs(radius[i]); vec1 *= Math.Abs(radius[i]); Vector3d[] bisectors_ = new Vector3d[] { vec0, vec1 }; //Array.Sort(bisectors_, new ClockwiseVector3dComparer()); sortedBisectors.AddRange(bisectors_, new GH_Path(i)); } } DataTree <Polyline> polylines = new DataTree <Polyline>(); // for(int i = 0; i < 1;i++){//TP.Count for (int i = 0; i < TP.Count; i++) { //for(int j = 1; j < 2;j++){//VAdj.Branch(i).Count for (int j = 0; j < VAdj.Branch(i).Count; j++) //VAdj.Branch(i).Count { int currentNei = sortedIDs.Branch(i)[j]; int[] neinei = sortedIDs.Branch(currentNei).ToArray(); int neiID = Array.IndexOf(neinei, i); neiID = NGonsCore.MathUtil.Wrap(neiID - 1, neinei.Length); Vector3d neiVec = new Vector3d(sortedBisectors.Branch(currentNei)[neiID]); if (neinei.Length == 1) { neiVec = new Vector3d(sortedBisectors.Branch(currentNei)[1]); } bool flag1 = sortedIDs.Branch(currentNei).Count == 1; bool flag0 = sortedIDs.Branch(i).Count == 1; Line line = Line.Unset; Polyline anchorsPoly = new Polyline(); Arc anchorsArc = Arc.Unset; Vector3d arcVec0 = Vector3d.Zero; Arc arc0 = Arc.Unset; if (flag0) { //Create arc for naked part arcVec0 = TP[i] - TP[currentNei]; arcVec0.Unitize(); arcVec0 *= radius[i];//Negative gaussian flip line = new Line(TP[i] + arcVec0, TP[i] + sortedBisectors.Branch(i)[j]); anchorsPoly = new Polyline(new Point3d[] { TP[i] + sortedBisectors.Branch(i)[j], TP[i] + arcVec0, TP[i] - sortedBisectors.Branch(i)[j] }); anchorsArc = new Arc(TP[i] + sortedBisectors.Branch(i)[j], TP[i] - arcVec0, TP[i] - sortedBisectors.Branch(i)[j]); // Rhino.RhinoDoc.ActiveDoc.Objects.AddArc(anchorsArc); Vector3d arcVec0mid = (sortedBisectors.Branch(i)[j] + arcVec0); arcVec0mid.Unitize(); arcVec0mid *= radius[i]; arc0 = new Arc( TP[i] + arcVec0, TP[i] + arcVec0mid, TP[i] + sortedBisectors.Branch(i)[j] ); // Rhino.RhinoDoc.ActiveDoc.Objects.AddArc(arc0); } Vector3d arcVec1 = Vector3d.Zero; Arc arc1 = Arc.Unset; if (flag1) { //Create arc for naked part arcVec1 = TP[i] - TP[currentNei]; arcVec1.Unitize(); arcVec1 *= -radius[currentNei];//Negative gaussian flip line = new Line(TP[currentNei] + arcVec1, TP[currentNei] + neiVec); Vector3d arcVec1mid = (neiVec + arcVec1); arcVec1mid.Unitize(); arcVec1mid *= -radius[currentNei]; arc1 = new Arc( TP[currentNei] + arcVec1, TP[currentNei] + arcVec1mid, TP[currentNei] + neiVec ); // Rhino.RhinoDoc.ActiveDoc.Objects.AddArc(arc1); } Polyline polyline = new Polyline(new Point3d[] { TP[i] + arcVec0, TP[i] + sortedBisectors.Branch(i)[j], TP[currentNei] + neiVec, TP[currentNei] + arcVec1, }); polyline.Close(); polys.Add(polyline); // if(neinei.Length == 1){ output.Add(polyline, new GH_Path(i)); //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(polyline.SegmentAt(1)); int dirV = (int)Math.Max(1, Math.Ceiling(polyline.SegmentAt(3).Length / DivisionDist)); //Rhino.RhinoApp.WriteLine(dirV.ToString()); if (DivisionDist == 0) { dirV = DivisionV; } //Create surface /* * Line line0 = new Line(TP[i] + arcVec0, TP[i] + sortedBisectors.Branch(i)[j]); * Line line1 = new Line(TP[currentNei] + arcVec1, TP[currentNei] + neiVec); * Brep loft = Brep.CreateFromLoft(new Curve[]{line0.ToNurbsCurve(),line1.ToNurbsCurve()}, Point3d.Unset, Point3d.Unset, LoftType.Tight, false)[0]; * * if(flag0){ * loft = Brep.CreateFromLoft(new Curve[]{arc0.ToNurbsCurve(),line1.ToNurbsCurve()}, Point3d.Unset, Point3d.Unset, LoftType.Tight, false)[0]; * }else if(flag1){ * loft = Brep.CreateFromLoft(new Curve[]{line0.ToNurbsCurve(),arc1.ToNurbsCurve()}, Point3d.Unset, Point3d.Unset, LoftType.Tight, false)[0]; * // Rhino.RhinoDoc.ActiveDoc.Objects.AddBrep(loft); * } */ Brep brep = Brep.CreateFromCornerPoints(polyline[0], polyline[1], polyline[2], polyline[3], Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance); if (brep != null) { int dirU = Math.Max(1, DivisionU); // if(line != Line.Unset){ // Point3d[] nakedPt; // line.ToNurbsCurve().DivideByCount(dirU, true, out nakedPt); // outputPt.AddRange(nakedPt, new GH_Path(i)); // } if (anchorsArc != Arc.Unset) { Point3d[] nakedPt; anchorsPoly.SegmentAt(0).ToNurbsCurve().DivideByCount(dirU, true, out nakedPt); outputPt.AddRange(nakedPt, new GH_Path(i)); anchorsPoly.SegmentAt(1).ToNurbsCurve().DivideByCount(dirU, true, out nakedPt); for (int k = 1; k < nakedPt.Length; k++) { outputPt.Add(nakedPt[k], new GH_Path(i)); } anchorsArc.ToNurbsCurve().DivideByCount(dirU * 2, true, out nakedPt); outputPtArc.AddRange(nakedPt, new GH_Path(i)); } Surface surf = brep.Surfaces[0]; Mesh mesh = NGonsCore.MeshCreate.QuadMesh(surf, dirU, dirV, true, false); outputMesh.Add(mesh, new GH_Path(i)); joinedMesh.Append(mesh); } } } joinedMesh.WeldUsingRTree(0.01); anchors0 = outputPt; anchors1 = outputPtArc; outlines = output; Circle[] circles = new Circle[data.Item1.Length]; for (int i = 0; i < circles.Length; i++) { circles[i] = new Circle(data.Item1[i], Math.Abs(radius[i])); } graphNodes = circles; return(joinedMesh); //A = sortedVecs; //B = sortedBisectors; // C = joinedMesh; //D = output; //E = outputPt;//anchors //F = outputPtArc;//anchors }
public static IMesh DualMesh(IMesh mesh) { IMesh nM = new IMesh(); // Face center points foreach (IElement e in mesh.Elements) { nM.AddVertex(e.Key, new ITopologicVertex(ISubdividor.ComputeAveragePosition(e.Vertices, mesh))); } int[] data1, data2; PointCloud cloud = new PointCloud(); List <int> global = new List <int>(); int vertexKey = nM.FindNextVertexKey(); foreach (ITopologicVertex v in mesh.Vertices) { data1 = mesh.Topology.GetVertexIncidentElementsSorted(v.Key); if (!mesh.Topology.IsNakedVertex(v.Key)) { nM.AddElement(new ISurfaceElement(data1)); } else { List <int> local = new List <int>(); data2 = mesh.Topology.GetVertexAdjacentVerticesSorted(v.Key); bool flag = false; foreach (int vv in data2) { if (mesh.Topology.IsNakedEdge(vv, v.Key)) { Point3d p = ISubdividor.ComputeAveragePoint(new[] { vv, v.Key }, mesh); int idx = cloud.ClosestPoint(p); if (idx == -1) { flag = true; } else { if (p.DistanceTo(cloud[idx].Location) > 0.01) { flag = true; } else { flag = false; } } if (flag) { cloud.Add(p); nM.AddVertex(vertexKey, new ITopologicVertex(p)); global.Add(vertexKey); local.Add(vertexKey); vertexKey++; } else { local.Add(global[idx]); } } } nM.AddVertex(vertexKey, new ITopologicVertex(v)); local.Insert(1, vertexKey); local.AddRange(data1.Reverse()); vertexKey++; nM.AddElement(new ISurfaceElement(local.ToArray())); } } nM.BuildTopology(true); return(nM); }
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); }
public int GetClosestVertexIndex(Point3d point) { PointCloud pointCloud = new PointCloud(Vertices); return(pointCloud.ClosestPoint(point)); }
/// <inheritdoc /> public Vector3d ClosestPoint(Vector3d point) { var index = _pointCloud.ClosestPoint(point); return(_pointCloud[index].Location); }