private void AddLayers(DrawArgs args)
		{
			IAssociatedTissues volume = args.SceneGraph.ParentPresentationImage as IAssociatedTissues;

			if (volume == null)
				return;

			GraphicCollection layers = volume.TissueLayers;
			vtkPropCollection props = _vtkRenderer.GetViewProps();

			foreach (VolumeGraphic volumeGraphic in layers)
			{
				if (props.IsItemPresent(volumeGraphic.VtkProp) == 0)
					_vtkRenderer.AddViewProp(volumeGraphic.VtkProp);

				//if (volumeLayer.OldVtkProp != null)
				//{

				//    if (props.IsItemPresent(volumeLayer.OldVtkProp) != 0)
				//    {
				//        props.RemoveItem(volumeLayer.OldVtkProp);
				//        volumeLayer.OldVtkProp = null;
				//    }
				//}
			}
		}
Example #2
0
        private void RenderImage(DrawArgs args)
        {
            if (args.DrawMode == DrawMode.Refresh)
            {
                RefreshImage(args);
                return;
            }

            if (_firstRender)
            {
                // the first time we try to render a freshly cloned image, we need to draw it twice
                // this is to make sure the client rectangle is updated when we try to compute the correct point of interest
                _firstRender = false;
                RenderImage(args);
            }

            try
            {
                var sourceTransform = (ImageSpatialTransform)((ISpatialTransformProvider)SelectedPresentationImage).SpatialTransform;
                var transform = (ImageSpatialTransform)((ISpatialTransformProvider)_magnificationImage).SpatialTransform;

                float scale = sourceTransform.Scale * ToolSettings.DefaultInstance.MagnificationFactor;
                transform.ScaleToFit = false;
                transform.Scale = scale;
                transform.TranslationX = 0;
                transform.TranslationY = 0;

                var midPoint = new PointF(args.RenderingSurface.ClientRectangle.Width / 2f, args.RenderingSurface.ClientRectangle.Height / 2f);
                var sourcePointOfInterest = sourceTransform.ConvertToSource(_tileLocation);
                // compute translation required to move the point of interest on the magnified image to the centre of the client area
                var translation = transform.ConvertToSource(midPoint) - new SizeF(sourcePointOfInterest);
                transform.TranslationX = translation.X;
                transform.TranslationY = translation.Y;

                _magnificationImage.Draw(args);

                // clear the rendering exception message
                _lastRenderExceptionMessage = null;
            }
            catch (Exception ex)
            {
                Platform.Log(LogLevel.Error, ex,
                             "An error has occured while rendering the magnified contents of the tile.");

                // a rendering exception was encountered, so set the message field
                _lastRenderExceptionMessage = ex is RenderingException
                                                  ? ((RenderingException)ex).UserMessage
                                                  : ex.Message;

                // we cannot simply pass the existing Graphics because we haven't released its hDC yet
                // if we do, we'll get a "Object is currently in use elsewhere" exception
                DrawErrorMessage(_lastRenderExceptionMessage, args.RenderingSurface.ContextID, args.RenderingSurface.ClientRectangle);
            }
        }
		private void AddLayers(DrawArgs args)
		{
			IAssociatedTissues volume = args.SceneGraph.ParentPresentationImage as IAssociatedTissues;

			if (volume == null)
				return;

			GraphicCollection layers = volume.TissueLayers;
			vtkPropCollection props = _vtkRenderer.GetViewProps();

			foreach (var graphic in layers)
			{
				var volumeGraphic = (VolumeGraphic) graphic;
				if (props.IsItemPresent(volumeGraphic.VtkProp) == 0)
					_vtkRenderer.AddViewProp(volumeGraphic.VtkProp);
			}
		}
