Ejemplo n.º 1
0
        SolveResults Compute(string fileLoc, List <Color> colors, int tskId)
        {
            var  rc           = new SolveResults();
            bool filterColors = colors.Any();

            List <GH_Colour>        topCols     = new List <GH_Colour>();
            List <GH_Integer>       colCount    = new List <GH_Integer>();
            GH_Structure <GH_Point> colLocation = new GH_Structure <GH_Point>();


            try
            {
                using (Bitmap bitmap = new Bitmap(fileLoc))
                {
                    GH_Integer pixCount = new GH_Integer();
                    GH_Convert.ToGHInteger(bitmap.Height * bitmap.Width, 0, ref pixCount);
                    rc.PixCount = pixCount;

                    ///https://www.grasshopper3d.com/forum/topics/unsafe?page=1&commentId=2985220%3AComment%3A808291&x=1#2985220Comment808291
                    GH_MemoryBitmap sampler = new GH_MemoryBitmap(bitmap);

                    Color col = Color.Transparent;
                    for (int x = 0; x < bitmap.Width; x++)
                    {
                        for (int y = 0; y < bitmap.Height; y++)
                        {
                            ///GH_MemoryBitmap Sample is faster than GetPixel
                            //col = bitmap.GetPixel(x, y);
                            if (sampler.Sample(x, y, ref col))
                            {
                                if (colors.Contains(col))
                                {
                                    GH_Path path = new GH_Path(tskId, colors.IndexOf(col));
                                    colLocation.Append(new GH_Point(new Point3d(x, y, 0)), path);
                                }
                                else if (!filterColors)
                                {
                                    colors.Add(col);
                                    GH_Path path = new GH_Path(tskId, colors.IndexOf(col));
                                    colLocation.Append(new GH_Point(new Point3d(x, y, 0)), path);
                                }
                            }
                        }
                    }

                    sampler.Release(false);
                    bitmap.Dispose();
                }
            }

            catch
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Could not load image from file path: " + fileLoc);
            }

            List <GH_Colour> ghColors = new List <GH_Colour>();

            foreach (var c in colors)
            {
                ghColors.Add(new GH_Colour(c));
            }

            rc.TopColors     = ghColors;
            rc.ColorLocation = colLocation;

            return(rc);
        }
Ejemplo n.º 2
0
        SolveResults Compute(string fileLoc, int numColors)
        {
            var rc = new SolveResults();
            Dictionary <Color, int> dictColors = new Dictionary <Color, int>();
            Dictionary <Color, List <GH_Point> > dictColorLocation = new Dictionary <Color, List <GH_Point> >();
            List <GH_Colour>        topCols     = new List <GH_Colour>();
            List <GH_Integer>       colCount    = new List <GH_Integer>();
            GH_Structure <GH_Point> colLocation = new GH_Structure <GH_Point>();


            try
            {
                using (Bitmap bitmap = new Bitmap(fileLoc))
                {
                    GH_Integer pixCount = new GH_Integer();
                    GH_Convert.ToGHInteger(bitmap.Height * bitmap.Width, 0, ref pixCount);
                    rc.PixCount = pixCount;

                    ///https://www.grasshopper3d.com/forum/topics/unsafe?page=1&commentId=2985220%3AComment%3A808291&x=1#2985220Comment808291
                    GH_MemoryBitmap sampler = new GH_MemoryBitmap(bitmap);

                    Color col = Color.Transparent;
                    for (int x = 0; x < bitmap.Width; x++)
                    {
                        for (int y = 0; y < bitmap.Height; y++)
                        {
                            ///GH_MemoryBitmap Sample is faster than GetPixel
                            //col = bitmap.GetPixel(x, y);
                            if (sampler.Sample(x, y, ref col))
                            {
                                if (!dictColors.ContainsKey(col))
                                {
                                    dictColors.Add(col, 1);
                                    //dictColorLocation.Add(col, new List<GH_Point> { new GH_Point(new Point3d(x,y,0)) });
                                }
                                else
                                {
                                    dictColors[col]++;
                                    //dictColorLocation[col].Add(new GH_Point(new Point3d(x,y,0)));
                                }
                            }
                        }
                    }

                    if (numColors > dictColors.Count || numColors <= 0)
                    {
                        numColors = dictColors.Count;
                    }

                    var sortedColorDict = (from entry in dictColors orderby entry.Value descending select entry)
                                          .Take(numColors)
                                          .ToDictionary(pair => pair.Key, pair => pair.Value);

                    //var sortedColorLocation = (from entry in dictColorLocation orderby entry.Value.Count descending select entry)
                    //    .Take(numColors)
                    //   .ToDictionary(pair => pair.Key, pair => pair.Value);

                    foreach (var clr in sortedColorDict)
                    {
                        GH_Colour gh_Col = new GH_Colour();
                        GH_Convert.ToGHColour(clr.Key, 0, ref gh_Col);
                        topCols.Add(gh_Col);

                        GH_Integer gh_Count = new GH_Integer();
                        GH_Convert.ToGHInteger(clr.Value, 0, ref gh_Count);
                        colCount.Add(gh_Count);
                    }

                    /*int i = 0;
                     * foreach (var clr in sortedColorLocation)
                     * {
                     *  GH_Path path = new GH_Path(i);
                     *  colLocation.AppendRange(clr.Value, path);
                     *  i++;
                     * }
                     */

                    sampler.Release(false);
                    bitmap.Dispose();
                }
            }

            catch
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Could not load image from file path: " + fileLoc);
            }

            rc.TopColors  = topCols;
            rc.ColorCount = colCount;
            //rc.ColorLocation = colLocation;

            return(rc);
        }
