Ejemplo n.º 1
0
		/// <summary>
		/// Saves the project item as image to the provided stream.
		/// </summary>
		/// <param name="item">The item to export, for instance an item of type <see cref="Altaxo.Graph.Gdi.GraphDocument"/> or <see cref="Altaxo.Graph.Graph3D.GraphDocument"/>.</param>
		/// <param name="options">The export options.</param>
		/// <param name="toStream">The stream to save the image to.</param>
		public void ExportAsImageToStream(Altaxo.Main.IProjectItem item, Altaxo.Graph.Gdi.GraphExportOptions options, System.IO.Stream toStream)
		{
			if (item == null)
				throw new ArgumentNullException(nameof(item));
			if (!(item is Altaxo.Graph.Graph3D.GraphDocument))
				throw new ArgumentException(string.Format("Expected item of type {0}, but it is of type {1}", typeof(Altaxo.Graph.Graph3D.GraphDocument), item.GetType()));
			var doc = (Altaxo.Graph.Graph3D.GraphDocument)item;

			double sourceDpi = options.SourceDpiResolution;

			var exporter = new D3D10BitmapExporter();

			var scene = new Viewing.D3D10Scene();

			var g = new D3D10GraphicsContext();

			doc.Paint(g);

			var matrix = doc.Camera.LookAtRHMatrix;

			var rect = new RectangleD3D(PointD3D.Empty, doc.RootLayer.Size);
			var bounds = RectangleD3D.NewRectangleIncludingAllPoints(rect.Vertices.Select(x => matrix.Transform(x)));

			int pixelsX = (int)Math.Ceiling(sourceDpi * bounds.SizeX / 72.0);
			pixelsX = (int)(4 * Math.Ceiling((pixelsX + 3) / 4.0));

			int pixelsY = (int)(sourceDpi * bounds.SizeY / 72.0);

			double aspectRatio = pixelsY / (double)pixelsX;

			var sceneCamera = doc.Camera;

			if (sceneCamera is OrthographicCamera)
			{
				var orthoCamera = (OrthographicCamera)sceneCamera;
				orthoCamera = (OrthographicCamera)orthoCamera.WithWidthAtZNear(bounds.SizeX);

				double offsX = -(1 + 2 * bounds.X / bounds.SizeX);
				double offsY = -(1 + 2 * bounds.Y / bounds.SizeY);
				sceneCamera = orthoCamera.WithScreenOffset(new PointD2D(offsX, offsY));
			}
			else if (sceneCamera is PerspectiveCamera)
			{
				var viewProj = sceneCamera.GetViewProjectionMatrix(1); // here we transform the points with AspectRatio=1, in order to get the AspectRatio of the ScreenBounds
				var screenBounds = RectangleD3D.NewRectangleIncludingAllPoints(rect.Vertices.Select(x => viewProj.Transform(x)));
				aspectRatio = screenBounds.SizeY / screenBounds.SizeX; // this is the aspectRatio of our image
				viewProj = sceneCamera.GetViewProjectionMatrix(aspectRatio); // now we get the transform with our aspectRatio determined above
				screenBounds = RectangleD3D.NewRectangleIncludingAllPoints(rect.Vertices.Select(x => viewProj.Transform(x))); // this are our actual screenBounds, of course in relative screen coordinates, thus the ratio of sizeX and sizeY should now be 1

				double scaleFactor = 2 / screenBounds.SizeX; // since SizeX and SizeY should now be the same, we could have used SizeY alternatively
				double offsX = -(1 + scaleFactor * screenBounds.X);
				double offsY = -(1 + scaleFactor * screenBounds.Y);

				pixelsY = (int)(4 * Math.Ceiling((aspectRatio * pixelsX + 3) / 4.0)); // now calculate the size of the image in y direction from the aspectRatio

				var perspCamera = (PerspectiveCamera)sceneCamera;

				sceneCamera = perspCamera.WithWidthAtZNear(perspCamera.WidthAtZNear / scaleFactor);
				sceneCamera = sceneCamera.WithScreenOffset(new PointD2D(offsX, offsY));
			}
			else
			{
				throw new NotImplementedException();
			}

			scene.SetCamera(sceneCamera);
			scene.SetLighting(doc.Lighting);
			scene.SetDrawing(g);

			exporter.Export(pixelsX, pixelsY, scene, options, toStream);
		}