Example #4
0
		/// <summary>
		/// Initializes a <see cref="RenderingException"/>.
		/// </summary>
		/// <param name="innerException">The actual exception that was thrown in the rendering pipeline.</param>
		/// <param name="drawArgs">The <see cref="DrawArgs"/> of the failed rendering operation.</param>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="innerException"/> is null.</exception>
		public RenderingException(Exception innerException, DrawArgs drawArgs)
			: base("An exception was thrown in the rendering pipeline.", innerException)
		{
			if (innerException == null)
				throw new ArgumentNullException("innerException", "An inner exception must be provided.");

			// record as much information as possible about the rendering operation for debugging purposes
			if (drawArgs != null)
			{
				DrawMode = drawArgs.DrawMode;
				if (drawArgs.RenderingSurface != null)
				{
					WindowId = drawArgs.RenderingSurface.WindowID;
					ContextId = drawArgs.RenderingSurface.ContextID;
					ClientRectangle = drawArgs.RenderingSurface.ClientRectangle;
					ClipRectangle = drawArgs.RenderingSurface.ClipRectangle;
				}
			}
		}
Example #5
0
		protected override void OnPaint(PaintEventArgs e)
		{
            if (_surface != null)
            {
                _surface.ContextID = e.Graphics.GetHdc();
                try
                {
                    var args = new DrawArgs(_surface, new WinFormsScreenProxy(Screen.FromControl(this)), DrawMode.Refresh);
                    _render(args);
                }
                finally
                {
                    e.Graphics.ReleaseHdc(_surface.ContextID);
                }
            }

		    //base.OnPaint(e);
        }
Example #6
0
        private void RenderImage()
        {
            if (_surface == null)
                return;

            using (var graphics = base.CreateGraphics())
            {
                _surface.ContextID = graphics.GetHdc();
                try
                {
                    var args = new DrawArgs(_surface, new WinFormsScreenProxy(Screen.FromControl(this)), DrawMode.Render);
                    _render(args);
                    args = new DrawArgs(_surface, new WinFormsScreenProxy(Screen.FromControl(this)), DrawMode.Refresh);
                    _render(args);
                }
                finally 
                {
                    graphics.ReleaseHdc(_surface.ContextID);
                }
            }
        }
Example #7
0
		/// <summary>
		/// Renders the <see cref="PresentationImage"/> without firing any events.
		/// </summary>
		/// <exception cref="RenderingException">Thrown if any <see cref="Exception"/> is encountered while rendering the image.</exception>
		protected void DrawNoEvents(DrawArgs drawArgs)
		{
			drawArgs.SceneGraph = this.SceneGraph;
			Rectangle oldRectangle = _clientRectangle;
			_clientRectangle = drawArgs.RenderingSurface.ClientRectangle;

			try
			{
				this.ImageRenderer.Draw(drawArgs);
			}
			finally
			{
				_clientRectangle = oldRectangle;
			}
		}
		public override void Draw(DrawArgs drawArgs)
		{
			if (_delayedEventPublisher == null && SynchronizationContext.Current != null)
				_delayedEventPublisher = new DelayedEventPublisher(OnDelayedProgressChanged, 1000, DelayedEventPublisherTriggerMode.Periodic);

			var asyncFrame = Frame;
			using (asyncFrame.AcquireLock())
			{
				if (!asyncFrame.IsAsyncLoaded)
				{
					if (!Visible) // if this is an off-screen draw, wait for data to be loaded
					{
						lock (_waitPixelData)
						{
							if (!asyncFrame.IsAsyncLoaded)
							{
								var completionHandler = new EventHandler((s, e) =>
								                                         	{
								                                         		lock (_waitPixelData)
								                                         		{
								                                         			Monitor.Pulse(_waitPixelData);
								                                         		}
								                                         	});
								var onFrameAsyncLoaded = new AsyncPixelDataEventHandler(completionHandler);
								var onFrameAsyncFaulted = new AsyncPixelDataFaultEventHandler(completionHandler);

								asyncFrame.AsyncLoaded += onFrameAsyncLoaded;
								asyncFrame.AsyncFaulted += onFrameAsyncFaulted;
								asyncFrame.GetNormalizedPixelData();

								// check the flag again, in case the event actually fired before we hooked up the handler
								if (!asyncFrame.IsAsyncLoaded)
									Monitor.Wait(_waitPixelData);

								asyncFrame.AsyncLoaded -= onFrameAsyncLoaded;
								asyncFrame.AsyncFaulted -= onFrameAsyncFaulted;
							}
						}
					}
					else if (!ApplicationGraphics.OfType<ProgressGraphic>().Any())
					{
						ProgressGraphic.Show(this, ApplicationGraphics, true, ProgressBarGraphicStyle.Continuous, false);
					}
				}

				base.Draw(drawArgs);
			}
		}
