예제 #1
0
        //TODO (CR Sept 2010): same comment as with the ProgressGraphic stuff; the API is unclear
        //as to what it is doing (return value) because it's trying to account for the async loading.

        /// <summary>
        /// Attempts to start loading the overlay data asynchronously, if not already loaded.
        /// </summary>
        /// <param name="progress">A value between 0 and 1 indicating the progress of the asynchronous loading operation.</param>
        /// <param name="message">A string message detailing the progress of the asynchronous loading operation.</param>
        /// <returns></returns>
        public bool BeginLoad(out float progress, out string message)
        {
            // update the last access time
            _largeObjectData.UpdateLastAccessTime();

            // if the data is already available without blocking, return success immediately

            //TODO (CR Sept 2010): because unloading the volume involves disposing it, if every operation that uses it
            //isn't in the same lock (e.g. lock(_syncVolumeDataLock)) you could be getting a disposed/null volume here.
            VolumeData volume = _volume;

            if (volume != null)
            {
                message  = SR.MessageFusionComplete;
                progress = 1f;
                return(true);
            }

            lock (_syncLoaderLock)
            {
                message  = SR.MessageFusionInProgress;
                progress = 0;
                if (_volumeLoaderTask == null)
                {
                    // if the data is available now, return success
                    volume = _volume;
                    if (volume != null)
                    {
                        message  = SR.MessageFusionComplete;
                        progress = 1f;
                        return(true);
                    }

                    _volumeLoaderTask = new BackgroundTask(c => this.LoadVolume(c), false, null)
                    {
                        ThreadUICulture = Application.CurrentUICulture
                    };
                    _volumeLoaderTask.Run();
                    _volumeLoaderTask.Terminated += OnVolumeLoaderTaskTerminated;
                }
                else
                {
                    // TODO (CR Apr 2013): See comment in OnVolumeLoaderTaskTerminated; if the task were not created
                    // on the UI thread, _volumeLoaderTask could be set to null before hitting this instruction.
                    if (_volumeLoaderTask.LastBackgroundTaskProgress != null)
                    {
                        message  = _volumeLoaderTask.LastBackgroundTaskProgress.Progress.Message;
                        progress = _volumeLoaderTask.LastBackgroundTaskProgress.Progress.Percent / 100f;
                    }
                }
            }
            return(false);
        }
예제 #2
0
        private VolumeData LoadVolume(IBackgroundTaskContext context)
        {
            // TODO (CR Apr 2013): Ideally, loading and unloading could be done with minimal locking; this way,
            // Unload actually has to wait for Load to finish and vice versa. I think a quicker way would be to
            // have a _loading field - have this method set it inside the lock, then proceed to do the load,
            // then set the _volume field when done. Have Unload check _loading and just return, otherwise set _volume to null.
            // Basically, you don't need to lock the entire load operation - you only need to guarantee that multiple loads
            // can't occur at once, and that Unload actually unloads it.

            // wait for synchronized access
            lock (_syncVolumeDataLock)
            {
                _largeObjectData.Lock();
                try
                {
                    // if the data is now available, return it immediately
                    // (i.e. we were blocked because we were already reading the data)
                    if (_volume != null)
                    {
                        return(_volume);
                    }

                    // load the volume data
                    if (context == null)
                    {
                        _volume = VolumeData.Create(_frames);
                    }
                    else
                    {
                        _volume = VolumeData.Create(_frames, (n, count) => context.ReportProgress(new BackgroundTaskProgress(n, count, SR.MessageFusionInProgress)));
                    }

                    // update our stats
                    _largeObjectData.BytesHeldCount   = 2 * _volume.ArrayLength;
                    _largeObjectData.LargeObjectCount = 1;
                    _largeObjectData.UpdateLastAccessTime();

                    // regenerating the volume data takes a few seconds
                    _largeObjectData.RegenerationCost = LargeObjectContainerData.PresetComputedData;

                    // register with memory manager
                    MemoryManager.Add(this);

                    return(_volume);
                }
                finally
                {
                    _largeObjectData.Unlock();
                }
            }
        }
예제 #3
0
        private void UnloadVolume()
        {
            // wait for synchronized access
            lock (_syncVolumeDataLock)
            {
                // dump our data
                if (_volume != null)
                {
                    _volume.Dispose();
                    _volume = null;
                }

                // update our stats
                _largeObjectData.BytesHeldCount   = 0;
                _largeObjectData.LargeObjectCount = 0;

                // unregister with memory manager
                MemoryManager.Remove(this);
            }

            this.OnUnloaded();
        }
예제 #4
0
		public VolumeSlice(Volume volume, VolumeSliceArgs sliceArgs, Vector3D imagePositionPatient, float? spacingBetweenSlices = null)
			: this(volume.CreateReference(), sliceArgs, imagePositionPatient, spacingBetweenSlices) {}
