public override Point3d ClosestPoint(Point3d pt) { if (!environment.IsPointInside(pt, Constants.AbsoluteTolerance, true)) { return(environment.ClosestPoint(pt)); } return(pt); }
private List <Vector3d> SortPartsClockwise() { var outerPt = OuterSurface.ClosestPoint(this.Plane.Origin); var innerPt = InnerSurface.ClosestPoint(this.Plane.Origin); ComponentIndex ci; double s, t; //Vector3d normal; OuterSurface.ClosestPoint(outerPt, out outerPt, out ci, out s, out t, 0, out Normal); if (Normal * (outerPt - innerPt) < 0) { Normal.Reverse(); } Normal = outerPt - innerPt; Normal.Unitize(); var beams = new Beam[4]; for (int i = 0; i < 4; ++i) { beams[i] = (Parts[i].Element as BeamElement).Beam; } var dirs = new Vector3d[4]; for (int i = 0; i < 4; ++i) { dirs[i] = beams[i].Centreline.PointAt(beams[i].Centreline.Domain.Mid) - this.Plane.Origin; } List <int> indices; GluLamb.Utility.SortVectorsAroundPoint(dirs.ToList(), this.Plane.Origin, Normal, out indices); var parts = new JointPart[4]; var vectors = new Vector3d[4]; for (int i = 0; i < indices.Count; ++i) { parts[i] = Parts[indices[i]]; vectors[i] = dirs[indices[i]]; } Parts = parts; return(vectors.ToList()); }
private void RunScript(List <Plane> iPlanes, List <double> iAngles, Curve iAxis, Brep iWorkEnvelope, ref object oAttractedPlanes, ref object oProcessedAngles) { // <Custom code> List <Plane> pulledPlanes = new List <Plane>(); List <double> processedAngles = new List <double>(); List <Point3d> circles = new List <Point3d>(); for (var index = 0; index < iPlanes.Count; index++) { Plane pln = iPlanes[index]; double angle = iAngles[index]; if (iWorkEnvelope.IsPointInside(pln.Origin, 0.01, true)) { pln.Origin = iWorkEnvelope.ClosestPoint(pln.Origin); //Print(index.ToString()); double newAngle; bool isValid; Point3d adjustedOrigin = adjustPlane(iAxis, pln, iWorkEnvelope, angle, out newAngle, out isValid); if (isValid) { pln.Origin = adjustedOrigin; angle = newAngle; } } processedAngles.Add(angle); pulledPlanes.Add(pln); } oProcessedAngles = processedAngles; oAttractedPlanes = pulledPlanes; // </Custom code> }
public override Vector3d GetOrientation(Curve crv, double t) { Point3d pt = crv.PointAt(t); double u, v; ComponentIndex ci; Point3d cp; Vector3d normal; m_surface.ClosestPoint(pt, out cp, out ci, out u, out v, 0, out normal); if (ci.ComponentIndexType == ComponentIndexType.BrepEdge) { int fi = m_surface.Edges[ci.Index].AdjacentFaces().First(); m_surface.Faces[fi].ClosestPoint(cp, out u, out v); normal = m_surface.Faces[fi].NormalAt(u, v); } else if (ci.ComponentIndexType == ComponentIndexType.BrepVertex) { int ei = m_surface.Vertices[ci.Index].EdgeIndices().First(); int fi = m_surface.Edges[ei].AdjacentFaces().First(); m_surface.Faces[fi].ClosestPoint(cp, out u, out v); normal = m_surface.Faces[fi].NormalAt(u, v); } return(NormalizeVector(crv, t, normal)); }
public static bool RegionsIntersect(Brep regionA, Brep regionB) { //Depreciated: brep split operation is slow and run twice if this is used. //Prefer running it in all cases, without this confirm method, and just counting number of results. Brep[] splitOperation = regionA.Split(regionB, 0.1); bool splitOcurred = (splitOperation.Length == 0) ? false : true; //Compensation for when a region is completely contained within another. Point3d regionCenterA = Utils.GetRegionCenter(regionA); Point3d regionCenterB = Utils.GetRegionCenter(regionB); double distAtoB = regionCenterA.DistanceTo(regionB.ClosestPoint(regionCenterA)); double distBtoA = regionCenterB.DistanceTo(regionA.ClosestPoint(regionCenterB)); bool AinB = (distAtoB < 0.1) ? true : false; bool BinA = (distBtoA < 0.1) ? true : false; Console.WriteLine(AinB.ToString() + " / " + BinA.ToString()); bool isContained = (AinB == true || BinA == true) ? true : false; //If any of the above are true, consider it an intersection. bool result = (splitOcurred == true || isContained == true) ? true : false; return(result); }
private List <Point3d> DispatchFlowPoints(Brep FLOW_SURFACE, Point3d initialStartPoint, double MOVE_DISTANCE, int FLOW_LIMIT) { var flowPoints = new List <Point3d>(); // Holds each step var startPoint = FLOW_SURFACE.ClosestPoint(initialStartPoint); flowPoints.Add(startPoint); while (true) { Point3d nextPoint; nextPoint = GetNextFlowStepOnSurface(FLOW_SURFACE, startPoint, MOVE_DISTANCE); if (nextPoint.DistanceTo(startPoint) <= RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) { break; // Test the point has actully moved } if (nextPoint.Z >= startPoint.Z) { break; // Test this point is actually lower } flowPoints.Add(nextPoint); if (FLOW_LIMIT != 0 && FLOW_LIMIT <= flowPoints.Count) { break; // Stop if iteration limit reached } startPoint = nextPoint; // Checks out; iterate on } return(flowPoints); }
private Point3d GetNextFlowStepOnSurface(Brep FLOW_SURFACE, Point3d startPoint, double MOVE_DISTANCE) { double closestS, closestT; double maximumDistance = 0; // TD: setting this as +ve speeds up the search? Vector3d closestNormal; ComponentIndex closestCI; Point3d closestPoint; // Get closest point FLOW_SURFACE.ClosestPoint(startPoint, out closestPoint, out closestCI, out closestS, out closestT, maximumDistance, out closestNormal); // Get the next point following the vector var nextFlowPoint = FlowCalculations.MoveFlowPoint(closestNormal, closestPoint, MOVE_DISTANCE); // Need to snap back to the surface (the vector may be pointing off the edge) return(FLOW_SURFACE.ClosestPoint(nextFlowPoint)); }
Point3d CreateRandomPoint(Random rnd, Brep brep, BoundingBox bbox) { var x = Remap(rnd.NextDouble(), 0.0, 1.0, bbox.Min.X, bbox.Max.X); var y = Remap(rnd.NextDouble(), 0.0, 1.0, bbox.Min.Y, bbox.Max.Y); var z = Remap(rnd.NextDouble(), 0.0, 1.0, bbox.Min.Z, bbox.Max.Z); return(brep.ClosestPoint(new Point3d(x, y, z))); }
/// <summary> /// Add an open brep (non inside detection) /// </summary> /// <param name="b"></param> /// <param name="exp"></param> /// <param name="mass"></param> /// <param name="vg"></param> public void AddOpenBrep(Brep b, double exp, double mass, ref ScalarGrid3D vg) { for (var i = 0; i < vg.Count; i++) { var pt = vg.EvaluatePoint(i); var cp = b.ClosestPoint(pt); var dist = pt.DistanceTo(cp); vg[i] += CalculateMass(dist, mass, exp); } }
public static bool IsInside(Point3d point, Brep polygon) { bool inside = true; double dist = point.DistanceTo(polygon.ClosestPoint(point)); if (dist > DocumentTolerance()) { inside = false; } return(inside); }
protected override void SolveInstance(IGH_DataAccess DA) { Brep B = null; Point3d P = Point3d.Unset; double maxDist = 0; if (!DA.GetData("Brep", ref B)) { return; } if (!DA.GetData("Point", ref P)) { return; } DA.GetData("Max Distance", ref maxDist); if (B == null || P == null) { return; } Point3d closestPoint; ComponentIndex componentIndex; double s; double t; Vector3d normal; B.ClosestPoint(P, out closestPoint, out componentIndex, out s, out t, maxDist, out normal); if (componentIndex.ComponentIndexType == ComponentIndexType.BrepEdge) { int[] faceIndices = B.Edges[componentIndex.Index].AdjacentFaces(); Vector3d tempNormal = new Vector3d(0, 0, 0); foreach (int i in faceIndices) { double u, v; B.Faces[i].ClosestPoint(P, out u, out v); tempNormal += B.Faces[i].NormalAt(u, v); } tempNormal.Unitize(); normal = tempNormal; } var ci = componentIndex.Index; var dist = closestPoint.DistanceTo(P); var ct = componentIndex.ComponentIndexType.ToString(); DA.SetData("Closest Point", closestPoint); DA.SetData("Distance", dist); DA.SetData("Normal", normal); DA.SetData("Component Index", ci); DA.SetData("Component Type", ct); }
public override Vector3d ClosestNormal(Point3d pt) { Brep brepEnv = environment.ToBrep(); Point3d closestPoint; ComponentIndex componentIndex; double s; double t; const double maxDist = 100; Vector3d normal; brepEnv.ClosestPoint(pt, out closestPoint, out componentIndex, out s, out t, maxDist, out normal); return(normal); }
/***************************************************/ // Populate the element with points - used for preview purposes to show pressure loads. public static List <Point3d> PopulateWithPoints(this Element2D element) { List <Point3d> corners = element.Nodes.Take(element.PrimaryNodeCount).Select(n => n.Location).ToList(); Surface srf; if (corners.Count == 3) { srf = NurbsSurface.CreateFromCorners(corners[0], corners[1], corners[2]); } else { srf = NurbsSurface.CreateFromCorners(corners[0], corners[1], corners[2], corners[3]); } corners.Add(corners[0]); Polyline perim = new Polyline(corners); double minDist = perim.Length * 0.01; List <Point3d> srfPts = new List <Point3d>(); Interval uDomain = srf.Domain(0); Interval vDomain = srf.Domain(1); double uMin = uDomain.Min; double uMax = uDomain.Max; double vMin = vDomain.Min; double vMax = vDomain.Max; double uStep = (uMax - uMin) / 3; double vStep = (vMax - vMin) / 3; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { srfPts.Add(srf.PointAt(uMin + i * uStep, vMin + j * vStep)); } } Brep srfBrep = srf.ToBrep(); List <Point3d> pts = new List <Point3d>(); foreach (Point3d pt in srfPts) { if (srfBrep.ClosestPoint(pt).DistanceTo(pt) <= minDist && perim.ClosestPoint(pt).DistanceTo(pt) > minDist) { pts.Add(pt); } } return(pts); }
/// <summary> /// Create glulam with frames that are aligned with a Surface. The input curve does not /// necessarily have to lie on the Surface. /// </summary> /// <param name="curve">Input centreline of the Glulam.</param> /// <param name="srf">Surface to align the Glulam orientation to.</param> /// <param name="num_samples">Number of orientation frames to use for alignment.</param> /// <returns>New Glulam oriented to the Surface.</returns> static public Glulam CreateGlulamNormalToSurface_old(Curve curve, Brep brep, int num_samples = 20, GlulamData data = null) { double[] t = curve.DivideByCount(num_samples, true); List <Plane> planes = new List <Plane>(); double u, v; Vector3d xaxis, yaxis, zaxis; ComponentIndex ci; Point3d pt; for (int i = 0; i < t.Length; ++i) { brep.ClosestPoint(curve.PointAt(t[i]), out pt, out ci, out u, out v, 0, out yaxis); zaxis = curve.TangentAt(t[i]); xaxis = Vector3d.CrossProduct(zaxis, yaxis); planes.Add(new Plane(curve.PointAt(t[i]), xaxis, yaxis)); } return(Glulam.CreateGlulam(curve, planes.ToArray(), data)); }
public void ParticleSwarmOptimisation(double particleLearningFactor, double globalLearningFactor, double influenceFactor, double maxVelocity, List <Curve> attract, double attractFactor, Brep boundary, double boundaryFactor) { foreach (Particle i in bodies) { Vector3d toPbest = new Vector3d(i.particleBest - i.position); toPbest.Unitize(); Vector3d toGbest = new Vector3d(globalBest - i.position); toGbest.Unitize(); double pbestMultiplier = particleLearningFactor * rnd.Next(); double gbestMultiplier = globalLearningFactor * rnd.Next(); Vector3d moveVector = (toPbest * pbestMultiplier) + (toGbest * gbestMultiplier); Vector3d rndInfluence = new Vector3d((rnd.Next() * 2) - 1, (rnd.Next() * 2) - 1, (rnd.Next() * 2) - 1) * influenceFactor; Vector3d attractVector = new Vector3d(); foreach (Curve c in attract) { c.ClosestPoint(i.position, out double t2); attractVector += (c.PointAt(t2) - i.position) * (1 / i.position.DistanceTo(c.PointAt(t2))); } attractVector.Unitize(); Vector3d boundaryVector = new Vector3d(); if (!boundary.IsPointInside(i.position, RhinoMath.SqrtEpsilon, false)) { boundaryVector += boundary.ClosestPoint(i.position) - i.position; boundaryVector.Unitize(); } i.velocity += (moveVector + rndInfluence + (attractVector * attractFactor) + (boundaryVector * boundaryFactor)); if (i.velocity.Length > maxVelocity) { i.velocity *= maxVelocity / i.velocity.Length; } } }
/// <summary> /// Add a solid brep /// </summary> /// <param name="b"></param> /// <param name="exp"></param> /// <param name="mass"></param> /// <param name="vg"></param> public void AddSolidBrep(Brep b, double exp, double mass, ref ScalarGrid3D vg) { // get the axis direction for each point var pt1 = vg.EvaluatePoint(new Point3i(0, 0, 0)); var pt2 = vg.EvaluatePoint(new Point3i(1, 0, 0)); var pln = new Plane(pt1, (pt2 - pt1)); for (var x = 0; x < vg.SizeUVW.X; x++) { pln.Origin = vg.EvaluatePoint(new Point3i(x, 0, 0)); Intersection.BrepPlane(b, pln, DocumentHelper.GetModelTolerance(), out var sections, out var pts); var surfaces = Brep.CreatePlanarBreps(sections); // perhaps check first if the points are inside the bounding box of the surface. if (surfaces == null) { continue; } for (var y = 0; y < vg.SizeUVW.Y; y++) { for (var z = 0; z < vg.SizeUVW.Z; z++) { var isInside = false; var pti = new Point3i(x, y, z); var pt = vg.EvaluatePoint(pti); var distance = b.ClosestPoint(pt).DistanceTo(pt); for (var i = 0; i < surfaces.Length; i++) { //BoundingBox bb = surfaces[i].GetBoundingBox(false); if (surfaces[i].ClosestPoint(pt).DistanceTo(pt) < DocumentHelper.GetModelTolerance()) { isInside = true; break; } } vg[pti] = +CalculateMass(distance, mass, exp, isInside); } } } }
/// <summary> /// Add a non closed brep by using a distance to the grid /// </summary> /// <param name="b"></param> /// <param name="vg"></param> public void AddOpenBrep(Brep b, ref VoxelGrid3D vg) { var bb = b.GetBoundingBox(false); bb.Inflate(Distance * 0.6); for (var i = 0; i < vg.Grid.Count; i++) { var pt = vg.EvaluatePoint(i); if (!bb.Contains(pt)) { continue; } var cp = b.ClosestPoint(pt); AddPt(cp, ref vg); if (pt.DistanceTo(cp) < Distance) { AddPt(pt, ref vg); } } }
/// <summary> /// Create frames that are aligned with a Brep. The input curve does not /// necessarily have to lie on the Brep. /// </summary> /// <param name="curve">Input centreline of the glulam.</param> /// <param name="brep">Brep to align the glulam orientation to.</param> /// <param name="num_samples">Number of orientation frames to use for alignment.</param> /// <returns>New Glulam oriented to the brep.</returns> public static Plane[] FramesNormalToSurface(Curve curve, Brep brep, int num_samples = 20) { num_samples = Math.Max(num_samples, 2); double[] t = curve.DivideByCount(num_samples - 1, true); Plane[] planes = new Plane[num_samples]; Vector3d xaxis, yaxis, zaxis; Point3d pt; ComponentIndex ci; for (int i = 0; i < t.Length; ++i) { brep.ClosestPoint(curve.PointAt(t[i]), out pt, out ci, out double u, out double v, 0, out yaxis); // From: https://discourse.mcneel.com/t/brep-closestpoint-normal-is-not-normal/15147/8 // If the closest point is found on an edge, average the face normals if (ci.ComponentIndexType == ComponentIndexType.BrepEdge) { BrepEdge edge = brep.Edges[ci.Index]; int[] faces = edge.AdjacentFaces(); yaxis = Vector3d.Zero; for (int j = 0; j < faces.Length; ++j) { BrepFace bf = edge.Brep.Faces[j]; if (bf.ClosestPoint(pt, out u, out v)) { Vector3d faceNormal = bf.NormalAt(u, v); yaxis += faceNormal; } } yaxis.Unitize(); } zaxis = curve.TangentAt(t[i]); xaxis = Vector3d.CrossProduct(zaxis, yaxis); planes[i] = new Plane(pt, xaxis, yaxis); } return(planes); }
/// <summary> /// Orient nodes to match the surface normals of a Brep. /// </summary> /// <param name="brep">Brep to orient to.</param> /// <param name="max_range">Maximum search range.</param> /// <returns>Number of nodes changed.</returns> public int OrientNodes(Brep brep, double max_range = 0.0) { int N = 0; Vector3d normal; double s, t; ComponentIndex ci; Point3d cp; Transform rot; foreach (Node n in NodeList) { if (n.Frame.IsValid) { if (brep.ClosestPoint(n.Frame.Origin, out cp, out ci, out s, out t, max_range, out normal)) { rot = Transform.Rotation(n.Frame.ZAxis, normal, n.Frame.Origin); n.Frame.Transform(rot); N++; } } } return(N); }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { Mesh meshSurf; List <Guid> ids = new List <Guid>(); double tolerance = doc.ModelAbsoluteTolerance; const Rhino.DocObjects.ObjectType geometryFilter = Rhino.DocObjects.ObjectType.Surface | Rhino.DocObjects.ObjectType.PolysrfFilter | Rhino.DocObjects.ObjectType.Mesh; GetObject gs = new Rhino.Input.Custom.GetObject(); gs.SetCommandPrompt("Surface to orient on"); gs.GeometryFilter = geometryFilter; gs.SubObjectSelect = true; gs.DeselectAllBeforePostSelect = true; gs.OneByOnePostSelect = true; gs.Get(); if (gs.CommandResult() != Result.Success) { return(gs.CommandResult()); } Rhino.DocObjects.ObjRef objref = gs.Object(0); Rhino.DocObjects.RhinoObject obj = objref.Object(); if (obj == null) { return(Result.Failure); } brepSurf = objref.Brep(); if (brepSurf == null) { meshSurf = objref.Mesh(); brepSurf = Brep.CreateFromMesh(meshSurf, true); } if (brepSurf == null) { return(Result.Failure); } obj.Select(false); while (true) { w_key_pressed = false; s_key_pressed = false; a_key_pressed = false; d_key_pressed = false; m_escape_key_pressed = false; RhinoApp.EscapeKeyPressed += RhinoApp_EscapeKeyPressed; RhinoApp.KeyboardEvent += OnRhinoKeyboardEvent; Point3d pt0; GetPoint getPointAction = new GetPoint(); getPointAction.SetCommandPrompt("Please select insert point(s) on surface."); getPointAction.Constrain(brepSurf, -1, -1, false); var stoneDiam = new Rhino.Input.Custom.OptionDouble(diamStone); var stoneOff = new Rhino.Input.Custom.OptionDouble(offSetStone); var boolOption = new Rhino.Input.Custom.OptionToggle(false, "Off", "On"); var moveOption = new Rhino.Input.Custom.OptionToggle(false, "Off", "On"); getPointAction.AddOptionDouble("StoneDiam", ref stoneDiam); getPointAction.AddOptionDouble("Offset", ref stoneOff); getPointAction.AddOptionToggle("Delete", ref boolOption); getPointAction.AddOptionToggle("Move", ref moveOption); getPointAction.DynamicDraw += RefCircleDraw; getPointAction.Tag = obj; getPointAction.AcceptString(false); getPointAction.AcceptNothing(true); var res = getPointAction.Get(); if (w_key_pressed || s_key_pressed) { RhinoApp.KeyboardEvent -= OnRhinoKeyboardEvent; w_key_pressed = false; s_key_pressed = false; stoneDiam.CurrentValue = diamStone; } if (a_key_pressed || d_key_pressed) { RhinoApp.KeyboardEvent -= OnRhinoKeyboardEvent; a_key_pressed = false; d_key_pressed = false; stoneOff.CurrentValue = offSetStone; } if (res == GetResult.Nothing) { break; } if (m_escape_key_pressed) { break; } diamStone = stoneDiam.CurrentValue; offSetStone = stoneOff.CurrentValue; optionBool = boolOption.CurrentValue; moveBool = moveOption.CurrentValue; RhinoApp.KeyboardEvent -= OnRhinoKeyboardEvent; if (moveBool == true) { RhinoApp.KeyboardEvent -= OnRhinoKeyboardEvent; while (true) { GetObject gcd = new Rhino.Input.Custom.GetObject(); gcd.SetCommandPrompt("Select circle(s) to move. Press enter when done"); gcd.GeometryFilter = Rhino.DocObjects.ObjectType.Curve; gcd.SubObjectSelect = false; gcd.DeselectAllBeforePostSelect = true; gcd.AcceptNothing(true); if (gcd.Get() == GetResult.Nothing) { break; } gcd.Get(); Rhino.DocObjects.ObjRef delobjref = gcd.Object(0); Rhino.DocObjects.RhinoObject delobj = delobjref.Object(); Curve curveRadius = delobjref.Curve(); Circle circleRadius = new Circle(); curveRadius.TryGetCircle(out circleRadius, tolerance); diamStone = circleRadius.Diameter; doc.Objects.Delete(delobj, true); doc.Views.Redraw(); getPointAction.Get(); pt0 = getPointAction.Point(); Point3d closestPoint; ComponentIndex compIndex; double u, v; Vector3d vt1; brepSurf.ClosestPoint(pt0, out closestPoint, out compIndex, out u, out v, 0.01, out vt1); Plane pl1 = new Plane(pt0, vt1); Circle cr1 = new Circle(pl1, pt0, diamStone / 2); var crgu = doc.Objects.AddCircle(cr1); ids.Add(crgu); doc.Views.Redraw(); } moveBool = false; } if (optionBool == true) { RhinoApp.KeyboardEvent -= OnRhinoKeyboardEvent; while (true) { GetObject gcd = new Rhino.Input.Custom.GetObject(); gcd.SetCommandPrompt("Select circle(s) to delete. Press enter when done"); gcd.GeometryFilter = Rhino.DocObjects.ObjectType.Curve; gcd.SubObjectSelect = false; gcd.DeselectAllBeforePostSelect = true; gcd.AcceptNothing(true); if (gcd.Get() == GetResult.Nothing) { break; } gcd.Get(); Rhino.DocObjects.ObjRef delobjref = gcd.Object(0); Rhino.DocObjects.RhinoObject delobj = delobjref.Object(); Curve curveRadius = delobjref.Curve(); Circle circleRadius = new Circle(); curveRadius.TryGetCircle(out circleRadius, tolerance); diamStone = circleRadius.Diameter; doc.Objects.Delete(delobj, true); doc.Views.Redraw(); } optionBool = false; } if (res == GetResult.Point) { pt0 = getPointAction.Point(); Point3d closestPoint; ComponentIndex compIndex; double u, v; Vector3d vt1; brepSurf.ClosestPoint(pt0, out closestPoint, out compIndex, out u, out v, 0.01, out vt1); Plane pl1 = new Plane(pt0, vt1); Circle cr1 = new Circle(pl1, pt0, diamStone / 2); var crgu = doc.Objects.AddCircle(cr1); ids.Add(crgu); doc.Views.Redraw(); } } RhinoApp.KeyboardEvent -= OnRhinoKeyboardEvent; RhinoApp.EscapeKeyPressed -= RhinoApp_EscapeKeyPressed; doc.Groups.Add(ids); return(Result.Success); }
private Brep[] GetBorderWalls(Curve borderCrv, IEnumerable <Point3d> pts, IEnumerable <Vector3d> nrmls, double dist) { List <Point3d> ptsOut = new List <Point3d>(); List <Point3d> ptsIn = new List <Point3d>(); IEnumerator ptEnum = pts.GetEnumerator(); IEnumerator nrmlEnum = nrmls.GetEnumerator(); while ((ptEnum.MoveNext()) && (nrmlEnum.MoveNext())) { Point3d pt = (Point3d)ptEnum.Current; Vector3d nrml = (Vector3d)nrmlEnum.Current; Transform mvOut = Transform.Translation(nrml * dist); Transform mvIn = Transform.Translation(nrml * -dist); Point3d ptOut = new Point3d(pt); Point3d ptIn = new Point3d(pt); ptOut.Transform(mvOut); ptIn.Transform(mvIn); ptsOut.Add(ptOut); ptsIn.Add(ptIn); } Curve crvOut; Curve crvIn; if (borderCrv.IsPolyline()) { crvOut = new PolylineCurve(ptsOut); crvIn = new PolylineCurve(ptsIn); } else { crvOut = Curve.CreateInterpolatedCurve(ptsOut, 3); crvIn = Curve.CreateInterpolatedCurve(ptsIn, 3); } List <Curve> crvs = new List <Curve>(); crvs.Add(crvOut); crvs.Add(crvIn); Brep[] lofts = Brep.CreateFromLoft(crvs, Point3d.Unset, Point3d.Unset, LoftType.Normal, false); Interval interval = new Interval(0, 1); double u, v; u = v = 0.05; BrepFace loftFace = lofts[0].Faces[0]; loftFace.SetDomain(0, interval); loftFace.SetDomain(1, interval); while (u < 1 && v < 1) { if (loftFace.IsPointOnFace(u, v).Equals(PointFaceRelation.Interior)) { break; } u += .05; v += .05; } Point3d loftPt = loftFace.PointAt(u, v); Vector3d loftNrml = loftFace.NormalAt(u, v); Point3d loftPtOut = loftPt; Point3d loftPtIn = loftPt; loftPtOut.Transform(Transform.Translation(loftNrml)); loftNrml.Reverse(); loftPtIn.Transform(Transform.Translation(loftNrml)); Point3d envPtOut = environment.ClosestPoint(loftPtOut); Point3d envPtIn = environment.ClosestPoint(loftPtIn); if (loftPtOut.DistanceTo(envPtOut) < loftPtIn.DistanceTo(envPtIn)) { foreach (Brep brep in lofts) { brep.Flip(); } } return(lofts); }
public override void Calculate() { if (Driver == null) { return; } int U = Direction ? 1 : 0; int V = Direction ? 0 : 1; Paths = new List <Path>(); Curve IsoFence; if (StartEnd) { IsoFence = Driver.Faces[0].IsoCurve(U, Driver.Faces[0].Domain(V).Min); } else { IsoFence = Driver.Faces[0].IsoCurve(U, Driver.Faces[0].Domain(V).Max); } double[] Uts; double length = IsoFence.GetLength(); double minOffset = IsoFence.Domain.Min; double maxOffset = IsoFence.Domain.Max; if (OffsetSides) { IsoFence.LengthParameter(Tool.StepOver, out minOffset); IsoFence.LengthParameter(length - Tool.StepOver, out maxOffset); IsoFence = IsoFence.Trim(new Interval(minOffset, maxOffset)); } Uts = IsoFence.DivideByLength(Tool.StepOver, true); if (Uts == null) { return; } List <double> UtsList = Uts.ToList(); UtsList.Add(maxOffset); /* * if (Boundary != null) * { * Boundary = Driver.Faces[0].Pullback(Boundary, 0.01); * } */ List <Curve> Isos = new List <Curve>(); for (int i = 0; i < UtsList.Count; ++i) { Isos.AddRange(Driver.Faces[0].TrimAwareIsoCurve(V, UtsList[i])); } for (int i = 0; i < Isos.Count; ++i) { //Curve Iso = Driver.Faces[0].IsoCurve(V, Uts[i]); Curve Iso = Isos[i]; /* * if (Boundary != null) * { * Rhino.Geometry.Intersect.CurveIntersections ci = Rhino.Geometry.Intersect.Intersection.CurveCurve(Boundary, Iso, 0.01, 0.01); * if (ci.Count == 2) * { * Iso = Iso.Trim(new Interval(ci[0].ParameterB, ci[1].ParameterB)); * } * } */ Polyline Pl = Misc.CurveToPolyline(Iso, Tolerance); Path OPl = new Path(); Vector3d nor, tan, x; foreach (Point3d p in Pl) { double t, u, v; Point3d cp; ComponentIndex ci; Driver.ClosestPoint(p, out cp, out ci, out u, out v, 0, out nor); if (Vector3d.Multiply(nor, Workplane.ZAxis) < 0.0) { nor.Reverse(); } Iso.ClosestPoint(p, out t); tan = Iso.TangentAt(t); x = -Vector3d.CrossProduct(nor, tan); //Plane plane = new Plane(p, nor); Plane plane = new Plane(p, x, tan); //if (Vector3d.Multiply(plane.ZAxis, Workplane.ZAxis) < 0.0) // plane = new Plane(p, Vector3d.CrossProduct(nor, tan), tan); OPl.Add(plane); } Paths.Add(OPl); } /* * if (Boundary != null && Boundary.IsClosed) * { * Polyline BPoly = Util.CurveToPolyline(Boundary, 0.1); * Polyline BFPoly = new Polyline(); * Point3d pt1, pt0; * double u, v; * * for (int i = 0; i < BPoly.Count; ++i) * { * Driver.Faces[0].ClosestPoint(BPoly[i], out u, out v); * BFPoly.Add(new Point3d(u, v, 0)); * } * * Curve BFCrv = BFPoly.ToNurbsCurve(); * PointContainment pc; * bool inside = false; * bool onsrf = false; * * List<OrientedPolyline> NewPaths = new List<OrientedPolyline>(); * * for (int i = 0; i < Paths.Count; ++i) * { * Polyline poly = new Polyline(); * OrientedPolyline new_op = new OrientedPolyline(); * * // get initial state * Driver.Faces[0].ClosestPoint(Paths[i][0].Origin, out u, out v); * pt1 = new Point3d(u, v, 0); * * pc = BFCrv.Contains(pt1); * * if (pc == PointContainment.Inside || pc == PointContainment.Coincident) * { * inside = true; * new_op.Add(Paths[i][0]); * } * * for (int j = 1; j < Paths[i].Count; ++j) * { * Driver.Faces[0].ClosestPoint(Paths[i][j].Origin, out u, out v); * pt0 = pt1; * pt1 = new Point3d(u, v, 0); * pc = BFCrv.Contains(pt1); * if (pc == PointContainment.Inside || pc == PointContainment.Coincident) * { * if (!inside) * new_op.AddRange(IntersectSegment(BFCrv, pt0, pt1, Paths[i][j - 1], Paths[i][j], ref inside)); * new_op.Add(Paths[i][j]); * inside = true; * } * else // the point is NOT within the boundary... * { * // find intersections between * new_op.AddRange(IntersectSegment(BFCrv, pt0, pt1, Paths[i][j - 1], Paths[i][j], ref inside)); * inside = false; * } * } * if (new_op.Count > 1) * NewPaths.Add(new_op); * * } * * Paths = NewPaths; * } */ }
public static Mesh QuadMeshDistanceFromBrep(Surface surface, int num, int num2, Brep target, double min, double max, double shift, ref double[] distances) { Mesh mesh = new Mesh(); surface.SetDomain(0, new Interval(0.0, 1.0)); surface.SetDomain(1, new Interval(0.0, 1.0)); double num5 = 1.0 / (double)num; double num6 = 1.0 / (double)num2; int v = 0; int f = 0; for (int i = 0; i < num; i++) { for (int j = 0; j < num2; j++) { Point3d pa = surface.PointAt((double)i * num5, (double)j * num6); Point3d pb = surface.PointAt((double)(i + 1) * num5, (double)j * num6); Point3d pc = surface.PointAt((double)(i + 1) * num5, (double)(j + 1) * num6); Point3d pd = surface.PointAt((double)i * num5, (double)(j + 1) * num6); mesh.Vertices.Add(pa); mesh.Vertices.Add(pb); mesh.Vertices.Add(pc); mesh.Vertices.Add(pd); mesh.Faces.AddFace(v + 2, v + 1, v + 0); mesh.Faces.AddFace(v + 3, v + 2, v + 0); MeshNgon ngon = MeshNgon.Create(new[] { v + 0, v + 1, v + 2, v + 3 }, new[] { f + 0, f + 1 }); mesh.Ngons.AddNgon(ngon); v += 4; f += 2; } } mesh.Vertices.CombineIdentical(true, true); mesh.FaceNormals.ComputeFaceNormals(); mesh.Normals.ComputeNormals(); mesh.Compact(); //Assign colors distances = new double[mesh.Vertices.Count]; for (int i = 0; i < mesh.Vertices.Count; i++) { double dist = target.ClosestPoint(mesh.Vertices[i]).DistanceTo(mesh.Vertices[i]); dist -= shift; distances[i] = dist; dist = MathUtil.Constrain(dist, min, max); int temp = MathUtil.MapInt(dist, min, max, 0, 255); //mesh.VertexColors.Add( Color.FromArgb(255, 255-temp,temp)); mesh.VertexColors.Add(Color.FromArgb(255 - temp, 255 - temp, 255 - temp)); //mesh.VertexColors.Add(Color.FromArgb(0,rAverage, gAverage, bAverage)); } return(mesh); }
public override void Calculate(List <KangarooSolver.Particle> p) { Point3d ThisPt = p[PIndex[0]].Position; //get the current position of the particle Move[0] = TargetBrep.ClosestPoint(ThisPt) - ThisPt; //assign the goal vector moving this particle towards its target }
/***************************************************/ // Apply support to the nodes laying within tolerance from the support geometry. private void ApplySupport(Support support) { foreach (GeometryBase g in support.Geometry) { if (g is Point) { Point p = g as Point; Point3d pt = p.Location; foreach (Node node in this._mesh.Nodes) { if (node.Primary && node.Location.DistanceTo(pt) <= this._tolerance) { support.Nodes.Add(node); } } } else if (g is Curve) { Curve c = g as Curve; double t; foreach (Node node in this._mesh.Nodes) { if (node.Primary) { c.ClosestPoint(node.Location, out t); if (c.PointAt(t).DistanceTo(node.Location) <= this._tolerance) { support.Nodes.Add(node); } } } } else if (g is Brep) { Brep b = g as Brep; foreach (Node node in this._mesh.Nodes) { if (node.Primary) { Point3d bpt = b.ClosestPoint(node.Location); if (node.Location.DistanceTo(bpt) <= this._tolerance) { support.Nodes.Add(node); } } } } else { throw new Exception("Unknown support geometry type! " + support.Name); } } // If the physical fixing of the support is chosen, then instead of fixing rotational stiffness within chosen nodes, fix translation in all nodes of the supported elements. if (support.SupportType.Physical) { List <Node> baseNodes = support.Nodes.ToList(); foreach (Element e in this._mesh.Elements) { Element2D el = e as Element2D; if (e == null) { continue; } HashSet <Node> elNodes = new HashSet <Node>(el.Nodes.Take(el.PrimaryNodeCount)); foreach (Node node in baseNodes) { if (elNodes.Any(n => n == node)) { support.Nodes.UnionWith(elNodes); break; } } } } }
/// <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) { Brep surface = new Brep(); double height = 0; double percent = 0; bool isSwitch = true; if (!DA.GetData(0, ref surface)) { return; } if (!DA.GetData(1, ref height)) { return; } if (!DA.GetData(2, ref percent)) { return; } if (!DA.GetData(3, ref isSwitch)) { return; } Brep x = surface; double h = height; double l = percent; bool b = isSwitch; if (b == false) { h = h * (-1); } if (l > 1 || l < 0) { l = 1; } Curve[] cs = x.DuplicateEdgeCurves(true); Curve[] joins = Curve.JoinCurves(cs); Point3d pt = SuperVipersClass.centerPoint(x.DuplicateVertices().ToList()); Point3d center;/////中点 ComponentIndex ci; double s; double t; double dist = 0; Vector3d vc;///////开口方向 x.ClosestPoint(pt, out center, out ci, out s, out t, dist, out vc); center.Transform(Transform.Translation(vc * h)); Point3d[] ptss = SuperVipersClass.sortPoints(x.DuplicateVertices().ToList(), joins[0]).ToArray(); for (int i = 0; i < ptss.Length; i++) { Vector3d vv = Point3d.Subtract(ptss[i], center); ptss[i].Transform(Transform.Translation(vv * l * (-1))); } Point3d[] ptss2 = SuperVipersClass.sortPoints(x.DuplicateVertices().ToList(), joins[0]).ToArray(); List <Brep> breps = new List <Brep>(); for (int i = 0; i < ptss.Length; i++) { if (i == ptss.Length - 1) { NurbsCurve[] n1 = { new Line(ptss[i], ptss[0]).ToNurbsCurve(), new Line(ptss[i], ptss2[i]).ToNurbsCurve(), new Line(ptss2[i], ptss2[0]).ToNurbsCurve(), new Line(ptss[0], ptss2[0]).ToNurbsCurve() }; Brep bbp = Brep.CreateEdgeSurface(n1); breps.Add(bbp); continue; } NurbsCurve[] n2 = { new Line(ptss[i], ptss[i + 1]).ToNurbsCurve(), new Line(ptss[i], ptss2[i]).ToNurbsCurve(), new Line(ptss2[i], ptss2[i + 1]).ToNurbsCurve(), new Line(ptss[i + 1], ptss2[i + 1]).ToNurbsCurve() }; Brep bbp2 = Brep.CreateEdgeSurface(n2); breps.Add(bbp2); } DA.SetDataList(0, breps); }
/// <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) { Curve cs = null; List <IGH_GeometricGoo> gs = new List <IGH_GeometricGoo>(); bool re = false; if (!DA.GetData(0, ref cs) || !DA.GetDataList(1, gs) || !DA.GetData(2, ref re)) { return; } double distance = double.MaxValue; Point3d pt1 = cs.PointAtStart; Point3d pt2 = cs.PointAtEnd; for (int i = 0; i < gs.Count; i++) { if (gs[i] is GH_Curve) { GH_Curve ccc = (GH_Curve)gs[i]; Curve ccc2 = ccc.Value; double t1 = 0; double t2 = 0; ccc2.ClosestPoint(pt1, out t1); ccc2.ClosestPoint(pt2, out t2); Point3d test1 = ccc2.PointAt(t1); Point3d test2 = ccc2.PointAt(t2); double distanceA = test1.DistanceTo(pt1); double distanceB = test2.DistanceTo(pt2); if (distance > distanceA) { distance = distanceA; } if (distance > distanceB) { distance = distanceB; cs.Reverse(); } } else if (gs[i] is GH_Brep) { GH_Brep bbb = (GH_Brep)gs[i]; Brep bbb2 = bbb.Value; Point3d test1 = bbb2.ClosestPoint(pt1); Point3d test2 = bbb2.ClosestPoint(pt2); double distanceA = test1.DistanceTo(pt1); double distanceB = test2.DistanceTo(pt2); if (distance > distanceA) { distance = distanceA; } if (distance > distanceB) { distance = distanceB; cs.Reverse(); } } else if (gs[i] is GH_Point) { GH_Point ppp = (GH_Point)gs[i]; Point3d ppp2 = ppp.Value; double distanceA = ppp2.DistanceTo(pt1); double distanceB = ppp2.DistanceTo(pt2); if (distance > distanceA) { distance = distanceA; } if (distance > distanceB) { distance = distanceB; cs.Reverse(); } } else if (gs[i] is GH_Mesh) { GH_Mesh mmm = (GH_Mesh)gs[i]; Mesh mmm2 = mmm.Value; Point3d test1 = mmm2.ClosestPoint(pt1); Point3d test2 = mmm2.ClosestPoint(pt2); double distanceA = test1.DistanceTo(pt1); double distanceB = test2.DistanceTo(pt2); if (distance > distanceA) { distance = distanceA; } if (distance > distanceB) { distance = distanceB; cs.Reverse(); } } pt1 = cs.PointAtStart; pt2 = cs.PointAtEnd; } if (re) { cs.Reverse(); } DA.SetData(0, cs); }
void SampleCell(object argumentsObject) { SampleCellArguments arguments = (SampleCellArguments)argumentsObject; Box cell = arguments.cell; int depth = arguments.depth; Random random = new Random(seed + depth); Point3d sample = cell.PointAt(random.NextDouble(), random.NextDouble(), random.NextDouble()); bool valid = true; if (sample.DistanceTo(boundary.ClosestPoint(sample)) < distance / 2) { valid = false; } if (valid) { if (!boundary.IsPointInside(sample, RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, true)) { valid = false; } } if (valid) { foreach (var point in samples) { if (sample.DistanceToSquared(point) < distanceSquared) { valid = false; break; } } } if (valid) { samples.Add(sample); } if (cell.X.Length < cellMinimum) { return; } List <Box> newCells = new List <Box>(); for (double u = 0; u < 1; u += 0.5) { for (double v = 0; v < 1; v += 0.5) { for (double w = 0; w < 1; w += 0.5) { Box newCell = new Box(cell.Plane, new Point3d[] { cell.PointAt(u, v, w), cell.PointAt(u + 0.5, v + 0.5, w + 0.5) }); newCells.Add(newCell); } } } List <Task> tasks = new List <Task>(4); for (int i = newCells.Count - 1; i >= 0; i--) { Box newCell = newCells[random.Next(i)]; newCells.Remove(newCell); SampleCellArguments newArguments = new SampleCellArguments(newCell, depth + 1); if (this.random) { Task task = new Task(new Action <object>(SampleCell), newArguments); tasks.Add(task); task.Start(); } else { SampleCell(newArguments); } } foreach (Task task in tasks) { task.Wait(); } return; }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Brep surface = new Brep(); double tolerance = 0; double angleToler = 0; double height = 0; double percent = 0; bool isSwitch = false; bool isCap = false; if (!DA.GetData(0, ref surface)) { return; } if (!DA.GetData(1, ref tolerance)) { return; } if (!DA.GetData(2, ref angleToler)) { return; } if (!DA.GetData(3, ref height)) { return; } if (!DA.GetData(4, ref percent)) { return; } if (!DA.GetData(5, ref isSwitch)) { return; } if (!DA.GetData(6, ref isCap)) { return; } Brep x = surface; double t = tolerance; double a = angleToler; double h = height; double p = percent; if (isSwitch) { h = h * (-1); } if (p > 1 || p < 0) { p = 1; } Curve[] cs = Curve.JoinCurves(x.DuplicateEdgeCurves(true)); Curve c = cs[0].Simplify(CurveSimplifyOptions.All, t, a); Curve[] cs2 = c.DuplicateSegments(); double xx = 0; double yy = 0; double zz = 0; for (int i = 0; i < cs2.Length; i++) { xx += cs2[i].PointAtStart.X; yy += cs2[i].PointAtStart.Y; zz += cs2[i].PointAtStart.Z; } Point3d center = new Point3d(xx / cs2.Length, yy / cs2.Length, zz / cs2.Length); Point3d pt; ComponentIndex ci; double tt; double s; Vector3d vc; x.ClosestPoint(center, out pt, out ci, out s, out tt, 0, out vc); Plane pln = new Plane(pt, vc);//////切割平面 pt.Transform(Transform.Translation(vc * h)); pln.Transform(Transform.Translation(vc * h * p)); List <Point3d> ptss = new List <Point3d>();///////平面与线段交点 for (int i = 0; i < cs2.Length; i++) { double param; Line l = new Line(cs2[i].PointAtStart, pt); Rhino.Geometry.Intersect.Intersection.LinePlane(l, pln, out param); ptss.Add(l.PointAt(param)); } List <Line> ls1 = new List <Line>(); List <NurbsCurve> ls11 = new List <NurbsCurve>(); ///轮廓线2 List <Line> ls2 = new List <Line>(); List <NurbsCurve> ls22 = new List <NurbsCurve>(); ///轮廓线3 List <Line> ls3 = new List <Line>(); for (int i = 0; i < cs2.Length; i++) { if (i == cs2.Length - 1) { ls1.Add(new Line(ptss[i], ptss[0])); ls11.Add(new Line(ptss[i], ptss[0]).ToNurbsCurve()); ls2.Add(new Line(cs2[i].PointAtStart, ptss[i])); ls22.Add(new Line(cs2[i].PointAtStart, ptss[i]).ToNurbsCurve()); ls3.Add(new Line(cs2[i].PointAtEnd, ptss[0])); continue; } ls1.Add(new Line(ptss[i], ptss[i + 1])); ls11.Add(new Line(ptss[i], ptss[i + 1]).ToNurbsCurve()); ls2.Add(new Line(cs2[i].PointAtStart, ptss[i])); ls22.Add(new Line(cs2[i].PointAtStart, ptss[i]).ToNurbsCurve()); ls3.Add(new Line(cs2[i].PointAtEnd, ptss[i + 1])); } List <Brep> sfs = new List <Brep>(); for (int i = 0; i < cs2.Length; i++) { Curve[] cc = { cs2[i], ls1[i].ToNurbsCurve(), ls2[i].ToNurbsCurve(), ls3[i].ToNurbsCurve() }; sfs.Add(Brep.CreateEdgeSurface(cc)); } if (isCap) { sfs.Add(Brep.CreatePlanarBreps(ls11)[0]);/////加顶盖 } List <Curve> curves = new List <Curve>(); curves.AddRange(cs2); curves.AddRange(ls11); curves.AddRange(ls22); DA.SetDataList(0, sfs); DA.SetDataList(1, curves); }