From ebf4fba3f42492bfcc5e7193c5559db6727fa28d Mon Sep 17 00:00:00 2001 From: Alessio Lombardi Date: Mon, 22 Feb 2021 11:55:03 +0000 Subject: [PATCH 1/6] Added ToRhino() for extrusion --- Rhinoceros_Engine/Convert/ToRhino.cs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Rhinoceros_Engine/Convert/ToRhino.cs b/Rhinoceros_Engine/Convert/ToRhino.cs index 1e66494..7821079 100644 --- a/Rhinoceros_Engine/Convert/ToRhino.cs +++ b/Rhinoceros_Engine/Convert/ToRhino.cs @@ -433,11 +433,29 @@ public static RHG.Brep ToRhino(this List surfaces) /***************************************************/ - [NotImplemented] public static RHG.Extrusion ToRhino(this BHG.Extrusion extrusion) { - // TODO Rhino_Adapter conversion to Extrusion - return null; + if (!extrusion.Curve.IIsPlanar()) { + BH.Engine.Reflection.Compute.RecordError("The provided BHoM Extrusion has a base curve that is not planar."); + return null; + } + + var planarCurve = extrusion.Curve.IToRhino(); + + RHG.Plane curvePlane; + planarCurve.TryGetPlane(out curvePlane); + + + double extrHeight = extrusion.Direction.Length(); + + double angle = RHG.Vector3d.VectorAngle(curvePlane.Normal, extrusion.Direction.ToRhino()) * (180 / Math.PI); + + if (angle > 90) + extrHeight = -extrHeight; + + RHG.Extrusion extr = Rhino.Geometry.Extrusion.Create(planarCurve, extrHeight, extrusion.Capped); + + return extr; } From ab1b9b2c224efe169d8c687db632875b726cc1f6 Mon Sep 17 00:00:00 2001 From: Alessio Lombardi Date: Mon, 22 Feb 2021 12:31:36 +0000 Subject: [PATCH 2/6] Added FromRhino() for extrusion --- Rhinoceros_Engine/Convert/FromRhino.cs | 37 +++++++++++++++++++++----- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/Rhinoceros_Engine/Convert/FromRhino.cs b/Rhinoceros_Engine/Convert/FromRhino.cs index 1b1cc7c..1c0e70a 100644 --- a/Rhinoceros_Engine/Convert/FromRhino.cs +++ b/Rhinoceros_Engine/Convert/FromRhino.cs @@ -51,6 +51,10 @@ public static BHG.IGeometry IFromRhino(this Rhino.IEpsilonComparable geome public static BHG.IGeometry IFromRhino(this object geometry) { + // Code to force testing of Extrusion: first convert toRhino, then fromRhino. + if (geometry is BH.oM.Geometry.Extrusion) + return Convert.FromRhino((geometry as BH.oM.Geometry.Extrusion).ToRhino()); + return (geometry == null) ? null : Convert.FromRhino(geometry as dynamic); } @@ -421,10 +425,10 @@ public static BHG.IGeometry FromRhino(this RHG.Brep brep) if (brep.Faces.Count == 0) return null; - + if (brep.IsSolid) return brep.ToBHoMSolid(); - + if (brep.IsPlanarSurface()) { BHG.ICurve externalEdge = RHG.Curve.JoinCurves(brep.DuplicateNakedEdgeCurves(true, false)).FirstOrDefault().FromRhino(); @@ -454,12 +458,33 @@ public static BHG.ISurface FromRhino(this RHG.BrepFace face) /***************************************************/ - public static BHG.Extrusion FromRhino(this RHG.Extrusion extrusion) + public static BHG.IGeometry FromRhino(this RHG.Extrusion extrusion) { if (extrusion == null) return null; - extrusion.PathLineCurve(); - throw new NotImplementedException(); // TODO Rhino_Adapter conversion from Extrusion + RHG.LineCurve line = extrusion.PathLineCurve(); + BHG.Vector extrVec = BH.Engine.Geometry.Create.Vector(line.PointAtStart.FromRhino(), line.PointAtEnd.FromRhino()); + + List extrs = new List(); + + var profileCurves = extrusion.GetWireframe(); + for (int i = 0; i < extrusion.ProfileCount; i++) + { + var profileConverted = profileCurves.ElementAt(i).FromRhino(); + BHG.Extrusion extr = BH.Engine.Geometry.Create.Extrusion(profileConverted, extrVec, extrusion.IsCappedAtBottom && extrusion.IsCappedAtTop); + + extrs.Add(extr); + } + + + if (extrs.Count == 1) + return extrs[0]; + + if (extrs.Count > 1) + return new BH.oM.Geometry.CompositeGeometry() { Elements = extrs.OfType().ToList() }; + + BH.Engine.Reflection.Compute.RecordError("Could not convert the extrusion."); + return null; } @@ -526,7 +551,7 @@ public static BHG.Torus FromRhino(this RHG.Torus torus) public static BHG.Cone FromRhino(this RHG.Cone cone) { - return new BHG.Cone { Centre = cone.BasePoint.FromRhino(), Axis = cone.Axis.FromRhino()*-1.0, Radius = cone.Radius, Height = cone.Height }; + return new BHG.Cone { Centre = cone.BasePoint.FromRhino(), Axis = cone.Axis.FromRhino() * -1.0, Radius = cone.Radius, Height = cone.Height }; } /***************************************************/ From c0fb36468622403e8969044d6da508b28f1f8271 Mon Sep 17 00:00:00 2001 From: Alessio Lombardi Date: Mon, 22 Feb 2021 14:09:11 +0000 Subject: [PATCH 3/6] Removed Testing code to enforce ToRhino() to be invoked for Extrusion --- Rhinoceros_Engine/Convert/FromRhino.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Rhinoceros_Engine/Convert/FromRhino.cs b/Rhinoceros_Engine/Convert/FromRhino.cs index 1c0e70a..94552fb 100644 --- a/Rhinoceros_Engine/Convert/FromRhino.cs +++ b/Rhinoceros_Engine/Convert/FromRhino.cs @@ -51,10 +51,6 @@ public static BHG.IGeometry IFromRhino(this Rhino.IEpsilonComparable geome public static BHG.IGeometry IFromRhino(this object geometry) { - // Code to force testing of Extrusion: first convert toRhino, then fromRhino. - if (geometry is BH.oM.Geometry.Extrusion) - return Convert.FromRhino((geometry as BH.oM.Geometry.Extrusion).ToRhino()); - return (geometry == null) ? null : Convert.FromRhino(geometry as dynamic); } @@ -467,9 +463,11 @@ public static BHG.IGeometry FromRhino(this RHG.Extrusion extrusion) List extrs = new List(); + // Exploits the fact that GetWireframe returns first the "profile" curves of the extrusion. var profileCurves = extrusion.GetWireframe(); for (int i = 0; i < extrusion.ProfileCount; i++) { + var profileConverted = profileCurves.ElementAt(i).FromRhino(); BHG.Extrusion extr = BH.Engine.Geometry.Create.Extrusion(profileConverted, extrVec, extrusion.IsCappedAtBottom && extrusion.IsCappedAtTop); From d24289bd6b966d4ac4e988c3fb8c079c8a04e2a5 Mon Sep 17 00:00:00 2001 From: Alessio Lombardi Date: Tue, 23 Feb 2021 11:09:25 +0000 Subject: [PATCH 4/6] ToRhino(): return Sweep if BH Extrusion not perpendicular to base curve --- Rhinoceros_Engine/Convert/ToRhino.cs | 55 +++++++++++++++++++++------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/Rhinoceros_Engine/Convert/ToRhino.cs b/Rhinoceros_Engine/Convert/ToRhino.cs index 7821079..bb23ae1 100644 --- a/Rhinoceros_Engine/Convert/ToRhino.cs +++ b/Rhinoceros_Engine/Convert/ToRhino.cs @@ -215,7 +215,7 @@ public static RHG.PolyCurve ToRhino(this BHG.PolyCurve bPolyCurve) return null; IEnumerable parts = bPolyCurve.Curves.Select(x => x.IToRhino()); - + // Check if bPolycurve is made of disconnected segments if (RHG.Curve.JoinCurves(parts).Length > 1) return null; @@ -385,8 +385,8 @@ public static RHG.GeometryBase ToRhino(this BHG.NurbsSurface surface) RHG.Brep brep = new RHG.Brep(); int srf = brep.AddSurface(rhSurface); RHG.BrepFace face = brep.Faces.Add(srf); - - foreach(BHG.SurfaceTrim trim in surface.OuterTrims) + + foreach (BHG.SurfaceTrim trim in surface.OuterTrims) { brep.AddBrepTrim(face, trim, RHG.BrepLoopType.Outer); } @@ -395,7 +395,7 @@ public static RHG.GeometryBase ToRhino(this BHG.NurbsSurface surface) { brep.AddBrepTrim(face, trim, RHG.BrepLoopType.Inner); } - + return brep.IsValid ? brep : null; } } @@ -433,9 +433,10 @@ public static RHG.Brep ToRhino(this List surfaces) /***************************************************/ - public static RHG.Extrusion ToRhino(this BHG.Extrusion extrusion) + public static RHG.GeometryBase ToRhino(this BHG.Extrusion extrusion) { - if (!extrusion.Curve.IIsPlanar()) { + if (!extrusion.Curve.IIsPlanar()) + { BH.Engine.Reflection.Compute.RecordError("The provided BHoM Extrusion has a base curve that is not planar."); return null; } @@ -445,17 +446,43 @@ public static RHG.Extrusion ToRhino(this BHG.Extrusion extrusion) RHG.Plane curvePlane; planarCurve.TryGetPlane(out curvePlane); + double angle = RHG.Vector3d.VectorAngle(curvePlane.Normal, extrusion.Direction.ToRhino()); + + double tolerance = 0.001; + if (angle > tolerance || (2 * Math.PI - tolerance < angle && angle < 2 * Math.PI + tolerance)) + { + // It can be represented by a Rhino extrusion (which enforces perpendicularity btw Curve plane and Vector) + + double extrHeight = extrusion.Direction.Length(); + + if (angle > Math.PI) + extrHeight = -extrHeight; - double extrHeight = extrusion.Direction.Length(); + RHG.Extrusion extr = Rhino.Geometry.Extrusion.Create(planarCurve, extrHeight, extrusion.Capped); - double angle = RHG.Vector3d.VectorAngle(curvePlane.Normal, extrusion.Direction.ToRhino()) * (180 / Math.PI); + return extr; + } + + // Otherwise, provide a Sweep to cover extrusion with a base curve that is not orthogonal to the extr direction + + // Create a Line to be the sweep rail. Use centroid/mid-point of base curve as start point. + RHG.Point3d centrePoint; + if (planarCurve.IsClosed) + { + var areaProp = Rhino.Geometry.AreaMassProperties.Compute(planarCurve); + centrePoint = areaProp.Centroid; + } + else + centrePoint = planarCurve.PointAt(0.5); - if (angle > 90) - extrHeight = -extrHeight; + RHG.Point3d endPoint = centrePoint + extrusion.Direction.ToRhino(); + var rail = new RHG.Line(centrePoint, endPoint); - RHG.Extrusion extr = Rhino.Geometry.Extrusion.Create(planarCurve, extrHeight, extrusion.Capped); + var joinedSweep = new RHG.SweepOneRail() + .PerformSweep(new RHG.LineCurve(rail), planarCurve) + .Aggregate((b1, b2) => { b1.Join(b2, tolerance, true); return b1; }); - return extr; + return joinedSweep; } @@ -711,7 +738,7 @@ private static void AddBrepTrim(this RHG.Brep brep, RHG.BrepFace face, BHG.Surfa } /***************************************************/ - + private static int AddVertex(this RHG.Brep brep, RHG.Point3d point) { int id = -1; @@ -734,7 +761,7 @@ private static int AddVertex(this RHG.Brep brep, RHG.Point3d point) } /***************************************************/ - + private static bool IsSameEdge(this RHG.Curve curve, RHG.BrepEdge edge) { double tolerance = BHG.Tolerance.Distance; From d5817ecf5215cdf3530a5e1e9a45df91a708eb45 Mon Sep 17 00:00:00 2001 From: Alessio Lombardi Date: Tue, 23 Feb 2021 12:51:06 +0000 Subject: [PATCH 5/6] Update ToRhino.cs --- Rhinoceros_Engine/Convert/ToRhino.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Rhinoceros_Engine/Convert/ToRhino.cs b/Rhinoceros_Engine/Convert/ToRhino.cs index bb23ae1..004b00d 100644 --- a/Rhinoceros_Engine/Convert/ToRhino.cs +++ b/Rhinoceros_Engine/Convert/ToRhino.cs @@ -449,7 +449,8 @@ public static RHG.GeometryBase ToRhino(this BHG.Extrusion extrusion) double angle = RHG.Vector3d.VectorAngle(curvePlane.Normal, extrusion.Direction.ToRhino()); double tolerance = 0.001; - if (angle > tolerance || (2 * Math.PI - tolerance < angle && angle < 2 * Math.PI + tolerance)) + + if (angle < tolerance || (2 * Math.PI - tolerance < angle && angle < 2 * Math.PI + tolerance)) { // It can be represented by a Rhino extrusion (which enforces perpendicularity btw Curve plane and Vector) @@ -476,10 +477,10 @@ public static RHG.GeometryBase ToRhino(this BHG.Extrusion extrusion) centrePoint = planarCurve.PointAt(0.5); RHG.Point3d endPoint = centrePoint + extrusion.Direction.ToRhino(); - var rail = new RHG.Line(centrePoint, endPoint); + var rail = new RHG.LineCurve(centrePoint, endPoint); var joinedSweep = new RHG.SweepOneRail() - .PerformSweep(new RHG.LineCurve(rail), planarCurve) + .PerformSweep(rail, planarCurve) .Aggregate((b1, b2) => { b1.Join(b2, tolerance, true); return b1; }); return joinedSweep; From 4acbbf09fcbcaec2069e50d392c663704dfeba8a Mon Sep 17 00:00:00 2001 From: Alessio Lombardi Date: Tue, 23 Feb 2021 13:50:48 +0000 Subject: [PATCH 6/6] Fix for Grasshopper to build. --- Rhinoceros_Engine/Convert/ToRhino.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Rhinoceros_Engine/Convert/ToRhino.cs b/Rhinoceros_Engine/Convert/ToRhino.cs index 004b00d..e258d67 100644 --- a/Rhinoceros_Engine/Convert/ToRhino.cs +++ b/Rhinoceros_Engine/Convert/ToRhino.cs @@ -433,7 +433,7 @@ public static RHG.Brep ToRhino(this List surfaces) /***************************************************/ - public static RHG.GeometryBase ToRhino(this BHG.Extrusion extrusion) + public static Rhino.Geometry.Surface ToRhino(this BHG.Extrusion extrusion) { if (!extrusion.Curve.IIsPlanar()) { @@ -483,7 +483,13 @@ public static RHG.GeometryBase ToRhino(this BHG.Extrusion extrusion) .PerformSweep(rail, planarCurve) .Aggregate((b1, b2) => { b1.Join(b2, tolerance, true); return b1; }); - return joinedSweep; + if (joinedSweep.IsSurface) + return joinedSweep.Surfaces[0]; + + BH.Engine.Reflection.Compute.RecordError("Could not convert this BHoM Extrusion to a Rhino Surface. The extrusion direction is not perpendicular to the base curve, and the base curve is too complex for a Sweep to return a valid Surface."); + + + return null; }