3 using UnityEngine.EventSystems;
4 using System.Collections;
5 using System.Collections.Generic;
10 public class DicomDisplayImage : MonoBehaviour, IScrollHandler, IPointerDownHandler, IPointerUpHandler, IPointerHoverHandler {
12 private Material mMaterial;
17 ViewSettings currentViewSettings =
new ViewSettings();
23 private bool dragLevelWindow =
false;
25 private bool dragPan =
false;
27 private bool dragZoom =
false;
30 private bool loadingSlice =
false;
32 private Texture2D mDefaultMask = null;
36 private bool touchpadUpPressed =
false;
37 private bool touchpadDownPressed =
false;
38 private float nextScrollAt = 0f;
40 private struct ViewSettings
48 public bool flipHorizontal;
49 public bool flipVertical;
52 private Dictionary<string, ViewSettings> savedViewSettings =
new Dictionary<string, ViewSettings>();
56 public void OnEnable()
58 dragLevelWindow =
false;
67 public void OnDisable()
72 public void OnScroll(PointerEventData eventData)
74 if (currentDICOM != null) {
76 int scrollAmount = Mathf.RoundToInt( eventData.scrollDelta.y*0.05f );
77 if( Mathf.Abs(scrollAmount) > 0 )
79 LayerChanged (currentViewSettings.slice + scrollAmount);
84 public void OnPointerDown( PointerEventData eventData )
86 if( eventData.button == PointerEventData.InputButton.Left )
87 dragLevelWindow =
true;
88 else if( eventData.button == PointerEventData.InputButton.Right )
90 else if( eventData.button == PointerEventData.InputButton.Middle )
93 public void OnPointerUp( PointerEventData eventData )
95 if( eventData.button == PointerEventData.InputButton.Left )
96 dragLevelWindow =
false;
97 else if( eventData.button == PointerEventData.InputButton.Right )
99 else if( eventData.button == PointerEventData.InputButton.Middle )
103 public void OnPointerHover( PointerEventData eventData )
105 if(currentDICOM != null)
109 if (cEventData != null) {
117 Text t = transform.Find (
"PositionText").GetComponent<Text> ();
118 t.text =
"(" + (int)Mathf.Round(pixel.x) +
", " + (int)Mathf.Round(pixel.y) +
", " + currentViewSettings.slice +
")";
120 GameObject pointer = GameObject.Find (
"3DPointer");
122 pointer.transform.localPosition = pos3D;
133 Vector2 dicomUV = imageUVtoLayerUV (uv);
135 Vector2 pixel =
new Vector3 (dicomUV.x * currentDICOM.
getTexture2D ().width,
136 dicomUV.y * currentDICOM.getTexture2D ().height);
158 return currentDICOM.transformPixelToPatientPos (pixel, currentViewSettings.slice);
161 public Vector2 imageUVtoLayerUV( Vector2 imageUV )
163 Rect uvRect = GetComponent<RawImage> ().uvRect;
164 Vector2 uv = imageUV;
166 uv = uv +
new Vector2( uvRect.min.x/uvRect.width, uvRect.min.y/uvRect.height );
167 uv.Scale (uvRect.size);
173 InputDevice inputDevice = InputDeviceManager.instance.currentInputDevice;
174 if (inputDevice.getDeviceType () == InputDeviceManager.InputDeviceType.Mouse) {
175 if (dragLevelWindow) {
177 float intensityChange = -inputDevice.getTexCoordDelta ().y * 0.25f;
178 float contrastChange = inputDevice.getTexCoordDelta ().x * 0.5f;
180 SetLevel (currentViewSettings.level + intensityChange);
181 SetWindow (currentViewSettings.window + contrastChange);
185 float dX = -inputDevice.getTexCoordDelta ().x;
186 float dY = -inputDevice.getTexCoordDelta ().y;
187 if (currentViewSettings.flipHorizontal)
189 if (currentViewSettings.flipVertical)
192 currentViewSettings.panX += dX * currentViewSettings.zoom;
193 currentViewSettings.panY += dY * currentViewSettings.zoom;
195 ApplyScaleAndPosition ();
199 float dY = -inputDevice.getTexCoordDelta ().y * 0.5f;
201 currentViewSettings.zoom = Mathf.Clamp (currentViewSettings.zoom + dY, 0.1f, 5f);
203 ApplyScaleAndPosition ();
208 if (inputDevice.getDeviceType () == InputDeviceManager.InputDeviceType.ViveController) {
213 Vector3 movement = c.positionDelta;
217 UnityEngine.Transform tf = Platform.instance.getCenterTransformForScreen (widget.layoutPosition.screen);
218 movement = tf.InverseTransformDirection (movement);
220 float dZ = -movement.z*2f*currentViewSettings.zoom;
221 currentViewSettings.zoom = Mathf.Clamp (currentViewSettings.zoom + dZ, 0.1f, 5f);
223 float dX = movement.x;
224 float dY = movement.y;
225 currentViewSettings.panX += dX*currentViewSettings.zoom;
226 currentViewSettings.panY += dY*currentViewSettings.zoom;
228 ApplyScaleAndPosition ();
233 if( c.touchpadButtonState == UnityEngine.EventSystems.PointerEventData.FramePressState.Released ) {
234 if (c.hoverTouchpadUp()) {
235 LayerChanged (currentViewSettings.slice + 1);
236 }
else if (c.hoverTouchpadDown()) {
237 LayerChanged (currentViewSettings.slice - 1);
239 touchpadDownPressed =
false;
240 touchpadUpPressed =
false;
243 if (c.touchpadButtonState == UnityEngine.EventSystems.PointerEventData.FramePressState.Pressed) {
244 if (c.hoverTouchpadUp ()) {
245 touchpadUpPressed =
true;
246 }
else if (c.hoverTouchpadDown ()) {
247 touchpadDownPressed =
true;
249 nextScrollAt = Time.time + 0.5f;
251 if (touchpadUpPressed) {
252 if (Time.time > nextScrollAt) {
253 LayerChanged (currentViewSettings.slice + 1);
254 nextScrollAt = Time.time + 0.05f;
256 }
else if (touchpadDownPressed) {
257 if (Time.time > nextScrollAt) {
258 LayerChanged (currentViewSettings.slice - 1);
259 nextScrollAt = Time.time + 0.05f;
265 Controller lc = InputDeviceManager.instance.leftController;
268 if( lc.touchpadButtonState == UnityEngine.EventSystems.PointerEventData.FramePressState.Released ) {
269 if (lc.hoverTouchpadUp()) {
270 SetLevel (currentViewSettings.level - 0.05f);
271 }
else if (lc.hoverTouchpadDown()) {
272 SetLevel (currentViewSettings.level + 0.05f);
273 }
else if (lc.hoverTouchpadLeft()) {
274 SetWindow (currentViewSettings.window - 0.05f);
275 }
else if (lc.hoverTouchpadRight()) {
276 SetWindow (currentViewSettings.window + 0.05f);
281 Vector2 scrollDelta = lc.touchpadDelta * 200;
283 float intensityChange = -scrollDelta.y / 2000f;
284 float contrastChange = scrollDelta.x / 2000f;
286 SetLevel (currentViewSettings.level + intensityChange);
287 SetWindow (currentViewSettings.window + contrastChange);
292 public void SetLevel(
float newLevel )
294 currentViewSettings.level = Mathf.Clamp (newLevel, -0.5f, 1.5f);
295 UpdateLevelWindow ();
299 public void SetWindow(
float newWindow )
301 currentViewSettings.window = Mathf.Clamp (newWindow, 0f, 1f);
302 UpdateLevelWindow ();
306 private void UpdateLevelWindow()
308 if (mMaterial == null)
311 mMaterial.SetFloat (
"level", currentViewSettings.level);
312 mMaterial.SetFloat (
"window", currentViewSettings.window);
315 private void SaveViewSettings()
317 if (currentDICOM == null)
320 string seriesUID = currentDICOM.seriesInfo.seriesUID;
321 if (savedViewSettings.ContainsKey (seriesUID)) {
322 savedViewSettings [seriesUID] = currentViewSettings;
324 savedViewSettings.Add (seriesUID, currentViewSettings);
328 private void LoadViewSettings()
330 if (currentDICOM == null)
333 string seriesUID = currentDICOM.seriesInfo.seriesUID;
334 if (savedViewSettings.ContainsKey (seriesUID)) {
335 currentViewSettings = savedViewSettings [seriesUID];
337 currentViewSettings =
new ViewSettings {
344 flipHorizontal =
false,
353 if (savedViewSettings.ContainsKey (seriesUID)) {
354 return savedViewSettings [seriesUID].slice;
376 public void LayerChanged(
float newVal )
378 if (currentDICOM != null) {
380 if (loadingSlice ==
false) {
382 int tmpSlice = (
int)Mathf.Clamp (newVal, 0, numLayers - 1);
391 public void SetDicom(
DICOM2D dicom )
393 if (mMaterial == null) {
394 mMaterial =
new Material (Shader.Find (
"Unlit/DICOM2D"));
395 GetComponent<RawImage> ().material = mMaterial;
398 Texture2D tex = dicom.getTexture2D ();
399 currentViewSettings.slice = dicom.slice;
403 GetComponent<RawImage> ().texture = tex;
406 bool seriesChanged =
false;
408 seriesChanged =
true;
410 currentDICOM = dicom;
411 loadingSlice =
false;
415 UpdateLevelWindow ();
416 ApplyScaleAndPosition ();
419 public void ApplyScaleAndPosition()
421 if (currentDICOM == null)
424 Texture2D tex = GetComponent<RawImage> ().texture as Texture2D;
429 Vector3 spacing =
new Vector3 ();
431 spacing.y = (
float)currentDICOM.pixelSpacing.y;
433 float imgWidth = GetComponent<RectTransform> ().rect.width;
434 float imgHeight = GetComponent<RectTransform> ().rect.height;
435 float aspectRatio = imgWidth / imgHeight;
438 float effectiveWidth = tex.width * spacing.x;
439 float effectiveHeight = tex.height * spacing.y;
441 if (effectiveWidth/imgWidth > effectiveHeight/imgHeight) {
442 scaleH = (float)effectiveWidth / (
float)effectiveHeight / aspectRatio;
444 scaleW = (float)effectiveHeight / (
float)effectiveWidth * aspectRatio;
447 float oX = currentViewSettings.panX*scaleW;
448 float oY = currentViewSettings.panY*scaleH;
450 if (currentViewSettings.flipHorizontal)
451 scaleW = scaleW * -1;
452 if (currentViewSettings.flipVertical)
453 scaleH = scaleH * -1;
455 Rect uvRect = GetComponent<RawImage> ().uvRect;
456 uvRect.size =
new Vector2 (scaleW*currentViewSettings.zoom, scaleH*currentViewSettings.zoom);
457 uvRect.center =
new Vector2 (0.5f + oX, 0.5f + oY);
458 GetComponent<RawImage> ().uvRect = uvRect;
463 public void FlipHorizontal()
465 Rect uvRect = GetComponent<RawImage> ().uvRect;
466 uvRect.width = -uvRect.width;
467 GetComponent<RawImage> ().uvRect = uvRect;
469 public void FlipVertical()
471 Rect uvRect = GetComponent<RawImage> ().uvRect;
472 uvRect.height = -uvRect.height;
473 GetComponent<RawImage> ().uvRect = uvRect;
480 if (mMaterial == null) {
481 mMaterial =
new Material (Shader.Find (
"Unlit/DICOM2D"));
482 GetComponent<RawImage> ().material = mMaterial;
484 mMaterial.SetTexture (
"_OverlayTex", texture);
490 if (mDefaultMask == null) {
492 mDefaultMask =
new Texture2D (1, 1, TextureFormat.ARGB32,
false);
493 mDefaultMask.SetPixel (0, 0,
new Color (0f, 0f, 0f, 0f));
494 mDefaultMask.Apply ();
static DICOMLoader instance
bool startLoading(DICOMSeries toLoad, int slice=0)
int savedLayerForSeriesUID(string seriesUID)
Vector3 pixelTo3DPos(Vector2 pixel)
void SetMask(Texture2D texture)
Vector2 uvToPixel(Vector2 uv)