Ejemplo n.º 2
0
        /// <summary>
        /// Saves the project item as image to the provided stream.
        /// </summary>
        /// <param name="item">The item to export, for instance an item of type <see cref="Altaxo.Graph.Gdi.GraphDocument"/> or <see cref="Altaxo.Graph.Graph3D.GraphDocument"/>.</param>
        /// <param name="options">The export options.</param>
        /// <param name="toStream">The stream to save the image to.</param>
        public (int PixelsX, int PixelsY) ExportAsImageToStream(Altaxo.Main.IProjectItem item, Altaxo.Graph.Gdi.GraphExportOptions options, System.IO.Stream toStream)
        {
            // SharpDX.Configuration.EnableObjectTracking = true;
            // var listOfActiveObjects = SharpDX.Diagnostics.ObjectTracker.FindActiveObjects();

            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }
            if (!(item is Altaxo.Graph.Graph3D.GraphDocument))
            {
                throw new ArgumentException(string.Format("Expected item of type {0}, but it is of type {1}", typeof(Altaxo.Graph.Graph3D.GraphDocument), item.GetType()));
            }
            var doc = (Altaxo.Graph.Graph3D.GraphDocument)item;

            double sourceDpi = options.SourceDpiResolution;

            Viewing.D3D10Scene   scene = null;
            D3D10GraphicsContext g     = null;

            try
            {
                scene = new Viewing.D3D10Scene();
                g     = new D3D10GraphicsContext();

                doc.Paint(g);

                var matrix = doc.Camera.LookAtRHMatrix;

                var rect   = new RectangleD3D(PointD3D.Empty, doc.RootLayer.Size);
                var bounds = RectangleD3D.NewRectangleIncludingAllPoints(rect.Vertices.Select(x => matrix.Transform(x)));

                int pixelsX = (int)Math.Ceiling(sourceDpi * bounds.SizeX / 72.0);
                pixelsX = (int)(4 * Math.Ceiling((pixelsX + 3) / 4.0));

                int pixelsY = (int)(sourceDpi * bounds.SizeY / 72.0);

                double aspectRatio = pixelsY / (double)pixelsX;

                var sceneCamera = doc.Camera;

                if (sceneCamera is OrthographicCamera)
                {
                    var orthoCamera = (OrthographicCamera)sceneCamera;
                    orthoCamera = (OrthographicCamera)orthoCamera.WithWidthAtZNear(bounds.SizeX);

                    double offsX = -(1 + 2 * bounds.X / bounds.SizeX);
                    double offsY = -(1 + 2 * bounds.Y / bounds.SizeY);
                    sceneCamera = orthoCamera.WithScreenOffset(new PointD2D(offsX, offsY));
                }
                else if (sceneCamera is PerspectiveCamera)
                {
                    var viewProj     = sceneCamera.GetViewProjectionMatrix(1);                                                    // here we transform the points with AspectRatio=1, in order to get the AspectRatio of the ScreenBounds
                    var screenBounds = RectangleD3D.NewRectangleIncludingAllPoints(rect.Vertices.Select(x => viewProj.Transform(x)));
                    aspectRatio  = screenBounds.SizeY / screenBounds.SizeX;                                                       // this is the aspectRatio of our image
                    viewProj     = sceneCamera.GetViewProjectionMatrix(aspectRatio);                                              // now we get the transform with our aspectRatio determined above
                    screenBounds = RectangleD3D.NewRectangleIncludingAllPoints(rect.Vertices.Select(x => viewProj.Transform(x))); // this are our actual screenBounds, of course in relative screen coordinates, thus the ratio of sizeX and sizeY should now be 1

                    double scaleFactor = 2 / screenBounds.SizeX;                                                                  // since SizeX and SizeY should now be the same, we could have used SizeY alternatively
                    double offsX       = -(1 + scaleFactor * screenBounds.X);
                    double offsY       = -(1 + scaleFactor * screenBounds.Y);

                    pixelsY = (int)(4 * Math.Ceiling((aspectRatio * pixelsX + 3) / 4.0)); // now calculate the size of the image in y direction from the aspectRatio

                    var perspCamera = (PerspectiveCamera)sceneCamera;

                    sceneCamera = perspCamera.WithWidthAtZNear(perspCamera.WidthAtZNear / scaleFactor);
                    sceneCamera = sceneCamera.WithScreenOffset(new PointD2D(offsX, offsY));
                }
                else
                {
                    throw new NotImplementedException();
                }

                scene.SetCamera(sceneCamera);
                scene.SetLighting(doc.Lighting);
                scene.SetDrawing(g);

                Export(pixelsX, pixelsY, scene, options, toStream);
                return(pixelsX, pixelsY);
            }
            finally
            {
                Disposer.RemoveAndDispose(ref g);
                Disposer.RemoveAndDispose(ref scene);
            }
        }