public ICurve PolylineToSpeckle(RH.Polyline poly, Interval domain, string units = null)
        {
            var u = units ?? ModelUnits;

            if (poly.Count == 2)
            {
                var l = LineToSpeckle(new RH.Line(poly[0], poly[1]), u);
                if (domain != null)
                {
                    l.domain = domain;
                }
                return(l);
            }

            var myPoly = new Polyline(PointsToFlatArray(poly), u);

            myPoly.closed = poly.IsClosed;

            if (myPoly.closed)
            {
                myPoly.value.RemoveRange(myPoly.value.Count - 3, 3);
            }

            myPoly.domain = domain;
            myPoly.bbox   = BoxToSpeckle(new RH.Box(poly.BoundingBox), u);
            myPoly.length = poly.Length;

            // TODO: Area of 3d polyline cannot be resolved...
            return(myPoly);
        }
        // Rh Capture
        public Base PolylineToSpeckle(PolylineCurve poly)
        {
            RH.Polyline polyline;

            if (poly.TryGetPolyline(out polyline))
            {
                if (polyline.Count == 2)
                {
                    return(new Line(PointsToFlatArray(polyline), ModelUnits));
                }

                var myPoly = new Polyline(PointsToFlatArray(polyline), ModelUnits);
                myPoly.closed = polyline.IsClosed;

                if (myPoly.closed)
                {
                    myPoly.value.RemoveRange(myPoly.value.Count - 3, 3);
                }

                myPoly.domain = IntervalToSpeckle(poly.Domain);

                return(myPoly);
            }

            return(null);
        }
        public Curve NurbsToSpeckle(NurbsCurve curve, string units = null)
        {
            var u         = units ?? ModelUnits;
            var tolerance = 0.0;

            curve.ToPolyline(0, 1, 0, 0, 0, 0.1, 0, 0, true).TryGetPolyline(out var poly);

            Polyline displayValue;

            if (poly.Count == 2)
            {
                displayValue       = new Polyline();
                displayValue.value = new List <double> {
                    poly[0].X, poly[0].Y, poly[0].Z, poly[1].X, poly[1].Y, poly[1].Z
                };
            }
            else
            {
                displayValue = PolylineToSpeckle(poly, u) as Polyline;
            }

            var myCurve    = new Curve(displayValue, u);
            var nurbsCurve = curve.ToNurbsCurve();

            // increase knot multiplicity to (# control points + degree + 1)
            // add extra knots at start & end  because Rhino's knot multiplicity standard is (# control points + degree - 1)
            var knots = nurbsCurve.Knots.ToList();

            knots.Insert(0, knots[0]);
            knots.Insert(knots.Count - 1, knots[knots.Count - 1]);

            // Hack: Rebuild curve to prevent interior knot multiplicities.
            //var max = Math.Min(nurbsCurve.Points.Count-1, 3);
            //nurbsCurve = nurbsCurve.Rebuild(nurbsCurve.Points.Count, max, true);

            myCurve.weights  = nurbsCurve.Points.Select(ctp => ctp.Weight).ToList();
            myCurve.points   = PointsToFlatArray(nurbsCurve.Points.Select(ctp => ctp.Location)).ToList();
            myCurve.knots    = knots;
            myCurve.degree   = nurbsCurve.Degree;
            myCurve.periodic = nurbsCurve.IsPeriodic;
            myCurve.rational = nurbsCurve.IsRational;
            myCurve.domain   = IntervalToSpeckle(nurbsCurve.Domain);
            myCurve.closed   = nurbsCurve.IsClosed;
            myCurve.length   = nurbsCurve.GetLength();
            myCurve.bbox     = BoxToSpeckle(new RH.Box(nurbsCurve.GetBoundingBox(true)), u);

            return(myCurve);
        }
        // Rectangles now and forever forward will become polylines
        public Polyline PolylineToSpeckle(Rectangle3d rect, string units = null)
        {
            var u      = units ?? ModelUnits;
            var length = rect.Height * 2 + rect.Width * 2;
            var sPoly  = new Polyline(
                PointsToFlatArray(new Point3d[] { rect.Corner(0), rect.Corner(1), rect.Corner(2), rect.Corner(3) }), u)
            {
                closed = true,
                area   = rect.Area,
                bbox   = BoxToSpeckle(new RH.Box(rect.BoundingBox), u),
                length = length,
                domain = new Interval(0, length)
            };

            return(sPoly);
        }
        // Deserialise
        public PolylineCurve PolylineToNative(Polyline poly)
        {
            List <Point3d> points = poly.points.Select(o => PointToNative(o).Location).ToList();

            if (poly.closed)
            {
                points.Add(points[0]);
            }

            var myPoly = new PolylineCurve(points);

            if (poly.domain != null)
            {
                myPoly.Domain = IntervalToNative(poly.domain);
            }

            return(myPoly);
        }
        // Deserialise
        public PolylineCurve PolylineToNative(Polyline poly)
        {
            var points = PointListToNative(poly.value, poly.units).ToList();

            if (poly.closed)
            {
                points.Add(points[0]);
            }

            var myPoly = new PolylineCurve(points);

            if (poly.domain != null)
            {
                myPoly.Domain = IntervalToNative(poly.domain);
            }

            return(myPoly);
        }
        public ICurve PolylineToSpeckle(RH.Polyline poly, Interval domain)
        {
            if (poly.Count == 2)
            {
                var l = new Line(PointsToFlatArray(poly), ModelUnits);
                l.domain = domain;
                return(l);
            }

            var myPoly = new Polyline(PointsToFlatArray(poly), ModelUnits);

            myPoly.closed = poly.IsClosed;

            if (myPoly.closed)
            {
                myPoly.value.RemoveRange(myPoly.value.Count - 3, 3);
            }

            myPoly.domain = domain;
            return(myPoly);
        }
        public Curve NurbsToSpeckle(NurbsCurve curve)
        {
            var tolerance = 0.0;

            curve.ToPolyline(0, 1, 0, 0, 0, 0.1, 0, 0, true).TryGetPolyline(out var poly);

            Polyline displayValue;

            if (poly.Count == 2)
            {
                displayValue       = new Polyline();
                displayValue.value = new List <double> {
                    poly[0].X, poly[0].Y, poly[0].Z, poly[1].X, poly[1].Y, poly[1].Z
                };
            }
            else
            {
                displayValue = PolylineToSpeckle(poly) as Polyline;
            }

            var myCurve    = new Curve(displayValue, ModelUnits);
            var nurbsCurve = curve.ToNurbsCurve();

            // Hack: Rebuild curve to prevent interior knot multiplicities.
            //var max = Math.Min(nurbsCurve.Points.Count-1, 3);
            //nurbsCurve = nurbsCurve.Rebuild(nurbsCurve.Points.Count, max, true);

            myCurve.weights  = nurbsCurve.Points.Select(ctp => ctp.Weight).ToList();
            myCurve.points   = PointsToFlatArray(nurbsCurve.Points.Select(ctp => ctp.Location)).ToList();
            myCurve.knots    = nurbsCurve.Knots.ToList();
            myCurve.degree   = nurbsCurve.Degree;
            myCurve.periodic = nurbsCurve.IsPeriodic;
            myCurve.rational = nurbsCurve.IsRational;
            myCurve.domain   = IntervalToSpeckle(nurbsCurve.Domain);
            myCurve.closed   = nurbsCurve.IsClosed;

            return(myCurve);
        }
        // Rh Capture
        public Base PolylineToSpeckle(PolylineCurve poly, string units = null)
        {
            var u = units ?? ModelUnits;

            RH.Polyline polyline;

            if (poly.TryGetPolyline(out polyline))
            {
                var intervalToSpeckle = IntervalToSpeckle(poly.Domain);
                if (polyline.Count == 2)
                {
                    var polylineToSpeckle = new Line(PointsToFlatArray(polyline), u)
                    {
                        domain = intervalToSpeckle
                    };
                    polylineToSpeckle.length = polyline.Length;
                    var box = new RH.Box(poly.GetBoundingBox(true));
                    polylineToSpeckle.bbox = BoxToSpeckle(box, u);
                    return(polylineToSpeckle);
                }

                var myPoly = new Polyline(PointsToFlatArray(polyline), u);
                myPoly.closed = polyline.IsClosed;

                if (myPoly.closed)
                {
                    myPoly.value.RemoveRange(myPoly.value.Count - 3, 3);
                }

                myPoly.domain = intervalToSpeckle;
                myPoly.bbox   = BoxToSpeckle(new RH.Box(poly.GetBoundingBox(true)), u);
                myPoly.length = poly.GetLength();
                return(myPoly);
            }

            return(null);
        }