SurfacePlot.cs 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181
  1. using OpenCvSharp;
  2. using System;
  3. using System.Drawing;
  4. using System.Drawing.Imaging;
  5. using System.IO;
  6. namespace PaintDotNet.Data.SurfacePlot
  7. {
  8. class SurfacePlot
  9. {
  10. private int gridWidth = 256;
  11. private int gridHeight = 256;
  12. private SurfacePlotData[] plotList = null;
  13. //Bitmap image;
  14. private int[] bufferPixels;
  15. private double[] zbufferPixels;
  16. private int bufferWidth;
  17. private int bufferHeight;
  18. private int lutNr = JRenderer3D.LUT_ORIGINAL;
  19. public Lut lut;
  20. private Transform tr;
  21. private double light;
  22. private int surfacePlotMode;
  23. private double xCenter;
  24. private double yCenter;
  25. private double zCenter;
  26. private int min = 0;
  27. private int max = 100;
  28. private int inversefactor = 1;
  29. private int[] pixelsOrigColor;
  30. private int[] pixelsOrigLum;
  31. private int widthOrig;
  32. private int heightOrig;
  33. private int widthTex;
  34. private int heightTex;
  35. private int[] pixelsTexColor;
  36. //private byte[] maskPixels;
  37. public bool hasOtherLut = false;
  38. public void draw()
  39. {
  40. surfacePlotLines();
  41. /**
  42. if (surfacePlotMode == JRenderer3D.SURFACEPLOT_FILLED)
  43. surfacePlotFilled();
  44. else if (surfacePlotMode == JRenderer3D.SURFACEPLOT_ISOLINES)
  45. surfacePlotIsoLines();
  46. else if (surfacePlotMode == JRenderer3D.SURFACEPLOT_MESH)
  47. surfacePlotMesh();
  48. else if (surfacePlotMode == JRenderer3D.SURFACEPLOT_LINES)
  49. surfacePlotLines();
  50. else if (surfacePlotMode == JRenderer3D.SURFACEPLOT_DOTS)
  51. surfacePlotDots();
  52. else if (surfacePlotMode == JRenderer3D.SURFACEPLOT_DOTSNOLIGHT)
  53. surfacePlotDotsNoLight();
  54. **/
  55. }
  56. public unsafe void setSurfacePlotImage(Bitmap imp)
  57. {
  58. int widthTmp = imp.Width;
  59. int heightTmp = imp.Height;
  60. int[] pixelsTmp = new int[widthTmp * heightTmp];
  61. Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(imp);
  62. lut = new Lut();
  63. int kk = 0;
  64. for (int i = 0; i < mat.Rows; i++)
  65. {
  66. for (int j = 0; j < mat.Cols; j++)
  67. {
  68. pixelsTmp[kk] = mat.At<int>(i, j);
  69. kk++;
  70. }
  71. }
  72. bool isLut = false; //ip.isColorLut();
  73. if (isLut)
  74. {
  75. lut.readLut(imp);
  76. hasOtherLut = true;
  77. }
  78. byte[] lutPixels = null;
  79. int bitDepth = Image.GetPixelFormatSize(imp.PixelFormat); //Depth();
  80. if (isLut)
  81. {
  82. if (bitDepth == 8)
  83. {
  84. lutPixels = ToByteArray(imp);//.(byte[])ip.getPixels();
  85. }
  86. else
  87. {
  88. lutPixels = new byte[widthTmp * heightTmp];
  89. double min_ = 0; //ip.getMin();
  90. double max_ = 255; //ip.getMax();
  91. double a = 0, b = 1;
  92. /**
  93. Calibration cal = imp.getCalibration();
  94. if (cal != null)
  95. {
  96. if (cal.calibrated())
  97. {
  98. min_ = cal.getCValue((int)min_);
  99. max_ = cal.getCValue((int)max_);
  100. double[] coef = cal.getCoefficients();
  101. if (coef != null)
  102. {
  103. a = coef[0];
  104. b = coef[1];
  105. }
  106. }
  107. }
  108. **/
  109. float scale = (float)(255f / (max_ - min_));
  110. if (bitDepth == 16)
  111. {
  112. byte[] pixels = ToByteArray(imp);
  113. int pos = 0;
  114. for (int y = 0; y < heightTmp; y++)
  115. {
  116. for (int x = 0; x < widthTmp; x++)
  117. {
  118. int val = (int)((int)(0xFFFF & pixels[pos++]) * b + a - min_);
  119. if (val < 0f) val = 0;
  120. val = (int)(val * scale);
  121. if (val > 255) val = 255;
  122. lutPixels[y * widthTmp + x] = (byte)(val);
  123. }
  124. }
  125. }
  126. if (bitDepth == 32)
  127. {
  128. byte[] pixels = ToByteArray(imp);
  129. int pos = 0;
  130. for (int y = 0; y < heightTmp; y++)
  131. {
  132. for (int x = 0; x < widthTmp; x++)
  133. {
  134. // float value = (float) (pixels[pos++] - min);
  135. float value = (float)(pixels[pos++] - min_); // LL ==============
  136. if (value < 0f) value = 0f;
  137. int ivalue = (int)(value * scale);
  138. if (ivalue > 255) ivalue = 255;
  139. lutPixels[y * widthTmp + x] = (byte)(ivalue);
  140. }
  141. }
  142. }
  143. }
  144. }
  145. Mat roi = null;//.getRoi();
  146. if (roi != null)
  147. {
  148. /**
  149. ImageProcessor mask = roi.getMask();
  150. ImageProcessor ipMask;
  151. maskPixels = null;
  152. if (mask != null)
  153. {
  154. ipMask = mask.duplicate();
  155. maskPixels = (byte[])ipMask.getPixels();
  156. }
  157. Rectangle rect = new Rectangle(); //roi.getBounds();
  158. if (rect.X < 0)
  159. rect.X = 0;
  160. if (rect.Y < 0)
  161. rect.Y = 0;
  162. widthOrig = rect.Width;
  163. heightOrig = rect.Height;
  164. pixelsOrigColor = new int[widthOrig * heightOrig];
  165. pixelsOrigLum = new int[widthOrig * heightOrig];
  166. for (int j = 0, y = rect.Y; y < rect.Y + rect.Height; y++)
  167. {
  168. int offset = y * widthTmp;
  169. for (int x = rect.X; x < rect.X + rect.Width; x++, j++)
  170. {
  171. int i = offset + x;
  172. int c = pixelsOrigColor[j] = pixelsTmp[i];
  173. int lum;
  174. if (!isLut)
  175. {
  176. int r = ((c >> 16) & 255);
  177. int g = ((c >> 8) & 255);
  178. int b = ((c) & 255);
  179. lum = (int)(0.299 * r + 0.587 * g + 0.114 * b);
  180. }
  181. else
  182. lum = (int)(0xFF & lutPixels[i]);
  183. pixelsOrigLum[j] = lum;
  184. }
  185. }**/
  186. }
  187. else
  188. {
  189. widthOrig = widthTmp;
  190. heightOrig = heightTmp;
  191. pixelsOrigColor = new int[widthOrig * heightOrig];
  192. pixelsOrigLum = new int[widthOrig * heightOrig];
  193. for (int y = 0; y < heightTmp; y++)
  194. {
  195. for (int x = 0; x < widthTmp; x++)
  196. {
  197. int pos = y * widthTmp + x;
  198. int c = pixelsOrigColor[pos] = pixelsTmp[pos];
  199. int lum;
  200. int r = ((c >> 16) & 255);
  201. int g = ((c >> 8) & 255);
  202. int b = ((c) & 255);
  203. if (!isLut)
  204. {
  205. lum = (int)Math.Round(0.299 * r + 0.587 * g + 0.114 * b);
  206. }
  207. else
  208. {
  209. lum = lutPixels[pos]; //(int)(0xFF & lutPixels[pos]);
  210. }
  211. pixelsOrigLum[pos] = lum;
  212. }
  213. }
  214. }
  215. }
  216. public void setSurfacePlotTextureImage(Bitmap imp)
  217. {
  218. widthTex = imp.Width;
  219. heightTex = imp.Height;
  220. pixelsTexColor = new int[widthTex * heightTex];
  221. /**
  222. image = imp;
  223. int kk = 0;
  224. for (int i = 0; i < image.Width; i++)
  225. {
  226. for (int j = 0; j < image.Height; j++)
  227. {
  228. pixelsTexColor[kk] = image.GetPixel(i, j).ToArgb();
  229. kk++;
  230. }
  231. }
  232. **/
  233. /**
  234. PixelGrabber pg = new PixelGrabber(image, 0, 0, widthTex, heightTex, pixelsTexColor, 0, widthTex);
  235. try
  236. {
  237. pg.grabPixels();
  238. }
  239. catch (Exception ex)
  240. {
  241. //---IJ.error("error grabbing pixels");
  242. pixelsTexColor = null;
  243. }
  244. **/
  245. }
  246. public void resample()
  247. {
  248. plotList = new SurfacePlotData[gridWidth * gridHeight];
  249. if (pixelsOrigColor != null && pixelsOrigLum != null)
  250. {
  251. double xOffset = xCenter;
  252. double yOffset = yCenter;
  253. double sx = widthOrig / (double)gridWidth;
  254. double sy = heightOrig / (double)gridHeight;
  255. for (int y = 0; y < gridHeight; y++)
  256. {
  257. int yB = (int)(y * sy);
  258. for (int x = 0; x < gridWidth; x++)
  259. {
  260. int posGrid = y * gridWidth + x;
  261. int xB = (int)(x * sx);
  262. int posOrig = yB * widthOrig + xB;
  263. plotList[posGrid] = new SurfacePlotData();
  264. plotList[posGrid].color = pixelsOrigColor[posOrig];
  265. plotList[posGrid].x = sx * (x + 0.5) - xOffset;
  266. plotList[posGrid].y = sy * (y + 0.5) - yOffset;
  267. plotList[posGrid].z = plotList[posGrid].zf = plotList[posGrid].lum =
  268. pixelsOrigLum[posOrig] - zCenter;
  269. /**
  270. if (maskPixels != null)
  271. {
  272. if (maskPixels[posOrig] != 0)
  273. plotList[posGrid].isVisible = true;
  274. else
  275. plotList[posGrid].isVisible = false;
  276. }
  277. else**/
  278. plotList[posGrid].isVisible = true;
  279. }
  280. }
  281. }
  282. if (pixelsTexColor != null)
  283. {
  284. double sx = widthTex / (double)gridWidth;
  285. double sy = heightTex / (double)gridHeight;
  286. for (int y = 0; y < gridHeight; y++)
  287. {
  288. int yB = (int)(y * sy);
  289. for (int x = 0; x < gridWidth; x++)
  290. {
  291. int pos = y * gridWidth + x;
  292. int xB = (int)(x * sx);
  293. plotList[pos].color = pixelsTexColor[yB * widthTex + xB];
  294. }
  295. }
  296. }
  297. computeNormals();
  298. }
  299. private void computeNormals()
  300. {
  301. for (int y = 0; y < gridHeight; y++)
  302. {
  303. for (int x = 0; x < gridWidth; x++)
  304. {
  305. int i = y * gridWidth + x;
  306. double dx1 = 0;
  307. double dy1 = 0;
  308. double dz1 = 0;
  309. for (int y_ = -1; y_ <= 1; y_++)
  310. {
  311. int yn = y + y_;
  312. if (yn < 0) yn = 0;
  313. if (yn >= gridHeight) yn = gridHeight - 1;
  314. for (int x_ = -1; x_ < 1; x_++)
  315. {
  316. int xn = x + x_;
  317. if (xn < 0) xn = 0;
  318. if (xn >= gridWidth) xn = gridWidth - 1;
  319. int xn1 = xn + 1;
  320. if (xn1 < 0) xn1 = 0;
  321. if (xn1 >= gridWidth) xn1 = gridWidth - 1;
  322. int posn = yn * gridWidth + xn;
  323. int posn1 = yn * gridWidth + xn1;
  324. dx1 += plotList[posn1].x - plotList[posn].x;
  325. dz1 += plotList[posn1].z - plotList[posn].z;
  326. }
  327. }
  328. double dx2 = 0;
  329. double dy2 = 0;
  330. double dz2 = 0;
  331. for (int y_ = -1; y_ < 1; y_++)
  332. {
  333. int yn = y + y_;
  334. if (yn < 0) yn = 0;
  335. if (yn >= gridHeight) yn = gridHeight - 1;
  336. int yn1 = yn + 1;
  337. if (yn1 < 0) yn1 = 0;
  338. if (yn1 >= gridHeight) yn1 = gridHeight - 1;
  339. for (int x_ = -1; x_ <= 1; x_++)
  340. {
  341. int xn = x + x_;
  342. if (xn < 0) xn = 0;
  343. if (xn >= gridWidth) xn = gridWidth - 1;
  344. int posn = yn * gridWidth + xn;
  345. int posn1 = yn1 * gridWidth + xn;
  346. dy2 += plotList[posn1].y - plotList[posn].y;
  347. dz2 += plotList[posn1].z - plotList[posn].z;
  348. }
  349. }
  350. // outer product
  351. double dx = (dy1 * dz2 - dz1 * dy2);
  352. double dy = (dz1 * dx2 - dx1 * dz2);
  353. double dz = (dx1 * dy2 - dy1 * dx2);
  354. double len = Math.Sqrt(dx * dx + dy * dy + dz * dz);
  355. plotList[i].dx = dx / len;
  356. plotList[i].dy = dy / len;
  357. plotList[i].dz = dz / len;
  358. }
  359. }
  360. }
  361. public void applyMinMax()
  362. {
  363. //System.out.println("applyMinMax inverseFactor: " + inversefactor);
  364. int add = 0;
  365. if (inversefactor == -1)
  366. add = -1;
  367. for (int i = 0; i < gridHeight * gridWidth; i++)
  368. {
  369. double val = (100 * (plotList[i].zf + zCenter - 2.55 * (min)) / (max - min) - zCenter);
  370. plotList[i].z = inversefactor * Math.Min(Math.Max(-128, val), 127) + add;
  371. }
  372. computeNormals();
  373. }
  374. public void applySmoothingFilter(double rad)
  375. {
  376. float[] pixels = new float[gridHeight * gridWidth];
  377. for (int i = 0; i < gridHeight * gridWidth; i++)
  378. {
  379. pixels[i] = (float)plotList[i].lum;
  380. }
  381. /**
  382. ImageProcessor ip = new FloatProcessor(gridWidth, gridHeight, pixels, null);
  383. new GaussianBlur().blur(ip, rad);
  384. pixels = (float[])ip.getPixels();
  385. for (int i = 0; i < gridHeight * gridWidth; i++)
  386. {
  387. plotList[i].z = plotList[i].zf = pixels[i];
  388. }
  389. applyMinMax();
  390. **/
  391. }
  392. public static byte[] ToByteArray(Bitmap bmp)
  393. {
  394. MemoryStream ms = new MemoryStream();
  395. bmp.Save(ms, ImageFormat.Jpeg);
  396. ms.Seek(0, SeekOrigin.Begin); //一定不要忘记将流的初始位置重置
  397. //byte[] bytes = new byte[ms.Length];
  398. byte[] bytes = new byte[bmp.Height * bmp.Width];
  399. ms.Read(bytes, 0, bytes.Length); //如果上面流没有seek 则这里读取的数据全会为0
  400. ms.Dispose();
  401. return bytes;
  402. }
  403. /**************************************************************************************
  404. *
  405. * Drawing Routines
  406. *
  407. **************************************************************************************/
  408. private int getColor(SurfacePlotData p0)
  409. {
  410. int c0 = p0.color;
  411. /**
  412. if (lutNr == JRenderer3D.LUT_ORIGINAL)
  413. {
  414. c0 = p0.color;
  415. }
  416. else if (lutNr == JRenderer3D.LUT_GRADIENT)
  417. {
  418. c0 = ((int)(p0.dx * 127 + 127) << 16) | ((int)(p0.dy * 127 + 127) << 8) | (int)(p0.dz * 127 + 127);
  419. }
  420. else if (lutNr == JRenderer3D.LUT_GRADIENT2)
  421. {
  422. c0 = ((int)(p0.dx2 * 127 + 127) << 16) | ((int)(p0.dy2 * 127 + 127) << 8) | (int)(0);
  423. }
  424. else
  425. {
  426. int index = (int)(p0.z + 128);
  427. if (index > 255)
  428. index = 255;
  429. if (index < 0)
  430. index = 0;
  431. c0 = lut.colors[index];
  432. }
  433. **/
  434. return c0;
  435. }
  436. private void surfacePlotFilled()
  437. {
  438. for (int row = 0; row < gridHeight - 1; row++)
  439. {
  440. for (int col = 0; col < gridWidth - 1; col++)
  441. {
  442. int i = row * gridWidth + col;
  443. SurfacePlotData p0 = plotList[i];
  444. if (p0.isVisible)
  445. {
  446. SurfacePlotData p1 = plotList[i + 1];
  447. SurfacePlotData p2 = plotList[i + gridWidth];
  448. SurfacePlotData p3 = plotList[i + gridWidth + 1];
  449. if (p1.isVisible && p2.isVisible && p3.isVisible)
  450. {
  451. tr.transform(p0);
  452. double x0 = tr.X, y0 = tr.Y, z0 = tr.Z;
  453. tr.x = p0.dx;
  454. tr.y = p0.dy;
  455. double light0 = tr.getScalarProduct();
  456. tr.transform(p1);
  457. double x1 = tr.X, y1 = tr.Y, z1 = tr.Z;
  458. tr.x = p1.dx;
  459. tr.y = p1.dy;
  460. double light1 = tr.getScalarProduct();
  461. tr.transform(p2);
  462. double x2 = tr.X, y2 = tr.Y, z2 = tr.Z;
  463. tr.x = p2.dx;
  464. tr.y = p2.dy;
  465. double light2 = tr.getScalarProduct();
  466. tr.transform(p3);
  467. double x3 = tr.X, y3 = tr.Y, z3 = tr.Z;
  468. tr.x = p3.dx;
  469. tr.y = p3.dy;
  470. double light3 = tr.getScalarProduct();
  471. if (!(x0 >= bufferWidth && x0 < 0 && y0 >= bufferHeight && y0 < 0 &&
  472. x1 >= bufferWidth && x1 < 0 && y1 >= bufferHeight && y1 < 0 &&
  473. x2 >= bufferWidth && x2 < 0 && y2 >= bufferHeight && y2 < 0 &&
  474. x3 >= bufferWidth && x3 < 0 && y3 >= bufferHeight && y3 < 0))
  475. {
  476. int c0 = getColor(p0);
  477. int c1 = getColor(p1);
  478. int c2 = getColor(p2);
  479. int c3 = getColor(p3);
  480. int r0 = ((c0 >> 16) & 0xff);
  481. int g0 = ((c0 >> 8) & 0xff);
  482. int b0 = ((c0) & 0xff);
  483. int r1 = ((c1 >> 16) & 0xff);
  484. int g1 = ((c1 >> 8) & 0xff);
  485. int b1 = ((c1) & 0xff);
  486. int r2 = ((c2 >> 16) & 0xff);
  487. int g2 = ((c2 >> 8) & 0xff);
  488. int b2 = ((c2) & 0xff);
  489. int r3 = ((c3 >> 16) & 0xff);
  490. int g3 = ((c3 >> 8) & 0xff);
  491. int b3 = ((c3) & 0xff);
  492. double n13 = Math.Abs(y1 - y3) + Math.Abs(x1 - x3);
  493. double n02 = Math.Abs(y0 - y2) + Math.Abs(x0 - x2);
  494. // double n13 = Math.sqrt((y1-y3)*(y1-y3) + (x1-x3)*(x1-x3));
  495. // double n02 = Math.sqrt((y0-y2)*(y0-y2) + (x0-x2)*(x0-x2));
  496. int stepsY = (int)(Math.Max(n13, n02) + 1);
  497. double dy = 1 / stepsY;
  498. double dx02 = (x2 - x0) * dy;
  499. double dy02 = (y2 - y0) * dy;
  500. double dx13 = (x3 - x1) * dy;
  501. double dy13 = (y3 - y1) * dy;
  502. double x02 = x0;
  503. double y02 = y0;
  504. double x13 = x1;
  505. double y13 = y1;
  506. double v = 0;
  507. for (int sy = 0; sy < stepsY; sy++, v += dy)
  508. {
  509. x02 += dx02;
  510. y02 += dy02;
  511. x13 += dx13;
  512. y13 += dy13;
  513. //int stepsX = (int) (Math.abs(x02-x13) + Math.abs(y02-y13) + 1);
  514. int stepsX = (int)(Math.Abs(x02 - x13) + Math.Abs(y02 - y13) + 1);
  515. double dx = 1 / stepsX;
  516. double dx0213 = (x13 - x02) * dx;
  517. double dy0213 = (y13 - y02) * dx;
  518. double x0213 = x02;
  519. double y0213 = y02;
  520. double h = 0;
  521. for (int sx = 0; sx < stepsX; sx++, h += dx)
  522. {
  523. x0213 += dx0213;
  524. y0213 += dy0213;
  525. if (x0213 >= 0 && x0213 < bufferWidth && y0213 >= 0 && y0213 < bufferHeight)
  526. {
  527. double d0 = (1 - h) * (1 - v);
  528. double d1 = h * (1 - v);
  529. double d2 = (1 - h) * v;
  530. double d3 = h * v;
  531. double z = d0 * z0 + d1 * z1 + d2 * z2 + d3 * z3;
  532. // System.out.println("x: " + (int)x0213 + " y: " + (int)y0213);
  533. int pos = (int)y0213 * bufferWidth + (int)x0213;
  534. if (z < zbufferPixels[pos])
  535. {
  536. zbufferPixels[pos] = z;
  537. int r = (int)(r3 * d3 + r2 * d2 + r1 * d1 + r0 * d0);
  538. int g = (int)(g3 * d3 + g2 * d2 + g1 * d1 + g0 * d0);
  539. int b = (int)(b3 * d3 + b2 * d2 + b1 * d1 + b0 * d0);
  540. double light0123 = d3 * light3 + d2 * light2 + d1 * light1 + d0 * light0;
  541. double l = -light * light0123 * 255;
  542. r = (int)Math.Min(255, Math.Max(0, r + l));
  543. g = (int)Math.Min(255, Math.Max(0, g + l));
  544. b = (int)Math.Min(255, Math.Max(0, b + l));
  545. uint temp = (uint)(0xff000000 | (uint)(r << 16) | (uint)(g << 8) | (uint)b);
  546. bufferPixels[pos] = (int)temp;//(0xff000000 | (r << 16) | (g << 8) | b);
  547. }
  548. }
  549. }
  550. }
  551. }
  552. }
  553. }
  554. }
  555. }
  556. }
  557. private void surfacePlotIsoLines()
  558. {
  559. for (int row = 0; row < gridHeight - 1; row++)
  560. {
  561. for (int col = 0; col < gridWidth - 1; col++)
  562. {
  563. int i = row * gridWidth + col;
  564. SurfacePlotData p0 = plotList[i];
  565. if (p0.isVisible)
  566. {
  567. SurfacePlotData p1 = plotList[i + 1];
  568. SurfacePlotData p2 = plotList[i + gridWidth];
  569. SurfacePlotData p3 = plotList[i + gridWidth + 1];
  570. if ((p1.isVisible) && (p2.isVisible) && (p3.isVisible))
  571. {
  572. tr.transform(p0);
  573. double x0 = tr.X, y0 = tr.Y, z0 = tr.Z;
  574. tr.x = p0.dx;
  575. tr.y = p0.dy;
  576. double light0 = tr.getScalarProduct();
  577. tr.transform(p1);
  578. double x1 = tr.X, y1 = tr.Y, z1 = tr.Z;
  579. tr.x = p1.dx;
  580. tr.y = p1.dy;
  581. double light1 = tr.getScalarProduct();
  582. tr.transform(p2);
  583. double x2 = tr.X, y2 = tr.Y, z2 = tr.Z;
  584. tr.x = p2.dx;
  585. tr.y = p2.dy;
  586. double light2 = tr.getScalarProduct();
  587. tr.transform(p3);
  588. double x3 = tr.X, y3 = tr.Y, z3 = tr.Z;
  589. tr.x = p3.dx;
  590. tr.y = p3.dy;
  591. double light3 = tr.getScalarProduct();
  592. if (!(x0 >= bufferWidth && x0 < 0 && y0 >= bufferHeight && y0 < 0 &&
  593. x1 >= bufferWidth && x1 < 0 && y1 >= bufferHeight && y1 < 0 &&
  594. x2 >= bufferWidth && x2 < 0 && y2 >= bufferHeight && y2 < 0 &&
  595. x3 >= bufferWidth && x3 < 0 && y3 >= bufferHeight && y3 < 0))
  596. {
  597. int c0 = getColor(p0);
  598. int c1 = getColor(p1);
  599. int c2 = getColor(p2);
  600. int c3 = getColor(p3);
  601. double lum0 = p0.z;
  602. double lum1 = p1.z;
  603. double lum2 = p2.z;
  604. double lum3 = p3.z;
  605. int r0 = ((c0 >> 16) & 0xff);
  606. int g0 = ((c0 >> 8) & 0xff);
  607. int b0 = ((c0) & 0xff);
  608. int r1 = ((c1 >> 16) & 0xff);
  609. int g1 = ((c1 >> 8) & 0xff);
  610. int b1 = ((c1) & 0xff);
  611. int r2 = ((c2 >> 16) & 0xff);
  612. int g2 = ((c2 >> 8) & 0xff);
  613. int b2 = ((c2) & 0xff);
  614. int r3 = ((c3 >> 16) & 0xff);
  615. int g3 = ((c3 >> 8) & 0xff);
  616. int b3 = ((c3) & 0xff);
  617. double n13 = Math.Abs(x1 - x3) + Math.Abs(y1 - y3);
  618. double n02 = Math.Abs(x0 - x2) + Math.Abs(y0 - y2);
  619. int stepsY = (int)(Math.Max(n13, n02) + 1);
  620. double dy = 1 / stepsY;
  621. double dx02 = (x2 - x0) * dy;
  622. double dy02 = (y2 - y0) * dy;
  623. double dx13 = (x3 - x1) * dy;
  624. double dy13 = (y3 - y1) * dy;
  625. double x02 = x0;
  626. double y02 = y0;
  627. double x13 = x1;
  628. double y13 = y1;
  629. double v = 0;
  630. for (int sy = 0; sy < stepsY; sy++, v += dy)
  631. {
  632. x02 += dx02;
  633. y02 += dy02;
  634. x13 += dx13;
  635. y13 += dy13;
  636. int stepsX = (int)(Math.Abs(x02 - x13) + Math.Abs(y02 - y13) + 1);
  637. double dx = 1 / stepsX;
  638. double dx0213 = (x13 - x02) * dx;
  639. double dy0213 = (y13 - y02) * dx;
  640. double x0213 = x02;
  641. double y0213 = y02;
  642. double h = 0;
  643. for (int sx = 0; sx < stepsX; sx++, h += dx)
  644. {
  645. x0213 += dx0213;
  646. y0213 += dy0213;
  647. double d0 = (1 - h) * (1 - v);
  648. double d1 = h * (1 - v);
  649. double d2 = (1 - h) * v;
  650. double d3 = h * v;
  651. double z = d0 * z0 + d1 * z1 + d2 * z2 + d3 * z3;
  652. if (x0213 >= 0 && x0213 < bufferWidth && y0213 >= 0 && y0213 < bufferHeight)
  653. {
  654. int pos = (int)y0213 * bufferWidth + (int)x0213;
  655. if (z < zbufferPixels[pos])
  656. {
  657. double lum = d0 * lum0 + d1 * lum1 + d2 * lum2 + d3 * lum3 + 132;
  658. if (lum - 12 * (int)(lum / 12) < 1.5)
  659. {
  660. zbufferPixels[pos] = z;
  661. int r = (int)(r3 * d3 + r2 * d2 + r1 * d1 + r0 * d0);
  662. int g = (int)(g3 * d3 + g2 * d2 + g1 * d1 + g0 * d0);
  663. int b = (int)(b3 * d3 + b2 * d2 + b1 * d1 + b0 * d0);
  664. double light0123 = d3 * light3 + d2 * light2 + d1 * light1 + d0 * light0;
  665. double l = -light * light0123 * 255;
  666. r = (int)Math.Min(255, Math.Max(0, r + l));
  667. g = (int)Math.Min(255, Math.Max(0, g + l));
  668. b = (int)Math.Min(255, Math.Max(0, b + l));
  669. //uint temp = (uint)(0xff000000 | (uint)(r << 16) | (uint)(g << 8) | (uint)b);
  670. bufferPixels[pos] = (int)(((uint)r << 16) | (ushort)(((ushort)g << 8) | b));
  671. //bufferPixels[pos] = (int)temp;// (0xff000000 | (r << 16) | (g << 8) | b);
  672. }
  673. }
  674. }
  675. }
  676. }
  677. }
  678. }
  679. }
  680. }
  681. }
  682. }
  683. private void surfacePlotMesh()
  684. {
  685. for (int row = 0; row < gridHeight; row++)
  686. {
  687. for (int col = 0; col < gridWidth; col++)
  688. {
  689. int i = row * gridWidth + col;
  690. SurfacePlotData p0 = plotList[i];
  691. int r0, g0, b0, r1, g1, b1, r2, g2, b2;
  692. if (p0.isVisible)
  693. {
  694. tr.transform(p0);
  695. double x0 = tr.X, y0 = tr.Y, z0 = tr.Z;
  696. int c0 = getColor(p0);
  697. r0 = ((c0 >> 16) & 0xff);
  698. g0 = ((c0 >> 8) & 0xff);
  699. b0 = ((c0) & 0xff);
  700. SurfacePlotData p1 = (col < gridWidth - 1) ? plotList[i + 1] : plotList[i];
  701. if (p1.isVisible)
  702. {
  703. tr.transform(p1);
  704. double x1 = tr.X, y1 = tr.Y, z1 = tr.Z;
  705. double dx10 = x1 - x0, dy10 = y1 - y0, dz10 = z1 - z0;
  706. int c1 = getColor(p1);
  707. r1 = ((c1 >> 16) & 0xff);
  708. g1 = ((c1 >> 8) & 0xff);
  709. b1 = ((c1) & 0xff);
  710. int numSteps = (int)(Math.Max(Math.Abs(dx10), Math.Abs(dy10)) + 1);
  711. double step = 1 / numSteps;
  712. for (int s = 0; s < numSteps; s++)
  713. {
  714. double f = s * step;
  715. int x = (int)(x0 + f * dx10);
  716. int y = (int)(y0 + f * dy10);
  717. if (x >= 0 && y >= 0 && x < bufferWidth && y < bufferHeight)
  718. {
  719. int pos = y * bufferWidth + x;
  720. int z = (int)(z0 + f * dz10);
  721. if (z < zbufferPixels[pos])
  722. {
  723. zbufferPixels[pos] = z;
  724. int r = (int)(f * r1 + (1 - f) * r0);
  725. int g = (int)(f * g1 + (1 - f) * g0);
  726. int b = (int)(f * b1 + (1 - f) * b0);
  727. tr.x = p0.dx;
  728. tr.y = p0.dy;
  729. double l = -light * tr.getScalarProduct() * 255;
  730. r = (int)Math.Min(255, Math.Max(0, r + l));
  731. g = (int)Math.Min(255, Math.Max(0, g + l));
  732. b = (int)Math.Min(255, Math.Max(0, b + l));
  733. bufferPixels[pos] = (int)(((uint)r << 16) | (ushort)(((ushort)g << 8) | b));
  734. //uint temp = (uint)(0xff000000 | (uint)(r << 16) | (uint)(g << 8) | (uint)b);
  735. //bufferPixels[pos] = (int)temp; //(int)(0xff000000 | (r << 16) | (g << 8) | b);
  736. }
  737. }
  738. }
  739. }
  740. SurfacePlotData p2 = (row < gridHeight - 1) ? plotList[i + gridWidth] : plotList[i];
  741. if (p2.isVisible)
  742. {
  743. tr.transform(p2);
  744. double x2 = tr.X, y2 = tr.Y, z2 = tr.Z;
  745. double dx20 = x2 - x0, dy20 = y2 - y0, dz20 = z2 - z0;
  746. int c2 = getColor(p2);
  747. r2 = ((c2 >> 16) & 0xff);
  748. g2 = ((c2 >> 8) & 0xff);
  749. b2 = ((c2) & 0xff);
  750. int numSteps = (int)(Math.Max(Math.Abs(dx20), Math.Abs(dy20)) + 1);
  751. double step = 1 / numSteps;
  752. for (int s = 0; s < numSteps; s++)
  753. {
  754. double f = s * step;
  755. int x = (int)(x0 + f * dx20);
  756. int y = (int)(y0 + f * dy20);
  757. if (x >= 0 && y >= 0 && x < bufferWidth && y < bufferHeight)
  758. {
  759. int pos = y * bufferWidth + x;
  760. int z = (int)(z0 + f * dz20);
  761. if (z < zbufferPixels[pos])
  762. {
  763. zbufferPixels[pos] = z;
  764. int r = (int)(f * r2 + (1 - f) * r0);
  765. int g = (int)(f * g2 + (1 - f) * g0);
  766. int b = (int)(f * b2 + (1 - f) * b0);
  767. tr.x = p0.dx;
  768. tr.y = p0.dy;
  769. double l = -light * tr.getScalarProduct() * 255;
  770. r = (int)Math.Min(255, Math.Max(0, r + l));
  771. g = (int)Math.Min(255, Math.Max(0, g + l));
  772. b = (int)Math.Min(255, Math.Max(0, b + l));
  773. bufferPixels[pos] = (int)(((uint)r << 16) | (ushort)(((ushort)g << 8) | b));
  774. /**
  775. uint temp = (uint)(0xff000000 | (uint)(r << 16) | (uint)(g << 8) | (uint)b);
  776. bufferPixels[pos] = (int)(temp);
  777. **/
  778. }
  779. }
  780. }
  781. }
  782. }
  783. }
  784. }
  785. }
  786. private void surfacePlotLines()
  787. {
  788. for (int row = 0; row < gridHeight; row++)
  789. {
  790. for (int col = 0; col < gridWidth - 1; col++)
  791. {
  792. int i = row * gridWidth + col;
  793. SurfacePlotData p0 = plotList[i];
  794. SurfacePlotData p1 = plotList[i + 1];
  795. if (p0.isVisible && p1.isVisible)
  796. {
  797. tr.transform(p0);
  798. double x0 = tr.X, y0 = tr.Y, z0 = tr.Z;
  799. int c0 = getColor(p0);
  800. int r0 = ((c0 >> 16) & 0xff);
  801. int g0 = ((c0 >> 8) & 0xff);
  802. int b0 = ((c0) & 0xff);
  803. tr.transform(p1);
  804. double x1 = tr.X, y1 = tr.Y, z1 = tr.Z;
  805. double dx1 = x1 - x0, dy1 = y1 - y0, dz1 = z1 - z0;
  806. int numSteps = (int)(Math.Max(Math.Abs(dx1), Math.Abs(dy1)) + 1);
  807. int c1 = getColor(p1);
  808. int r1 = ((c1 >> 16) & 0xff);
  809. int g1 = ((c1 >> 8) & 0xff);
  810. int b1 = ((c1) & 0xff);
  811. double step = 1 / numSteps;
  812. int r, g, b;
  813. for (int s = 0; s < numSteps; s++)
  814. {
  815. double f = s * step;
  816. int x = (int)(x0 + f * dx1);
  817. int y = (int)(y0 + f * dy1);
  818. if (x >= 0 && y >= 0 && x < bufferWidth && y < bufferHeight)
  819. {
  820. int pos = y * bufferWidth + x;
  821. double z = z0 + f * dz1;
  822. if (z < zbufferPixels[pos])
  823. {
  824. zbufferPixels[pos] = z;
  825. r = (int)((1 - f) * r0 + f * r1);
  826. g = (int)((1 - f) * g0 + f * g1);
  827. b = (int)((1 - f) * b0 + f * b1);
  828. tr.x = p0.dx;
  829. tr.y = p0.dy;
  830. double l = -light * tr.getScalarProduct() * 255;
  831. r = (int)Math.Min(255, Math.Max(0, r + l));
  832. g = (int)Math.Min(255, Math.Max(0, g + l));
  833. b = (int)Math.Min(255, Math.Max(0, b + l));
  834. bufferPixels[pos] = (int)(((uint)r << 16) | (ushort)(((ushort)g << 8) | b));
  835. /*
  836. long lv = (0xff000000 | (r << 16) | (g << 8) | b);
  837. if (lv > int.MaxValue)
  838. {
  839. bufferPixels[pos] = int.MaxValue;
  840. }
  841. else {
  842. bufferPixels[pos] = (int)lv;
  843. }**/
  844. }
  845. }
  846. }
  847. }
  848. }
  849. }
  850. }
  851. private void surfacePlotDots()
  852. {
  853. for (int i = plotList.Length - 1; i >= 0; i--)
  854. {
  855. SurfacePlotData p0 = plotList[i];
  856. if (p0.isVisible)
  857. {
  858. tr.transform(p0);
  859. int x = (int)tr.X, y = (int)tr.Y;
  860. if (x >= 0 && y >= 0 && x < bufferWidth && y < bufferHeight)
  861. {
  862. int pos = y * bufferWidth + x;
  863. int z = (int)tr.Z;
  864. if (z < zbufferPixels[pos])
  865. {
  866. zbufferPixels[pos] = z;
  867. int c0 = getColor(p0);
  868. int r0 = ((c0 >> 16) & 0xff);
  869. int g0 = ((c0 >> 8) & 0xff);
  870. int b0 = ((c0) & 0xff);
  871. tr.x = p0.dx;
  872. tr.y = p0.dy;
  873. double l = -light * tr.getScalarProduct() * 255;
  874. int r = (int)Math.Min(255, Math.Max(0, r0 + l));
  875. int g = (int)Math.Min(255, Math.Max(0, g0 + l));
  876. int b = (int)Math.Min(255, Math.Max(0, b0 + l));
  877. uint temp = (uint)(0xff000000 | (uint)(r << 16) | (uint)(g << 8) | (uint)b);
  878. bufferPixels[pos] = (int)temp; //(int)(0xff000000 | (r << 16) | (g << 8) | b);
  879. }
  880. }
  881. }
  882. }
  883. }
  884. public void surfacePlotDotsNoLight()
  885. {
  886. int delta = Math.Max(gridHeight, gridWidth) / 128;
  887. if (delta < 1)
  888. delta = 1;
  889. for (int row = 0; row < gridHeight; row += delta)
  890. {
  891. for (int col = 0; col < gridWidth; col += delta)
  892. {
  893. int i = row * gridWidth + col;
  894. SurfacePlotData p0 = plotList[i];
  895. if (p0.isVisible)
  896. {
  897. tr.transform(p0);
  898. int x = (int)tr.X;
  899. int y = (int)tr.Y;
  900. if (x >= 0 && y >= 0 && x < bufferWidth - 1 && y < bufferHeight - 1)
  901. {
  902. int pos = y * bufferWidth + x;
  903. int z = (int)tr.Z;
  904. if (z < zbufferPixels[pos])
  905. {
  906. int c0 = (int)(0xFF000000 | getColor(p0));
  907. zbufferPixels[pos] = z;
  908. zbufferPixels[pos + 1] = z;
  909. zbufferPixels[pos + bufferWidth] = z;
  910. zbufferPixels[pos + bufferWidth + 1] = z;
  911. bufferPixels[pos] = c0;
  912. bufferPixels[pos + 1] = c0;
  913. bufferPixels[pos + bufferWidth] = c0;
  914. bufferPixels[pos + bufferWidth + 1] = c0;
  915. }
  916. }
  917. }
  918. }
  919. }
  920. }
  921. public void setSurfacePLotSetLight(double light)
  922. {
  923. this.light = light;
  924. }
  925. public void setSurfaceGridSize(int width, int height)
  926. {
  927. this.gridWidth = width;
  928. this.gridHeight = height;
  929. }
  930. public void setSurfacePlotMode(int surfacePlotMode)
  931. {
  932. this.surfacePlotMode = surfacePlotMode;
  933. }
  934. public void setBuffers(int[] bufferPixels, double[] zbufferPixels, int bufferWidth, int bufferHeight)
  935. {
  936. this.bufferPixels = bufferPixels;
  937. this.zbufferPixels = zbufferPixels;
  938. this.bufferWidth = bufferWidth;
  939. this.bufferHeight = bufferHeight;
  940. }
  941. public void setTransform(Transform transform)
  942. {
  943. this.tr = transform;
  944. }
  945. public void setSurfacePlotCenter(double xCenter, double yCenter, double zCenter)
  946. {
  947. this.xCenter = xCenter;
  948. this.yCenter = yCenter;
  949. this.zCenter = zCenter;
  950. }
  951. public void setSurfacePlotLut(int lutNr)
  952. {
  953. this.lutNr = lutNr;
  954. if (lut != null)
  955. lut.setLut(lutNr);
  956. }
  957. public int getSurfacePlotLut()
  958. {
  959. return lut.getLutNr();
  960. }
  961. public void setMinMax(int min, int max)
  962. {
  963. this.min = min;
  964. this.max = max;
  965. }
  966. public void setInverse(bool b)
  967. {
  968. inversefactor = (b) ? -1 : 1;
  969. for (int i = 0; i < plotList.Length; i++)
  970. plotList[i].z = inversefactor * plotList[i].zf;
  971. }
  972. public int getInversefactor()
  973. {
  974. return inversefactor;
  975. }
  976. }
  977. }