Example #9
0
		/// <summary>
		/// Forces a render of the specified image and setting the image's client rectangle property at the same time.
		/// </summary>
		public static Bitmap RenderImage(this IPresentationImage image, Rectangle clientRectangle)
		{
			// we can't just call image.DrawToBitmap because we also want to force the client rectangle of the image
			// which wouldn't be set correctly because the image has possibly never been drawn in a Tile before

			var presentationImage = image as PresentationImage;
			if (presentationImage != null)
			{
				var bmp = new Bitmap(clientRectangle.Width, clientRectangle.Height, PixelFormat.Format32bppArgb);
				var graphics = System.Drawing.Graphics.FromImage(bmp);
				var contextId = graphics.GetHdc();
				try
				{
					using (var surface = presentationImage.ImageRenderer.CreateRenderingSurface(IntPtr.Zero, clientRectangle.Width, clientRectangle.Height, RenderingSurfaceType.Offscreen))
					{
						surface.ContextID = contextId;
						surface.ClipRectangle = new Rectangle(0, 0, clientRectangle.Width, clientRectangle.Height);

						var drawArgs = new DrawArgs(surface, null, DrawMode.Render);
						presentationImage.Draw(drawArgs);
						drawArgs = new DrawArgs(surface, null, DrawMode.Refresh);
						presentationImage.Draw(drawArgs);
					}
				}
				finally
				{
					graphics.ReleaseHdc(contextId);
					graphics.Dispose();
				}
				return bmp;
			}
			else
			{
				throw new NotSupportedException("Image type is not supported");
			}
		}
Example #10
0
		/// <summary>
		/// Initializes the member variables before calling <see cref="Render"/> or <see cref="Refresh"/>.
		/// </summary>
		protected virtual void Initialize(DrawArgs drawArgs)
		{
			_drawMode = drawArgs.DrawMode;
			_sceneGraph = drawArgs.SceneGraph;
			_surface = drawArgs.RenderingSurface;
			Dpi = drawArgs.Dpi;
		}
