public void AddIntersections(KeyValuePair <Guid, Curve> curveBData, CurveIntersections intersections) { foreach (var inter in intersections) { var fryIntersection = new FryIntersection(inter, myCurveData, curveBData); this.myIntersections.Add(fryIntersection); } }
DataTree <Point3d> findAllAxisPoints(Point3d startP, List <Vector3d> directions) { /// 'Walk out' from the center using a list of directions to find all points in this surface 'axis' /// Will output a tree with as many branches as directions where input /// MAIN BEHAVIOUR /// Create an arc using the normal, the direction and the negative normal of size DesiredLength /// Intersect the arc with the surface to find next point. /// After finding the next point, update current u,v values and current Direction /// If no intersections are found BREAK: You have reached the limit of the surface DataTree <Point3d> axis = new DataTree <Point3d>(); //Create an empty array of List<Point3d> for (int i = 0; i < _axisNum; i++) { // Iterate for every axis List <Point3d> pts = new List <Point3d>(); double u0, v0; Vector3d d = directions[i]; // Set direction to starting dir _surface.ClosestPoint(startP, out u0, out v0); // Get U,V of the startingPoint double u = u0; double v = v0; for (int j = 0; j < _MAXITERATIONS; j++) { // Iterate until no intersections or maxIterations is reached // Get the current point and normal Point3d pt = _surface.PointAt(u, v); Vector3d n = _surface.NormalAt(u, v); pts.Add(pt); // Add the point to the list n *= _desiredLength; // Set n length to desired d.Unitize(); // Make shure d is unitary d *= _desiredLength; // Set d lenght to desired Arc intArc = new Arc(pt + n, pt + d, pt - n); CurveIntersections cvint = Intersection.CurveSurface(intArc.ToNurbsCurve(), _surface, 0.01, 0.01); // Intersect arc with geometry if (cvint.Count > 0) { cvint[0].SurfacePointParameter(out u, out v); // Find u,v of intersection point } else { break; // Break if no intersections are found } d = _surface.PointAt(u, v) - pt; // Update direction } axis.AddRange(pts, new GH_Path(i)); // Add axis points list to branch } return(axis); //Return the axis points of the grid }
private Point3d FindMaxMTemp(Curve c, Plane p) { CurveIntersections ci = Intersection.CurvePlane(c, p, RhinoDoc.ActiveDoc.ModelAbsoluteTolerance); if (ci == null) return new Point3d(0.1, 0.1, 0); List<Point3d> points = new List<Point3d>(); foreach (IntersectionEvent ie in ci) { points.Add(ie.PointA); } return points.Max(); }
private double FindMaxM(Curve c, Plane p, Axis direction) { CurveIntersections ci = Intersection.CurvePlane(c,p, RhinoDoc.ActiveDoc.ModelAbsoluteTolerance); if (ci == null) return 0.1; List<Point3d> points = new List<Point3d>(); foreach (IntersectionEvent ie in ci) { points.Add(ie.PointA); } return (direction == Axis.ZAxis? points.Select(o => o.Z).Max() : points.Select(o => o.Y).Max()); }
/// <summary> /// Basic collision detection routine for single item placement. /// </summary> /// <param name="room">Room currently being populated.</param> /// <param name="candidate">PlacementPackaged being checked for fidelity.</param> /// <param name="pm"></param> /// <returns></returns> public static bool PlacementIsValid(RoomPackage room, PlacementPackage candidate, ProgramManifest pm) { //Verify placed item does not clash with previously placed items. foreach (PlacementPackage placedItem in room.PlacedItems) { if (Confirm.CurvesIntersect(placedItem.Bounds, candidate.Bounds, true)) { if (Confirm.CurvesIntersect(placedItem.Bounds, candidate.Bounds, false)) { return(false); } CurveIntersections ccx = Intersection.CurveCurve(placedItem.Bounds, candidate.Bounds, 0.1, 0.1); if (ccx.Count(x => x.IsOverlap) > 1) { return(false); } } PointContainment insideCheck = placedItem.Bounds.Contains(candidate.Bounds.GetBoundingBox(Plane.WorldXY).Center); if (insideCheck == PointContainment.Inside || insideCheck == PointContainment.Coincident) { return(false); } } //Verify item is completely within boundary of room. foreach (Curve edgeCurve in room.AllEdgeCurves) { if (Confirm.CurvesIntersect(candidate.Bounds, edgeCurve, false)) { return(false); } /* * if (!Confirm.PointInRegion(room.Region, new CurveBounds(candidate.Bounds).Center)) * { * return false; * } */ } //Verify program area is not larger than total room area. if (room.Region.GetArea() < pm.ProgramPackages[candidate.ProgramIndex].OccupationArea) { return(false); } return(true); }
// Find the best fitting geodesic curve for a set of public double ComputeError(int n, double[] x) { double alpha = x[0]; Curve curve = perpGeodesics[startIndex]; Point3d pt = curve.PointAt(perpParameters[startIndex]); Vector3d vector = curve.TangentAt(perpParameters[startIndex]); MeshPoint mPt = mesh.ClosestMeshPoint(pt, 0.0); Vector3d normal = mesh.NormalAt(mPt); Vector3d cP = Vector3d.CrossProduct(vector, normal); cP.Rotate(alpha, normal); Curve newG = MeshGeodesicMethods.getGeodesicCurveOnMesh(mesh, pt, cP, maxIter).ToNurbsCurve(); if (bothDir) { Curve newG2 = MeshGeodesicMethods.getGeodesicCurveOnMesh(mesh, pt, -cP, maxIter).ToNurbsCurve(); newG = Curve.JoinCurves(new List <Curve> { newG, newG2 })[0]; } // Assign resulting geodesic to global property for output. selectedGeodesic = newG; // Calculate error double error = 0; for (int i = 0; i < perpGeodesics.Count - 1; i++) { Curve g = perpGeodesics[i]; CurveIntersections cvInt = Intersection.CurveCurve(newG, g, 0.00001, 0.00001); if (cvInt.Count > 0) { // Compute distance if intersection is found double param = cvInt[0].ParameterB; Interval domain = new Interval(param, perpParameters[i]); double distance = g.GetLength(domain); // Add squared distance to error error += Math.Pow(distance, 2); } else { // Penalize if no intersection is found on this perp geodesic error += 10; } } return(error); }
internal Plane LocationPlane(double tol) { Tuple <IfcGridAxis, IfcGridAxis> axes = IntersectingAxes; #if (RHINO || GH) Curve c1 = axes.Item1.Curve(tol), c2 = axes.Item2.Curve(tol); CurveIntersections ci = Intersection.CurveCurve(c1, c2, tol, tol); if (ci != null && ci.Count > 0) { return(new Plane(ci[0].PointA + OffsetVector, Vector3d.ZAxis)); } #endif return(Plane.WorldXY); }
}//eof /// <summary> /// This is the method that actually does the work. /// </summary> protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> curves = new List <Curve>(); double tlr = 0; if (!DA.GetDataList(0, curves)) { return; } DA.GetData(1, ref tlr); List <List <double> > intersectPoints = new List <List <double> >(); for (int i = 0; i < curves.Count; ++i) { intersectPoints.Add(new List <double>()); } List <Curve> outputCurves = new List <Curve>(); for (int i = 0; i < curves.Count - 1; ++i) { for (int j = i + 1; j < curves.Count; ++j) { CurveIntersections cis = Intersection.CurveCurve(curves[i], curves[j], tlr, 0); for (int k = 0; k < cis.Count; ++k) { intersectPoints[i].Add(cis[k].ParameterA); intersectPoints[j].Add(cis[k].ParameterB); } } } for (int i = 0; i < curves.Count; ++i) { Curve[] crvI = curves[i].DuplicateCurve().Split(intersectPoints[i]); for (int j = 0; j < crvI.Length; ++j) { outputCurves.Add(crvI[j]); } } DA.SetDataList(0, outputCurves); }//eof
private (Point3d, int, bool) GetNewMovePt(Polyline pline, List <Point3d> linePts, RhinoDoc doc, int tempDirPtIndex) { Point3d randomPt = new Point3d(); int tryCounter = 0; bool isIntersecting = false, stuckPt = false; do { tryCounter++; if (tryCounter == 10000) { stuckPt = true; break; } isIntersecting = false; int recentDirIndex; (randomPt, recentDirIndex) = GetRandomPt(linePts.Last()); Line newLinePart = new Line(linePts.Last(), randomPt); if (pline.Count == 0) { continue; // first entrance } CurveIntersections intersections = Intersection.CurveCurve(newLinePart.ToNurbsCurve(), pline.ToNurbsCurve(), doc.ModelAbsoluteTolerance, doc.ModelAbsoluteTolerance); if (intersections.Count != 1) { isIntersecting = true; } if (tempDirPtIndex == recentDirIndex) { isIntersecting = true; } if (linePts.Contains(randomPt)) { isIntersecting = true; } tempDirPtIndex = recentDirIndex; } while (isIntersecting); return(randomPt, tempDirPtIndex, stuckPt); }
public static ZOffsetAtIntersection OffsetAtIntersection(List <Curve> crvs, double LayerWidth, double LayerHeight, double ResolutionMultiplier) { List <Curve> _crvs = new List <Curve>() { crvs[0] }; for (int i = 1; i < crvs.Count; i++) { CurveIntersections ci = Intersection.CurveCurve(crvs[i], crvs[j], 0.01, 0.01); crvs[i].DivideByLength(LayerWidth, true, out Point3d[] pts); foreach (Curve c in _crvs) { c.ClosestPoint } foreach (Point3d p in pts) { p.dis } } return(null); }
// Find the best fitting geodesic curve for a set of public new double ComputeError(int n, double[] x) { double alpha = x[0]; bestFitInterval = new int[] { }; Curve curve = perpGeodesics[startIndex]; Point3d pt = curve.PointAt(perpParameters[startIndex]); Vector3d vector = curve.TangentAt(perpParameters[startIndex]); MeshPoint mPt = mesh.ClosestMeshPoint(pt, 0.0); Vector3d normal = mesh.NormalAt(mPt); Vector3d cP = Vector3d.CrossProduct(vector, normal); cP.Rotate(alpha, normal); if (refDir == Vector3d.Unset) { refDir = cP; } double angle = Vector3d.VectorAngle(cP, refDir); if (angle >= 0.1 * Math.PI) { cP = -cP; } Vector3d.VectorAngle(cP, refDir); Curve newG = MeshGeodesicMethods.getGeodesicCurveOnMesh(mesh, pt, cP, maxIter).ToNurbsCurve(); if (bothDir) { Curve newG2 = MeshGeodesicMethods.getGeodesicCurveOnMesh(mesh, pt, -cP, maxIter).ToNurbsCurve(); newG = Curve.JoinCurves(new List <Curve> { newG, newG2 })[0]; } // Assign resulting geodesic to global property for output. selectedGeodesic = newG; // Calculate error double error = 0; List <double> distances = new List <double>(); List <double> signedDistances = new List <double>(); for (int i = 0; i < perpGeodesics.Count - 1; i++) { Curve g = perpGeodesics[i]; CurveIntersections cvInt = Intersection.CurveCurve(newG, g, 0.00001, 0.00001); double signedDistance = g.GetLength(new Interval(0, perpParameters[i])); signedDistances.Add(signedDistance); if (cvInt.Count > 0) { // Compute distance if intersection is found double param = cvInt[0].ParameterB; double distance = g.GetLength(new Interval(0, param)); distances.Add(distance); // Add squared distance to error error += Math.Pow(signedDistance - distance, 2); } else { // Penalize if no intersection is found on this perp geodesic distances.Add(1000); error += 1000; } } //Calculate longest interval within threshold. for (int k = (distances.Count - 1); k >= 2; k--) { for (int i = 0; i < (distances.Count - k); i++) { //Check if interval i->k is within bounds bool flag = true; for (int j = i; j < i + k; j++) { double Lbound = signedDistances[j] * (1 - threshold); double Ubound = signedDistances[j] * (1 + threshold); if (Lbound > distances[j] || distances[j] > Ubound) { flag = false; break; } } if (flag && bestFitInterval.Length == 0) { bestFitInterval = new int[] { i, i + k }; } } } if (bestFitInterval.Length == 0) { error += 1000000; return(error); } error = error / (bestFitInterval[1] - bestFitInterval[0]); //if (invertDir) selectedGeodesic.Reverse(); return(error); }
/// <summary> /// Test for a curve that is a polyline (or looks like a polyline). /// </summary> bool IsPolyline(Curve curve, ref int point_count, ref bool bClosed, ref bool bPlanar, ref bool bLength, ref bool bAngle, ref bool bIntersect) { if (null == curve) { return(false); } List <Point3d> points = new List <Point3d>(); // Is the curve a polyline curve? PolylineCurve polyline_curve = curve as PolylineCurve; if (null != polyline_curve) { if (polyline_curve.PointCount <= 2) { return(false); } for (int i = 0; i < polyline_curve.PointCount; i++) { points.Add(polyline_curve.Point(i)); } } // Is the curve a polycurve that looks like an polyline? PolyCurve poly_curve = curve as PolyCurve; if (null != poly_curve) { Polyline polyline; if (poly_curve.TryGetPolyline(out polyline)) { if (polyline.Count <= 2) { return(false); } for (int i = 0; i < polyline.Count; i++) { points.Add(polyline[i]); } } } // Is the curve a NURBS curve that looks like an polyline? NurbsCurve nurbs_curve = curve as NurbsCurve; if (null != nurbs_curve) { Polyline polyline; if (nurbs_curve.TryGetPolyline(out polyline)) { if (polyline.Count <= 2) { return(false); } for (int i = 0; i < polyline.Count; i++) { points.Add(polyline[i]); } } } if (0 == points.Count) { return(false); } // Is the curve closed? bClosed = curve.IsClosed; // Is the curve planar? bPlanar = curve.IsPlanar(); // Get the point (vertex) count. point_count = (bClosed ? points.Count - 1 : points.Count); // Test for self-intersection. CurveIntersections intesections = Intersection.CurveSelf(curve, m_tolerance); bIntersect = (intesections.Count > 0) ? true : false; // If the curve is not closed, no reason to continue... if (!bClosed) { return(true); } // Test if the distance between each point is identical. double distance = 0.0; for (int i = 1; i < points.Count; i++) { Point3d p0 = points[i - 1]; Point3d p1 = points[i]; Vector3d v = p0 - p1; double d = v.Length; if (i == 1) { distance = d; continue; } else if (Math.Abs(distance - d) < m_tolerance) { continue; } else { distance = RhinoMath.UnsetValue; break; } } // Set return value. bLength = RhinoMath.IsValidDouble(distance); // Test if the angle between each point is identical. double angle = 0.0; for (int i = 1; i < points.Count - 1; i++) { Point3d p0 = points[i - 1]; Point3d p1 = points[i]; Point3d p2 = points[i + 1]; Vector3d v0 = p1 - p0; Vector3d v1 = p1 - p2; v0.Unitize(); v1.Unitize(); double a = Vector3d.VectorAngle(v0, v1); if (i == 1) { angle = a; continue; } else if (Math.Abs(angle - a) < m_angle_tolerance) { continue; } else { angle = RhinoMath.UnsetValue; break; } } // Set return value. bAngle = RhinoMath.IsValidDouble(angle); 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) { Surface S = null; if (!DA.GetData(0, ref S)) { return; } Point3d P = Point3d.Unset; if (!DA.GetData(1, ref P)) { P = S.PointAt(S.Domain(0).Mid, S.Domain(1).Mid); } double R = Rhino.RhinoMath.UnsetValue; if (!DA.GetData(2, ref R)) { return; } double A = Rhino.RhinoMath.UnsetValue; if (!DA.GetData(3, ref A)) { return; } int max = 0; if (!DA.GetData(4, ref max)) { return; } Boolean extend = false; if (!DA.GetData(5, ref extend)) { return; } if (R <= 0) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Mesh edge length must be a positive, non-zero number."); return; } // Extend surface beyond boundaries to get a better coverage from the net if (extend) { S = S.Extend(IsoStatus.North, R, true); S = S.Extend(IsoStatus.East, R, true); S = S.Extend(IsoStatus.South, R, true); S = S.Extend(IsoStatus.West, R, true); } // starting point double u0, v0; S.ClosestPoint(P, out u0, out v0); // get two (four) orthogonal directions (in plane of surface at starting point) Plane plane = new Plane(S.PointAt(u0, v0), S.NormalAt(u0, v0)); plane.Rotate(Rhino.RhinoMath.ToRadians(A), S.NormalAt(u0, v0)); Vector3d[] dir = new Vector3d[] { plane.XAxis * R, plane.YAxis * R, plane.XAxis * -R, plane.YAxis * -R }; // for each direction, walk out (and store list of points) double u, v; List <Point3d>[] axis = new List <Point3d> [4]; for (int i = 0; i < 4; i++) { // set u and v to starting point u = u0; v = v0; List <Point3d> pts = new List <Point3d>(); for (int j = 0; j < max + 1; j++) { // get point and normal for uv Point3d pt = S.PointAt(u, v); Vector3d n = S.NormalAt(u, v); n *= R; // add point to list pts.Add(pt); // create forward facing arc and find intersection point with surface (as uv) Arc arc = new Arc(pt + n, pt + dir[i], pt - n); CurveIntersections isct = Intersection.CurveSurface(arc.ToNurbsCurve(), S, 0.01, 0.01); if (isct.Count > 0) { isct[0].SurfacePointParameter(out u, out v); } else { break; } // adjust direction vector (new position - old position) dir[i] = S.PointAt(u, v) - pt; } axis[i] = pts; } // now that we have the axes, start to build up the mesh quads in between GH_PreviewUtil preview = new GH_PreviewUtil(GetValue("Animate", false)); Rhino.Geometry.Mesh mesh = new Rhino.Geometry.Mesh(); // target mesh for (int k = 0; k < 4; k++) { int k0 = (k + 1) % 4; int padding = 10; Rhino.Geometry.Mesh qmesh = new Rhino.Geometry.Mesh(); // local mesh for quadrant Point3d[,] quad = new Point3d[axis[k].Count + padding, axis[k0].Count + padding]; // 2d array of points int[,] qindex = new int[axis[k].Count + padding, axis[k0].Count + padding]; // 2d array of points' indices in local mesh int count = 0; for (int i = 0; i < axis[k0].Count; i++) { // add axis vertex to mesh and store point and index in corresponding 2d arrays quad[0, i] = axis[k0][i]; qmesh.Vertices.Add(axis[k0][i]); qindex[0, i] = count++; } for (int i = 1; i < quad.GetLength(0); i++) { if (i < axis[k].Count) { // add axis vertex quad[i, 0] = axis[k][i]; qmesh.Vertices.Add(axis[k][i]); qindex[i, 0] = count++; } // for each column attempt to locate a new vertex in the grid for (int j = 1; j < quad.GetLength(1); j++) { // if quad[i - 1, j] doesn't exist, try to add it and continue (or else break the current row) if (quad[i - 1, j] == new Point3d()) { if (j < 2) { break; } CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j - 1], quad[i - 1, j - 2], R); if (isct.Count > 0) { quad[i - 1, j] = isct[0].PointB; qmesh.Vertices.Add(quad[i - 1, j]); qindex[i - 1, j] = count++; } else { break; } } // if quad[i, j - 1] doesn't exist, try to create quad[i, j] by projection and skip mesh face creation if (quad[i, j - 1] == new Point3d()) { if (i < 2) { break; } CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j], quad[i - 2, j], R); if (isct.Count > 0) { quad[i, j] = isct[0].PointB; qmesh.Vertices.Add(quad[i, j]); qindex[i, j] = count++; continue; } } // construct a sphere at each neighbouring vertex ([i,j-1] and [i-1,j]) and intersect Sphere sph1 = new Sphere(quad[i, j - 1], R); Sphere sph2 = new Sphere(quad[i - 1, j], R); Circle cir; if (Intersection.SphereSphere(sph1, sph2, out cir) == SphereSphereIntersection.Circle) { // intersect circle with surface CurveIntersections cin = Intersection.CurveSurface(NurbsCurve.CreateFromCircle(cir), S, 0.01, 0.01); // attempt to find the new vertex (i.e not [i-1,j-1]) foreach (IntersectionEvent ie in cin) { if ((ie.PointA - quad[i - 1, j - 1]).Length > 0.2 * R) // compare with a tolerance, rather than exact comparison { quad[i, j] = ie.PointA; qmesh.Vertices.Add(quad[i, j]); qindex[i, j] = count++; // create quad-face qmesh.Faces.AddFace(qindex[i, j], qindex[i - 1, j], qindex[i - 1, j - 1], qindex[i, j - 1]); break; } } if (preview.Enabled) { preview.Clear(); preview.AddMesh(mesh); preview.AddMesh(qmesh); preview.Redraw(); } } } } // add local mesh to target mesh.Append(qmesh); } // weld mesh to remove duplicate vertices along axes mesh.Weld(Math.PI); mesh.Compact(); mesh.Normals.ComputeNormals(); DA.SetData(0, mesh); preview.Clear(); }
public static void Make3d(string schemeName) { string inputLayerPath = schemeName + "::EJLT Shapes"; string outputLayerPath = schemeName + "::Walls"; string doorsLayerPath = schemeName + "::Doors"; List <int> layerIndexs; List <Curve> curves = LayerHelper.GetCurvesFromChild(inputLayerPath, out layerIndexs); List <Curve> doors = LayerHelper.GetCurvesFrom(doorsLayerPath); List <LineCurve> afterCut = new List <LineCurve>(); List <Line> exploded = new List <Line>(); foreach (Curve c in curves) { Polyline poly; c.TryGetPolyline(out poly); exploded.AddRange(poly.GetSegments()); } List <Line> lineSegDoor = new List <Line>(); List <List <LineCurve> > doorsPerSeg = new List <List <LineCurve> >(); foreach (Line lineSeg in exploded) { List <LineCurve> doorsThisSeg = new List <LineCurve>(); foreach (Curve door in doors) { CurveIntersections inter = Intersection.CurveLine(door, lineSeg, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, 0.0); if (inter.Count == 2) { LineCurve l1; Point3d p1 = inter.First().PointA; Point3d p2 = inter[1].PointA; l1 = new LineCurve(p1, p2); doorsThisSeg.Add(l1); } } if (doorsThisSeg.Count > 0) { lineSegDoor.Add(lineSeg); doorsPerSeg.Add(doorsThisSeg); } else { // no intersection, add to after cut afterCut.Add(new LineCurve(lineSeg)); } } for (int i = 0; i < lineSegDoor.Count; i++) { // points from all intersection points List <Point3d> intersectionPts = new List <Point3d>(); intersectionPts.Add(lineSegDoor[i].From); intersectionPts.Add(lineSegDoor[i].To); foreach (LineCurve doorLine in doorsPerSeg[i]) { intersectionPts.Add(doorLine.PointAtStart); intersectionPts.Add(doorLine.PointAtEnd); } List <Point3d> sortedPoints = intersectionPts.OrderBy(pnt => pnt.Y).ThenBy(pnt => pnt.X).ToList(); // construct line segments for (int pi = 0; pi < sortedPoints.Count; pi = pi + 2) { LineCurve cuttedSegment = new LineCurve(sortedPoints[pi], sortedPoints[pi + 1]); bool indoor = false; foreach (Curve door in doors) { if (door.Contains(cuttedSegment.PointAt(0.5), Plane.WorldXY, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) == PointContainment.Inside) { indoor = true; break; } } if (!indoor) { afterCut.Add(cuttedSegment); } } } UnitSystem currentDocUnits = RhinoDoc.ActiveDoc.ModelUnitSystem; double unitSystemScaler = RhinoMath.UnitScale(UnitSystem.Feet, currentDocUnits); foreach (LineCurve wallLine in afterCut) { LayerHelper.BakeObjectToLayer(Extrusion.Create(wallLine, 8 * unitSystemScaler, false).ToBrep(), "Walls", schemeName); } Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); }
public static List <Curve> BestSplitterCurves(List <Brep> zones, List <Curve> circ, Curve core) { int numZones = zones.Count; int numCircCurves = circ.Count; List <Curve> splitterCurves = new List <Curve>(); for (int i = 0; i < numZones; i++) { int validCircCurves = 0; List <bool> intersects = new List <bool>(); List <double> intersectionInterval = new List <double>(); //RhinoApp.WriteLine("---"); for (int j = 0; j < numCircCurves; j++) { if (Confirm.CurveRegionIntersection(circ[j], zones[i]) && circ[j].Degree == 1) { //RhinoApp.WriteLine("Region intersection exists."); validCircCurves++; intersects.Add(true); CurveIntersections csx = Intersection.CurveSurface(circ[j], zones[i].Surfaces[0], 0.1, 0.1); //RhinoApp.WriteLine("--{0} csx event(s). (Overlap: {1})", csx.Count, csx[0].OverlapA.ToString()); intersectionInterval.Add(csx[0].OverlapA.T1 - csx[0].OverlapB.T0); } else { //RhinoApp.WriteLine("Region intersection does not exist."); intersects.Add(false); intersectionInterval.Add(0); } } if (validCircCurves == 0) { //RhinoApp.WriteLine("No circulation options."); Curve newSplitCurve = Select.GenerateSplitCurve(zones[i], core); splitterCurves.Add(newSplitCurve); } if (validCircCurves == 1) { //RhinoApp.WriteLine("Only one option."); splitterCurves.Add(circ[intersects.IndexOf(true)]); } else if (validCircCurves > 1) { //RhinoApp.WriteLine(validCircCurves.ToString() + " options."); splitterCurves.Add(circ[intersectionInterval.IndexOf(intersectionInterval.Max())]); } intersects.Clear(); intersectionInterval.Clear(); } return(splitterCurves); }
DataTree <Point3d> getAllGridPoints(DataTree <Point3d> axisPoints) { // Assigns to '_grid' a tree with as many ranches as items contained in the gridAxisList DataTree <Point3d> resultingPoints = new DataTree <Point3d>(); for (int i = 0; i < axisPoints.BranchCount; i++) { // Iterate on all axises DataTree <Point3d> quarterGrid = new DataTree <Point3d>(); List <Point3d> xAxis; List <Point3d> yAxis; if (i % 2 == 0) { xAxis = axisPoints.Branch(new GH_Path(i + 1)); yAxis = axisPoints.Branch(new GH_Path(i)); if (i == axisPoints.BranchCount - 1) { xAxis = axisPoints.Branch(new GH_Path(0)); yAxis = axisPoints.Branch(new GH_Path(i)); } } else { xAxis = axisPoints.Branch(new GH_Path(i)); yAxis = axisPoints.Branch(new GH_Path(i + 1)); if (i == axisPoints.BranchCount - 1) { xAxis = axisPoints.Branch(new GH_Path(i)); yAxis = axisPoints.Branch(new GH_Path(0)); } } // Fill x and y axis list and wrap in the last index int[] complexPath = new int[] { i, 0 }; quarterGrid.AddRange(xAxis, new GH_Path(complexPath)); //Add xAxis to path 0 of the quarter for (int j = 1; j < yAxis.Count; j++) { // Iterate on all yAxis Points EXCEPT the first one complexPath = new int[] { i, j }; Point3d lastPoint = yAxis[j]; quarterGrid.Add(lastPoint, new GH_Path(complexPath)); //Add yAxis Point to list for (int k = 1; k < xAxis.Count; k++) { // Iterate on all xAxis Points EXCEPT the first one //Intersection!!! Sphere sphere1 = new Sphere(lastPoint, _desiredLength); Sphere sphere2 = new Sphere(xAxis[k], _desiredLength); Circle cir1; Intersection.SphereSphere(sphere1, sphere2, out cir1); CurveIntersections crvint = Intersection.CurveSurface(cir1.ToNurbsCurve(), _surface, 0.001, 0.001); if (crvint.Count <= 1) { // If one or 0 intersections are found BREAK break; } else { // If 2 points are found, filter by distance to diagonal point double u, v; foreach (IntersectionEvent iE in crvint) { iE.SurfacePointParameter(out u, out v); Point3d tmpPt = _surface.PointAt(u, v); //int[] diagPath = new int[] { i, j - 1 }; //Point3d diagPt = quarterGrid[new GH_Path(diagPath), k - 1]; double dist = tmpPt.DistanceTo(xAxis[k - 1]); if (dist < 0.02) { // Do nothing } else { quarterGrid.Add(tmpPt, new GH_Path(complexPath)); lastPoint = tmpPt; break; } } } } xAxis = quarterGrid.Branch(complexPath); } resultingPoints.MergeTree(quarterGrid); // Generate net using Grid createNetFromPoints(quarterGrid); } return(resultingPoints); }
//public VariableDivide() { } public static VariableDivide Divide(Curve crv, List <double> distanceList, int rep) { VariableDivide vd = new VariableDivide(); if (distanceList.Count == 0) { return(null); } if (rep > 2 | rep < 0) { rep = 0; } //Dictionary<int, List<double>>.ValueCollection values = dictDistances.Values; crv.Domain = new Interval(0, crv.GetLength()); double t1 = crv.Domain.T1; double tol = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; int i, j; i = j = -1; List <Curve> crvList = new List <Curve>(); List <Point3d> ptList = new List <Point3d>() { crv.PointAtStart }; List <Vector3d> vecList = new List <Vector3d>() { crv.TangentAtStart }; List <double> paramList = new List <double>() { 0.0 }; bool tolBool = false; bool endPtsBool = false; //warning message if (crv.PointAtStart.DistanceTo(crv.PointAtEnd) < distanceList.Max()) { endPtsBool = true; } List <Curve> curves = new List <Curve>(); curves.Sort((x, y) => x.PointAtStart.Z.CompareTo(y.PointAtStart.Z)); // Sort curve based on Height //recursion while (true) { //reset i if distance list end reached but curve is still long. if (i >= distanceList.Count - 1) { switch (rep) { case 0: i = -1; break; case 1: i = distanceList.Count - 2; break; case 2: goto Finish; } } // increment i++; j++; //intersection properties for double currentParam = paramList[j]; double currentDistance = distanceList[i]; NurbsSurface nurbsSrf = new Sphere(crv.PointAt(currentParam), currentDistance).ToNurbsSurface(); if (currentDistance < tol) // if current distance is smaller than document tolerance, remove distance from computation { tolBool = true; distanceList.RemoveAt(i); } currentDistance = crv.Split(currentParam)[0].GetLength() + (distanceList[i] * 1.1); // sphere-curve intersection // using overload with curve domain to limit intersection area- allows to break while-loop when curve reaches the end. CurveIntersections events = Intersection.CurveSurface(crv, new Interval(currentParam, currentDistance), nurbsSrf, tol, tol); if (events != null && events.Count > 0) { if (events.Last().ParameterA > paramList.Last()) { ptList.Add(events.Last().PointA); vecList.Add(crv.TangentAt(events.Last().ParameterA)); paramList.Add(events.Last().ParameterA); } else { break; } } else { break; } } Finish: crvList.Add(crv); ptList.Add(crv.PointAtEnd); vecList.Add(crv.TangentAtEnd); paramList.Add(crv.Domain.Max); vd.Curves = crvList; vd.Points = ptList; vd.Tangents = vecList; vd.Parameters = paramList; vd.WarningMessageTol = tolBool; vd.WarningMessageEndPts = endPtsBool; return(vd); }
public List <Curve> Compute(Mesh msh, Vector3d vec, List <Mesh> pMesh) { Plane pln = new Plane(new Point3d(0, 0, 0), vec); List <Curve> crvList = new List <Curve>(); double tol = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; List <PolyCurve> ppc = new List <PolyCurve>(); List <Curve> pc = new List <Curve>(); Polyline[] plArr = msh.GetOutlines(pln); List <PolylineCurve> _ppcs = new List <PolylineCurve>(); Parallel.For(0, plArr.Length, i => { _ppcs.Add(plArr[i].ToPolylineCurve()); }); Curve[] _ppc = Curve.JoinCurves(_ppcs); foreach (var c in _ppc) { ppc.Add(c as PolyCurve); } // for each mesh in projection Mesh , Get The outline as polyline. convert to curve and join Parallel.ForEach(pMesh, pM => { Polyline[] _pPl = pM.GetOutlines(pln); List <PolylineCurve> _pcs = new List <PolylineCurve>(); Parallel.For(0, _pPl.Length, i => { _pcs.Add(_pPl[i].ToPolylineCurve()); }); Curve[] _pc = Curve.JoinCurves(_pcs); foreach (Curve c in _pc) { pc.Add(c); } }); Parallel.For(0, plArr.Length, i => { Curve[] _crv = Curve.ProjectToMesh(ppc[i], pMesh, vec, tol); Parallel.ForEach(_crv, c => { if (c.IsClosed) { crvList.Add(c); } else { foreach (Curve curve in _ppcs) { CurveIntersections inter = Intersection.CurveCurve(c, curve, tol, tol); } } }); }); return(crvList); }
protected override void SolveInstance(IGH_DataAccess DA) { iPoints = new List <Point3d>(); DA.GetDataList <Point3d>("Points", iPoints); iApicals = new List <Circle>(); DA.GetDataList <Circle>("Apicals", iApicals); iMasses = new List <double>(); DA.GetDataList <double>("Masses", iMasses); DA.GetData <Curve>("Boundary Curve", ref iBoundaryCurve); DA.GetData <double>("Rest Length Scale", ref iRestLengthScale); DA.GetData <double>("Rest Length Offset", ref iRestLengthOffset); DA.GetData <double>("Stiffness", ref iStiffness); DA.GetData <double>("Bending Stiffness", ref iBendingStiffness); DA.GetData <bool>("In/Out Switch", ref iInOutSwitch); DA.GetData <double>("In/Out Threshold", ref iInOutThreshold); DA.GetData <double>("Boundary Vertex Threshold", ref iBoundaryVertexThreshold); iFixedPointExclusion = new List <Curve>(); DA.GetDataList <Curve>("Fixed Point Exclusion", iFixedPointExclusion); iFixedPointInclusion = new List <Curve>(); DA.GetDataList <Curve>("Fixed Point Inclusion", iFixedPointInclusion); // =========================================================================================== // Compute Delaunay Triangulation // =========================================================================================== List <DelaunayVertex> delaunayVertices = new List <DelaunayVertex>(); foreach (Point3d point in iPoints) { delaunayVertices.Add(new DelaunayVertex(point.X, point.Y)); } List <Triad> triads = new DelaunayTriangulator().Triangulation(delaunayVertices); HashSet <Tuple <int, int> > delaunayEdgeTuples = new HashSet <Tuple <int, int> >(); for (int i = 0; i < triads.Count; i++) { Triad triad = triads[i]; delaunayEdgeTuples.Add(triad.a < triad.b ? new Tuple <int, int>(triad.a, triad.b) : new Tuple <int, int>(triad.b, triad.a)); delaunayEdgeTuples.Add(triad.b < triad.c ? new Tuple <int, int>(triad.b, triad.c) : new Tuple <int, int>(triad.c, triad.b)); delaunayEdgeTuples.Add(triad.c < triad.a ? new Tuple <int, int>(triad.c, triad.a) : new Tuple <int, int>(triad.a, triad.c)); } // =========================================================================================== // Convert Delaunay mesh to particle-spring mesh // =========================================================================================== oSpringMesh = new SpringMesh(); Curve boundaryCurveXY = Curve.ProjectToPlane(iBoundaryCurve, Plane.WorldXY); // Create edge list ----------------------------------------------------------------------------------------------- foreach (Tuple <int, int> delaunayEdgeTuple in delaunayEdgeTuples) { Point3d A = iPoints[delaunayEdgeTuple.Item1]; Point3d B = iPoints[delaunayEdgeTuple.Item2]; Point3d M = 0.5 * (A + B); // Skip if the edge lies outside of the boundary double t; boundaryCurveXY.ClosestPoint(M, out t); Point3d N = boundaryCurveXY.PointAt(t); if (Vector3d.CrossProduct(boundaryCurveXY.TangentAt(t), M - N).Z *(iInOutSwitch ? -1.0 : 1.0) < 0.0 && Utils.DistanceSquared(M, N) > iInOutThreshold * iInOutThreshold) { continue; } double edgeLength = Utils.Distance(A, B); double restLength = iRestLengthScale * edgeLength + iRestLengthOffset; oSpringMesh.Edges.Add(new Edge(delaunayEdgeTuple.Item1, delaunayEdgeTuple.Item2, restLength, iStiffness, Math.PI, iBendingStiffness)); } // Create vertex list ----------------------------------------------------------------------------------------------- List <HashSet <int> > neighborVerticesSets = new List <HashSet <int> >(); for (int i = 0; i < iPoints.Count; i++) { neighborVerticesSets.Add(new HashSet <int>()); } foreach (Edge edge in oSpringMesh.Edges) { neighborVerticesSets[edge.FirstVertexIndex].Add(edge.SecondVertexIndex); neighborVerticesSets[edge.SecondVertexIndex].Add(edge.FirstVertexIndex); } for (int i = 0; i < iPoints.Count; i++) { Point3d p = iPoints[i]; double t; boundaryCurveXY.ClosestPoint(p, out t); bool vertexFixedness = false; bool isBoundaryVertex = false; bool isColumnVertex = false; if (Utils.Distance(p, boundaryCurveXY.PointAt(t)) < iBoundaryVertexThreshold) { vertexFixedness = true; isBoundaryVertex = true; } else { foreach (Curve curve in iFixedPointInclusion) { if (curve.Contains(p) == PointContainment.Inside) { vertexFixedness = true; isColumnVertex = true; break; } } } Vertex vertex = new Vertex(p, Vector3d.Zero, neighborVerticesSets[i].ToList <int>(), iMasses.Count == 1 ? iMasses[0] : iMasses[i], vertexFixedness); vertex.IsBoundaryVertex = isBoundaryVertex; vertex.IsColumnVertex = isColumnVertex; oSpringMesh.Vertices.Add(vertex); } // Set boundary edge ----------------------------------------------------------------------------------------------- foreach (Edge edge in oSpringMesh.Edges) { if (oSpringMesh.Vertices[edge.FirstVertexIndex].IsBoundaryVertex && oSpringMesh.Vertices[edge.SecondVertexIndex].IsBoundaryVertex) { edge.IsBoundaryEdge = true; } else if (oSpringMesh.Vertices[edge.FirstVertexIndex].IsColumnVertex && oSpringMesh.Vertices[edge.SecondVertexIndex].IsColumnVertex) { edge.IsColumnEdge = true; } } // Create triangle list ------------------------------------------------------------------------------------------------ Dictionary <Tuple <int, int, int>, int> tripletDict = new Dictionary <Tuple <int, int, int>, int>(); for (int k = 0; k < oSpringMesh.Edges.Count; k++) { Edge edge = oSpringMesh.Edges[k]; Vertex A = oSpringMesh.Vertices[edge.FirstVertexIndex]; Vertex B = oSpringMesh.Vertices[edge.SecondVertexIndex]; for (int i = 0; i < A.NeighborVertexIndices.Count; i++) { for (int j = 0; j < B.NeighborVertexIndices.Count; j++) { if (A.NeighborVertexIndices[i] == B.NeighborVertexIndices[j]) { Tuple <int, int, int> triplet = sortTriplet(edge.FirstVertexIndex, edge.SecondVertexIndex, A.NeighborVertexIndices[i]); if (tripletDict.ContainsKey(triplet)) { if (edge.FirstTriangleIndex < 0) { edge.FirstTriangleIndex = tripletDict[triplet]; edge.FirstAdjacentVertexIndex = A.NeighborVertexIndices[i]; } else { edge.SecondTriangleIndex = tripletDict[triplet]; edge.SecondAdjacentVertexIndex = A.NeighborVertexIndices[i]; } } else { oSpringMesh.Triangles.Add(new Triangle(triplet.Item1, triplet.Item2, triplet.Item3)); int triangleIndex = oSpringMesh.Triangles.Count - 1; if (edge.FirstTriangleIndex < 0) { edge.FirstTriangleIndex = triangleIndex; edge.FirstAdjacentVertexIndex = A.NeighborVertexIndices[i]; } else { edge.SecondTriangleIndex = triangleIndex; edge.SecondAdjacentVertexIndex = A.NeighborVertexIndices[i]; } tripletDict.Add(triplet, triangleIndex); } } } } } // =========================================================================================== // Compute edge indices for each triangle // =========================================================================================== for (int i = 0; i < oSpringMesh.Edges.Count; i++) { Edge edge = oSpringMesh.Edges[i]; Triangle triangle = oSpringMesh.Triangles[edge.FirstTriangleIndex]; if (triangle.FirstEdgeIndex == -1) { triangle.FirstEdgeIndex = i; } else if (triangle.SecondEdgeIndex == -1) { triangle.SecondEdgeIndex = i; } else { triangle.ThirdEdgeIndex = i; } if (edge.SecondTriangleIndex == -1) { continue; } triangle = oSpringMesh.Triangles[edge.SecondTriangleIndex]; if (triangle.FirstEdgeIndex == -1) { triangle.FirstEdgeIndex = i; } else if (triangle.SecondEdgeIndex == -1) { triangle.SecondEdgeIndex = i; } else { triangle.ThirdEdgeIndex = i; } } // =========================================================================================== // Rearange the vertex order in each triangle so the normal calculation is consistent // =========================================================================================== for (int i = 0; i < oSpringMesh.Triangles.Count; i++) { if (oSpringMesh.ComputeTriangleNormal(i).Z < 0.0) { int temp = oSpringMesh.Triangles[i].SecondVertexIndex; oSpringMesh.Triangles[i].SecondVertexIndex = oSpringMesh.Triangles[i].ThirdVertexIndex; oSpringMesh.Triangles[i].ThirdVertexIndex = temp; } } // =========================================================================================== // Rearranging edge adjacent vertex indices for consitency // =========================================================================================== foreach (Edge edge in oSpringMesh.Edges) { if (edge.SecondAdjacentVertexIndex == -1) { Point3d A = oSpringMesh.Vertices[edge.FirstVertexIndex].Position; Point3d B = oSpringMesh.Vertices[edge.SecondVertexIndex].Position; Point3d M = oSpringMesh.Vertices[edge.FirstAdjacentVertexIndex].Position; if (Vector3d.CrossProduct(B - A, M - A) * oSpringMesh.ComputeTriangleNormal(edge.FirstTriangleIndex) < 0.0) { Point3d temp = A; A = B; B = temp; } } else { Point3d A = oSpringMesh.Vertices[edge.FirstVertexIndex].Position; Point3d B = oSpringMesh.Vertices[edge.SecondVertexIndex].Position; Point3d M = oSpringMesh.Vertices[edge.FirstAdjacentVertexIndex].Position; Point3d N = oSpringMesh.Vertices[edge.SecondAdjacentVertexIndex].Position; if (Vector3d.CrossProduct(B - A, M - A) * oSpringMesh.ComputeTriangleNormal(edge.FirstAdjacentVertexIndex) < 0.0) { int temp = edge.FirstAdjacentVertexIndex; edge.FirstAdjacentVertexIndex = edge.SecondAdjacentVertexIndex; edge.SecondAdjacentVertexIndex = temp; temp = edge.FirstTriangleIndex; edge.FirstTriangleIndex = edge.SecondTriangleIndex; edge.SecondTriangleIndex = temp; } } } // =========================================================================================== // Compute adjacent vertex index for each triangle // =========================================================================================== //foreach (Triangle triangle in oSpringMesh.Triangles) //{ // Vertex firstVertex = oSpringMesh.Vertices[triangle.FirstVertexIndex]; // Vertex secondVertex = oSpringMesh.Vertices[triangle.SecondVertexIndex]; // Vertex thirdVertex = oSpringMesh.Vertices[triangle.ThirdVertexIndex]; // foreach (int firstNeighbourIndex in firstVertex.NeighborVertexIndices) // foreach (int secondNeighbourIndex in secondVertex.NeighborVertexIndices) // if (firstNeighbourIndex == secondNeighbourIndex && firstNeighbourIndex != triangle.ThirdVertexIndex) // triangle.FirstSecondAdjacentVertexIndex = firstNeighbourIndex; // foreach (int secondNeighbourIndex in secondVertex.NeighborVertexIndices) // foreach (int thirdNeighbourIndex in thirdVertex.NeighborVertexIndices) // if (secondNeighbourIndex == thirdNeighbourIndex && secondNeighbourIndex != triangle.FirstVertexIndex) // triangle.SecondThirdAdjacentVertexIndex = secondNeighbourIndex; // foreach (int thirdNeighbourIndex in thirdVertex.NeighborVertexIndices) // foreach (int firstNeighbourIndex in firstVertex.NeighborVertexIndices) // if (thirdNeighbourIndex == firstNeighbourIndex && thirdNeighbourIndex != triangle.SecondVertexIndex) // triangle.ThirdFirstAdjacentVertexIndex = thirdNeighbourIndex; //} // =========================================================================================== // 3D Boundary Curve // =========================================================================================== //Brep brep = Brep.CreatePatch(new List<GeometryBase>() { iBoundaryCurve }, null, DocumentTolerance()); //DA.SetDataList(2, new List<Brep>() { brep }); foreach (Vertex vertex in oSpringMesh.Vertices) { if (vertex.IsBoundaryVertex) { double t; boundaryCurveXY.ClosestPoint(vertex.Position, out t); Plane frame; boundaryCurveXY.PerpendicularFrameAt(t, out frame); CurveIntersections curveInteresections = Intersection.CurvePlane(iBoundaryCurve, frame, DocumentTolerance()); Point3d intersection = Point3d.Unset; double minDist = 999999.0; for (int i = 0; i < curveInteresections.Count; i++) { double d = vertex.Position.DistanceTo(curveInteresections[i].PointA); if (d < minDist) { minDist = d; intersection = curveInteresections[i].PointA; } } vertex.Position = intersection; } else { //LineCurve lineCurve = new LineCurve( // new Point3d(vertex.Position.X, vertex.Position.Y, vertex.Position.Z - 10.0), // new Point3d(vertex.Position.X, vertex.Position.Y, vertex.Position.Z + 10.0) // ); //Curve[] overlapCurves; //Point3d[] intersectionPoints; //Intersection.CurveBrep(lineCurve, brep, DocumentTolerance(), out overlapCurves, out intersectionPoints); //if (intersectionPoints.Length > 0) // vertex.Position = intersectionPoints[0]; } } // =========================================================================================== // Initial curving bias // =========================================================================================== DA.GetData <double>("Initial Curving Bias", ref iInitialCurvingBias); DA.GetData <bool>("Bias Apical Regions", ref iBiasApicalRegion); foreach (Vertex vertex in oSpringMesh.Vertices) { if (vertex.IsBoundaryVertex || vertex.IsFixed) { continue; } vertex.Position.Z = computeBiasHeight(vertex.Position, iBiasApicalRegion, boundaryCurveXY); } // =========================================================================================== // Conclusion // =========================================================================================== foreach (Edge edge in oSpringMesh.Edges) { oDebugCurves1.Add(new LineCurve(oSpringMesh.Vertices[edge.FirstVertexIndex].Position, oSpringMesh.Vertices[edge.SecondVertexIndex].Position)); } DA.SetData(0, oInfo); DA.SetDataList(1, oDebugCurves1); DA.SetData(6, oSpringMesh); }
protected override void SolveInstance(IGH_DataAccess DA) { //Input Surface S = null; if (!DA.GetData(0, ref S)) { return; } Point3d P = Point3d.Unset; if (!DA.GetData(1, ref P)) { P = S.PointAt(S.Domain(0).Mid, S.Domain(1).Mid); } double R = Rhino.RhinoMath.UnsetValue; if (!DA.GetData(2, ref R)) { return; } double A = Rhino.RhinoMath.UnsetValue; if (!DA.GetData(3, ref A)) { return; } int max = 0; if (!DA.GetData(4, ref max)) { return; } Boolean extend = false; if (!DA.GetData(5, ref extend)) { return; } if (R <= 0) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Mesh edge length must be a positive, non-zero number."); return; } Surface Sold = S; if (extend) //Extend more and trim edges? { S = S.Extend(IsoStatus.North, R * 2, true); S = S.Extend(IsoStatus.East, R * 2, true); S = S.Extend(IsoStatus.South, R * 2, true); S = S.Extend(IsoStatus.West, R * 2, true); } //----------------------------------------------------------------------------------------------------------// //Solution // starting point double u0, v0; S.ClosestPoint(P, out u0, out v0); //Create plane on surface by point and surface normal, plane x,y axis are directions for the net Plane plane = new Plane(S.PointAt(u0, v0), S.NormalAt(u0, v0)); plane.Rotate(Rhino.RhinoMath.ToRadians(A), S.NormalAt(u0, v0)); Vector3d[] dir = new Vector3d[] { plane.XAxis *R, plane.YAxis *R, plane.XAxis * -R, plane.YAxis * -R }; //Surface Curve[] MyNakedEdges = Sold.ToBrep().DuplicateNakedEdgeCurves(true, false); Mesh[] meshes = new Mesh[] { new Mesh(), new Mesh(), new Mesh(), new Mesh() }; //----------------------------------------------------------------------------------------------------------// //Create axis // for each direction, walk out (and store list of points) double u, v; List <Point3d>[] axis = new List <Point3d> [4]; List <Arc>[] arcs = new List <Arc> [4]; polylines = new List <Polyline>(); for (int i = 0; i < 4; i++) { // set u and v to starting point u = u0; v = v0; List <Point3d> pts = new List <Point3d>(); List <Arc> arcCurrent = new List <Arc>(); for (int j = 0; j < max + 1; j++) { Point3d pt = S.PointAt(u, v); // get point and normal for uv pts.Add(pt); Vector3d srfNormal = S.NormalAt(u, v) * R; Arc arc = new Arc(pt + srfNormal, pt + dir[i], pt - srfNormal); // create forward facing arc and find intersection point with surface (as uv) arcCurrent.Add(arc); CurveIntersections isct = Intersection.CurveSurface(arc.ToNurbsCurve(), S, 0.01, 0.01); if (isct.Count > 0) { isct[0].SurfacePointParameter(out u, out v); } else { break; } // adjust direction vector (new position - old position) dir[i] = S.PointAt(u, v) - pt; } axis[i] = pts; arcs[i] = arcCurrent; } //----------------------------------------------------------------------------------------------------------// //Build up the mesh quads in between GH_PreviewUtil preview = new GH_PreviewUtil(GetValue("Animate", false)); Mesh mesh = new Mesh(); // target mesh for (int k = 0; k < 4; k++) //Loop through each axis { Mesh qmesh = new Mesh(); // local mesh for quadrant int k0 = (k + 1) % 4; //Take neighbour id Point3d[,] quad = new Point3d[axis[k].Count + 10, axis[k0].Count + 10]; // 2d array of points int[,] qindex = new int[axis[k].Count + 10, axis[k0].Count + 10]; // 2d array of points' indices in local mesh int count = 0; for (int i = 0; i < axis[k0].Count; i++) { quad[0, i] = axis[k0][i]; //store 2nd axis points in point array qmesh.Vertices.Add(axis[k0][i]); //also add 2nd axis points to mesh qindex[0, i] = count++; //store indicies } for (int i = 1; i < quad.GetLength(0); i++) { if (i < axis[k].Count) // add axis vertex { quad[i, 0] = axis[k][i]; //store 1st axis points in point array qmesh.Vertices.Add(axis[k][i]); //also add 1st axis points to mesh qindex[i, 0] = count++; //store indicies } // for each column attempt to locate a new vertex in the grid for (int j = 1; j < quad.GetLength(1); j++) { // if quad[i - 1, j] doesn't exist, try to add it and continue (or else break the current row) if (quad[i - 1, j] == new Point3d()) { if (j < 2) { break; } CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j - 1], quad[i - 1, j - 2], R); if (isct.Count > 0) { quad[i - 1, j] = isct[0].PointB; qmesh.Vertices.Add(quad[i - 1, j]); qindex[i - 1, j] = count++; } else { break; } } // if quad[i, j - 1] doesn't exist, try to create quad[i, j] by projection and skip mesh face creation if (quad[i, j - 1] == new Point3d()) { if (i < 2) { break; } CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j], quad[i - 2, j], R); if (isct.Count > 0) { quad[i, j] = isct[0].PointB; qmesh.Vertices.Add(quad[i, j]); qindex[i, j] = count++; continue; } } // construct a sphere at each neighbouring vertex ([i,j-1] and [i-1,j]) and intersect Sphere sph1 = new Sphere(quad[i, j - 1], R); Sphere sph2 = new Sphere(quad[i - 1, j], R); Circle cir; if (Intersection.SphereSphere(sph1, sph2, out cir) == SphereSphereIntersection.Circle) { CurveIntersections cin = Intersection.CurveSurface(NurbsCurve.CreateFromCircle(cir), S, 0.01, 0.01);// intersect circle with surface // attempt to find the new vertex (i.e not [i-1,j-1]) foreach (IntersectionEvent ie in cin) { if ((ie.PointA - quad[i - 1, j - 1]).Length > 0.2 * R) // compare with a tolerance, rather than exact comparison { quad[i, j] = ie.PointA; qmesh.Vertices.Add(quad[i, j]); qindex[i, j] = count++; Point3d[] facePt = new Point3d[] { quad[i, j], quad[i - 1, j], quad[i - 1, j - 1], quad[i, j - 1] }; Sold.ClosestPoint(quad[i, j], out double u1, out double v1); Sold.ClosestPoint(quad[i - 1, j], out double u2, out double v2); Sold.ClosestPoint(quad[i - 1, j - 1], out double u3, out double v3); Sold.ClosestPoint(quad[i, j - 1], out double u4, out double v4); double tolerance = 0.01; bool[] flag = new bool[] { Sold.PointAt(u1, v1).DistanceTo(quad[i, j]) < tolerance, Sold.PointAt(u2, v2).DistanceTo(quad[i - 1, j]) < tolerance, Sold.PointAt(u3, v3).DistanceTo(quad[i - 1, j - 1]) < tolerance, Sold.PointAt(u4, v4).DistanceTo(quad[i, j - 1]) < tolerance }; if (flag[0] && flag[1] && flag[2] && flag[3]) { qmesh.Faces.AddFace(qindex[i, j], qindex[i - 1, j], qindex[i - 1, j - 1], qindex[i, j - 1]);// create quad-face } else if (flag[0] || flag[1] || flag[2] || flag[3]) { Polyline temp = new Polyline(); for (int p = 0; p < 4; p++) { switch (Convert.ToInt32(flag[p]) * 10 + Convert.ToInt32(flag[(p + 1) % 4])) { case (11): temp.Add(facePt[p]); break; case (10): temp.Add(facePt[p]); temp.Add(ClosestPointOnNakedEdge(MyNakedEdges, facePt[p], new Line(facePt[p], facePt[(p + 1) % 4]))); break; case (1): temp.Add(ClosestPointOnNakedEdge(MyNakedEdges, facePt[p], new Line(facePt[p], facePt[(p + 1) % 4]))); break; case (0): Sold.ClosestPoint(facePt[p], out double u6, out double v6); temp.Add(Sold.PointAt(u6, v6)); break; } } temp.Close(); polylines.Add(temp); //qmesh.Faces.AddFace(qindex[i, j], qindex[i - 1, j], qindex[i - 1, j - 1], qindex[i, j - 1]);// create quad-face } //qmesh.Faces.AddFace(qindex[i, j], qindex[i - 1, j], qindex[i - 1, j - 1], qindex[i, j - 1]);// create quad-face break; } } if (preview.Enabled) { preview.Clear(); preview.AddMesh(mesh); preview.AddMesh(qmesh); preview.Redraw(); } } } } ; mesh.Append(qmesh);// add local mesh to target } //----------------------------------------------------------------------------------------------------------// //Output mesh.Weld(Math.PI); mesh.Compact(); mesh.Normals.ComputeNormals(); DA.SetData(0, mesh); DA.SetDataTree(1, NGonsCore.GrasshopperUtil.IEOfIEToTree(axis, 0)); DA.SetDataList(2, polylines); preview.Clear(); }
public Curve CutCurveBetweenPerpIndexes(Curve g, List <Curve> perpGs, int index1, int index2) { Curve tempG = g.DuplicateCurve(); tempG.Domain = new Interval(0, 1); CurveIntersections curveInt = Intersection.CurveCurve(tempG, perpGs[index1], 0.0001, 0.0001); CurveIntersections curveInt2 = Intersection.CurveCurve(tempG, perpGs[index2], 0.0001, 0.0001); double t1 = tempG.Domain.T0; double t2 = tempG.Domain.T1; if (curveInt.Count != 0) { t1 = curveInt[0].ParameterA; } if (curveInt2.Count != 0) { t2 = curveInt2[0].ParameterA; } double tMid; if (t1 > t2) { double temp = t1; t1 = t2; t2 = temp; } tMid = (t2 + t1) / 2; Point3d midPoint = tempG.PointAt(tMid); if (curveInt.Count != 0 && t1 > tempG.Domain.T0) { Curve[] splitCurves = tempG.Split(t1); foreach (Curve crv in splitCurves) { double closestT; crv.ClosestPoint(midPoint, out closestT); double distance = midPoint.DistanceTo(crv.PointAt(closestT)); if (distance < 0.001) { tempG = crv; } } } tempG.Domain = new Interval(0, 1); t2 = tempG.Domain.T1; curveInt2 = Intersection.CurveCurve(tempG, perpGs[index2], 0.0001, 0.0001); if (curveInt2.Count != 0) { t2 = curveInt2[0].ParameterA; } if (curveInt2.Count != 0 && t2 < tempG.Domain.T1 && t2 > 0) { Curve[] splitCurves = tempG.Split(t2); foreach (Curve crv in splitCurves) { double closestT; crv.ClosestPoint(midPoint, out closestT); double distance = midPoint.DistanceTo(crv.PointAt(closestT)); if (distance < 0.001) { tempG = crv; } } } return(tempG); }
internal void indentifyAllFlippedEdges() { flippedEdgeInfo = new List <FlippedEdge>(); for (int i = 0; i < proxyToMesh.faces.Count; i++) { Face face = proxyToMesh.faces[i]; Curve curve = face.convertFaceToPolyLine().ToNurbsCurve(); CurveIntersections intersections = Intersection.CurveSelf(curve, 0.1); if (intersections.Count > 0) { controller.errorContainer.Add("Flipped edge check: " + intersections.Count.ToString() + " intersection(s) found"); for (int j = 0; j < intersections.Count; j++) { IntersectionEvent intersection = intersections[j]; if (intersection.IsPoint) { int refA = (int)Math.Floor(intersection.ParameterA); int refB = (int)Math.Floor(intersection.ParameterB); if (refB == face.faceEdges.Count) { //has rounded up to the end of the curve //is this possible maybe happening in lots of places //not ideal!!! //refB--; } if (face.faceEdges.Count == 4) {//if 4 add both... List <int> refsToAdd = new List <int>(); for (int k = 0; k < 4; k++) { if (k != refA && k != refB) { refsToAdd.Add(k); } } if (refsToAdd.Count != 2) { } addToFlippedEdgeInfo(refsToAdd[0], face, intersection); addToFlippedEdgeInfo(refsToAdd[1], face, intersection); } else { int flippedEdgeIndex; if (refB - refA == 2) { flippedEdgeIndex = refB - 1; } else if ((refA + face.faceEdges.Count) - refB == 2) { flippedEdgeIndex = (refB + 1) % face.faceEdges.Count; } else { flippedEdgeIndex = -1; //do not have a simple flipped edge, need to do something else } if (flippedEdgeIndex != -1) { addToFlippedEdgeInfo(flippedEdgeIndex, face, intersection); } } } } } } }
protected override void SolveInstance(IGH_DataAccess DA) { try { //Input Surface S = s; //if (!DA.GetData(0, ref S)) { return; } DA.GetData(0, ref S); Point3d P = Point3d.Unset; if (!DA.GetData(1, ref P)) { P = S.PointAt(S.Domain(0).Mid, S.Domain(1).Mid); } double R = Rhino.RhinoMath.UnsetValue; if (!DA.GetData(2, ref R)) { return; } double A = Rhino.RhinoMath.UnsetValue; if (!DA.GetData(3, ref A)) { return; } int max = 0; if (!DA.GetData(4, ref max)) { return; } Boolean extend = false; if (!DA.GetData(5, ref extend)) { return; } if (R <= 0) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Mesh edge length must be a positive, non-zero number."); return; } Mesh cutter = new Mesh(); //DA.GetData(8, ref cutter); Surface Sold = S; Sold.SetDomain(0, new Interval(0, 1)); Sold.SetDomain(1, new Interval(0, 1)); PointCloud cornerPoints = new PointCloud(new Point3d[] { Sold.PointAt(0, 0), Sold.PointAt(0, 1), Sold.PointAt(1, 0), Sold.PointAt(1, 1) }); if (extend) //Extend more and trim edges? { S = S.Extend(IsoStatus.North, R * 2, true); S = S.Extend(IsoStatus.East, R * 2, true); S = S.Extend(IsoStatus.South, R * 2, true); S = S.Extend(IsoStatus.West, R * 2, true); } //int L = 0; //int W = 0; //DA.GetData(6, ref L); //DA.GetData(7, ref W); //----------------------------------------------------------------------------------------------------------// //Solution // starting point double u0, v0; S.ClosestPoint(P, out u0, out v0); //Create plane on surface by point and surface normal, plane x,y axis are directions for the net Plane plane = new Plane(S.PointAt(u0, v0), S.NormalAt(u0, v0)); plane.Rotate(Rhino.RhinoMath.ToRadians(A), S.NormalAt(u0, v0)); Vector3d[] dir = new Vector3d[] { plane.XAxis *R, plane.YAxis *R, plane.XAxis * -R, plane.YAxis * -R }; //Surface Curve[] MyNakedEdges = Sold.ToBrep().DuplicateNakedEdgeCurves(true, false); Curve SurfaceNakedEdge = Curve.JoinCurves(MyNakedEdges)[0]; Mesh[] meshes = new Mesh[] { new Mesh(), new Mesh(), new Mesh(), new Mesh() }; //----------------------------------------------------------------------------------------------------------// //Create axis // for each direction, walk out (and store list of points) double u, v; List <Point3d>[] axis = new List <Point3d> [4]; List <Arc>[] arcs = new List <Arc> [4]; polylines = new List <Polyline>(); for (int i = 0; i < 4; i++) { // set u and v to starting point u = u0; v = v0; List <Point3d> pts = new List <Point3d>(); List <Arc> arcCurrent = new List <Arc>(); for (int j = 0; j < max + 1; j++) { Point3d pt = S.PointAt(u, v); // get point and normal for uv pts.Add(pt); Vector3d srfNormal = S.NormalAt(u, v) * R; Arc arc = new Arc(pt + srfNormal, pt + dir[i], pt - srfNormal); // create forward facing arc and find intersection point with surface (as uv) arcCurrent.Add(arc); CurveIntersections isct = Intersection.CurveSurface(arc.ToNurbsCurve(), S, 0.01, 0.01); if (isct.Count > 0) { isct[0].SurfacePointParameter(out u, out v); } else { break; } // adjust direction vector (new position - old position) dir[i] = S.PointAt(u, v) - pt; } axis[i] = pts; arcs[i] = arcCurrent; } //----------------------------------------------------------------------------------------------------------// //Build up the mesh quads in between Rhino.RhinoApp.ClearCommandHistoryWindow(); GH_PreviewUtil preview = new GH_PreviewUtil(GetValue("Animate", false)); Mesh mesh = new Mesh(); // target mesh Mesh[] fourMeshes = new Mesh[4]; List <int>[] faceID = new List <int>[] { new List <int>(), new List <int>(), new List <int>(), new List <int>() }; //columns lengths List <List <Polyline> >[] strips = new List <List <Polyline> >[] { new List <List <Polyline> >(), new List <List <Polyline> >(), new List <List <Polyline> >(), new List <List <Polyline> >() }; //columns lengths //List<Polyline> cuts = new List<Polyline>(); for (int k = 0; k < 4; k++) //Loop through each axis { Mesh qmesh = new Mesh(); // local mesh for quadrant Point3d[,] quad = new Point3d[axis[k].Count + 10, axis[(k + 1) % 4].Count + 10]; // 2d array of points int[,] qindex = new int[axis[k].Count + 10, axis[(k + 1) % 4].Count + 10]; // 2d array of points' indices in local mesh int count = 0; //Add 2nd axis particles for (int i = 0; i < axis[(k + 1) % 4].Count; i++) { quad[0, i] = axis[(k + 1) % 4][i]; //store 2nd axis points in point array qmesh.Vertices.Add(axis[(k + 1) % 4][i]); //also add 2nd axis points to mesh qindex[0, i] = count++; //store indicies } for (int i = 1; i < quad.GetLength(0); i++) { if (i < axis[k].Count) // add axis vertex { quad[i, 0] = axis[k][i]; //store 1st axis points in point array qmesh.Vertices.Add(axis[k][i]); //also add 1st axis points to mesh qindex[i, 0] = count++; //store indicies } int counter = 0; List <Polyline> currentStrip = new List <Polyline>(); // for each column attempt to locate a new vertex in the grid for (int j = 1; j < quad.GetLength(1); j++) { // if quad[i - 1, j] doesn't exist, try to add it and continue (or else break the current row) if (quad[i - 1, j] == new Point3d()) { if (j < 2) { break; } CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j - 1], quad[i - 1, j - 2], R); if (isct.Count > 0) { quad[i - 1, j] = isct[0].PointB; qmesh.Vertices.Add(quad[i - 1, j]); qindex[i - 1, j] = count++; } else { break; } } // if quad[i, j - 1] doesn't exist, try to create quad[i, j] by projection and skip mesh face creation if (quad[i, j - 1] == new Point3d()) { if (i < 2) { break; } CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j], quad[i - 2, j], R); if (isct.Count > 0) { quad[i, j] = isct[0].PointB; qmesh.Vertices.Add(quad[i, j]); qindex[i, j] = count++; continue; } } // construct a sphere at each neighbouring vertex ([i,j-1] and [i-1,j]) and intersect Sphere sph1 = new Sphere(quad[i, j - 1], R); Sphere sph2 = new Sphere(quad[i - 1, j], R); Circle cir; if (Intersection.SphereSphere(sph1, sph2, out cir) == SphereSphereIntersection.Circle) { CurveIntersections cin = Intersection.CurveSurface(NurbsCurve.CreateFromCircle(cir), S, 0.01, 0.01);// intersect circle with surface // attempt to find the new vertex (i.e not [i-1,j-1]) foreach (IntersectionEvent ie in cin) { if ((ie.PointA - quad[i - 1, j - 1]).Length > 0.2 * R) // compare with a tolerance, rather than exact comparison { quad[i, j] = ie.PointA; qmesh.Vertices.Add(quad[i, j]); qindex[i, j] = count++; Point3d[] facePt = new Point3d[] { quad[i, j], quad[i - 1, j], quad[i - 1, j - 1], quad[i, j - 1] }; Sold.ClosestPoint(quad[i, j], out double u1, out double v1); Sold.ClosestPoint(quad[i - 1, j], out double u2, out double v2); Sold.ClosestPoint(quad[i - 1, j - 1], out double u3, out double v3); Sold.ClosestPoint(quad[i, j - 1], out double u4, out double v4); double tolerance = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance * 10; bool[] flag = new bool[] { Sold.PointAt(u1, v1).DistanceTo(quad[i, j]) < tolerance, Sold.PointAt(u2, v2).DistanceTo(quad[i - 1, j]) < tolerance, Sold.PointAt(u3, v3).DistanceTo(quad[i - 1, j - 1]) < tolerance, Sold.PointAt(u4, v4).DistanceTo(quad[i, j - 1]) < tolerance }; if (flag[0] && flag[1] && flag[2] && flag[3]) { qmesh.Faces.AddFace(qindex[i, j], qindex[i - 1, j], qindex[i - 1, j - 1], qindex[i, j - 1]);// create quad-face currentStrip.Add(new Polyline() { quad[i, j], quad[i - 1, j], quad[i - 1, j - 1], quad[i, j - 1], quad[i, j] }); counter++; } else if (flag[0] || flag[1] || flag[2] || flag[3]) { Polyline temp = new Polyline() { quad[i, j], quad[i - 1, j], quad[i - 1, j - 1], quad[i, j - 1] }; Polyline trimmedTemp = new Polyline(); //temp = new Polyline() { quad[i, j], quad[i - 1, j], quad[i - 1, j - 1], quad[i, j - 1], quad[i, j] }; double t = R * 0.1; HashSet <int> intersectedSurfaceEdgeId = new HashSet <int>(); for (int l = 0; l < 4; l++) { //If point is ons surface Sold.ClosestPoint(temp[l], out double cpu, out double cpv); if (Sold.PointAt(cpu, cpv).DistanceTo(temp[l]) < Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) { trimmedTemp.Add(temp[l]); } //Intersect line segment with closed brep Line faceSegment = new Line(temp[l], temp[MathUtil.Wrap(l + 1, 4)]); Point3d[] meshLinePts = Intersection.MeshLine(cutter, faceSegment, out int[] faceIds); if (meshLinePts.Length > 0) { trimmedTemp.Add(meshLinePts[0]); } } trimmedTemp.Close(); //cuts.Add(trimmedTemp); } break; } } if (preview.Enabled) { preview.Clear(); preview.AddMesh(mesh); preview.AddMesh(qmesh); preview.Redraw(); } } //if sphere intersection } //for j if (currentStrip.Count > 0) { strips[k].Add(currentStrip); } }//for i mesh.Append(qmesh);// add local mesh to target fourMeshes[k] = qmesh; }//for k //----------------------------------------------------------------------------------------------------------// //Output mesh.Weld(Math.PI); mesh.Compact(); mesh.Normals.ComputeNormals(); DA.SetData(0, mesh); DA.SetDataTree(1, NGonsCore.GrasshopperUtil.IE2(axis, 0)); this.PreparePreview(mesh, DA.Iteration, null, true, null, mesh.GetEdges()); //DA.SetDataList(2, cuts); //DA.SetDataTree(3, NGonsCore.GrasshopperUtil.IE4(patches.ToList(), 0)); //DA.SetDataList(4, fourMeshes); //DA.SetDataTree(5, GrasshopperUtil.IE3(strips, 0)); preview.Clear(); }catch (Exception e) { GrasshopperUtil.Debug(e); } }
private SolveResults ComputeDivs(Curve crv, ConcurrentDictionary <int, List <double> > distanceList) { distanceList.Values[1] if (distanceList.Count == 0) { return(null); } if (crv.PointAtStart.DistanceTo(crv.PointAtEnd) < distanceList.Max()) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, " Distance between start and end points of curve(s) may be too small." + " If it yields undesirable results, consider increasing distance between them to max value in the supplied distances."); } // if parameter is within region A, use items from dictionary list A ) // SolveResults result = new SolveResults(); crv.Domain = new Interval(0, crv.GetLength()); double t1 = crv.Domain.T1; double tol = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; int i, j; i = j = -1; List <Curve> crvList = new List <Curve>(); List <Point3d> ptList = new List <Point3d>() { crv.PointAtStart }; List <double> paramList = new List <double>() { 0.0 }; //List<double> div2 = distanceList2; // TODO: Fix intersection issues with curves that have their start and End points too close to each other; eg:closed curves. while (true) { //reset i if distance list end reached and curve still exists. if (i >= distanceList.Count - 1) { i = -1; } // increment i++; j++; if (distanceList[i] < tol) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, " Distances less than or equal to rhino model tolerance will be ignored"); distanceList.RemoveAt(i); } // sphere-curve intersection // using overload with curve domain to limit intersection area- allows to break while-loop when curve reaches the end. CurveIntersections events = Intersection.CurveSurface(crv, new Interval(paramList[j], t1), new Sphere(crv.PointAt(paramList[j]), distanceList[i]).ToNurbsSurface(), tol, tol); if (events != null && events.Count > 0) { paramList.Add(events.Last().ParameterA); ptList.Add(events.Last().PointA); } else { break; } } crvList.Add(crv); ptList.Add(crv.PointAtEnd); paramList.Add(crv.Domain.Max); result.Curves = crvList; result.Points = ptList; result.Parameters = paramList; //result.div2 = div2; return(result); }
//Create inner Parkinglots private void CreateInnerParkinglots(Curve boundaryCurve, LocalRules localRules, Plane plane) { //Create offset curve with outer booth and driveway distance BoundingBox bx = boundaryCurve.GetBoundingBox(Plane.WorldXY); Point3d[] bxPT = bx.GetCorners(); Vector3d outsideVector = bxPT[0] - bxPT[2]; outsideVector.Unitize(); Point3d outsidePT = bxPT[0] + outsideVector; Curve[] innerBounderyCrv = boundaryCurve.Offset(outsidePT, Vector3d.ZAxis, -(localRules.BoothDepth + localRules.ManeuveringArea), 0.5, CurveOffsetCornerStyle.Sharp); //Sometimes offset fails. This checks for that and uses alternative method, less precise method if (innerBounderyCrv[0].GetLength() < ((localRules.BoothDepth + localRules.ManeuveringArea) * 2) + Math.Sqrt((Math.Pow(localRules.BoothDepth + localRules.ManeuveringArea, 2) * 2)) + 1) { innerBounderyCrv = boundaryCurve.Offset(Plane.WorldXY, localRules.BoothDepth + localRules.ManeuveringArea, 0.01, CurveOffsetCornerStyle.Sharp); //Check direction if (innerBounderyCrv[0].Contains(boundaryCurve.PointAtStart, Plane.WorldXY, 0.01) == PointContainment.Inside) { innerBounderyCrv = boundaryCurve.Offset(Plane.WorldXY, -(localRules.BoothDepth + localRules.ManeuveringArea), 0.01, CurveOffsetCornerStyle.Sharp); } } debug.AddRange(innerBounderyCrv); //Create BB and centerlines innerBounderyCrv[0].GetBoundingBox(plane, out Box boundarybox); Point3d[] boxCorners = boundarybox.GetCorners(); Line startLine = new Line(boxCorners[0], boxCorners[1]); Line endLine = new Line(boxCorners[3], boxCorners[2]); // Direction of inner booths Vector3d boothDir = startLine.UnitTangent; boothDir.Unitize(); boothDir = Vector3d.Multiply(localRules.BoothDepth, boothDir); //Copy center lines according to distancerules List <Curve> copyLines = new List <Curve>(); for (double i = localRules.BoothDepth; i < startLine.Length;) { Point3d startPT = startLine.PointAtLength(i); Point3d endPT = endLine.PointAtLength(i); copyLines.Add(new Line(startPT, endPT).ToNurbsCurve()); i = i + (localRules.BoothDepth * 2) + localRules.ManeuveringArea; } //Find inner curves foreach (Curve crvline in copyLines) { var curveEvent = Intersection.CurveCurve(innerBounderyCrv[0], crvline, 0, 0); if (curveEvent != null) { List <double> curveT = new List <double>(); for (int i = 0; i < curveEvent.Count; i++) { var crvLine = curveEvent[i]; curveT.Add(crvLine.ParameterB); } Curve[] curveSplit = crvline.Split(curveT); foreach (Curve curve in curveSplit) { double midT = (curve.Domain.T0 + curve.Domain.T1) / 2; if (innerBounderyCrv[0].Contains(curve.PointAt(midT), Plane.WorldXY, 0).Equals(PointContainment.Inside)) { CenterLines.Add(curve); } } } } //Parking Booths foreach (Curve curve in CenterLines) { curve.DivideByLength(localRules.BoothWidth, true, false, out Point3d[] points); if (points == null) { continue; } foreach (Point3d point in points) { //One way Plane boothPlane = new Plane(point, curve.TangentAt(0.1), boothDir); Parkingspace parkingspace = new Parkingspace(boothPlane, localRules, true); parkingLinesLeft.Add(parkingspace); //Opposite way boothDir.Reverse(); boothPlane = new Plane(point, curve.TangentAt(0.1), boothDir); parkingspace = new Parkingspace(boothPlane, localRules, true); parkingLinesLeft.Add(parkingspace); //Return Vector boothDir.Reverse(); } PointCloud startPTsLeft = new PointCloud(); PointCloud startPTsRight = new PointCloud(); PointCloud allStartPT = new PointCloud(); //Check for collision with driving path List <Parkingspace> finalParkingLinesLeft = new List <Parkingspace>(); List <Parkingspace> finalParkingLinesRight = new List <Parkingspace>(); for (int i = 0; i < parkingLinesLeft.Count; i++) { CurveIntersections crvEvent = Intersection.CurveCurve(innerBounderyCrv[0], parkingLinesLeft[i].Curves, 0.0001, 0.0000); if (crvEvent.Count > 0) { parkingEnds.Add(parkingLinesLeft[i].Curves); } else { finalParkingLinesLeft.Add(parkingLinesLeft[i]); startPTsLeft.Add(parkingLinesLeft[i].Curves.PointAtStart); allStartPT.Add(parkingLinesLeft[i].Curves.PointAtStart); } } for (int i = 0; i < parkingLinesRight.Count; i++) { CurveIntersections crvEvent = Intersection.CurveCurve(innerBounderyCrv[0], parkingLinesRight[i].Curves, 0.0001, 0.0000); if (crvEvent.Count > 0) { parkingEnds.Add(parkingLinesRight[i].Curves); } else { finalParkingLinesRight.Add(parkingLinesRight[i]); startPTsRight.Add(parkingLinesRight[i].Curves.PointAtStart); allStartPT.Add(parkingLinesRight[i].Curves.PointAtStart); } } //try //{ // //Fix one end // Point3d crvEnd = curve.PointAtEnd; // Curve endCurve = createEnds(innerBounderyCrv, startPTsLeft, startPTsRight, finalParkingLinesLeft, finalParkingLinesRight, crvEnd); // notParkingSpaces.Add(endCurve); // Curve splitCurveOne = splitend(curve, allStartPT, crvEnd); // //Fix the other end // Point3d crvStart = curve.PointAtStart; // endCurve = createEnds(innerBounderyCrv, startPTsLeft, startPTsRight, finalParkingLinesLeft, finalParkingLinesRight, crvStart); // notParkingSpaces.Add(endCurve); // notParkingSpaces.Add(splitend(splitCurveOne, allStartPT, crvStart)); //} //catch //{ //} Spaces.AddRange(finalParkingLinesLeft); Spaces.AddRange(finalParkingLinesRight); parkingLinesLeft.Clear(); parkingLinesRight.Clear(); } parkingspaceNO = Spaces.Count; }
public Curve SplitGeodesicWithCurves(Curve geod, Curve perp1, Curve perp2) { Curve tempG = geod.DuplicateCurve(); // Copy curve to temp tempG.Domain = new Interval(0, 1); // Normalize curve domain // Get intersections CurveIntersections curveInt = Intersection.CurveCurve(tempG, perp1, 0.0001, 0.0001); CurveIntersections curveInt2 = Intersection.CurveCurve(tempG, perp2, 0.0001, 0.0001); double t1 = tempG.Domain.T0; double t2 = tempG.Domain.T1; if (curveInt.Count != 0) { t1 = curveInt[0].ParameterA; } if (curveInt2.Count != 0) { t2 = curveInt2[0].ParameterA; } double tMid; if (t1 > t2) { double temp = t1; t1 = t2; t2 = temp; } tMid = (t2 + t1) / 2; Point3d midPoint = tempG.PointAt(tMid); if (curveInt.Count != 0 && t1 > tempG.Domain.T0) { Curve[] splitCurves = tempG.Split(t1); if (splitCurves != null) { foreach (Curve crv in splitCurves) { double closestT; crv.ClosestPoint(midPoint, out closestT); double distance = midPoint.DistanceTo(crv.PointAt(closestT)); if (distance < 0.001) { tempG = crv; } } } } tempG.Domain = new Interval(0, 1); t2 = tempG.Domain.T1; curveInt2 = Intersection.CurveCurve(tempG, perp2, 0.0001, 0.0001); if (curveInt2.Count != 0) { t2 = curveInt2[0].ParameterA; } if (curveInt2.Count != 0 && t2 < tempG.Domain.T1 && t2 > 0) { Curve[] splitCurves = tempG.Split(t2); if (splitCurves != null) { foreach (Curve crv in splitCurves) { double closestT; crv.ClosestPoint(midPoint, out closestT); double distance = midPoint.DistanceTo(crv.PointAt(closestT)); if (distance < 0.001) { tempG = crv; } } } } return(tempG); }
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); }