mcneel / rhinocommon

RhinoCommon is the .NET SDK for Rhino5 / Grasshopper
http://wiki.mcneel.com/developer/rhinocommon
243 stars 93 forks source link

Issue with DrawSprite? #170

Open nicolas-chaulet opened 8 years ago

nicolas-chaulet commented 8 years ago

Hi, I have been using the DrawSprite method from the DIsplayConduit lately and I realized that it was generating a memory leak. Below is a code that can be used in a plugin to recreate the issue. There may be something wrong in the way I use the method but I couldn't find it.

   public class TestSprite : Command
    {
        public TestSprite()
        {
            // Rhino only creates one instance of each command class defined in a
            // plug-in, so it is safe to store a refence in a static property.
            Instance = this;
        }

        ///<summary>The only instance of this command.</summary>
        public static TestSprite Instance
        {
            get; private set;
        }

        ///<returns>The command name as it appears on the Rhino command line.</returns>
        public override string EnglishName
        {
            get { return "DrawRectangle"; }
        }

        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            return Test.SpriteDrawing(doc);
        }
    }

    public class Test
    {
        static float m_sprite_size = 200;

        public static Rhino.Commands.Result SpriteDrawing(RhinoDoc doc)
        {
            var size_option = new Rhino.Input.Custom.OptionDouble(m_sprite_size);
            var go = new Rhino.Input.Custom.GetOption();
            go.SetCommandPrompt("Sprite drawing mode");
            go.AddOptionDouble("Size", ref size_option);

            Rhino.Display.DisplayPipeline.PostDrawObjects += DisplayRectangle;

            doc.Views.Redraw();
            while (go.Get() == Rhino.Input.GetResult.Option)
            {
                m_sprite_size = (float)size_option.CurrentValue;
                doc.Views.Redraw();
            }

            Rhino.Display.DisplayPipeline.PostDrawObjects -= DisplayRectangle;
            return Rhino.Commands.Result.Success;
        }

        static Rhino.Display.DisplayBitmap mm;
        static void DisplayRectangle(object sender, Rhino.Display.DrawEventArgs e)
        {
            Bitmap bit = new Bitmap((int)m_sprite_size, (int)m_sprite_size);
            using (Graphics graphics = Graphics.FromImage(bit))
            {
                // Main frame
                using (Pen pen = new Pen(Color.Black))
                {
                    graphics.FillRectangle(Brushes.White, 0, 0, m_sprite_size, m_sprite_size);
                    graphics.DrawRectangle(pen, 0, 0, m_sprite_size, m_sprite_size);
                }
            }

            // Display
            RectangleF bounds = e.Viewport.Bounds;
            mm = new Rhino.Display.DisplayBitmap(bit);
            e.Display.DrawSprite(mm, new Point2d(bounds.Width/2 + m_sprite_size / 2, bounds.Height/2 + m_sprite_size/2), m_sprite_size);
            bit.Dispose();mm.Dispose();
        }
    }