Example #11
0
		protected override void OnPaint(PaintEventArgs e)
		{
			//Assume anything Vista or later has the same issues.
			if (IsVistaOrLater())
			{
				//Windows Vista is opportunistic when it comes to wait conditions (e.g. locks, Mutexes, etc)
				//in that it will actually process WM_PAINT messages on the current thread, even though
				//it is supposed to be blocking in a WaitSleepJoin state.  This behaviour can actually
				//break rendering for a couple of reasons:
				//  1. We do custom double-buffering, and it's possible that we could process a paint message
				//     for an image that hasn't actually been rendered to the back buffer yet.
				//  2. The renderer itself accesses the pixel data of the ImageSops, which is a synchronized operation.
				//     In the case where 2 threads try to load the pixel data of an image simultaneously, the renderer can end up
				//     blocking execution on the main UI thread in the middle of a rendering operation.  If we
				//     allow another tile to paint in this situation, it actually causes some GDI errors because
				//     the previous rendering operation has not yet completed.
				if (_isDrawing || _painting)
				{
					e.Graphics.Clear(Color.Black);

					//Queue this tile up for deferred painting and return.
					if (!_tilesToRepaint.Contains(this))
						_tilesToRepaint.Add(this);

					return;
				}

				//We're about to paint this tile, so remove it from the queue.
				_tilesToRepaint.Remove(this);
			}

			if (_tile.PresentationImage == null)
				DisposeSurface();

			if (this.Surface == null)
			{
				// Make sure tile gets blacked out if there's
				// no presentation image in it
				e.Graphics.Clear(Color.Black);
			}
			else
			{
				this.Surface.WindowID = this.Handle;
				this.Surface.ContextID = e.Graphics.GetHdc();
				this.Surface.ClientRectangle = this.ClientRectangle;
				this.Surface.ClipRectangle = e.ClipRectangle;

				DrawArgs args = new DrawArgs(this.Surface,
				                             new WinFormsScreenProxy(Screen.FromControl(this)),
				                             DrawMode.Refresh);

				_painting = true;

				try
				{
					_tile.Draw(args);

					// if an exception was encountered the last time we rendered the buffer, refresh the error text now
					if (!string.IsNullOrEmpty(_lastRenderExceptionMessage))
					{
						// we cannot simply pass the Graphics because we haven't released its hDC yet
						// if we do, we'll get a "Object is currently in use elsewhere" exception
						DrawErrorMessage(_lastRenderExceptionMessage, Surface.ContextID, ClientRectangle);
					}
				}
				catch (Exception ex)
				{
					Platform.Log(LogLevel.Error, ex, "An error has occured while refreshing the contents of a tile.");

					var exceptionMessage = ex is RenderingException ? ((RenderingException) ex).UserMessage : ex.Message;

					// we cannot simply pass the existing Graphics because we haven't released its hDC yet
					// if we do, we'll get a "Object is currently in use elsewhere" exception
					DrawErrorMessage(exceptionMessage, Surface.ContextID, ClientRectangle);
				}
				finally
				{
					e.Graphics.ReleaseHdc(this.Surface.ContextID);

					_painting = false;
				}
			}

			// Now that we've finished painting this tile, we can process the deferred paint jobs.
			// The code below is self-fulfilling, in that we remove one tile from the queue and
			// invalidate it, causing it to paint.  When it's done painting, it will remove and
			// invalidate the next one, and so on.
			if (IsVistaOrLater() && _tilesToRepaint.Count > 0)
			{
				TileControl tileToRepaint = _tilesToRepaint[0];
				_tilesToRepaint.RemoveAt(0);

				tileToRepaint.Invalidate();
				tileToRepaint.Update();
			}

			//base.OnPaint(e);
		}
Example #12
0
		private void DoDraw()
		{
			EventsHelper.Fire(_drawing, this, EventArgs.Empty);

			CodeClock clock = new CodeClock();
			clock.Start();

			if (this.Surface != null)
			{
				System.Drawing.Graphics graphics = this.CreateGraphics();

				this.Surface.WindowID = this.Handle;
				this.Surface.ContextID = graphics.GetHdc();
				this.Surface.ClientRectangle = this.ClientRectangle;
				this.Surface.ClipRectangle = this.ClientRectangle;

				DrawArgs args = new DrawArgs(this.Surface,
				                             new WinFormsScreenProxy(Screen.FromControl(this)),
				                             DrawMode.Render);

				_isDrawing = true;

				try
				{
					_tile.Draw(args);

					_lastRenderExceptionMessage = null;
				}
				catch (Exception ex)
				{
					Platform.Log(LogLevel.Error, ex, "An error has occured while rendering the contents of a tile.");

					_lastRenderExceptionMessage = ex is RenderingException ? ((RenderingException) ex).UserMessage : ex.Message;

					// we cannot simply pass the existing Graphics because we haven't released its hDC yet
					// if we do, we'll get a "Object is currently in use elsewhere" exception
					DrawErrorMessage(_lastRenderExceptionMessage, Surface.ContextID, ClientRectangle);
				}
				finally
				{
					graphics.ReleaseHdc(this.Surface.ContextID);
					graphics.Dispose();

					_isDrawing = false;
				}
			}

			//Cause the tile to paint/refresh.
			Invalidate();
			Update();

			clock.Stop();
			string str = String.Format("TileControl.Draw: {0}, {1}\n", clock.ToString(), this.Size.ToString());
			Trace.Write(str);
		}
		public void Draw(DrawArgs args)
		{
			CreateRenderer();
			AddLayers(args);
			_surface.Draw();
		}
