public static ICurve GridCurveToSpeckle(ITFGridCurve gridCurve, DPoint3d origin, double angle, double minimumValueX = 0, double minimumValueY = 0, double maximumValueX = 0, double maximumValueY = 0, string units = null)
        {
            ICurve baseLine;

            gridCurve.GetType(0, out TFdGridCurveType curveType);
            gridCurve.GetMinimumValue(0, out double minimumValue);
            gridCurve.GetMaximumValue(0, out double maximumValue);
            gridCurve.GetValue(0, out double gridValue);

            Point startPoint, endPoint;

            switch (curveType)
            {
            case (TFdGridCurveType.TFdGridCurveType_OrthogonalX):
                if (minimumValue == 0)
                {
                    minimumValue = minimumValueY;
                }
                if (maximumValue == 0)
                {
                    maximumValue = maximumValueY;
                }

                startPoint = Translate(Rotate(new Point(gridValue, minimumValue, 0, units), angle), origin.X, origin.Y);
                endPoint   = Translate(Rotate(new Point(gridValue, maximumValue, 0, units), angle), origin.X, origin.Y);
                baseLine   = new Line(startPoint, endPoint, units);
                break;

            case (TFdGridCurveType.TFdGridCurveType_OrthogonalY):
                if (minimumValue == 0)
                {
                    minimumValue = minimumValueX;
                }
                if (maximumValue == 0)
                {
                    maximumValue = maximumValueX;
                }

                startPoint = Translate(Rotate(new Point(minimumValue, gridValue, 0, units), angle), origin.X, origin.Y);
                endPoint   = Translate(Rotate(new Point(maximumValue, gridValue, 0, units), angle), origin.X, origin.Y);
                baseLine   = new Line(startPoint, endPoint, units);
                break;

            default:
                throw new NotSupportedException("GridCurveType " + curveType + " not supported!");
            }
            return(baseLine);
        }
        public Base GridSystemsToSpeckle(ITFDrawingGrid drawingGrid, string units = null)
        {
            Base        container = new Base();
            List <Base> gridLines = new List <Base>();

            container["Grid Lines"] = gridLines;

            drawingGrid.GetGridSystems(0, out ITFGridSystemList gridSystems);
            if (gridSystems == null)
            {
                return(null);
            }

            for (ITFGridSystem gridSystem = gridSystems.AsTFGridSystem;
                 gridSystem != null;
                 gridSystems.GetNext("", out gridSystems), gridSystem = (gridSystems != null) ? gridSystems.AsTFGridSystem : null)
            {
                gridSystem.GetGridCurves(0, out ITFGridCurveList curves);

                if (curves == null)
                {
                    continue;
                }

                gridSystem.GetLCS(out DPoint3d origin, 0, out double angle);

                gridSystem.GetMinGridLineExtension(0, out double mindGridLineExtendsion);

                // find overall minimum/maximum extends of grid lines
                double minimumValueX        = 0;
                double minimumValueY        = 0;
                double maximumValueX        = 0;
                double maximumValueY        = 0;
                double maximumRadius        = 0;
                double maximumCircularAngle = 0;

                List <ITFGridCurve> gridCurveList = new List <ITFGridCurve>();
                for (ITFGridCurve gridCurve = curves.AsTFGridCurve; gridCurve != null; curves.GetNext("", out curves), gridCurve = curves != null ? curves.AsTFGridCurve : null)
                {
                    gridCurveList.Add(gridCurve);
                    gridCurve.GetType(0, out TFdGridCurveType curveType);
                    gridCurve.GetValue(0, out double gridValue);
                    gridCurve.GetMinimumValue(0, out double minimumValue);

                    switch (curveType)
                    {
                    case (TFdGridCurveType.TFdGridCurveType_OrthogonalX):
                        if (gridValue < minimumValueX)
                        {
                            minimumValueX = gridValue;
                        }
                        // grid lines pick up the minimum value of their neighbors
                        if (minimumValue < minimumValueY)
                        {
                            minimumValueY = minimumValue;
                        }
                        if (gridValue > maximumValueX)
                        {
                            maximumValueX = gridValue;
                        }
                        break;

                    case (TFdGridCurveType.TFdGridCurveType_OrthogonalY):
                        if (gridValue < minimumValueY)
                        {
                            minimumValueY = gridValue;
                        }
                        // grid lines pick up the minimum value of their neighbors
                        if (minimumValue < minimumValueX)
                        {
                            minimumValueX = minimumValue;
                        }
                        if (gridValue > maximumValueY)
                        {
                            maximumValueY = gridValue;
                        }
                        break;

                    case (TFdGridCurveType.TFdGridCurveType_Circular):
                        if (gridValue > maximumRadius)
                        {
                            maximumRadius = gridValue;
                        }
                        break;

                    case (TFdGridCurveType.TFdGridCurveType_Radial):
                        if (gridValue > maximumCircularAngle)
                        {
                            maximumCircularAngle = gridValue;
                        }
                        break;

                    default:
                        break;
                    }
                }

                // for some reason only angles are scaled
                maximumCircularAngle *= UoR;

                foreach (ITFGridCurve gridCurve in gridCurveList)
                {
                    ICurve baseLine;

                    gridCurve.GetLabel(0, out string label);
                    gridCurve.GetType(0, out TFdGridCurveType curveType);
                    gridCurve.GetValue(0, out double gridValue);
                    //gridCurve.GetMsElementDescrP(out Element obj, 0);

                    var u = units ?? ModelUnits;

                    //if (obj != null)
                    //{
                    //    // coordinate transformation
                    //    //double axx = Math.Cos(angle);
                    //    //double axy = -Math.Sin(angle);
                    //    //double axz = 0;
                    //    //double axw = origin.X;
                    //    //double ayx = Math.Sin(angle);
                    //    //double ayy = Math.Cos(angle);
                    //    //double ayz = 0;
                    //    //double ayw = origin.Y;
                    //    //double azx = 0;
                    //    //double azy = 0;
                    //    //double azz = 1;
                    //    //double azw = origin.Z;
                    //    //DTransform3d transform = new DTransform3d(axx, axy, axz, axw, ayx, ayy, ayz, ayw, azx, azy, azz, azw);
                    //    if (obj is LineElement)
                    //    {
                    //        Line line = LineToSpeckle((LineElement)obj, u);
                    //        baseLine = TransformCurve(line, origin, angle);
                    //    }
                    //    else if (obj is ArcElement)
                    //    {
                    //        ICurve arc = ArcToSpeckle((ArcElement)obj, u);
                    //        baseLine = arc;
                    //        baseLine = TransformCurve(arc, origin, angle);
                    //    }
                    //    else
                    //    {
                    //        throw new NotSupportedException("GridCurveType " + curveType + " not supported!");
                    //    }
                    //    gridLines.Add(CreateGridLine(baseLine, label, u));
                    //}
                    switch (curveType)
                    {
                    case TFdGridCurveType.TFdGridCurveType_OrthogonalX:
                    case TFdGridCurveType.TFdGridCurveType_OrthogonalY:
                        baseLine = GridCurveToSpeckle(gridCurve, origin, angle, minimumValueX, minimumValueY, maximumValueX, maximumValueY, u);
                        break;

                    case TFdGridCurveType.TFdGridCurveType_Circular:
                        Plane xy = new Plane(new Point(origin.X, origin.Y, 0, u), new Vector(0, 0, 1, u), new Vector(1, 0, 0, u), new Vector(0, 1, 0, u), u);
                        baseLine = new Arc(xy, gridValue, angle, maximumCircularAngle + angle, maximumCircularAngle, u);
                        break;

                    case TFdGridCurveType.TFdGridCurveType_Radial:
                        Point startPoint = Translate(Rotate(new Point(0, 0, 0, u), angle), origin.X, origin.Y);
                        Point endPoint   = Translate(Rotate(Rotate(new Point(maximumRadius, 0, 0, u), gridValue * UoR), angle), origin.X, origin.Y);
                        baseLine = new Line(startPoint, endPoint, u);
                        break;

                    default:
                        continue;
                    }
                    gridLines.Add(CreateGridLine(baseLine, label, u));
                }
            }
            return(container);
        }