示例#1
0
        private bool _isDisposed = false; // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!_isDisposed)
            {
                if (disposing)
                {
                    _altaxoDrawingGeometry?.Dispose();
                    _altaxoDrawingGeometry = null;
                    _altaxoMarkerGeometry?.Dispose();
                    _altaxoMarkerGeometry = null;
                    _altaxoOverlayGeometry?.Dispose();
                    _altaxoOverlayGeometry = null;
                    _altaxoCamera          = null;
                    _altaxoLightSettings   = null;
                }

                if (null != _cachedDevice)
                {
                    Detach();
                }

                _isDisposed = true;
            }
        }
示例#2
0
        private void BringDrawingIntoBuffers(D3D10GraphicsContext altaxoDrawingGeometry)
        {
            Device device = _cachedDevice;

            if (device == null || device.IsDisposed)
            {
                return;
            }

            var altaxoBuffersOfType =
                new IEnumerable <KeyValuePair <MaterialKey, IndexedTriangleBuffer> >[]
            {
                altaxoDrawingGeometry.PositionIndexedTriangleBuffersAsIndexedTriangleBuffers,
                altaxoDrawingGeometry.PositionColorIndexedTriangleBuffersAsIndexedTriangleBuffers,
                altaxoDrawingGeometry.PositionUVIndexedTriangleBuffersAsIndexedTriangleBuffers,
                altaxoDrawingGeometry.PositionNormalIndexedTriangleBuffersAsIndexedTriangleBuffers,
                altaxoDrawingGeometry.PositionNormalColorIndexedTriangleBuffersAsIndexedTriangleBuffers,
                altaxoDrawingGeometry.PositionNormalUVIndexedTriangleBuffersAsIndexedTriangleBuffers,
                altaxoDrawingGeometry.PositionNormalUIndexedTriangleBuffersAsIndexedTriangleBuffers
            };

            for (int i = 0; i < altaxoBuffersOfType.Length; ++i)
            {
                var newDeviceBuffers = new List <VertexAndIndexDeviceBuffer>();
                foreach (var altaxoBuffer in altaxoBuffersOfType[i])
                {
                    var altaxoTriangleBuffer = altaxoBuffer.Value;
                    if (altaxoTriangleBuffer.TriangleCount == 0)
                    {
                        continue;
                    }

                    var vertexBuffer = Buffer.Create <float>(device, altaxoTriangleBuffer.VertexStream, new BufferDescription()
                    {
                        BindFlags      = BindFlags.VertexBuffer,
                        CpuAccessFlags = CpuAccessFlags.None,
                        OptionFlags    = ResourceOptionFlags.None,
                        SizeInBytes    = altaxoTriangleBuffer.VertexStreamLength,
                        Usage          = ResourceUsage.Default
                    });

                    var indexBuffer = Buffer.Create <int>(device, altaxoTriangleBuffer.IndexStream, new BufferDescription()
                    {
                        BindFlags      = BindFlags.IndexBuffer,
                        CpuAccessFlags = CpuAccessFlags.None,
                        OptionFlags    = ResourceOptionFlags.None,
                        SizeInBytes    = altaxoTriangleBuffer.IndexStreamLength,
                        Usage          = ResourceUsage.Default
                    });
                    var indexCount = altaxoTriangleBuffer.TriangleCount * 3;

                    Plane[] clipPlanes = null;
                    if (altaxoBuffer.Key is MaterialPlusClippingKey)
                    {
                        var axoClipPlanes = ((MaterialPlusClippingKey)altaxoBuffer.Key).ClipPlanes;
                        if (null != axoClipPlanes)
                        {
                            clipPlanes = axoClipPlanes.Select(axoPlane => new Plane((float)axoPlane.X, (float)axoPlane.Y, (float)axoPlane.Z, (float)-axoPlane.W)).ToArray();
                        }
                    }

                    byte[] uColors  = null;
                    var    material = altaxoBuffer.Key.Material;
                    if (altaxoTriangleBuffer is PositionNormalUIndexedTriangleBuffer && altaxoBuffer.Key is MaterialPlusClippingPlusColorProviderKey)
                    {
                        var bufs          = (PositionNormalUIndexedTriangleBuffer)altaxoTriangleBuffer;
                        var colorProvider = ((MaterialPlusClippingPlusColorProviderKey)(altaxoBuffer.Key)).ColorProvider;
                        var fColors       = bufs.GetColorArrayForColorProvider(colorProvider);
                        uColors = new byte[fColors.Length * 4];
                        System.Buffer.BlockCopy(fColors, 0, uColors, 0, uColors.Length);
                        material = material.WithColor(new NamedColor(colorProvider.GetAxoColor(double.NaN))); // Material needs to have InvalidColor, because this can not be represented in the Texture1D
                    }
                    newDeviceBuffers.Add(new VertexAndIndexDeviceBuffer(material: altaxoBuffer.Key.Material, vertexBuffer: vertexBuffer, vertexCount: altaxoTriangleBuffer.VertexCount, indexBuffer: indexBuffer, indexCount: indexCount, clipPlanes: clipPlanes, uColors: uColors));
                }
                System.Threading.Interlocked.Exchange(ref _nextTriangleDeviceBuffers[i], newDeviceBuffers);
            }
        }
示例#3
0
 public void SetDrawing(D3D10GraphicsContext drawing)
 {
     _altaxoDrawingGeometry = drawing;
     BringDrawingIntoBuffers(drawing);
 }
示例#4
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);
            }
        }