Search code examples
imageexportsceneilnumerics

ILNumerics: Export part of a scene as image without affecting original scene


I have created a Scene with ILNumerics that consists of 3 PlotCubes and a Colorbar.

Screenshot of the ILPanel

I wanted to add a method that exports the scene as an image in two ways, the first being the screenshot you see above. The second export is supposed to only show the centric cube.

I attempted to follow the guidelines of ILNumerics for scene management.

I wrote the following code:

public void ExportAsImage(int resolutionWidth, int resolutionHeight, string path, bool includeSubCubes)
    {
        using (ILScope.Enter())
        {
            ILGDIDriver backgroundDriver = new ILGDIDriver(resolutionWidth, resolutionHeight, ilPanel1.Scene);

            if (includeSubCubes)
            {
                // code for standard export here
            }
            else
            {
                // setting left and top cube and color bar invisible and
                // adjusting main cube size is affecting the ilPanel.Scene
                backgroundDriver.Scene.First<ILColorbar>().Visible = false;
                GetElementByTag<ILPlotCube>(backgroundDriver.Scene, _leftCubeTag).Visible = false;
                GetElementByTag<ILPlotCube>(backgroundDriver.Scene, _topCubeTag).Visible = false;

                GetElementByTag<ILPlotCube>(backgroundDriver.Scene, _mainCubeTag).ScreenRect = new RectangleF(0, 0, 1, 1);
                GetElementByTag<ILPlotCube>(backgroundDriver.Scene, _mainCubeTag).DataScreenRect = new RectangleF.Empty;

                backgroundDriver.Scene.Configure();
                backgroundDriver.Render();

                // save image
                backgroundDriver.BackBuffer.Bitmap.Save(path,System.Drawing.Imaging.ImageFormat.Png);

                // revert changes done to cubes and color bar
                backgroundDriver.Scene.First<ILColorbar>().Visible = true;
                GetElementByTag<ILPlotCube>(backgroundDriver.Scene, _leftCubeTag).Visible = true;
                GetElementByTag<ILPlotCube>(backgroundDriver.Scene, _topCubeTag).Visible = true;
                AdjustCubeSizes();
            }
        }
    }

Note: "GetElementByTag" is an own implementation to retrieve objects in the ILNumerics Scene.

I first expected that the new driver basically creates a copy of the Scene I can work on, but like the code shows I have to revert all changed after the export or the displayed ilPanel only shows the scene the way I exported it.

Is it possible at all to do export to image without affecting the real Scene? Am I just missing some details?

Regards, Florian S.


Solution

  • Florian, it does make a copy. But you need to add the interesting part to a new scene. The magic is happening in the Add() method:

    var scene4render = new ILScene(); 
    scene4render.Add(oldScene.First<ILPlotCube>(mytag)); 
    // ... configure scene4render here, it will be detached from the original scene
    // with the exception of shared buffers.
    
    // ... proceed with rendering
    

    In order to also include + render interactive state changes to the original plot cube (let's say rotations by the users mouse) you'd use something like that:

    scene4render.Add(panel.SceneSyncRoot.First<ILPlotCube>(mytag)); 
    

    Also, I wonder what GetElementByTag does better than ILGroup.First<T>(tag, predicate) or ILGroup.Find<T>(...)?

    See also: http://ilnumerics.net/scene-management.html