I have created a Scene with ILNumerics that consists of 3 PlotCubes and a Colorbar.
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.
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>(...)
?