VIS2 SS2013 CVD DVR
 All Classes Namespaces Functions Enumerations Properties
Data.cs
1 #region Using Statements
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.IO;
7 using Microsoft.Xna.Framework;
8 using Microsoft.Xna.Framework.Audio;
9 using Microsoft.Xna.Framework.Content;
10 using Microsoft.Xna.Framework.GamerServices;
11 using Microsoft.Xna.Framework.Graphics;
12 using Microsoft.Xna.Framework.Input;
13 using Microsoft.Xna.Framework.Media;
14 using Microsoft.Xna.Framework.Net;
15 using Microsoft.Xna.Framework.Storage;
16 using visLU.Effects;
17 using Microsoft.Xna.Framework.Graphics.PackedVector;
18 #endregion
19 
20 namespace visLU
21 {
26  {
27  #region variables
28  //: change Byte order with NetworkToHostOrder(Int16) if needed
29 
30  #region Ray Casting parameters
31  public Vector3 stepSize;
32  public Vector4 scaleFactor;
33  public int iterations;
34  public float scaleSteps = 1.0f; //the size of the step to take. == sample distance
35  //Lower means shorter steps. 0.5f or 1.0f are good values.
36  public float slice = 0.5f;
37  #endregion
38 
39  #region transfer function
40  private List<TransferControlPoint> colorControlPoints;
41  private List<TransferControlPoint> alphaControlPoints;
42  public Texture2D transferTexture;
43  public Texture2D transferTextureAlpha; //TDDO:do we use this??? -> if not delete
44  #endregion
45 
46  #region data
47  private List<float> densityValues;
48  private float[] densityArray;
49  private float[] distinctDensityValuesArray;
50  private int[] countDensityValuesArray;
51 
52  private Vector3[] gradients;
53 
54  public Matrix worldMatrix;
55  #endregion
56 
57 
58  //declare variables for header information
59  ushort sizeX, sizeY, sizeZ;
60 
61  private String fileName;
62 
63  public Texture3D volumeData;
64  public Texture3D volumeGradients; //TDDO: do we use this??? -> if not delete
65 
66  public Model cube;
67 
68  //private BasicEffect basicEffect; //for debug
69  int texturesSaved = 0; //TDDO:do we use this??? -> if not delete
70 
71  ContentManager content;
72 
73  #region view modes
74  private Camera camera;
75  private int currentView = 0; //3d view mode
76  #endregion
77 
78  #endregion
79 
80  #region Properties
81  public Camera Camera
82  {
83  set { camera = value; }
84  get { return camera; }
85  }
86  public int CurrentCamera
87  {
88  set { currentView = value; }
89  }
90 
91  public Texture3D VolumeData
92  {
93  get { return volumeData; }
94  }
95  public Vector3 DataDimensions
96  {
97  get { return new Vector3(sizeX, sizeY, sizeZ); }
98  }
99  #endregion
100 
101  #region Constructor
102  public Data(string _fileName)
108  {
109  worldMatrix = Matrix.Identity;
110  //game.Content.RootDirectory = "Content";
111  string a = "" + Directory.GetParent((string)Directory.GetCurrentDirectory());
112  string b = "" + Directory.GetParent(a);
113  string c = "" + Directory.GetParent(b);
114 
115  this.fileName = c + "\\" + _fileName;
116 
117  if (string.IsNullOrEmpty(fileName))
118  {
119  throw new ArgumentNullException(fileName);
120  }
121 
122  if (!File.Exists(fileName))
123  {
124  Console.WriteLine(fileName);
125  throw new ArgumentException("file not found: " + fileName);
126  }
127 
128  }
129  #endregion
130 
131  #region Initialize()
132  //-----------------------------------INITIALIZE()-------------------------------------------
133 
139  protected override void Initialize()
140  {
141  }
142  //__________________________________________________________________________________________
143  #endregion
144 
145  #region LoadContent
146 
147  #region LoadContent()
148  protected override void LoadContent()
154  {
155  if (GameProperties.Instance.debugOutput)
156  {
157  Console.WriteLine("LOADING DATA CONTENT");
158  }
159  loadDatafromFile();
160 
161  #region calculate Ray Casting Parameters
162  //calculate stepsize (has to be the ratio of the largest component)
163  scaleSteps = GameProperties.Instance.currSampleDist;
164  float max = (float)Math.Max(sizeX, Math.Max(sizeY, sizeZ));
165  stepSize = Vector3.One / max;
166 
167  /*Matrix rotate; -> für debug auskommentriert
168  if (GameProperties.Instance.dataFilename.StartsWith("skewed_head"))
169  {
170  rotate = Matrix.CreateRotationZ(90.0f);
171  }*/
172  worldMatrix = Matrix.CreateTranslation(new Vector3(-(sizeX / max) / 2.0f,
173  -(sizeY / max) / 2.0f,
174  -(sizeZ / max) / 2.0f)); //rotate;
175 
176  //calculate number of iterations
177  iterations = (int)(max * (1.0f / scaleSteps));
178 
179  //calculate scaleFactor
180  Vector3 sizeVector = new Vector3(sizeX, sizeY, sizeZ);
181  Vector3 scale = Vector3.One / ((Vector3.One * max) / sizeVector);
182  scaleFactor = new Vector4(scale.X, scale.Y, scale.Z, 1.0f);
183  #endregion
184 
185  #region content manager
186  //get the content manager
187  if (GameProperties.Instance.debugOutput)
188  {
189  Console.WriteLine("creating content manager");
190  }
191  content = Services.GetService(typeof(ContentManager)) as ContentManager;
192  if (content == null)
193  {
194  //throw new InvalidOperationException("Content Manager Service not found.");
195  content = new ContentManager(Services, "Content");
196  Services.AddService<ContentManager>(content);
197  if (GameProperties.Instance.debugOutput)
198  {
199  Console.WriteLine("content manager created");
200  }
201  }
202  try
203  {
204  cube = content.Load<Model>("Models/box");
205  if (GameProperties.Instance.debugOutput)
206  {
207  Console.WriteLine("cube loaded");
208  }
209  }
210  catch (Exception e)
211  {
212  Console.WriteLine("Problem loading cube: " + e);
213  throw;
214  }
215  #endregion
216 
217  colorControlPoints = GameProperties.Instance.colorControlPoints;
218  alphaControlPoints = GameProperties.Instance.alphaControlPoints;
219 
220  transferTexture = new Texture2D(GraphicsDevice, 256, 1, false, SurfaceFormat.Color); ;
221 
222  //update slice controls
223  setSliceRange(sizeX, sizeY, sizeZ);
224 
225  }
226  #endregion
227 
228  #region loadDatafromFile()
229  private void loadDatafromFile()
239  {
240  if (GameProperties.Instance.debugOutput)
241  {
242  Console.WriteLine("LOADING DATA FROM FILE");
243  }
244  #region read data
245  Stream file = new FileStream(fileName, FileMode.Open);
246 
247  BinaryReader reader = new BinaryReader(file);
248 
249  //read header
250  sizeX = reader.ReadUInt16();
251  sizeY = reader.ReadUInt16();
252  sizeZ = reader.ReadUInt16();
253 
254  //Console.WriteLine("sizeX =" + sizeX + " sizeY =" + sizeY + " sizeZ =" + sizeZ);
255 
256  volumeData = new Texture3D(GraphicsDevice, sizeX, sizeY, sizeZ, false, SurfaceFormat.Rgba64);
257 
258  ushort[] buffer = new ushort[sizeX * sizeY * sizeZ];
259 
260  int l = 0;
261  while (reader.BaseStream.Position < reader.BaseStream.Length)
262  {
263 
264  buffer[l] = reader.ReadUInt16();
265  l++;
266  }
267  reader.Close();
268  #endregion
269  if (GameProperties.Instance.debugOutput)
270  {
271  Console.WriteLine("LOADING DATA FROM FILE");
272  }
273 
274  #region scale data
275  //scale the scalar values to [0, 1]
276  densityValues = new List<float>();
277  float maxValue = 1.0f / buffer.Max();
278  for (int i = 0; i < buffer.Length; i++)
279  {
280  densityValues.Add((float)buffer[i] * maxValue);
281  }
282  #endregion
283 
284 
285 
286  GameProperties.Instance.dataOrigin = new Vector3(0.5f, 0.5f, sizeZ / 2.0f); //TODO: do we need it?
287 
288  #region add gradients to VolumeData
289  //filter volume data
290  if (GameProperties.Instance.enableGaussFilter) { filterGaussian(0.3f); }
291  if (GameProperties.Instance.enableAvgFilter) { filterNxNxN(3, true); }
292 
293 
294 
295 
296  //calculate gradients
297  calculateGradients();
298  //filter the gradients with an NxNxN box filter
299  filterNxNxN(3, false);
300  //scale gradients
301  scaleGradients();
302 
303  #region add black border
304  //TODO: better to extend the texture with black border and modify the texture coordinates
305  for (int k = 0; k < sizeZ; k++)
306  {
307  for (int j = 0; j < sizeY; j++)
308  {
309  for (int i = 0; i < sizeX; i++)
310  {
311  int idx = i + (j * sizeX) + (k * sizeX * sizeY);
312  if (!((i >= 1 && i < sizeX - 1) &&
313  (j >= 1 && i < sizeY - 1) &&
314  (k >= 1 && k < sizeZ - 1)))
315  {
316 
317  densityValues[idx] = 0.0f;
318 
319  }
320 
321  }
322  }
323  }
324  #endregion
325 
326  Rgba64[] densityVectors = new Rgba64[buffer.Length];
327  for (int i = 0; i < buffer.Length; i++)
328  {
329  densityVectors[i] = new Rgba64(gradients[i].X,
330  gradients[i].Y,
331  gradients[i].Z,
332  densityValues[i]);
333  }
334  #endregion
335  //set data to texture
336 
337  volumeData.SetData<Rgba64>(densityVectors);
338 
339  #region sort data
340  densityValues.Sort();
341  sortDensityValues();
342 
343  /*for (int i = 480000; i < 489000; i++) // for debug
344  {
345  Console.WriteLine(densityValues[i]);
346  }*/
347  #endregion
348  if (GameProperties.Instance.debugOutput)
349  {
350  Console.WriteLine("DATA LOADED FROM FILE");
351  }
352  }
353  #endregion
354 
355  #region sortDensityValues()
356  //: DEBUG THIS
363  private void sortDensityValues()
364  {
365 
366  List<float> distinctDensityValues = new List<float>();
367  List<int> countDensityValues = new List<int>();
368 
369  #region debug
370  /*int countAll = densityValues.Count();
371  int testCountAll = 0;
372  int totalValues = 0;*/
373  #endregion
374 
375  for (int i = 0; i < densityValues.Count(); i++)
376  {
377  int value1 = (int)(densityValues[i] * 255);
378  int count = 1;
379 
380  while (i < (densityValues.Count() - 1))
381  {
382  int value2 = (int)(densityValues[i + 1] * 255);
383  if ((value1 == value2))
384  {
385  count++;
386  i++;
387  }
388  else
389  {
390  break;
391  }
392 
393  }
394 
395  #region debug
396  /*testCountAll += count;
397  totalValues++;
398  Console.WriteLine("value" + i + " = " + value1 + " x" + count);*/
399  #endregion
400 
401  distinctDensityValues.Add(value1);
402  countDensityValues.Add(count);
403 
404  }
405  distinctDensityValuesArray = distinctDensityValues.ToArray();
406  countDensityValuesArray = countDensityValues.ToArray();
407 
408  GameProperties.Instance.distinctDensityValues = distinctDensityValuesArray;
409  GameProperties.Instance.countDensityValues = countDensityValuesArray;
410 
411  }
412  #endregion
413 
414  #endregion
415 
416  #region Update()
417  protected override void Update() //OLD STUFF->DELETE? -> Leave function empty, it should be overridden by this class
424  {
425  #region DEBUG
426  //Console.WriteLine("Data Update Call");
427  //GameProperties.Instance.countDataUpdates++;
428  //Console.WriteLine("Doing Data Update Number " + GameProperties.Instance.countDataUpdates);
429  #endregion
430 
431  #region move camera TODO
432  /*currentMouseState = Mouse.GetState();
433  if (currentMouseState.LeftButton == ButtonState.Pressed)
434  {
435  float fX, fY;
436  fX = MathHelper.ToRadians(currentMouseState.X - lastMouseState.X);
437  fY = MathHelper.ToRadians(currentMouseState.Y - lastMouseState.Y);
438 
439  *= Matrix.CreateRotationX(fX) * Matrix.CreateRotationY(-fY);
440 
441  }
442  lastMouseState = currentMouseState;*/
443  #endregion
444 
445  #region set parameters for rendering
446  /*GraphicsDevice.BlendState = BlendState.Additive;
447  shader.CurrentTechnique = shader.Techniques["RenderPosition"];
448  shader.SetEffectParameter(worldMatrix * camera.ViewProjection, worldMatrix);
449  shader.SetEffectParameter(camera.CameraPosition);*/
450  #endregion
451 
452  }
453  #endregion
454 
455  #region Draw
456 
457  #region Draw()
458  protected override void Draw() //OLD STUFF->DELETE? -> Leave function empty, it should be overridden by this class
464  {
465  #region DEBUG
466  //Console.WriteLine("Draw()");
467  //Console.WriteLine("Data Draw Call");
468  //Console.WriteLine("3 DRAWING VOLUME for cam=" + currentView + "-----------------------------------------------------");
469  #endregion
470 
471  DrawCoordinateSystem(); //for debug
472 
473  }
474  #endregion
475 
476 
477 
478  #region DrawCoordinateSystem()
479  public void DrawCoordinateSystem()
484  {
485  Console.WriteLine("DRAWING COORDINATE SYSTEM");
486  #region coordinate system
487  //Camera camera = (Camera)Game.Services.GetService(typeof(Camera));
488  BasicEffect basicEffect = new BasicEffect(GraphicsDevice);
489  GraphicsDevice.DepthStencilState = DepthStencilState.None;
490 
491  basicEffect.LightingEnabled = false;
492  basicEffect.TextureEnabled = false;
493  basicEffect.VertexColorEnabled = true;
494  basicEffect.World = Matrix.Identity;
495  basicEffect.Projection = camera.Projection;
496  basicEffect.View = camera.View;
497 
498  foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
499  {
500  pass.Apply();
501  VertexPositionColor[] pointList = {
502  //Z axis
503  new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.DarkBlue),
504  new VertexPositionColor(new Vector3(0.0f, 0.0f, -3000.0f), Color.DarkBlue),
505  new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.Blue),
506  new VertexPositionColor(new Vector3(0.0f, 0.0f, 3000.0f), Color.Blue),
507  //Y axis
508  new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.DarkGreen),
509  new VertexPositionColor(new Vector3(0.0f, -3000.0f, 0.0f), Color.DarkGreen),
510  new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.Green),
511  new VertexPositionColor(new Vector3(0.0f, 3000.0f, 0.0f), Color.Green),
512  //X axis
513  new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.DarkRed),
514  new VertexPositionColor(new Vector3(-3000.0f, 0.0f, 0.0f), Color.DarkRed),
515  new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.Red),
516  new VertexPositionColor(new Vector3(3000.0f, 0.0f, 0.0f), Color.Red),
517  //X
518  new VertexPositionColor(new Vector3(10.0f + 2.5f, 5.0f, 0.0f), Color.DarkRed),
519  new VertexPositionColor(new Vector3(10.0f + 1.25f, 1.25f, 0.0f), Color.DarkRed),
520  new VertexPositionColor(new Vector3(10.0f + 1.25f, 5.0f, 0.0f), Color.DarkRed),
521  new VertexPositionColor(new Vector3(10.0f + 2.5f, 1.25f, 0.0f), Color.DarkRed),
522  //Y
523  new VertexPositionColor(new Vector3(1.875f, 10.0f + 3.125f, 0.0f), Color.DarkGreen),
524  new VertexPositionColor(new Vector3(1.875f, 10.0f + 1.125f, 0.0f), Color.DarkGreen),
525  new VertexPositionColor(new Vector3(1.875f, 10.0f + 3.125f, 0.0f), Color.DarkGreen),
526  new VertexPositionColor(new Vector3(2.5f, 10.0f + 5.0f, 0.0f), Color.DarkGreen),
527  new VertexPositionColor(new Vector3(1.875f, 10.0f + 3.125f, 0.0f), Color.DarkGreen),
528  new VertexPositionColor(new Vector3(1.125f, 10 + 5.0f, 0.0f), Color.DarkGreen),
529  //Z
530  new VertexPositionColor(new Vector3(0.0f, 5.0f, 10.0f + 2.5f), Color.DarkBlue),
531  new VertexPositionColor(new Vector3(0.0f, 5.0f, 10.0f + 1.25f), Color.DarkBlue),
532  new VertexPositionColor(new Vector3(0.0f, 1.25f, 10.0f + 2.5f), Color.DarkBlue),
533  new VertexPositionColor(new Vector3(0.0f, 1.25f, 10.0f + 1.25f), Color.DarkBlue),
534  new VertexPositionColor(new Vector3(0.0f, 1.25f, 10.0f + 2.5f), Color.DarkBlue),
535  new VertexPositionColor(new Vector3(0.0f, 5.0f, 10.0f + 1.25f), Color.DarkBlue)
536 
537  };
538  short[] lineListIndices = new short[28] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 };
539  GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
540  PrimitiveType.LineList,
541  pointList,
542  0, // vertex buffer offset to add to each element of the index buffer
543  28, // number of vertices in pointList
544  lineListIndices, // the index buffer
545  0, // first index element to read
546  14 // number of primitives to draw
547  );
548  }
549  GraphicsDevice.DepthStencilState = DepthStencilState.Default;
550  #endregion
551  }
552  #endregion
553 
554  #endregion
555 
556  #region transfer function
557  public void setControlpoints()
562  {
563  colorControlPoints = GameProperties.Instance.colorControlPoints;
564  alphaControlPoints = GameProperties.Instance.alphaControlPoints;
565 
566  float amount = 0.0f;
567  Color[] colorArray = new Color[256];
568  float[] alphaArray = new float[256];
569 
570  #region interpolate between ControlPoints
571 
572  // sort ControlPoints by isoValue
573  colorControlPoints.Sort(delegate(TransferControlPoint p1,
574  TransferControlPoint p2) { return p1.isoValue.CompareTo(p2.isoValue); });
575  alphaControlPoints.Sort(delegate(TransferControlPoint p1,
576  TransferControlPoint p2) { return p1.isoValue.CompareTo(p2.isoValue); });
577 
578  // before first ControlPoint: fill with black and alpha 0.0f
579  for (int i = 0; i < colorControlPoints[0].isoValue; i++)
580  {
581  colorArray[i] = new Color(0.0f, 0.0f, 0.0f, 0.0f);
582  alphaArray[i] = 0.0f;
583  }
584 
585  for (int j = 0; j < colorControlPoints.Count - 1; j++)
586  {
587  for (int i = colorControlPoints[j].isoValue; i <= colorControlPoints[j + 1].isoValue; i++)
588  {
589  amount = (((float)i - colorControlPoints[j].isoValue) /
590  (colorControlPoints[j + 1].isoValue - colorControlPoints[j].isoValue));
591  colorArray[i] = Color.Lerp(new Color(colorControlPoints[j].color),
592  new Color(colorControlPoints[j + 1].color), amount);
593 
594  //interpolate alpha
595  alphaArray[i] = alphaControlPoints[j].color.W * (1.0f - amount) +
596  alphaControlPoints[j + 1].color.W * amount;
597 
598  colorArray[i].A = (byte)(alphaArray[i] * 255);
599  }
600  }
601 
602  //after last ControlPoint: fill with black and alpha
603  for (int i = colorControlPoints[colorControlPoints.Count - 1].isoValue + 1; i < 256; i++)
604  {
605  colorArray[i] = new Color(0.0f, 0.0f, 0.0f, 0.0f);
606  alphaArray[i] = 0.0f;
607  }
608  #endregion
609 
610  #region debug
611  /*Console.WriteLine("Call Data TF- " + "TF Count:" + colorControlPoints.Count);
612  for (int i = 0; i < colorControlPoints.Count; i++)
613  {
614  Console.WriteLine("CP ISO:" + i + " =" + colorControlPoints[i].isoValue);
615  Console.WriteLine("CP COLOR:" + i + " =" + colorControlPoints[i].color);
616  Console.WriteLine("CP ALPHA:" + i + " =" + alphaControlPoints[i].color);
617  Console.WriteLine("TF for ISO: " + colorControlPoints[i].isoValue + ": " + colorArray[colorControlPoints[i].isoValue]);
618  }*/
619  #endregion
620 
621  #region write to textures
622  //write to a textures
623  transferTexture = new Texture2D(GraphicsDevice, 256, 1, false, SurfaceFormat.Color);
624  transferTextureAlpha = new Texture2D(GraphicsDevice, 256, 1, false, SurfaceFormat.Color);
625 
626 
627  Color[] alphaValues = new Color[256];
628 
629  for (int i = 0; i < 256; i++)
630  {
631 
632  /*if (i < 5 || i > 250)
633  {
634  colorArray[i] = new Color(0.0f, 0.0f, 0.0f, 0.0f);
635  alphaValues[i] = new Color(0.0f, 0.0f, 0.0f, 0.0f);
636  continue;
637  }*/
638  alphaValues[i] = new Color(alphaArray[i], alphaArray[i], alphaArray[i], alphaArray[i]);
639 
640 
641  }
642 
643  transferTexture.SetData<Color>(colorArray);
644  transferTextureAlpha.SetData<Color>(alphaValues);
645  //saveScreenshot(transferTexture, "ReferenceTF1", "png");
646  #endregion
647 
648  }
649 
650  #endregion
651 
652  #region Gradients
653 
661  private float getSampleAt(int x, int y, int z)
662  {
663  x = (int)MathHelper.Clamp(x, 0, sizeX - 1);
664  y = (int)MathHelper.Clamp(y, 0, sizeY - 1);
665  z = (int)MathHelper.Clamp(z, 0, sizeZ - 1);
666 
667  //y*width -> move rows down
668  //z* (width*height) -> move planes into the volume
669  int arrayIndex = x + y * sizeX + z * sizeX * sizeY;
670 
671  //Console.WriteLine("Sampe at pos:" + arrayIndex + ":" + densityValues[arrayIndex]);
672 
673  return densityValues[arrayIndex];
674 
675  //return (float)mScalars[x + (y * mWidth) + (z * mWidth * mHeight)].ToVector4().W;
676  }
677 
685  private void calculateGradients()
686  {
687  /*use Central difference in x-, y- & z-direction (in voxel):
688  * ( f(x+1) - f(x-1) )
689  * gradient f(x,y,z) = 1/2 * | f(y+1) - f(y-1) |
690  * ( f(z+1) - f(z-1) )
691  * */
692 
693  int sampleSize = GameProperties.Instance.gradientSampleSize;
694 
695  gradients = new Vector3[sizeX * sizeY * sizeZ];
696 
697  Vector3 normal = Vector3.Zero;
698  //Vector3 min = Vector3.One;
699  //Vector3 max = Vector3.Zero;
700  int i = 0;
701  for (int z = 0; z < sizeZ; z++)
702  {
703  for (int y = 0; y < sizeY; y++)
704  {
705  for (int x = 0; x < sizeX; x++)
706  {
707  //todo check this!!!!
708  Vector3 gradient = new Vector3(
709  getSampleAt(x + sampleSize, y, z) - getSampleAt(x - sampleSize, y, z),
710  getSampleAt(x, y + sampleSize, z) - getSampleAt(x, y - sampleSize, z),
711  getSampleAt(x, y, z + sampleSize) - getSampleAt(x, y, z - sampleSize));
712 
713  // does not matter how long gradient is => normalize (instead of * 1/2)
714  gradients[i] = Vector3.Normalize(gradient);
715  //gradients[i].X = gradient.Length(); gradients[i].Y = gradient.Length(); gradients[i].Z = gradient.Length();
716  //or use magnitude az normal if results are not ok
717 
718  //scale and bias to [0,1]
719  //gradients[i].X = (gradients[i].X + 1.0f) / 2.0f; gradients[i].Y = (gradients[i].Y + 1.0f) / 2.0f; gradients[i].Z = (gradients[i].Z + 1.0f) / 2.0f;
720  if (float.IsNaN(gradients[i].X)) gradients[i] = Vector3.Zero;
721  //Console.WriteLine("Gradient " + i + ":" + gradients[i].X + ", " + gradients[i].Y + ", " + gradients[i].Z);
722  //min.X = Math.Min(min.X, gradients[i].X); min.Y = Math.Min(min.Y, gradients[i].Y); min.Z = Math.Min(min.Z, gradients[i].Z);
723  //max.X = Math.Max(max.X, gradients[i].X); max.Y = Math.Max(max.Y, gradients[i].Y); max.Z = Math.Max(max.Z, gradients[i].Z);
724  i++;
725  }
726  }
727  }
728  }
729 
730 
731  private void scaleGradients()
732  {
733  for (int i = 0; i < gradients.Length; i++)
734  {
735  //scale and bias to [0,1]
736  gradients[i].X = (gradients[i].X + 1.0f) / 2.0f; gradients[i].Y = (gradients[i].Y + 1.0f) / 2.0f; gradients[i].Z = (gradients[i].Z + 1.0f) / 2.0f;
737 
738  }
739  }
746  private void filterNxNxN(int n = 3, bool filterData = false)
747  {
748  List<float> valuesTmpSingle = new List<float>();
749  List<Vector3> valuesTmp = new List<Vector3>();
750  int i = 0;
751  for (int z = 0; z < sizeZ; z++)
752  {
753  for (int y = 0; y < sizeY; y++)
754  {
755  for (int x = 0; x < sizeX; x++)
756  {
757  if (filterData)
758  {
759  valuesTmpSingle.Add(sampleNxNxNSingle(x, y, z, n));
760  }
761  else
762  {
763  valuesTmp.Add(sampleNxNxN(x, y, z, n));
764  }
765  i++;
766  }
767  }
768  }
769  if (filterData) { densityValues = valuesTmpSingle; }
770  else {gradients = valuesTmp.ToArray<Vector3>(); }
771  }
772 
782  private Vector3 sampleNxNxN(int x, int y, int z, int n)
783  {
784  n = (n - 1) / 2;
785 
786  Vector3 average = Vector3.Zero;
787  int num = 0;
788 
789  for (int k = z - n; k <= z + n; k++)
790  {
791  for (int j = y - n; j <= y + n; j++)
792  {
793  for (int i = x - n; i <= x + n; i++)
794  {
795  if (isInBounds(i, j, k))
796  {
797  average += gradients[i + (j * sizeX) + (k * sizeX * sizeY)];
798  num++;
799  }
800  }
801  }
802  }
803 
804  average /= (float)num;
805  if (average.X != 0.0f && average.Y != 0.0f && average.Z != 0.0f)
806  average.Normalize();
807 
808  return average;
809  }
810 
818  private bool isInBounds(int x, int y, int z)
819  {
820  return ((x >= 0 && x < sizeX) &&
821  (y >= 0 && y < sizeY) &&
822  (z >= 0 && z < sizeZ));
823  }
824 
834  private float sampleNxNxNSingle(int x, int y, int z, int n)
835  {
836  n = (n - 1) / 2;
837 
838  float average = 0.0f;
839  int num = 0;
840 
841  for (int k = z - n; k <= z + n; k++)
842  {
843  for (int j = y - n; j <= y + n; j++)
844  {
845  for (int i = x - n; i <= x + n; i++)
846  {
847  if (isInBounds(i, j, k))
848  {
849  average += densityValues[i + (j * sizeX) + (k * sizeX * sizeY)];
850  num++;
851  }
852  }
853  }
854  }
855 
856  average /= (float)num;
857  return average;
858  }
859 
865  private void filterGaussian(float sigma)
866  {
867  List<float> valuesTmpSingle = new List<float>();
868  float[] gaussianKernel = calculateGaussianKernel(sigma);
869  int i = 0;
870  for (int z = 0; z < sizeZ; z++)
871  {
872  for (int y = 0; y < sizeY; y++)
873  {
874  for (int x = 0; x < sizeX; x++)
875  {
876 
877  valuesTmpSingle.Add(sampleGaussKernel(x, y, z, gaussianKernel));
878 
879  i++;
880  }
881  }
882  }
883  densityValues = valuesTmpSingle;
884  }
885 
894  private float sampleGaussKernel(int x, int y, int z, float[] gaussianKernel)
895  {
896  int n = (int)Math.Pow(gaussianKernel.Length, 1 / 3);
897  n = (n - 1) / 2;
898 
899  float average = 0.0f;
900  int kk = 0; int jk = 0; int ik = 0;
901 
902  for (int k = z - n; k <= z + n; k++)
903  {
904  for (int j = y - n; j <= y + n; j++)
905  {
906  for (int i = x - n; i <= x + n; i++)
907  {
908  if (isInBounds(i, j, k))
909  {
910  average += densityValues[i + (j * sizeX) + (k * sizeX * sizeY)] * gaussianKernel[ik + (jk * n) + (kk * n * n)];
911 
912  }
913  ik++;
914  }
915  jk++;
916  }
917  kk++;
918  }
919 
920  return average;
921  }
922 
923 
929  private float[] calculateGaussianKernel(float sigma)
930  {
931  //obtain minimum kernel size
932  int kernelSize = (int)(6 * (sigma) - 1);
933  if (kernelSize < 3) kernelSize = 3;
934 
935  int width = kernelSize; int height = kernelSize; int depth = kernelSize;
936 
937  float[] gaussianKernel = new float[width * height * depth];
938 
939  int x_offset = (-1) * (width - 1) / 2;
940  int y_offset = (-1) * (height - 1) / 2;
941  int z_offset = (-1) * (depth - 1) / 2;
942 
943  float norm = 0.0f;
944 
945  for (int k = 0; k < depth; k++)
946  {
947  y_offset = (-1) * (width - 1) / 2;
948  for (int j = 0; j < width; j++)
949  {
950  x_offset = (-1) * (width - 1) / 2;
951  for (int i = 0; i < width; i++)
952  {
953  int idx = k * (width * width) + j * (width) + i;
954 
955  //obtain kernel coeff
956  gaussianKernel[idx] = 1 / (float)(Math.Sqrt(2 * Math.PI) * sigma * Math.Sqrt(2 * Math.PI) * sigma * Math.Sqrt(2 * Math.PI) * sigma * Math.Exp(-((x_offset * x_offset + y_offset * y_offset + z_offset * z_offset) / (2 * sigma * sigma))));
957 
958  norm = norm + gaussianKernel[idx];
959 
960  x_offset = x_offset + 1;
961  }
962  y_offset = y_offset + 1;
963  }
964  z_offset = z_offset + 1;
965  }
966 
967  //normalize to one
968  for (int i = 0; i < gaussianKernel.Length; i++)
969  {
970  gaussianKernel[i] = gaussianKernel[i] / norm;
971  }
972 
973  return gaussianKernel;
974  }
975 
976  #endregion
977 
978  #region help functions
979  private void saveScreenshot(Texture2D texture, String name)
980  {
981  try
982  {
983  FileStream stream = File.OpenWrite(name + ".png");
984  texture.SaveAsPng(stream, texture.Width, texture.Height);
985 
986  }
987  catch (Exception e)
988  {
989  Console.WriteLine("Save Screenshot: ");
990  Console.WriteLine(e);
991  }
992  }
993 
999  private void saveScreenshot(Texture2D texture, String name, String ext)
1000  {
1001  Console.WriteLine("saving " + name);
1002  try
1003  {
1004  if (!name.ElementAt(name.Length - 4).Equals(".")) name = name + "." + ext;
1005  FileStream stream = File.OpenWrite(name);
1006  switch (ext)
1007  {
1008  case "png":
1009  texture.SaveAsPng(stream, texture.Width, texture.Height);
1010  break;
1011  case "jpg":
1012  texture.SaveAsJpeg(stream, texture.Width, texture.Height);
1013  break;
1014  default:
1015  if (name.ElementAt(name.Length - 4).Equals(".")) name = name.Substring(0, name.Length - 4);
1016  name = name + ".png";
1017  texture.SaveAsPng(stream, texture.Width, texture.Height);
1018  break;
1019  }
1020 
1021  }
1022  catch (Exception e)
1023  {
1024  Console.WriteLine("Save Screenshot: ");
1025  Console.WriteLine(e);
1026  }
1027 
1028  }
1029 
1030 
1031  private void setSliceRange(int xRange, int yRange, int zRange)
1032  {
1033  GameProperties.Instance.xDataRange = xRange;
1034  GameProperties.Instance.yDataRange = yRange;
1035  GameProperties.Instance.zDataRange = zRange;
1036  //GameProperties.Instance.updateGuiForm = true; old stuff -> delete TODO: do we need this? if not delete
1037  }
1038  #endregion
1039  }
1040 }