Example #14
0
		/// <summary>
		/// Initializes the member variables before calling <see cref="RendererBase.Render"/> or <see cref="RendererBase.Refresh"/>.
		/// </summary>
		protected override void Initialize(DrawArgs drawArgs)
		{
			base.Initialize(drawArgs);
		}
Example #15
0
        private void RefreshImage(DrawArgs args)
        {
            try
            {
                // if there was an exception the last time we rendered the buffer, don't refresh from the buffer and instead redraw the error message
                if (string.IsNullOrEmpty(_lastRenderExceptionMessage))
                {
                    _magnificationImage.Draw(args);
                }
                else
                {
                    // we cannot simply pass the existing Graphics because we haven't released its hDC yet
                    // if we do, we'll get a "Object is currently in use elsewhere" exception
                    DrawErrorMessage(_lastRenderExceptionMessage, args.RenderingSurface.ContextID, args.RenderingSurface.ClientRectangle);
                }
            }
            catch (Exception ex)
            {
                Platform.Log(LogLevel.Error, ex, "An error has occured while refreshing the magnified contents of the tile.");

                var exceptionMessage = ex is RenderingException ? ((RenderingException)ex).UserMessage : ex.Message;

                // we cannot simply pass the Graphics because we haven't released its hDC yet
                // if we do, we'll get a "Object is currently in use elsewhere" exception
                DrawErrorMessage(exceptionMessage, args.RenderingSurface.ContextID, args.RenderingSurface.ClientRectangle);
            }
        }
Example #16
0
			public void Draw(DrawArgs drawArgs)
			{
				Wrapper.Item.Draw(drawArgs);
			}
Example #17
0
		/// <summary>
		/// Raises the <see cref="EventBroker.ImageDrawing"/> event and
		/// renders the <see cref="PresentationImage"/>.
		/// </summary>
		/// <param name="drawArgs"></param>
		/// <remarks>
		/// For internal Framework use only.
		/// </remarks>
		/// <exception cref="RenderingException">Thrown if any <see cref="Exception"/> is encountered while rendering the image.</exception>
		public virtual void Draw(DrawArgs drawArgs)
		{
			drawArgs.SceneGraph = this.SceneGraph;
			_clientRectangle = drawArgs.RenderingSurface.ClientRectangle;

			// Let others know that we're about to draw
			ImageDrawingEventArgs args = new ImageDrawingEventArgs(this);
			if (this.ImageViewer != null && this.ImageViewer.EventBroker != null)
				this.ImageViewer.EventBroker.OnImageDrawing(args);

			OnDrawing();

			this.ImageRenderer.Draw(drawArgs);
		}
Example #18
0
		/// <summary>
		/// Renders the specified scene graph to the graphics surface.
		/// </summary>
		/// <remarks>
		/// Calling code should take care to handle any exceptions in a manner suitable to the context of
		/// the rendering operation. For example, the view control for an
		/// <see cref="ITile"/> may wish to display the error message in the tile's client area <i>without
		/// crashing the control</i>, whereas an image export routine may wish to notify the user via an error
		/// dialog and have the export output <i>fail to be created</i>. Automated routines (such as unit
		/// tests) may even wish that the exception bubble all the way to the top for debugging purposes.
		/// </remarks>
		/// <param name="drawArgs">A <see cref="DrawArgs"/> object that specifies the graphics surface and the scene graph to be rendered.</param>
		/// <exception cref="RenderingException">Thrown if any <see cref="Exception"/> is encountered in the rendering pipeline.</exception>
		public virtual void Draw(DrawArgs drawArgs)
		{
			try
			{
				Initialize(drawArgs); 
				
				if (drawArgs.RenderingSurface.ClientRectangle.Width == 0 || drawArgs.RenderingSurface.ClientRectangle.Height == 0)
					return;
								
				if (DrawMode == DrawMode.Render)
					Render();
				else
					Refresh();
			}
			catch (Exception e)
			{
				throw new RenderingException(e, drawArgs);
			}
			finally
			{
				_sceneGraph = null;
				_surface = null;
			}
		}