예제 #5
0
			public void Dispose()
			{
				if (_volume != null)
				{
					_volume.OnReferenceDisposed();
					_volume = null;
				}
			}
예제 #6
0
			public VolumeReference(Volume volume)
			{
				_volume = volume;
				_volume.OnReferenceCreated();
			}
예제 #7
0
		private static vtkImageData CreateVtkVolume(Volume volume)
		{
			var vtkVolume = new vtkImageData();
			vtkVolume.RegisterVtkErrorEvents();
			vtkVolume.SetDimensions(volume.ArrayDimensions.Width, volume.ArrayDimensions.Height, volume.ArrayDimensions.Depth);
			vtkVolume.SetOrigin(0, 0, 0);
			vtkVolume.SetSpacing(volume.VoxelSpacing.X, volume.VoxelSpacing.Y, volume.VoxelSpacing.Z);

			if (volume.BitsPerVoxel == 16)
			{
				if (!volume.Signed)
				{
					using (var array = new vtkUnsignedShortArray())
					{
						array.SetArray((ushort[]) volume.Array, (VtkIdType) volume.ArrayLength, 1);

						vtkVolume.SetScalarTypeToUnsignedShort();
						vtkVolume.GetPointData().SetScalars(array);
					}
				}
				else
				{
					using (var array = new vtkShortArray())
					{
						array.SetArray((short[]) volume.Array, (VtkIdType) volume.ArrayLength, 1);

						vtkVolume.SetScalarTypeToShort();
						vtkVolume.GetPointData().SetScalars(array);
					}
				}
			}
			else if (volume.BitsPerVoxel == 8)
			{
				if (!volume.Signed)
				{
					using (var array = new vtkUnsignedCharArray())
					{
						array.SetArray((byte[]) volume.Array, (VtkIdType) volume.ArrayLength, 1);

						vtkVolume.SetScalarTypeToUnsignedChar();
						vtkVolume.GetPointData().SetScalars(array);
					}
				}
				else
				{
					using (var array = new vtkSignedCharArray())
					{
						array.SetArray((sbyte[]) volume.Array, (VtkIdType) volume.ArrayLength, 1);

						vtkVolume.SetScalarTypeToSignedChar();
						vtkVolume.GetPointData().SetScalars(array);
					}
				}
			}
			else
			{
				throw new NotSupportedException("Unsupported volume scalar type.");
			}

			// This call is necessary to ensure vtkImageData data's info is correct (e.g. updates WholeExtent values)
			vtkVolume.UpdateInformation();

			return vtkVolume;
		}
예제 #8
0
		private void UnloadVolume()
		{
			// wait for synchronized access
			lock (_syncVolumeDataLock)
			{
				// dump our data
				if (_volume != null)
				{
					_volume.Dispose();
					_volume = null;
				}

				// update our stats
				_largeObjectData.BytesHeldCount = 0;
				_largeObjectData.LargeObjectCount = 0;

				// unregister with memory manager
				MemoryManager.Remove(this);
			}

			this.OnUnloaded();
		}
예제 #9
0
		private VolumeData LoadVolume(IBackgroundTaskContext context)
		{
			// TODO (CR Apr 2013): Ideally, loading and unloading could be done with minimal locking; this way,
			// Unload actually has to wait for Load to finish and vice versa. I think a quicker way would be to
			// have a _loading field - have this method set it inside the lock, then proceed to do the load,
			// then set the _volume field when done. Have Unload check _loading and just return, otherwise set _volume to null.
			// Basically, you don't need to lock the entire load operation - you only need to guarantee that multiple loads
			// can't occur at once, and that Unload actually unloads it.

			// wait for synchronized access
			lock (_syncVolumeDataLock)
			{
				_largeObjectData.Lock();
				try
				{
					// if the data is now available, return it immediately
					// (i.e. we were blocked because we were already reading the data)
					if (_volume != null)
						return _volume;

					// load the volume data
					if (context == null)
						_volume = VolumeData.Create(_frames);
					else
						_volume = VolumeData.Create(_frames, (n, count) => context.ReportProgress(new BackgroundTaskProgress(n, count, SR.MessageFusionInProgress)));

					// update our stats
					_largeObjectData.BytesHeldCount = 2*_volume.ArrayLength;
					_largeObjectData.LargeObjectCount = 1;
					_largeObjectData.UpdateLastAccessTime();

					// regenerating the volume data takes a few seconds
					_largeObjectData.RegenerationCost = LargeObjectContainerData.PresetComputedData;

					// register with memory manager
					MemoryManager.Add(this);

					return _volume;
				}
				finally
				{
					_largeObjectData.Unlock();
				}
			}
		}