Volume.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. using System;
  2. using System.Drawing;
  3. using System.Runtime.CompilerServices;
  4. namespace PaintDotNet.Data.SurfacePlot
  5. {
  6. class Volume
  7. {
  8. Image imp;
  9. private int widthX;
  10. private int heightY;
  11. private int depthZ;
  12. private int widthXm1;
  13. private int heightYm1;
  14. private int depthZm1;
  15. int[][] volumeLimits = new int[8][];
  16. int[][] cornerT = new int[8][];
  17. //double a = 0, b = 1;
  18. //private double min, max;
  19. //double oldMin, oldMax;
  20. //bool firstTime = true;
  21. private double zAspect = 1;
  22. private byte[][][] data3D;
  23. private int cutDist = -1000;
  24. private Lut lut = null;
  25. private int[] bufferPixels;
  26. private double[] zbufferPixels;
  27. private int bufferWidth;
  28. private int bufferHeight;
  29. private Transform tr;
  30. private int drawMode;
  31. private int threshold;
  32. //private int lutNr;
  33. private int dotsDeltaX = 1; // subsampling factor in x direction (used by dots drawing)
  34. private int dotsDeltaY = 1; // subsampling factor in y direction (used by dots drawing)
  35. private int dotsDeltaZ = 1; // subsampling factor in z direction (used by dots drawing)
  36. private int renderDepth = 6;
  37. public Volume(Image imp)
  38. {
  39. this.imp = imp;
  40. //this.ip = imp.getProcessor();
  41. widthX = imp.Width;
  42. heightY = imp.Height;
  43. //这个应该是获取最亮的值
  44. depthZ = 255; //imp.getStackSize();
  45. volumeLimits[0][0] = 0; volumeLimits[0][1] = 0; volumeLimits[0][2] = 0; // left front down [0]
  46. volumeLimits[1][0] = 0; volumeLimits[1][1] = heightY; volumeLimits[1][2] = depthZ; // left back top [1]
  47. volumeLimits[2][0] = widthX; volumeLimits[2][1] = 0; volumeLimits[2][2] = depthZ; // right front top [2]
  48. volumeLimits[3][0] = widthX; volumeLimits[3][1] = heightY; volumeLimits[3][2] = 0; // right back down [3]
  49. volumeLimits[4][0] = 0; volumeLimits[4][1] = 0; volumeLimits[4][2] = depthZ; // left front top [4]
  50. volumeLimits[5][0] = 0; volumeLimits[5][1] = heightY; volumeLimits[5][2] = 0; // left back down [5]
  51. volumeLimits[6][0] = widthX; volumeLimits[6][1] = 0; volumeLimits[6][2] = 0; // right front down [6]
  52. volumeLimits[7][0] = widthX; volumeLimits[7][1] = heightY; volumeLimits[7][2] = depthZ; // right back top [7]
  53. widthXm1 = widthX - 1;
  54. heightYm1 = heightY - 1;
  55. depthZm1 = depthZ - 1;
  56. //data3D = new byte[depthZ][heightY][widthX]; //z y x
  57. data3D = new byte[depthZ][][];
  58. getMinMax();
  59. init();
  60. }
  61. public void setBuffers(int[] bufferPixels, double[] zbufferPixels, int bufferWidth, int bufferHeight)
  62. {
  63. this.bufferPixels = bufferPixels;
  64. this.zbufferPixels = zbufferPixels;
  65. this.bufferWidth = bufferWidth;
  66. this.bufferHeight = bufferHeight;
  67. }
  68. public void setTransform(Transform transform)
  69. {
  70. this.tr = transform;
  71. }
  72. private bool getMinMax()
  73. {
  74. /**
  75. ip.MinMaxLoc(out min, out max);
  76. Calibration cal = imp.getCalibration();
  77. if (cal != null)
  78. {
  79. if (cal.calibrated())
  80. {
  81. min = cal.getCValue((int)min);
  82. max = cal.getCValue((int)max);
  83. double[] coef = cal.getCoefficients();
  84. if (coef != null)
  85. {
  86. a = coef[0];
  87. b = coef[1];
  88. }
  89. }
  90. }
  91. if (firstTime)
  92. {
  93. if (zAspect == 1)
  94. zAspect = (float)(cal.pixelDepth / cal.pixelWidth);
  95. if (zAspect == 0)
  96. zAspect = 1;
  97. lut = new Lut();
  98. lut.readLut(imp);
  99. oldMin = min;
  100. oldMax = max;
  101. firstTime = false;
  102. }
  103. bool changed;
  104. if (oldMin == min && oldMax == max)
  105. changed = false;
  106. else
  107. changed = true;
  108. oldMin = min;
  109. oldMax = max;
  110. return changed;
  111. **/
  112. return false;
  113. }
  114. private void init()
  115. {
  116. /**
  117. ImageStack stack = imp.getStack();
  118. int bitDepth = imp.Depth();
  119. if (bitDepth == 8)
  120. {
  121. float scale = (float)(255f / (max - min));
  122. for (int z = 0; z < depthZ; z++)
  123. {
  124. byte[] pixels = (byte[])stack.getPixels(z + 1);
  125. int pos = 0;
  126. for (int y = 0; y < heightY; y++)
  127. {
  128. for (int x = 0; x < widthX; x++)
  129. {
  130. int val = 0xff & pixels[pos++];
  131. val = (int)((val - min) * scale);
  132. if (val < 0f) val = 0;
  133. if (val > 255) val = 255;
  134. data3D[z][y][x] = (byte)(0xff & val);
  135. }
  136. }
  137. }
  138. }
  139. if (bitDepth == 16)
  140. {
  141. float scale = (float)(255f / (max - min));
  142. for (int z = 0; z < depthZ; z++)
  143. {
  144. short[] pixels = (short[])stack.getPixels(z + 1);
  145. int pos = 0;
  146. for (int y = 0; y < heightY; y++)
  147. {
  148. for (int x = 0; x < widthX; x++)
  149. {
  150. int val = (int)((int)(0xFFFF & pixels[pos++]) * b + a - min);
  151. if (val < 0f) val = 0;
  152. val = (int)(val * scale);
  153. if (val > 255) val = 255;
  154. data3D[z][y][x] = (byte)(val);
  155. }
  156. }
  157. }
  158. }
  159. if (bitDepth == 32)
  160. {
  161. float scale = (float)(255f / (max - min));
  162. for (int z = 0; z < depthZ; z++)
  163. {
  164. float[] pixels = (float[])stack.getPixels(z + 1);
  165. int pos = 0;
  166. for (int y = 0; y < heightY; y++)
  167. {
  168. for (int x = 0; x < widthX; x++)
  169. {
  170. float value = (float)(pixels[pos++] - min);
  171. if (value < 0f) value = 0f;
  172. int ivalue = (int)(value * scale);
  173. if (ivalue > 255) ivalue = 255;
  174. data3D[z][y][x] = (byte)(ivalue);
  175. }
  176. }
  177. }
  178. }
  179. **/
  180. }
  181. private void volumeDotsOrig()
  182. {
  183. int[] v = new int[3];
  184. byte[][] datay;
  185. byte[] datax;
  186. double step = dotsDeltaX / (widthX - 1);
  187. for (int z = 0; z < data3D.Length; z += dotsDeltaZ)
  188. {
  189. v[2] = z;
  190. datay = data3D[z];
  191. for (int y = 0; y < datay.Length; y += dotsDeltaY)
  192. {
  193. v[1] = y;
  194. datax = datay[y];
  195. v[0] = 0;
  196. tr.xyzPos(v);
  197. double x1 = tr.X;
  198. double y1 = tr.Y;
  199. double z1 = tr.Z;
  200. v[0] = datax.Length - 1;
  201. tr.xyzPos(v);
  202. double dx = (tr.X - x1) * step;
  203. double dy = (tr.Y - y1) * step;
  204. double dz = (tr.Z - z1) * step;
  205. for (int x = 0; x < widthX; x += dotsDeltaX)
  206. {
  207. int val = 0xff & datax[x];
  208. if (val >= threshold)
  209. {
  210. double z_ = z1;
  211. if (z_ > cutDist)
  212. {
  213. int x_ = (int)(x1);
  214. int y_ = (int)(y1);
  215. if (x_ >= 0 && y_ >= 0 && x_ < bufferWidth && y_ < bufferHeight)
  216. {
  217. int pos = y_ * bufferWidth + x_;
  218. if (z_ < zbufferPixels[pos])
  219. {
  220. zbufferPixels[pos] = z_;
  221. bufferPixels[pos] = val + 1;
  222. }
  223. }
  224. }
  225. }
  226. z1 += dz;
  227. y1 += dy;
  228. x1 += dx;
  229. }
  230. }
  231. }
  232. for (int i = bufferPixels.Length - 1; i >= 0; i--)
  233. {
  234. int val = bufferPixels[i];
  235. if (val > 255)
  236. val = 255;
  237. if (val > 0)
  238. bufferPixels[i] = lut.colors[val];
  239. }
  240. }
  241. private void volumeDots()
  242. {
  243. int[] v = new int[3];
  244. byte[][] datay;
  245. byte[] datax;
  246. for (int z = 0; z < data3D.Length; z += dotsDeltaZ)
  247. {
  248. v[2] = z;
  249. datay = data3D[z];
  250. for (int y = 0; y < datay.Length; y += dotsDeltaY)
  251. {
  252. v[1] = y;
  253. datax = datay[y];
  254. for (int x = 0; x < widthX; x += dotsDeltaX)
  255. {
  256. v[0] = x;
  257. tr.xyzPos(v);
  258. double x1 = tr.X;
  259. double y1 = tr.Y;
  260. double z1 = tr.Z;
  261. int val = 0xff & datax[x];
  262. if (val >= threshold)
  263. {
  264. if (z1 > cutDist)
  265. {
  266. int x_ = (int)(x1);
  267. int y_ = (int)(y1);
  268. if (x_ >= 0 && y_ >= 0 && x_ < bufferWidth && y_ < bufferHeight)
  269. {
  270. int pos = y_ * bufferWidth + x_;
  271. if (z1 < zbufferPixels[pos])
  272. {
  273. zbufferPixels[pos] = z1;
  274. bufferPixels[pos] = lut.colors[val];
  275. }
  276. }
  277. }
  278. }
  279. }
  280. }
  281. }
  282. }
  283. private void volumeSliceNearestNeighbor()
  284. {
  285. int xMin = bufferWidth - 1, xMax = 0, yMin = bufferHeight - 1, yMax = 0;
  286. for (int i = 0; i < 8; i++)
  287. {
  288. tr.xyzPos(volumeLimits[i]);
  289. int xi = (int)tr.X;
  290. if (xi < xMin) xMin = xi;
  291. if (xi > xMax) xMax = xi;
  292. int yi = (int)tr.Y;
  293. if (yi < yMin) yMin = yi;
  294. if (yi > yMax) yMax = yi;
  295. }
  296. xMin = (xMin < 0) ? 0 : xMin;
  297. xMax = (xMax >= bufferWidth) ? bufferWidth - 1 : xMax;
  298. yMin = (yMin < 0) ? 0 : yMin;
  299. yMax = (yMax >= bufferHeight) ? bufferHeight - 1 : yMax;
  300. int[] v = new int[3];
  301. v[2] = cutDist; // z
  302. for (int y = yMin; y < yMax; y++)
  303. {
  304. v[1] = y;
  305. int posOffset = y * bufferWidth;
  306. for (int x = xMin; x < xMax; x++)
  307. {
  308. v[0] = x;
  309. tr.invxyzPosf(v);
  310. double x_ = tr.x;
  311. double y_ = tr.y;
  312. double z_ = tr.z;
  313. if (x_ >= 0 && x_ < widthX && y_ >= 0 && y_ < heightY && z_ >= 0 && z_ < depthZ)
  314. {
  315. int val = 0xff & data3D[(int)z_][(int)y_][(int)x_];
  316. int pos = posOffset + x;
  317. int v_ = (cutDist * 20) + 128;
  318. v_ = Math.Min(Math.Max(0, v_), 255);
  319. v_ = (int)(0xFF000000 | (v_ << 8));
  320. bufferPixels[pos] = lut.colors[val];
  321. zbufferPixels[pos] = cutDist;
  322. }
  323. }
  324. }
  325. }
  326. private void volumeSliceTrilinear()
  327. {
  328. int xMin = bufferWidth - 1, xMax = 0, yMin = bufferHeight - 1, yMax = 0;
  329. for (int i = 0; i < 8; i++)
  330. {
  331. tr.xyzPos(volumeLimits[i]);
  332. int xi = (int)tr.X;
  333. if (xi < xMin) xMin = xi;
  334. if (xi > xMax) xMax = xi;
  335. int yi = (int)tr.Y;
  336. if (yi < yMin) yMin = yi;
  337. if (yi > yMax) yMax = yi;
  338. }
  339. xMin = (xMin < 0) ? 0 : xMin;
  340. xMax = (xMax >= bufferWidth) ? bufferWidth - 1 : xMax;
  341. yMin = (yMin < 0) ? 0 : yMin;
  342. yMax = (yMax >= bufferHeight) ? bufferHeight - 1 : yMax;
  343. int[] v = new int[3];
  344. // draw slice at dist
  345. v[2] = cutDist; // z
  346. for (int y = yMin; y <= yMax; y++)
  347. {
  348. v[1] = y;
  349. int posOffset = y * bufferWidth;
  350. for (int x = xMin; x <= xMax; x++)
  351. {
  352. v[0] = x;
  353. tr.invxyzPosf(v);
  354. double x_ = tr.x;
  355. double y_ = tr.y;
  356. double z_ = tr.z;
  357. if ((x_ >= 0 && x_ < widthX) && (y_ >= 0 && y_ < heightY) && (z_ >= 0 && z_ < depthZ))
  358. {
  359. int pos = posOffset + x;
  360. int val = trilinear(z_, y_, x_);
  361. bufferPixels[pos] = lut.colors[val];
  362. zbufferPixels[pos] = cutDist;
  363. }
  364. }
  365. }
  366. }
  367. private bool isInside(int x, int y)
  368. {
  369. int[] p = new int[3];
  370. p[0] = x;
  371. p[1] = y;
  372. if (Misc.inside(p, cornerT[0], cornerT[1], cornerT[4])) return true;
  373. if (Misc.inside(p, cornerT[0], cornerT[1], cornerT[5])) return true;
  374. if (Misc.inside(p, cornerT[2], cornerT[3], cornerT[6])) return true;
  375. if (Misc.inside(p, cornerT[2], cornerT[3], cornerT[7])) return true;
  376. if (Misc.inside(p, cornerT[1], cornerT[3], cornerT[5])) return true;
  377. if (Misc.inside(p, cornerT[1], cornerT[3], cornerT[7])) return true;
  378. if (Misc.inside(p, cornerT[0], cornerT[2], cornerT[4])) return true;
  379. if (Misc.inside(p, cornerT[0], cornerT[2], cornerT[6])) return true;
  380. if (Misc.inside(p, cornerT[1], cornerT[2], cornerT[4])) return true;
  381. if (Misc.inside(p, cornerT[1], cornerT[2], cornerT[7])) return true;
  382. if (Misc.inside(p, cornerT[0], cornerT[3], cornerT[5])) return true;
  383. if (Misc.inside(p, cornerT[0], cornerT[3], cornerT[6])) return true;
  384. return false;
  385. }
  386. [MethodImplAttribute(MethodImplOptions.Synchronized)]
  387. public void volumeProjection_trilinear_front()
  388. {
  389. double width = widthX - 0.5f;
  390. double height = heightY - 0.5f;
  391. double depth = depthZ - 0.5f;
  392. transformVolumeLimits();
  393. int xMin = bufferWidth - 1, xMax = 0;
  394. int yMin = bufferHeight - 1, yMax = 0;
  395. int zMin = cutDist, zMax = cutDist;
  396. for (int i = 0; i < 8; i++)
  397. {
  398. tr.xyzPos(volumeLimits[i]);
  399. int xi = (int)tr.X;
  400. if (xi < xMin) xMin = xi;
  401. if (xi > xMax) xMax = xi;
  402. int yi = (int)tr.Y;
  403. if (yi < yMin) yMin = yi;
  404. if (yi > yMax) yMax = yi;
  405. int zi = (int)tr.Z;
  406. if (zi < zMin) zMin = zi;
  407. if (zi > zMax) zMax = zi;
  408. }
  409. xMin = (xMin < 0) ? 0 : xMin;
  410. xMax = (xMax >= bufferWidth) ? bufferWidth - 1 : xMax;
  411. yMin = (yMin < 0) ? 0 : yMin;
  412. yMax = (yMax >= bufferHeight) ? bufferHeight - 1 : yMax;
  413. int[] v1 = new int[3];
  414. int[] v2 = new int[3];
  415. if (cutDist > zMin)
  416. zMin = cutDist;
  417. int nd = zMax - zMin;
  418. if (nd > 0)
  419. {
  420. float scaleLum = (renderDepth > 1) ? (renderDepth * 255 / ((renderDepth - 1) * 255f)) : 2; ;
  421. v1[2] = zMin;
  422. v2[2] = zMax;
  423. double nd1 = 1 / nd;
  424. double d_z = (zMax - zMin) * nd1;
  425. for (int y = yMin; y <= yMax; y++)
  426. {
  427. v1[1] = v2[1] = y;
  428. int percent = 100 * (y - yMin) / (yMax - yMin);
  429. for (int x = xMin; x <= xMax; x++)
  430. {
  431. if (isInside(x, y))
  432. {
  433. double z = zMin;
  434. int pos = y * bufferWidth + x;
  435. v1[0] = v2[0] = x;
  436. int alpha = 255;
  437. int V = 0;
  438. int alpha2 = 255;
  439. int V2 = 0;
  440. tr.invxyzPosf(v1);
  441. double xd1 = tr.x;
  442. double yd1 = tr.y;
  443. double zd1 = tr.z;
  444. tr.invxyzPosf(v2);
  445. double xd2 = tr.x;
  446. double yd2 = tr.y;
  447. double zd2 = tr.z;
  448. double dx = (xd2 - xd1) * nd1;
  449. double dy = (yd2 - yd1) * nd1;
  450. double dz = (zd2 - zd1) * nd1;
  451. int k = 0;
  452. for (int n = nd; n >= 0; n--)
  453. {
  454. z += d_z;
  455. if (xd1 >= 0 && xd1 < width &&
  456. yd1 >= 0 && yd1 < height &&
  457. zd1 >= 0 && zd1 < depth)
  458. {
  459. int val1 = trilinear(zd1, yd1, xd1);
  460. int f = 255 - 10 * Math.Abs(val1 - threshold);
  461. if (f < 0)
  462. f = 0;
  463. if (f > 10)
  464. {
  465. alpha += f;
  466. V += f * 255;
  467. if (++k >= renderDepth)
  468. break;
  469. }
  470. }
  471. xd1 += dx;
  472. yd1 += dy;
  473. zd1 += dz;
  474. }
  475. int val = (int)(scaleLum * V / alpha);
  476. if (val > 255)
  477. val = 255;
  478. int val2 = (int)(scaleLum * V2 / alpha2);
  479. if (val2 > 255)
  480. val2 = 255;
  481. bufferPixels[pos] = lut.colors[val];
  482. zbufferPixels[pos] = z;
  483. }
  484. }
  485. }
  486. }
  487. }
  488. private void volumeProjection_trilinear_back()
  489. {
  490. double width = widthX - 0.5f;
  491. double height = heightY - 0.5f;
  492. double depth = depthZ - 0.5f;
  493. transformVolumeLimits();
  494. int xMin = bufferWidth - 1, xMax = 0;
  495. int yMin = bufferHeight - 1, yMax = 0;
  496. int zMin = 10000, zMax = -10000;
  497. for (int i = 0; i < 8; i++)
  498. {
  499. tr.xyzPos(volumeLimits[i]);
  500. int xi = (int)tr.X;
  501. if (xi < xMin) xMin = xi;
  502. if (xi > xMax) xMax = xi;
  503. int yi = (int)tr.Y;
  504. if (yi < yMin) yMin = yi;
  505. if (yi > yMax) yMax = yi;
  506. int zi = (int)tr.Z;
  507. if (zi < zMin) zMin = zi;
  508. if (zi > zMax) zMax = zi;
  509. }
  510. xMin = (xMin < 0) ? 0 : xMin;
  511. xMax = (xMax >= bufferWidth) ? bufferWidth - 1 : xMax;
  512. yMin = (yMin < 0) ? 0 : yMin;
  513. yMax = (yMax >= bufferHeight) ? bufferHeight - 1 : yMax;
  514. xMin = (xMin < 0) ? 0 : xMin;
  515. xMax = (xMax > 511) ? 511 : xMax;
  516. yMin = (yMin < 0) ? 0 : yMin;
  517. yMax = (yMax > 511) ? 511 : yMax;
  518. int[] v1 = new int[3];
  519. int[] v2 = new int[3];
  520. if (cutDist < zMin)
  521. cutDist = zMin;
  522. int nd = zMax - cutDist;
  523. double dx, dy, dz;
  524. int[] vals = new int[zMax - cutDist];
  525. if (nd > 0)
  526. {
  527. v1[2] = cutDist;
  528. v2[2] = zMax;
  529. double nd1 = 1f / nd;
  530. for (int y = yMin; y <= yMax; y++)
  531. {
  532. v1[1] = v2[1] = y;
  533. int percent = 100 * (y - yMin) / (yMax - yMin);
  534. for (int x = xMin; x <= xMax; x++)
  535. {
  536. if (isInside(x, y))
  537. {
  538. int pos = y * bufferWidth + x;
  539. v1[0] = v2[0] = x;
  540. int V = 0;
  541. tr.invxyzPosf(v1);
  542. double x1 = tr.x;
  543. double y1 = tr.y;
  544. double z1 = tr.z;
  545. tr.invxyzPosf(v2);
  546. dx = (tr.x - x1) * nd1;
  547. dy = (tr.y - y1) * nd1;
  548. dz = (tr.z - z1) * nd1;
  549. int k = 0;
  550. for (int n = nd; n >= 0; n--)
  551. {
  552. if (x1 >= 0 && x1 < width &&
  553. y1 >= 0 && y1 < height &&
  554. z1 >= 0 && z1 < depth)
  555. {
  556. int val1 = trilinear(z1, y1, x1);
  557. if (val1 >= threshold)
  558. {
  559. vals[k++] = val1;
  560. if (k > renderDepth)
  561. break;
  562. }
  563. }
  564. x1 += dx;
  565. y1 += dy;
  566. z1 += dz;
  567. }
  568. for (int i = k - 1; i >= 0; i--)
  569. {
  570. int a = (vals[i] - threshold) + 50;
  571. if (a > 255)
  572. a = 255;
  573. V = (a * vals[i] + V * (255 - a)) / 255;
  574. }
  575. int val = V + 1;
  576. if (val > 255) val = 255;
  577. bufferPixels[pos] = lut.colors[val];
  578. zbufferPixels[pos] = (int)tr.z;
  579. }
  580. }
  581. }
  582. }
  583. }
  584. private void transformVolumeLimits()
  585. {
  586. for (int i = 0; i < 8; i++)
  587. {
  588. tr.xyzPos(volumeLimits[i]);
  589. cornerT[i][0] = (int)tr.X;
  590. cornerT[i][1] = (int)tr.Y;
  591. cornerT[i][2] = (int)tr.Z;
  592. }
  593. }
  594. private int trilinear(double z, double y, double x)
  595. {
  596. int tx = (int)x;
  597. double dx = x - tx;
  598. int tx1 = (tx < widthXm1) ? tx + 1 : tx;
  599. int ty = (int)y;
  600. double dy = y - ty;
  601. int ty1 = (ty < heightYm1) ? ty + 1 : ty;
  602. int tz = (int)z;
  603. double dz = z - tz;
  604. int tz1 = (tz < depthZm1) ? tz + 1 : tz;
  605. int v000 = (int)(0xff & data3D[tz][ty][tx]);
  606. int v001 = (int)(0xff & data3D[tz1][ty][tx]);
  607. int v010 = (int)(0xff & data3D[tz][ty1][tx]);
  608. int v011 = (int)(0xff & data3D[tz1][ty1][tx]);
  609. int v100 = (int)(0xff & data3D[tz][ty][tx1]);
  610. int v101 = (int)(0xff & data3D[tz1][ty][tx1]);
  611. int v110 = (int)(0xff & data3D[tz][ty1][tx1]);
  612. int v111 = (int)(0xff & data3D[tz1][ty1][tx1]);
  613. return (int)(
  614. (v100 - v000) * dx +
  615. (v010 - v000) * dy +
  616. (v001 - v000) * dz +
  617. (v110 - v100 - v010 + v000) * dx * dy +
  618. (v011 - v010 - v001 + v000) * dy * dz +
  619. (v101 - v100 - v001 + v000) * dx * dz +
  620. (v111 + v100 + v010 + v001 - v110 - v101 - v011 - v000) * dx * dy * dz + v000);
  621. }
  622. public int getWidth()
  623. {
  624. return widthX;
  625. }
  626. public int getHeight()
  627. {
  628. return heightY;
  629. }
  630. public double getZaspectRatio()
  631. {
  632. return zAspect;
  633. }
  634. public void setVolumeDrawMode(int volume_drawMode)
  635. {
  636. this.drawMode = volume_drawMode;
  637. }
  638. public void draw()
  639. {
  640. if (drawMode == JRenderer3D.VOLUME_DOTS)
  641. volumeDots();
  642. else if (drawMode == JRenderer3D.VOLUME_SLICE_NEAREST_NEIGHBOR)
  643. volumeSliceNearestNeighbor();
  644. else if (drawMode == JRenderer3D.VOLUME_SLICE_TRILINEAR)
  645. volumeSliceTrilinear();
  646. else if (drawMode == JRenderer3D.VOLUME_DOTS)
  647. volumeDots();
  648. else if (drawMode == JRenderer3D.VOLUME_PROJECTION_TRILINEAR_FRONT)
  649. volumeProjection_trilinear_front();
  650. }
  651. public void setVolumeThreshold(int volume_threshold)
  652. {
  653. this.threshold = volume_threshold;
  654. }
  655. public void setVolumeCutDist(int volume_cutDist)
  656. {
  657. this.cutDist = volume_cutDist;
  658. }
  659. public void setVolumeLut(int volume_lutNr)
  660. {
  661. if (lut != null)
  662. lut.setLut(volume_lutNr);
  663. }
  664. public void setVolumeDotsSubsampling(int volume_dotsDeltaX, int volume_dotsDeltaY, int volume_dotsDeltaZ)
  665. {
  666. this.dotsDeltaX = volume_dotsDeltaX;
  667. this.dotsDeltaY = volume_dotsDeltaY;
  668. this.dotsDeltaZ = volume_dotsDeltaZ;
  669. }
  670. }
  671. }