Example #19
0
		/// <summary>
		/// Renders the <see cref="PresentationImage"/> to a provided offscreen <see cref="Bitmap"/>.
		/// </summary>
		/// <param name="bmp">The offscreen bitmap to render to.</param>
		/// <returns></returns>
		/// <remarks>
		/// This method can be used anywhere an offscreen bitmap is required, such as 
		/// paper/DICOM printing, thumbnail generation, creation of new DICOM images, etc.
		/// </remarks>
		/// <exception cref="ArgumentNullException">Thrown if <paramref name="bmp"/> is null.</exception>
		/// <exception cref="ArgumentException">Thrown if <paramref name="bmp"/> has invalid dimensions.</exception>
		/// <exception cref="RenderingException">Thrown if any <see cref="Exception"/> is encountered while rendering the image.</exception>
		public virtual void DrawToBitmap(Bitmap bmp)
		{
			Platform.CheckForNullReference(bmp, "bmp");

			Platform.CheckPositive(bmp.Width, "bmp.Width");
			Platform.CheckPositive(bmp.Height, "bmp.Height");

			var graphics = System.Drawing.Graphics.FromImage(bmp);
			var contextId = graphics.GetHdc();
			try
			{
				using (var surface = ImageRenderer.GetRenderingSurface(IntPtr.Zero, bmp.Width, bmp.Height))
				{
					surface.ContextID = contextId;
					surface.ClipRectangle = new Rectangle(0, 0, bmp.Width, bmp.Height);

					var drawArgs = new DrawArgs(surface, null, DrawMode.Render);
					DrawNoEvents(drawArgs);
					drawArgs = new DrawArgs(surface, null, DrawMode.Refresh);
					DrawNoEvents(drawArgs);
				}
			}
			finally
			{
				graphics.ReleaseHdc(contextId);
				graphics.Dispose();
			}
		}
Example #20
0
		private static Bitmap ImageDrawToBitmap(IPresentationImage presentationImage, int width, int height, float dpi)
		{
			if (!(presentationImage is PresentationImage))
				return presentationImage.DrawToBitmap(width, height);

			var image = (PresentationImage) presentationImage;
			var bmp = new Bitmap(width, height);

			var graphics = System.Drawing.Graphics.FromImage(bmp);
			var contextId = graphics.GetHdc();
			try
			{
				using (var surface = image.ImageRenderer.CreateRenderingSurface(IntPtr.Zero, bmp.Width, bmp.Height, RenderingSurfaceType.Offscreen))
				{
					surface.ContextID = contextId;
					surface.ClipRectangle = new Rectangle(0, 0, bmp.Width, bmp.Height);

					var drawArgs = new DrawArgs(surface, null, DrawMode.Render) {Dpi = dpi, Tag = bmp};
					image.Draw(drawArgs);
                    drawArgs = new DrawArgs(surface, null, DrawMode.Refresh) { Dpi = dpi, Tag = bmp};
					image.Draw(drawArgs);
				}
			}
			finally
			{
				graphics.ReleaseHdc(contextId);
				graphics.Dispose();
			}
			return bmp;
		}
 public void Draw(DrawArgs drawArgs)
 {
     Wrapper.Item.Draw(drawArgs);
 }