internal VolumeSlice(IVolumeReference volumeReference, IVolumeSlicerParams slicerParams, Vector3D throughPoint) { Platform.CheckForNullReference(throughPoint, "throughPoint"); var volume = volumeReference.Volume; _volumeReference = volumeReference; _slicerParams = slicerParams; _throughPoint = throughPoint; // keep a direct reference to the prototype, so that attribute values are available even if the referenced volume is unloaded via memory management _prototypeDataSet = volume.DataSet; // JY: ideally, each slicing plane is represented by a single multiframe SOP where the individual slices are the frames. // We need to support multi-valued Slice Location in the base viewer first. // When that is implemented, the SOPs should be created on the first frame of the slicing (i.e. one of the end slices) // and the Slice Location Vector will simply store the slice locations relative to that defined in these attributes. // Also, the rows and columns will have to be computed to be the MAX possible size (all frames must have same size) // compute Rows and Columns to reflect actual output size var frameSize = GetSliceExtent(volume, slicerParams); Colums = frameSize.Width; Rows = frameSize.Height; // compute Image Orientation (Patient) var matrix = new Matrix(slicerParams.SlicingPlaneRotation); matrix[3, 0] = _throughPoint.X; matrix[3, 1] = _throughPoint.Y; matrix[3, 2] = _throughPoint.Z; var resliceAxesPatientOrientation = _volumeReference.Volume.RotateToPatientOrientation(matrix); var orientation = new DicomAttributeDS(DicomTags.ImageOrientationPatient); orientation.SetFloat32(0, resliceAxesPatientOrientation[0, 0]); orientation.SetFloat32(1, resliceAxesPatientOrientation[0, 1]); orientation.SetFloat32(2, resliceAxesPatientOrientation[0, 2]); orientation.SetFloat32(3, resliceAxesPatientOrientation[1, 0]); orientation.SetFloat32(4, resliceAxesPatientOrientation[1, 1]); orientation.SetFloat32(5, resliceAxesPatientOrientation[1, 2]); ImageOrientationPatient = orientation.ToString(); // compute Image Position (Patient) var topLeftOfSlicePatient = GetTopLeftOfSlicePatient(frameSize, _throughPoint, volume, slicerParams); var position = new DicomAttributeDS(DicomTags.ImagePositionPatient); position.SetFloat32(0, topLeftOfSlicePatient.X); position.SetFloat32(1, topLeftOfSlicePatient.Y); position.SetFloat32(2, topLeftOfSlicePatient.Z); ImagePositionPatient = position.ToString(); }
internal VolumeSlice(IVolumeReference volumeReference, VolumeSliceArgs sliceArgs, Vector3D imagePositionPatient, float? spacingBetweenSlices) { Platform.CheckForNullReference(volumeReference, "volumeReference"); Platform.CheckForNullReference(sliceArgs, "slicerArgs"); Platform.CheckForNullReference(imagePositionPatient, "imagePositionPatient"); _volumeReference = volumeReference; _sliceArgs = sliceArgs; _imagePositionPatient = imagePositionPatient; // compute Rows and Columns to reflect actual output size Columns = sliceArgs.Columns; Rows = sliceArgs.Rows; // compute Slice Thickness var sliceThickness = sliceArgs.SliceThickness; SliceThickness = new DicomAttributeDS(DicomTags.SliceThickness) {Values = sliceThickness}.ToString(); SpacingBetweenSlices = spacingBetweenSlices.HasValue ? new DicomAttributeDS(DicomTags.SpacingBetweenSlices) {Values = spacingBetweenSlices.Value}.ToString() : string.Empty; // compute Pixel Spacing var spacing = new DicomAttributeDS(DicomTags.PixelSpacing); spacing.SetFloat32(0, sliceArgs.RowSpacing); spacing.SetFloat32(1, sliceArgs.ColumnSpacing); PixelSpacing = spacing.ToString(); // compute Image Orientation (Patient) var rowOrientation = sliceArgs.RowOrientationPatient; var columnOrientation = sliceArgs.ColumnOrientationPatient; var orientation = new DicomAttributeDS(DicomTags.ImageOrientationPatient); orientation.SetFloat32(0, rowOrientation.X); orientation.SetFloat32(1, rowOrientation.Y); orientation.SetFloat32(2, rowOrientation.Z); orientation.SetFloat32(3, columnOrientation.X); orientation.SetFloat32(4, columnOrientation.Y); orientation.SetFloat32(5, columnOrientation.Z); ImageOrientationPatient = orientation.ToString(); // compute Image Position (Patient) var position = new DicomAttributeDS(DicomTags.ImagePositionPatient); position.SetFloat32(0, _imagePositionPatient.X); position.SetFloat32(1, _imagePositionPatient.Y); position.SetFloat32(2, _imagePositionPatient.Z); ImagePositionPatient = position.ToString(); }