protected override Result RunCommand(RhinoDoc doc, RunMode mode) { Rhino.Geometry.Point3d[] corners; Result rc = Rhino.Input.RhinoGet.GetRectangle(out corners); if (rc != Result.Success) { return(rc); } Rhino.Geometry.Plane plane = new Rhino.Geometry.Plane(corners[0], corners[1], corners[2]); Rhino.Geometry.Interval x_interval = new Rhino.Geometry.Interval(0, corners[0].DistanceTo(corners[1])); Rhino.Geometry.Interval y_interval = new Rhino.Geometry.Interval(0, corners[1].DistanceTo(corners[2])); Rhino.Geometry.Mesh mesh = Rhino.Geometry.Mesh.CreateFromPlane(plane, x_interval, y_interval, 10, 10); //mesh.FaceNormals.ComputeFaceNormals(); //mesh.Normals.ComputeNormals(); SampleCsDrawMeshConduit conduit = new SampleCsDrawMeshConduit(); conduit.Mesh = mesh; conduit.Enabled = true; doc.Views.Redraw(); string out_str = null; rc = Rhino.Input.RhinoGet.GetString("Press <Enter> to continue", true, ref out_str); conduit.Enabled = false; doc.Views.Redraw(); return(Result.Success); }
/// <summary> /// always returns array of divided interval of length n+1 /// </summary> /// <param name="IntervalStart"></param> /// <param name="IntervalEnd"></param> /// <param name="n"></param> /// <returns></returns> public static double[] Range(double IntervalStart, double IntervalEnd, int n) { Rhino.Geometry.Interval interval = new Rhino.Geometry.Interval(IntervalStart, IntervalEnd); double[] tInterval = new double[n + 1]; for (int i = 0; i <= n; i++) { tInterval[i] = interval.ParameterAt((double)i / (double)n); } return(tInterval); }
/***************************************************/ public static RHG.Box ToRhino(this BHG.Cuboid cuboid) { if (cuboid == null) { return(default(RHG.Box)); } RHG.Interval ix = new RHG.Interval((cuboid.Length / -2.0), (cuboid.Length / 2.0)); RHG.Interval iy = new RHG.Interval((cuboid.Depth / -2.0), (cuboid.Depth / 2.0)); RHG.Interval iz = new RHG.Interval((cuboid.Height / -2.0), (cuboid.Height / 2.0)); return(new RHG.Box(cuboid.CoordinateSystem.ToRhino(), ix, iy, iz)); }
public SurfaceConverter(CurveConverter curveConv, Vector3DConverter vecConv, Point3dConverter ptConv) { //extrusion surfaces AddConverter(new PipeConverter <rh.Extrusion, pps.Extrusion>( (rhE) => { ppc.Line path = (ppc.Line)curveConv.ConvertToPipe <rh.Curve, ppc.Curve>(rhE.PathLineCurve()); pps.Extrusion extr = new pps.Extrusion(curveConv.ConvertToPipe <rh.Curve, ppc.Curve>(rhE.Profile3d(0, 0)), vecConv.ConvertToPipe <rh.Vector3d, pp.Vec>(rhE.PathTangent), path.Length); for (int i = 1; i < rhE.ProfileCount; i++) { extr.Holes.Add(curveConv.ConvertToPipe <rh.Curve, ppc.Curve>(rhE.Profile3d(i, 0))); } extr.CappedAtStart = rhE.IsCappedAtBottom; extr.CappedAtEnd = rhE.IsCappedAtTop; extr.SurfaceNormal = vecConv.ToPipe <rh.Vector3d, pp.Vec>(rhE.NormalAt(rhE.Domain(0).Mid, rhE.Domain(1).Mid)); return(extr); }, (ppE) => { if (1 - ppE.Direction.Dot(new pp.Vec(0, 0, 1)) > 1e-3) { //the extrusion is not vertical throw new InvalidOperationException("Cannot create this extrusion. " + "Try converting it into a polysurface and pushing it again"); } var profile = curveConv.FromPipe <rh.Curve, ppc.Curve>(ppE.ProfileCurve); rh.Extrusion extr = rh.Extrusion.Create(profile, ppE.Height, ppE.CappedAtEnd || ppE.CappedAtStart); ppE.Holes.ForEach((h) => extr.AddInnerProfile(curveConv.FromPipe <rh.Curve, ppc.Curve>(h))); //extr.SetOuterProfile(profile, false); //extr.SetPathAndUp(profile.PointAtStart, profile.PointAtStart + pathVec, pathVec); string msg; if (!extr.IsValidWithLog(out msg)) { System.Diagnostics.Debug.WriteLine(msg); throw new InvalidOperationException("Cannot create a valid extrusion from the received data: \n" + msg); } var rhNorm = extr.NormalAt(extr.Domain(0).Mid, extr.Domain(1).Mid); if (rh.Vector3d.Multiply(rhNorm, vecConv.FromPipe <rh.Vector3d, pp.Vec>(ppE.SurfaceNormal)) < 0) { //extrusions don't need to be flipped; } return(extr); } )); //NurbsSurfaces AddConverter(new PipeConverter <rh.NurbsSurface, pps.NurbsSurface>( (rns) => { pps.NurbsSurface nurbs = new pps.NurbsSurface(rns.Points.CountU, rns.Points.CountV, rns.Degree(0), rns.Degree(1)); for (int u = 0; u < rns.Points.CountU; u++) { for (int v = 0; v < rns.Points.CountV; v++) { nurbs.SetControlPoint(ptConv.ToPipe <rh.Point3d, pp.Vec>(rns.Points.GetControlPoint(u, v).Location), u, v); nurbs.SetWeight(rns.Points.GetControlPoint(u, v).Weight, u, v); } } rh.Interval uDomain = rns.Domain(0); rh.Interval vDomain = rns.Domain(1); Func <double, rh.Interval, double> scaleKnot = (k, domain) => (k - domain.Min) / (domain.Length); nurbs.UKnots = rns.KnotsU.Select((k) => scaleKnot.Invoke(k, uDomain)).ToList(); nurbs.VKnots = rns.KnotsV.Select((k) => scaleKnot.Invoke(k, vDomain)).ToList(); nurbs.IsClosedInU = rns.IsClosed(0); nurbs.IsClosedInV = rns.IsClosed(1); nurbs.SurfaceNormal = vecConv.ToPipe <rh.Vector3d, pp.Vec>(rns.NormalAt(rns.Domain(0).Mid, rns.Domain(1).Mid)); return(nurbs); }, (pns) => { if (pns.IsClosedInU) { pns.WrapPointsToCloseSurface(0); } if (pns.IsClosedInV) { pns.WrapPointsToCloseSurface(1); } var nurbs = rh.NurbsSurface.Create(3, true, pns.UDegree + 1, pns.VDegree + 1, pns.UCount, pns.VCount); for (int u = 0; u < pns.UCount; u++) { for (int v = 0; v < pns.VCount; v++) { var cp = new rh.ControlPoint(ptConv.FromPipe <rh.Point3d, pp.Vec>(pns.GetControlPointAt(u, v)), pns.GetWeightAt(u, v)); nurbs.Points.SetControlPoint(u, v, cp); } } rh.Interval uDomain = nurbs.Domain(0); rh.Interval vDomain = nurbs.Domain(1); Func <double, rh.Interval, double> scaleKnot = (k, domain) => k * (domain.Length) + domain.Min; if (nurbs.KnotsU.Count == pns.UKnots.Count) { for (int i = 0; i < nurbs.KnotsU.Count; i++) { nurbs.KnotsU[i] = scaleKnot.Invoke(pns.UKnots[i], uDomain); } } if (nurbs.KnotsV.Count == pns.VKnots.Count) { for (int i = 0; i < nurbs.KnotsV.Count; i++) { nurbs.KnotsV[i] = scaleKnot.Invoke(pns.VKnots[i], vDomain); } } string msg; if (!nurbs.IsValidWithLog(out msg)) { System.Diagnostics.Debug.WriteLine(msg); if (!nurbs.IsPeriodic(0)) { nurbs.KnotsU.CreateUniformKnots(1.0 / (nurbs.Points.CountU)); } else { nurbs.KnotsU.CreatePeriodicKnots(1.0 / (nurbs.Points.CountU)); } if (!nurbs.IsPeriodic(1)) { nurbs.KnotsV.CreateUniformKnots(1.0 / (nurbs.Points.CountV)); } else { nurbs.KnotsV.CreatePeriodicKnots(1.0 / (nurbs.Points.CountV)); } if (!nurbs.IsValid) { throw new InvalidOperationException("Cannot create a valid NURBS surface: \n" + msg); } } var rhNorm = nurbs.NormalAt(nurbs.Domain(0).Mid, nurbs.Domain(1).Mid); if (rh.Vector3d.Multiply(rhNorm, vecConv.FromPipe <rh.Vector3d, pp.Vec>(pns.SurfaceNormal)) < 0) { //need not flip rhino surfaces } return(nurbs); } )); }
public static Collections.Interval ToRhino(this RG.Interval interval) => new Collections.Interval(interval.Min, interval.Max);
/***************************************************/ /**** Private methods ****/ /***************************************************/ private static void AddBrepTrim(this RHG.Brep brep, RHG.BrepFace face, BHG.SurfaceTrim trim, RHG.BrepLoopType loopType) { RHG.BrepLoop loop = brep.Loops.Add(loopType, face); List <BHG.ICurve> subParts3d = trim.Curve3d.ISubParts().ToList(); List <BHG.ICurve> subParts2d = trim.Curve2d.ISubParts().ToList(); double rhinoTolerance = Query.DocumentTolerance(); for (int i = 0; i < subParts3d.Count; i++) { BHG.ICurve bhc = subParts3d[i]; RHG.Curve rhc = bhc.IToRhino(); int startId = brep.AddVertex(rhc.PointAtStart); int endId = brep.AddVertex(rhc.PointAtEnd); RHG.BrepTrim rhTrim; RHG.Curve rhc2d = subParts2d[i].IToRhino(); rhc2d.ChangeDimension(2); int crv2d = brep.Curves2D.Add(rhc2d); if (rhc.IsValid) { bool rev3d = true; RHG.BrepEdge edge = null; foreach (RHG.BrepEdge e in brep.Edges) { if (e.StartVertex.VertexIndex == endId && e.EndVertex.VertexIndex == startId && rhc.IsSameEdge(e)) { edge = e; break; } } if (edge == null) { int crv = brep.Curves3D.Add(rhc); edge = brep.Edges.Add(startId, endId, crv, rhinoTolerance); rev3d = false; } rhTrim = brep.Trims.Add(edge, rev3d, loop, crv2d); } else { rhTrim = brep.Trims.AddSingularTrim(brep.Vertices[startId], loop, RHG.IsoStatus.None, crv2d); } rhTrim.SetTolerances(rhinoTolerance, rhinoTolerance); //TODO: In Rhino 6 this could be replaced with Surface.IsIsoParametric(Curve) RHG.Point3d start = rhc2d.PointAtStart; RHG.Point3d end = rhc2d.PointAtEnd; if (rhc2d.IsLinear()) { if (Math.Abs(start.X - end.X) <= rhinoTolerance) { RHG.Interval domainU = brep.Surfaces[face.SurfaceIndex].Domain(0); if (Math.Abs(start.X - domainU.Min) <= rhinoTolerance) { rhTrim.IsoStatus = RHG.IsoStatus.West; } else if (Math.Abs(start.X - domainU.Max) <= rhinoTolerance) { rhTrim.IsoStatus = RHG.IsoStatus.East; } else { rhTrim.IsoStatus = RHG.IsoStatus.X; } } else if (Math.Abs(start.Y - end.Y) <= rhinoTolerance) { RHG.Interval domainV = brep.Surfaces[face.SurfaceIndex].Domain(1); if (Math.Abs(start.Y - domainV.Min) <= rhinoTolerance) { rhTrim.IsoStatus = RHG.IsoStatus.South; } else if (Math.Abs(start.Y - domainV.Max) <= rhinoTolerance) { rhTrim.IsoStatus = RHG.IsoStatus.North; } else { rhTrim.IsoStatus = RHG.IsoStatus.Y; } } } } }
/// <summary> /// Find the boolean difference of an interval and a set of other intervals which /// subtract from it. /// </summary> /// <param name="intervals"></param> /// <param name="detractors"></param> /// <param name="domain"></param> /// <returns></returns> public static void BooleanDifference(this Rhino.Geometry.Interval interval, IList <Rhino.Geometry.Interval> subtractors, IList <Interval> outList) { if (subtractors.Count > 0) { double t = interval.T0; Interval cutter = subtractors.FindEnclosing(t); // Test whether the start point is inside a cutter bool wrapped = false; // Have we wrapped around the domain yet? int cutterCount = 0; while (true) { if (cutterCount > subtractors.Count) { return; } if (cutter != Interval.Unset) { if (cutter.IsDecreasing && t >= cutter.T0) { wrapped = true; // } // Move to the end of the current cutter: t = cutter.T1; // Check for a next enclosing cutter: cutter = subtractors.FindEnclosing(t); cutterCount++; } else { double tNext = interval.T1; // Move to the start of the next cutter: cutter = subtractors.FindNext(t); if (cutter != Interval.Unset && ((interval.IsIncreasing && tNext > cutter.T0) || (interval.IsDecreasing))) { // Move to the start of the next cutter: tNext = cutter.T0; } else if (cutter == Interval.Unset && !wrapped && interval.IsDecreasing) { // Wrap around to the start if the interval does: cutter = subtractors.FindNext(double.MinValue); wrapped = true; // Move to the start of the next cutter: if (cutter != Interval.Unset && cutter.T0 < tNext) { tNext = cutter.T0; } } if (tNext != t) { outList.Add(new Interval(t, tNext)); } else { tNext = t.NextValidValue(); //Nudge it forward! Bit hacky... } t = tNext; } // Check end conditions: if (interval.IsIncreasing && (t >= interval.T1 || wrapped)) { return; } if (interval.IsDecreasing && (t >= interval.T1 && wrapped)) { return; } if (outList.Count > subtractors.Count) { return; } } } else { outList.Add(interval); } //================================== /*foreach (Interval subtractor in subtractors) * { * if (interval.IsIncreasing == subtractor.IsIncreasing) // Both wrapping or both not * { * if (interval.T1 <= subtractor.T1 && subtractor.T0 < interval.T0) return; * else if (interval.T0 < subtractor.T0 && subtractor.T1 < interval.T1) * { * // Split in two: * Interval newInterval = new Interval(subtractor.T1, interval.T1); * if (Math.Abs(newInterval.Length) > 0.0001) BooleanDifference(newInterval, subtractors, outList); * interval = new Interval(interval.T0, subtractor.T0); * if (Math.Abs(interval.Length) < 0.0001) return; * continue; * } * } * else //One wrapping, one not * { * if ((interval.T0 >= subtractor.T0 || interval.T0 <= subtractor.T1) && * () * if (interval.T0 < subtractor.T1 && subtractor.T0 < interval.T1) * { * interval = new Interval(subtractor.T1, subtractor.T0); * continue; * } * } * * // Trim ends: * if (interval.T0 < subtractor.T1 && subtractor.T0 < interval.T0) * interval = new Interval(subtractor.T1, interval.T1); * else if (interval.T1 < subtractor.T1 && subtractor.T0 < interval.T1) * interval = new Interval(interval.T0, subtractor.T0); * * /* * * * // Interval is annihilated: * if (subtractor.IntervalContains(interval)) return; * if (interval == subtractor) return; * * if (IntervalContains(interval, subtractor)) // Interval wholly contains subtractor * { * // Split in two: * Interval newInterval = new Interval(subtractor.T1, interval.T1); * if (Math.Abs(newInterval.Length) > 0.0001) BooleanDifference(newInterval, subtractors, outList); * interval = new Interval(interval.T0, subtractor.T0); * if (Math.Abs(interval.Length) < 0.0001) return; * } * else // Does interval partially contain subtractor? * { * if (interval.IntervalContains(subtractor.T0)) * interval = new Interval(interval.T0, subtractor.T0); * * if (interval.IntervalContains(subtractor.T1)) * interval = new Interval(subtractor.T1, interval.T1); * } * * * //else if (IntervalContains(subtractor, interval.T0)) * //{ * // //if (IntervalContains(subtractor, interval.T1)) * // //{ * // // return; // Interval is wholly inside - shortcut out * // //} * // //else * // interval = new Interval(subtractor.T1, interval.T1); * //} * //else if (IntervalContains(subtractor, interval.T1)) * //{ * // interval = new Interval(interval.Min, subtractor.T0); * //} * //else if (IntervalContains(interval, subtractor)) * //{ * // // Split in two: * // Interval newInterval = new Interval(subtractor.T1, interval.T1); * // if (Math.Abs(newInterval.Length) > 0.0001) BooleanDifference(newInterval, subtractors, outList); * // interval = new Interval(interval.T0, subtractor.T0); * // if (Math.Abs(interval.Length) < 0.0001) return; * //} * * } * * outList.Add(interval); */ }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; //Reference adaptive = uidoc.Selection.PickObject(ObjectType.Element, "Select adaptive family"); //Element adaptiveEle = doc.GetElement(adaptive); //PlanarFace pf = GetFace(adaptiveEle); //TaskDialog.Show("tr", "I am done"); //TaskDialog.Show("tr", "so done"); //TaskDialog.Show("tr", "done done"); List <RG.Point3d> pts = new List <RG.Point3d> { new RG.Point3d(0, 0, 0), new RG.Point3d(5, 10, 0), new RG.Point3d(15, 5, 0), new RG.Point3d(20, 0, 0) }; RG.PolylineCurve pc = new RG.PolylineCurve(pts); RG.Interval d = pc.Domain; //TaskDialog.Show("r", d.ToString()); RG.NurbsCurve value = pc.ToNurbsCurve(); value.IncreaseDegree(3); int newDegree = 3; var degree = value.Degree; var knots = ToDoubleArray(value.Knots, newDegree); var controlPoints = ToXYZArray(value.Points, 1); var weights = value.Points.ConvertAll(x => x.Weight); XYZ normal = new XYZ(0, 0, 1); XYZ origin = new XYZ(0, 0, 0); Plane rvtPlane = Plane.CreateByNormalAndOrigin(normal, origin); string knot = ""; foreach (var item in knots) { knot += item.ToString() + "\n"; } //TaskDialog.Show("r", knot); //TaskDialog.Show("R", $"ControlPoints > Degree: {controlPoints.Length} > {degree}\nKnots = degree + control points + 1 = {controlPoints.Length + degree + 1} "); Curve rvtN = NurbSpline.CreateCurve(newDegree, knots, controlPoints); //Trace.WriteLine() using (Transaction t = new Transaction(doc, "a")) { t.Start(); SketchPlane sketchPlane = SketchPlane.Create(doc, rvtPlane); doc.Create.NewModelCurve(rvtN, sketchPlane); t.Commit(); } return(Result.Succeeded); }