//Render triangles dRectly to a grid by drawing the triangles
        public void RenderTrianglesToGrid(Triangles triangles, Grid grid)
        {
            if (triangles == null || grid == null)
            {
                return;
            }

            IPainter    painter = new CPainter();
            GridContext bgc     = new GridContext(grid);

            float sx = grid.SizeX - 1;
            float sy = grid.SizeY - 1;
            float sz = grid.SizeZ - 1;

            bgc.Pen.Rgba = RasterLib.RasterApi.Rgba2Ulong(255, 255, 255, 255);
            foreach (Triangle triangle in triangles.GetTriangleArray())
            {
                var x1 = (int)((triangle.Vertex1[0] + 0.5f) * sx);
                var y1 = (int)((triangle.Vertex1[1] + 0.5f) * sy);
                var z1 = (int)((triangle.Vertex1[2] + 0.5f) * sz);

                var x2 = (int)((triangle.Vertex2[0] + 0.5f) * sx);
                var y2 = (int)((triangle.Vertex2[1] + 0.5f) * sy);
                var z2 = (int)((triangle.Vertex2[2] + 0.5f) * sz);

                var x3 = (int)((triangle.Vertex3[0] + 0.5f) * sx);
                var y3 = (int)((triangle.Vertex3[1] + 0.5f) * sy);
                var z3 = (int)((triangle.Vertex3[2] + 0.5f) * sz);

                //This requires a filled triangle3d function
                painter.DrawFillTriangle3D(bgc, x1, y1, z1, x2, y2, z2, x3, y3, z3);
            }
        }
        //Render Isometricly and return
        public Grid RenderIsometricCellsScaled(Grid grid, byte bgR, byte bgG, byte bgB, byte bgA, int cellWidth, int cellHeight, string title = "")
        {
            if (grid == null)
            {
                return(null);
            }

            int cellSizeX = cellWidth;
            int cellSizeY = cellHeight;

            int maxSize = (grid.SizeX > grid.SizeZ) ? grid.SizeX : grid.SizeZ;
            int ix      = (int)(maxSize * cellSizeX * 2.2);
            //int iy = (int)(maxSize * cellSizeY * 1.2);//1.6);
            int  iy    = (int)(maxSize * cellSizeY * 2.2);
            Grid grid2 = new Grid(ix, iy, 1, grid.Bpp);

            GridContext bgc = new GridContext(grid2)
            {
                Pen = { Rgba = RasterLib.RasterApi.Rgba2Ulong(bgR, bgG, bgB, bgA) }
            };

            IPainter painter = new CPainter();

            painter.DrawFastFillRect(bgc, 0, 0, 0, grid2.SizeX, grid2.SizeY, 1);

            RenderIsometricCellsSetScaled(grid, grid2, cellSizeX, cellSizeY, title);
            return(grid2);
        }
        //Render a cell at x,y coords
        public static void RenderCell(GridContext bgc, int x, int y)
        {
            IPainter  painter = new CPainter();
            const int cellSize = 12;
            ulong     color = bgc.Pen.Rgba;
            const int subSize = 8;
            const int tinSize = (cellSize - subSize);
            byte      r, g, b, a;

            RasterLib.RasterApi.Ulong2Rgba(color, out r, out g, out b, out a);

            bgc.Pen.Rgba = RasterLib.RasterApi.Rgba2Ulong(16, 16, 16, 255);
            painter.DrawHollowRect(bgc, x + tinSize, y, 0, x + cellSize - 1, y + subSize - 1, 0);

            int ir = r;
            int ig = g;
            int ib = b;

            //Top side
            bgc.Pen.Rgba = RasterLib.RasterApi.Rgba2Ulong((byte)ir, (byte)ig, (byte)ib, 255);
            painter.DrawLine2D(bgc, x + tinSize, y + 1, x + subSize + 1, y + 1, 0);
            painter.DrawLine2D(bgc, x + tinSize - 1, y + 2, x + subSize, y + 2, 0);
            painter.DrawLine2D(bgc, x + tinSize - 2, y + 3, x + subSize - 1, y + 3, 0);

            //Front side
            ir           = r;
            ig           = g;
            ib           = b;
            bgc.Pen.Rgba = RasterLib.RasterApi.Rgba2Ulong((byte)ir, (byte)ig, (byte)ib, 255);
            painter.DrawFastFillRect(bgc, x + 1, y + tinSize + 1, 0, x + subSize, y + subSize + 2, 0);

            //Right side
            ir           = r / 2;
            ig           = g / 2;
            ib           = b / 2;
            bgc.Pen.Rgba = RasterLib.RasterApi.Rgba2Ulong((byte)ir, (byte)ig, (byte)ib, 255);
            painter.DrawLine2D(bgc, x + cellSize - 2, y + 2, x + cellSize - 2, y + subSize, 0);
            painter.DrawLine2D(bgc, x + cellSize - 3, y + 2, x + cellSize - 3, y + subSize, 0);
            painter.DrawLine2D(bgc, x + cellSize - 4, y + 3, x + cellSize - 4, y + subSize + 1, 0);

            //Front rect
            bgc.Pen.Rgba = RasterLib.RasterApi.Rgba2Ulong(32, 32, 32, 255);
            painter.DrawHollowRect(bgc, x, y + tinSize, 0, x + subSize - 1, y + cellSize - 1, 0);

            //Lines
            painter.DrawLine2D(bgc, x, y + tinSize, x + tinSize, y, 0);
            painter.DrawLine2D(bgc, x + subSize - 1, y + tinSize, x + cellSize - 1, y, 0);
            painter.DrawLine2D(bgc, x + subSize - 1, y + cellSize - 1, x + cellSize - 1, y + subSize - 1, 0);
        }
        //Render a set of rects into a grid as little filled 3d rectangles
        public void RenderRectsToGrid(RectList rects, Grid grid)
        {
            if (rects == null || grid == null)
            {
                return;
            }

            GridContext bgc     = new GridContext(grid);
            IPainter    painter = new CPainter();

            //Draw background
            painter.DrawFastFillRect(bgc, 0, 0, 0, bgc.Grid.SizeX, bgc.Grid.SizeY, bgc.Grid.SizeZ);

            //Then draw each triangle, adjusting for inclusive numbering
            const int inclusiveOffset = 1;

            foreach (Rect rect in rects)
            {
                bgc.Pen.SetColor(rect.Properties.Rgba);
                painter.DrawFastFillRect(bgc, (int)rect.Pt1[0], (int)rect.Pt1[1], (int)rect.Pt1[2], (int)rect.Pt2[0] - inclusiveOffset, (int)rect.Pt2[1] - inclusiveOffset, (int)rect.Pt2[2] - inclusiveOffset);
            }
        }
        //Render obliquely and return
        public Grid RenderObliqueCellsRects(RectList rects)
        {
            if (rects == null)
            {
                return(null);
            }

            const int cellSize = 12;
            int       ix       = rects.SizeX * cellSize;
            int       iy       = rects.SizeY * cellSize;
            Grid      grid2    = new Grid(ix, iy, 1, 4);

            GridContext bgc = new GridContext(grid2)
            {
                Pen = { Rgba = RasterLib.RasterApi.Rgba2Ulong(255, 255, 255, 255) }
            };

            IPainter painter = new CPainter();

            painter.DrawFastFillRect(bgc, 0, 0, 0, grid2.SizeX, grid2.SizeY, 1);

            RenderObliqueCellsSetRects(rects, grid2);
            return(grid2);
        }
        //Render obliquely and return
        public Grid RenderObliqueCells(Grid grid)
        {
            if (grid == null)
            {
                return(null);
            }

            const int cellSize = 12;
            int       ix       = grid.SizeX * cellSize;
            int       iy       = grid.SizeZ * cellSize;// +grid.SizeY * cellSize;
            Grid      grid2    = new Grid(ix, iy, 1, grid.Bpp);

            GridContext bgc = new GridContext(grid2)
            {
                Pen = { Rgba = RasterLib.RasterApi.Rgba2Ulong(255, 255, 255, 255) }
            };

            IPainter painter = new CPainter();

            painter.DrawFastFillRect(bgc, 0, 0, 0, grid2.SizeX, grid2.SizeY, 1);

            RenderObliqueCellsSet(grid, grid2);
            return(grid2);
        }
        //Render a cell at x,y coords
        private static void RenderIsometricCellScaled(GridContext bgc, int x, int y, int cellWidth, int cellHeight)
        {
            IPainter painter = new CPainter();
            ulong    color   = bgc.Pen.Rgba;
            //const int subSize = 8;
            //const int tinSize = (cellSize - subSize);
            byte r, g, b, a;

            RasterLib.RasterApi.Ulong2Rgba(color, out r, out g, out b, out a);

            int ir = r;
            int ig = g;
            int ib = b;

            bgc.Pen.Rgba = RasterLib.RasterApi.Rgba2Ulong((byte)ir, (byte)ig, (byte)ib, 255);

            bool skipWire = false;

            if (cellWidth == 1 && cellHeight == 1)
            {
                painter.DrawPen(bgc, x, y, 0);
                return;
            }
            else if (cellWidth <= 4 && cellHeight <= 4)
            {
                skipWire = true;
            }

            cellWidth  = cellWidth * 2;
            cellHeight = cellHeight * 2;

            int Is11 = (cellHeight / 4) * 3 - 1;

            //Top Left
            painter.DrawFillTriangle2D(bgc,
                                       x + 1, y + cellHeight / 4,
                                       x + cellWidth / 2, y + 0,
                                       x + cellWidth / 2, y + cellHeight / 2);

            //Top Right
            painter.DrawFillTriangle2D(bgc,
                                       x + cellWidth, y + cellHeight / 4,
                                       x + cellWidth / 2, y + 0,
                                       x + cellWidth / 2 - 1, y + cellHeight / 2);

            //Left
            ir           = (byte)(r / 1.5);
            ig           = (byte)(g / 1.5);
            ib           = (byte)(b / 1.5);
            bgc.Pen.Rgba = RasterLib.RasterApi.Rgba2Ulong((byte)ir, (byte)ig, (byte)ib, 255);
            painter.DrawFillTriangle2D(bgc,
                                       x + 0, y + cellHeight / 4,
                                       x + cellWidth / 2, y + cellHeight / 2,
                                       x + 0, y + Is11 + 1);

            painter.DrawFillTriangle2D(bgc,
                                       x + 0, y + Is11 + 1,
                                       x + cellWidth / 2, y + cellHeight / 2,
                                       x + cellWidth / 2, y + cellHeight);


            //right
            ir           = r / 2;
            ig           = g / 2;
            ib           = b / 2;
            bgc.Pen.Rgba = RasterLib.RasterApi.Rgba2Ulong((byte)ir, (byte)ig, (byte)ib, 255);
            painter.DrawFillTriangle2D(bgc,
                                       x + cellWidth, y + cellHeight / 4,
                                       x + cellWidth / 2 + 1, y + cellHeight / 2,
                                       x + cellWidth / 2 + 1, y + cellHeight);

            painter.DrawFillTriangle2D(bgc,
                                       x + cellWidth, y + cellHeight / 4,
                                       x + cellWidth, y + Is11 + 1,
                                       x + cellWidth / 2 + 1, y + cellHeight);



            if (skipWire)
            {
                return;
            }

            ir = (byte)(r / 2.5);
            ig = (byte)(g / 2.5);
            ib = (byte)(b / 2.5);

            //Top side
            bgc.Pen.Rgba = RasterLib.RasterApi.Rgba2Ulong((byte)ir, (byte)ig, (byte)ib, 255);
            painter.DrawLine2D(bgc,
                               x + 0, y + cellWidth / 4,
                               x + cellWidth / 2 - 1, y + 0,
                               0);
            //Top right
            painter.DrawLine2D(bgc,
                               x + cellWidth / 2 - 1, y + 0,
                               x + cellWidth - 1, y + cellHeight / 4,
                               0);

            //ToCenter - Top
            painter.DrawLine2D(bgc,
                               x + 0, y + cellWidth / 4,
                               x + cellWidth / 2 - 1, y + cellHeight / 2,
                               0);
            //FromCenter - Top
            painter.DrawLine2D(bgc,
                               x + cellWidth / 2 - 1, y + cellHeight / 2,
                               x + cellWidth - 1, y + cellHeight / 4,
                               0);

            //Halfway

            //Left Side
            painter.DrawLine2D(bgc,
                               x + 0, y + cellWidth / 4,
                               x + 0, y + Is11,
                               0);
            //Right side
            painter.DrawLine2D(bgc,
                               x + cellWidth, y + cellHeight / 4,
                               x + cellWidth, y + Is11,
                               0);

            //Right Bottom
            painter.DrawLine2D(bgc,
                               x + cellWidth, y + Is11 + 1,
                               x + cellWidth / 2, y + cellHeight,
                               0);
            //Right Left
            painter.DrawLine2D(bgc,
                               x + cellWidth / 2, y + cellHeight,
                               x + 0, y + Is11 + 1,
                               0);
        }