Ejemplo n.º 3
0
        public static Bitmap ConvertCubicToEquirectangular(Bitmap bm, int w)
        {
            //algorithm from https://stackoverflow.com/questions/34250742/converting-a-cubemap-into-equirectangular-panorama
            //for cube maps with the following format:
            //  empty top empty empty
            //  left forward right backward
            //  empty bottom empty empty

            Bitmap          equiTexture = new Bitmap(w, w / 2, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            GH_MemoryBitmap ghEquiMap   = new GH_MemoryBitmap(equiTexture);

            ///GH_MemoryBitmap Sample faster than GetPixel
            ///https://www.grasshopper3d.com/forum/topics/unsafe?page=1&commentId=2985220%3AComment%3A808291&x=1#2985220Comment808291
            GH_MemoryBitmap ghBitmap = new GH_MemoryBitmap(bm);

            double u, v;       //Normalised texture coordinates, from 0 to 1, starting at lower left corner
            double phi, theta; //Polar coordinates
            int    cubeFaceWidth, cubeFaceHeight;


            cubeFaceWidth  = bm.Width / 4;  //4 horizontal faces
            cubeFaceHeight = bm.Height / 3; //3 vertical faces


            for (int j = 0; j < equiTexture.Height; j++)
            {
                //Rows start from the bottom
                v     = 1 - ((double)j / equiTexture.Height);
                theta = v * Math.PI;

                for (int i = 0; i < equiTexture.Width; i++)
                {
                    //Columns start from the left
                    u   = ((double)i / equiTexture.Width);
                    phi = u * 2 * Math.PI;

                    double x, y, z; //Unit vector
                    x = Math.Sin(phi) * Math.Sin(theta) * -1;
                    y = Math.Cos(theta);
                    z = Math.Cos(phi) * Math.Sin(theta) * -1;

                    double xa, ya, za;
                    double a;

                    double[] maxArr = new double[3] {
                        Math.Abs(x), Math.Abs(y), Math.Abs(z)
                    };
                    //a = Math.Max(new double[3] { Math.Abs(x), Math.Abs(y), Math.Abs(z) });
                    a = maxArr.Max();

                    //Vector Parallel to the unit vector that lies on one of the cube faces
                    xa = x / a;
                    ya = y / a;
                    za = z / a;

                    Color color = Color.Transparent;
                    int   xPixel, yPixel;
                    int   xOffset, yOffset;

                    if (xa == 1)
                    {
                        //Right
                        xPixel  = (int)((((za + 1) / 2) - 1) * cubeFaceWidth);
                        xOffset = 2 * cubeFaceWidth; //Offset
                        yPixel  = (int)((((ya + 1) / 2)) * cubeFaceHeight);
                        yOffset = cubeFaceHeight;    //Offset
                    }
                    else if (xa == -1)
                    {
                        //Left
                        xPixel  = (int)((((za + 1) / 2)) * cubeFaceWidth);
                        xOffset = 0;
                        yPixel  = (int)((((ya + 1) / 2)) * cubeFaceHeight);
                        yOffset = cubeFaceHeight;
                    }
                    else if (ya == 1)
                    {
                        //Up
                        xPixel  = (int)((((xa + 1) / 2)) * cubeFaceWidth);
                        xOffset = cubeFaceWidth;
                        yPixel  = (int)((((za + 1) / 2) - 1) * cubeFaceHeight);
                        yOffset = 2 * cubeFaceHeight;
                    }
                    else if (ya == -1)
                    {
                        //Down
                        xPixel  = (int)((((xa + 1) / 2)) * cubeFaceWidth);
                        xOffset = cubeFaceWidth;
                        yPixel  = (int)((((za + 1) / 2)) * cubeFaceHeight);
                        yOffset = 0;
                    }
                    else if (za == 1)
                    {
                        //Front
                        xPixel  = (int)((((xa + 1) / 2)) * cubeFaceWidth);
                        xOffset = cubeFaceWidth;
                        yPixel  = (int)((((ya + 1) / 2)) * cubeFaceHeight);
                        yOffset = cubeFaceHeight;
                    }
                    else if (za == -1)
                    {
                        //Back
                        xPixel  = (int)((((xa + 1) / 2) - 1) * cubeFaceWidth);
                        xOffset = 3 * cubeFaceWidth;
                        yPixel  = (int)((((ya + 1) / 2)) * cubeFaceHeight);
                        yOffset = cubeFaceHeight;
                    }
                    else
                    {
                        //Debug.LogWarning("Unknown face, something went wrong");
                        xPixel  = 0;
                        yPixel  = 0;
                        xOffset = 0;
                        yOffset = 0;
                    }

                    xPixel = Math.Abs(xPixel);
                    yPixel = Math.Abs(yPixel);

                    xPixel += xOffset;
                    yPixel += yOffset;

                    if (xPixel < 0 || yPixel < 0)
                    {
                        throw new ArgumentNullException("x = " + xPixel.ToString() + " y = " + yPixel.ToString());
                    }

                    if (xPixel > (bm.Width - 1))
                    {
                        xPixel = xPixel - 1;
                        //throw new ArgumentNullException("x = " + xPixel.ToString() + " y = " + yPixel.ToString()+" i="+i+" j="+j);
                    }

                    if (yPixel > (bm.Height - 1))
                    {
                        yPixel = yPixel - 1;
                        //throw new ArgumentNullException("x = " + xPixel.ToString() + " y = " + yPixel.ToString()+" i="+i+" j="+j);
                    }

                    //sampler.Sample(xPixel, yPixel, ref color);
                    color = ghBitmap.Colour(xPixel, yPixel);

                    ghEquiMap.Colour(i, j, color);
                }
            }

            ghBitmap.Release(false);
            ghEquiMap.Release(true);

            return(equiTexture);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <Plane> camPlanes = new List <Plane>();

            DA.GetDataList <Plane>(0, camPlanes);

            string folder = string.Empty;

            DA.GetData <string>(1, ref folder);
            bool saveCubemaps = !string.IsNullOrEmpty(folder);

            if (saveCubemaps)
            {
                folder = Path.GetFullPath(folder);
                if (!folder.EndsWith(Path.DirectorySeparatorChar.ToString()))
                {
                    folder += Path.DirectorySeparatorChar;
                }
            }

            string prefix = string.Empty;

            DA.GetData <string>(2, ref prefix);

            int imageWidth = 0;

            DA.GetData <int>(3, ref imageWidth);
            imageWidth = imageWidth / 4;
            Size size = new Size(imageWidth, imageWidth);

            string displayMode = string.Empty;

            DA.GetData <string>(4, ref displayMode);

            List <Color> colors = new List <Color>();

            DA.GetDataList <Color>(5, colors);
            bool filterColors = colors.Any();

            GH_Structure <GH_Mesh> ghObstacles = new GH_Structure <GH_Mesh>();

            DA.GetDataTree <GH_Mesh>(6, out ghObstacles);

            ///Flatten obstacle meshes and join them into one mesh
            ghObstacles.FlattenData();
            Mesh obstacles = new Mesh();
            bool showRays  = false;

            if (ghObstacles.DataCount > 0)
            {
                showRays = true;
                foreach (var obstacle in ghObstacles)
                {
                    Mesh temp = new Mesh();
                    GH_Convert.ToMesh(obstacle, ref temp, GH_Conversion.Primary);
                    obstacles.Append(temp);
                }
            }


            bool run = false;

            DA.GetData <bool>(7, ref run);

            int pad = camPlanes.Count.ToString().Length;

            List <string> cubemaps = new List <string>();

            GH_Structure <GH_Line>   rayTree   = new GH_Structure <GH_Line>();
            GH_Structure <GH_Colour> colorTree = new GH_Structure <GH_Colour>();

            ///Save the intial camera
            saveCam = camFromVP(Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.ActiveViewport);

            ///Set the display mode to be used for bitmaps
            ///TODO: Add menu item to use "Heron View Analysis" display mode
            DisplayModeDescription viewMode = Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.ActiveViewport.DisplayMode;

            if (DisplayModeDescription.FindByName(displayMode) != null)
            {
                viewMode = DisplayModeDescription.FindByName(displayMode);
            }

            Message = viewMode.EnglishName;

            if (run)
            {
                for (int i = 0; i < camPlanes.Count; i++)
                {
                    ///TODO: setup ability to save cameras to the Rhino doc
                    ///Setup camera
                    Rhino.Display.RhinoView     view = Rhino.RhinoDoc.ActiveDoc.Views.ActiveView;
                    Rhino.Display.RhinoViewport vp   = view.ActiveViewport;

                    ///Get the bounding box of all visible object in the doc for use in setting up the camera
                    ///target so that the far frustrum plane doesn't clip anything
                    double zoomDistance = Rhino.RhinoDoc.ActiveDoc.Objects.BoundingBoxVisible.Diagonal.Length;

                    Plane    camPlane = camPlanes[i];
                    Point3d  camPoint = camPlane.Origin;
                    Vector3d camDir   = camPlane.YAxis;
                    Point3d  tarPoint = Transform.Translation(camDir * zoomDistance / 2) * camPoint;


                    vp.ChangeToPerspectiveProjection(false, 12.0);
                    vp.Size        = size;
                    vp.DisplayMode = viewMode;
                    //view.Redraw();

                    ///Set up final bitmap
                    Bitmap cubemap = new Bitmap(imageWidth * 4, imageWidth * 3);

                    ///Place the images on cubemap bitmap
                    using (Graphics gr = Graphics.FromImage(cubemap))
                    {
                        ///Grab bitmap

                        ///Set up camera directions
                        Point3d        tarLeft    = Transform.Translation(-camPlane.XAxis * zoomDistance / 2) * camPoint;
                        Point3d        tarFront   = Transform.Translation(camPlane.YAxis * zoomDistance / 2) * camPoint;
                        Point3d        tarRight   = Transform.Translation(camPlane.XAxis * zoomDistance / 2) * camPoint;
                        Point3d        tarBack    = Transform.Translation(-camPlane.YAxis * zoomDistance / 2) * camPoint;
                        Point3d        tarUp      = Transform.Translation(camPlane.ZAxis * zoomDistance / 2) * camPoint;
                        Point3d        tarDown    = Transform.Translation(-camPlane.ZAxis * zoomDistance / 2) * camPoint;
                        List <Point3d> camTargets = new List <Point3d>()
                        {
                            tarLeft, tarFront, tarRight, tarBack, tarUp, tarDown
                        };

                        ///Loop through pano directions
                        int insertLoc = 0;
                        for (int d = 0; d < 4; d++)
                        {
                            ///Set camera direction
                            vp.SetCameraLocations(camTargets[d], camPoint);
                            //view.Redraw();

                            Bitmap bitmap = new Bitmap(view.CaptureToBitmap(size, viewMode));

                            if (saveCubemaps)
                            {
                                gr.DrawImage(bitmap, insertLoc, imageWidth);
                            }

                            if (showRays)
                            {
                                GH_MemoryBitmap sampler = new GH_MemoryBitmap(bitmap);
                                Color           col     = Color.Transparent;
                                for (int x = 0; x < bitmap.Width; x++)
                                {
                                    for (int y = 0; y < bitmap.Height; y++)
                                    {
                                        if (sampler.Sample(x, y, ref col))
                                        {
                                            if (colors.Contains(col))
                                            {
                                                GH_Path path = new GH_Path(i, colors.IndexOf(col));

                                                Line line = vp.ClientToWorld(new System.Drawing.Point(x, y));

                                                Ray3d   ray             = new Ray3d(vp.CameraLocation, -line.Direction);
                                                double  rayEnd          = (double)Rhino.Geometry.Intersect.Intersection.MeshRay(obstacles, ray);
                                                Point3d rayIntersection = ray.PointAt(rayEnd);
                                                Line    ln = new Line(camPoint, rayIntersection);

                                                if (ln.IsValid & rayEnd > 0)
                                                {
                                                    rayTree.Append(new GH_Line(ln), path);
                                                    colorTree.Append(new GH_Colour(col), path);
                                                }
                                            }
                                            else if (!filterColors)
                                            {
                                                colors.Add(col);
                                                GH_Path path = new GH_Path(i, colors.IndexOf(col));

                                                Line line = vp.ClientToWorld(new System.Drawing.Point(x, y));

                                                Ray3d   ray             = new Ray3d(vp.CameraLocation, -line.Direction);
                                                double  rayEnd          = (double)Rhino.Geometry.Intersect.Intersection.MeshRay(obstacles, ray);
                                                Point3d rayIntersection = ray.PointAt(rayEnd);
                                                Line    ln = new Line(camPoint, rayIntersection);

                                                if (ln.IsValid & rayEnd > 0)
                                                {
                                                    rayTree.Append(new GH_Line(ln), path);
                                                    colorTree.Append(new GH_Colour(col), path);
                                                }
                                            }
                                        }
                                    }
                                }
                                sampler.Release(false);
                            }

                            insertLoc = insertLoc + imageWidth;

                            bitmap.Dispose();
                        }


                        ///Get up and down views

                        ///Get up view
                        vp.SetCameraLocations(tarUp, camPoint);
                        view.Redraw();

                        Bitmap bitmapUp = new Bitmap(view.CaptureToBitmap(size, viewMode));

                        if (showRays)
                        {
                            GH_MemoryBitmap sampler = new GH_MemoryBitmap(bitmapUp);
                            Color           col     = Color.Transparent;
                            for (int x = 0; x < bitmapUp.Width; x++)
                            {
                                for (int y = 0; y < bitmapUp.Height; y++)
                                {
                                    if (sampler.Sample(x, y, ref col))
                                    {
                                        if (colors.Contains(col))
                                        {
                                            GH_Path path = new GH_Path(i, colors.IndexOf(col));

                                            Line line = vp.ClientToWorld(new System.Drawing.Point(x, y));

                                            Ray3d   ray             = new Ray3d(vp.CameraLocation, -line.Direction);
                                            double  rayEnd          = (double)Rhino.Geometry.Intersect.Intersection.MeshRay(obstacles, ray);
                                            Point3d rayIntersection = ray.PointAt(rayEnd);
                                            Line    ln = new Line(camPoint, rayIntersection);

                                            if (ln.IsValid & rayEnd > 0)
                                            {
                                                rayTree.Append(new GH_Line(ln), path);
                                                colorTree.Append(new GH_Colour(col), path);
                                            }
                                        }
                                        else if (!filterColors)
                                        {
                                            colors.Add(col);
                                            GH_Path path = new GH_Path(i, colors.IndexOf(col));

                                            Line line = vp.ClientToWorld(new System.Drawing.Point(x, y));

                                            Ray3d   ray             = new Ray3d(vp.CameraLocation, -line.Direction);
                                            double  rayEnd          = (double)Rhino.Geometry.Intersect.Intersection.MeshRay(obstacles, ray);
                                            Point3d rayIntersection = ray.PointAt(rayEnd);
                                            Line    ln = new Line(camPoint, rayIntersection);

                                            if (ln.IsValid & rayEnd > 0)
                                            {
                                                rayTree.Append(new GH_Line(ln), path);
                                                colorTree.Append(new GH_Colour(col), path);
                                            }
                                        }
                                    }
                                }
                            }
                            sampler.Release(false);
                        }

                        bitmapUp.RotateFlip(RotateFlipType.Rotate180FlipNone);
                        if (saveCubemaps)
                        {
                            gr.DrawImage(bitmapUp, imageWidth, 0);
                        }

                        bitmapUp.Dispose();


                        ///Get down view
                        vp.SetCameraLocations(tarDown, camPoint);
                        view.Redraw();

                        Bitmap bitmapDown = new Bitmap(view.CaptureToBitmap(size, viewMode));

                        if (saveCubemaps)
                        {
                            gr.DrawImage(bitmapDown, imageWidth, imageWidth * 2);
                        }

                        if (showRays)
                        {
                            GH_MemoryBitmap sampler = new GH_MemoryBitmap(bitmapDown);
                            Color           col     = Color.Transparent;
                            for (int x = 0; x < bitmapDown.Width; x++)
                            {
                                for (int y = 0; y < bitmapDown.Height; y++)
                                {
                                    if (sampler.Sample(x, y, ref col))
                                    {
                                        if (colors.Contains(col))
                                        {
                                            GH_Path path = new GH_Path(i, colors.IndexOf(col));

                                            Line line = vp.ClientToWorld(new System.Drawing.Point(x, y));

                                            Ray3d   ray             = new Ray3d(vp.CameraLocation, -line.Direction);
                                            double  rayEnd          = (double)Rhino.Geometry.Intersect.Intersection.MeshRay(obstacles, ray);
                                            Point3d rayIntersection = ray.PointAt(rayEnd);
                                            Line    ln = new Line(camPoint, rayIntersection);

                                            if (ln.IsValid & rayEnd > 0)
                                            {
                                                rayTree.Append(new GH_Line(ln), path);
                                                colorTree.Append(new GH_Colour(col), path);
                                            }
                                        }

                                        else if (!filterColors)
                                        {
                                            colors.Add(col);
                                            GH_Path path = new GH_Path(i, colors.IndexOf(col));

                                            Line line = vp.ClientToWorld(new System.Drawing.Point(x, y));

                                            Ray3d   ray             = new Ray3d(vp.CameraLocation, -line.Direction);
                                            double  rayEnd          = (double)Rhino.Geometry.Intersect.Intersection.MeshRay(obstacles, ray);
                                            Point3d rayIntersection = ray.PointAt(rayEnd);
                                            Line    ln = new Line(camPoint, rayIntersection);

                                            if (ln.IsValid & rayEnd > 0)
                                            {
                                                rayTree.Append(new GH_Line(ln), path);
                                                colorTree.Append(new GH_Colour(col), path);
                                            }
                                        }
                                    }
                                }
                            }
                            sampler.Release(false);
                        }

                        bitmapDown.Dispose();
                    }
                    ///End pano directions loop

                    if (saveCubemaps)
                    {
                        ///Save cubemap bitmap
                        string s        = i.ToString().PadLeft(pad, '0');
                        string saveText = folder + prefix + "_" + s + ".png";
                        cubemap.Save(saveText, System.Drawing.Imaging.ImageFormat.Png);
                        cubemaps.Add(saveText);
                    }
                    cubemap.Dispose();
                }
            }

            ///Restore initial camera
            setCamera(saveCam, Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.ActiveViewport);
            Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.Redraw();

            DA.SetDataList(0, cubemaps);
            DA.SetDataTree(1, rayTree);
            DA.SetDataTree(2, colorTree);
        }