PageRenderTime 178ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/Graphics/vtkImageDataGeometryFilter.cxx

https://github.com/b3c/VTK-5.8
C++ | 483 lines | 393 code | 42 blank | 48 comment | 81 complexity | 2bd00b6f457e81ae3708a314a5d671da MD5 | raw file
  1. /*=========================================================================
  2. Program: Visualization Toolkit
  3. Module: vtkImageDataGeometryFilter.cxx
  4. Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  5. All rights reserved.
  6. See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  7. This software is distributed WITHOUT ANY WARRANTY; without even
  8. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  9. PURPOSE. See the above copyright notice for more information.
  10. =========================================================================*/
  11. #include "vtkImageDataGeometryFilter.h"
  12. #include "vtkCellArray.h"
  13. #include "vtkCellData.h"
  14. #include "vtkImageData.h"
  15. #include "vtkInformation.h"
  16. #include "vtkInformationVector.h"
  17. #include "vtkObjectFactory.h"
  18. #include "vtkPointData.h"
  19. #include "vtkPolyData.h"
  20. vtkStandardNewMacro(vtkImageDataGeometryFilter);
  21. // Construct with initial extent of all the data
  22. vtkImageDataGeometryFilter::vtkImageDataGeometryFilter()
  23. {
  24. this->Extent[0] = 0;
  25. this->Extent[1] = VTK_LARGE_INTEGER;
  26. this->Extent[2] = 0;
  27. this->Extent[3] = VTK_LARGE_INTEGER;
  28. this->Extent[4] = 0;
  29. this->Extent[5] = VTK_LARGE_INTEGER;
  30. this->ThresholdCells = 0;
  31. this->ThresholdValue = 0.0;
  32. this->OutputTriangles = 0;
  33. }
  34. int vtkImageDataGeometryFilter::RequestData(
  35. vtkInformation *vtkNotUsed(request),
  36. vtkInformationVector **inputVector,
  37. vtkInformationVector *outputVector)
  38. {
  39. // get the info objects
  40. vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  41. vtkInformation *outInfo = outputVector->GetInformationObject(0);
  42. // get the input and output
  43. vtkImageData *input = vtkImageData::SafeDownCast(
  44. inInfo->Get(vtkDataObject::DATA_OBJECT()));
  45. vtkPolyData *output = vtkPolyData::SafeDownCast(
  46. outInfo->Get(vtkDataObject::DATA_OBJECT()));
  47. int *dims, dimension, dir[3], diff[3];
  48. int i, j, k, extent[6], s, threshok;
  49. vtkIdType idx, startIdx, startCellIdx;
  50. vtkIdType ptIds[4], cellId, triIds[3];
  51. vtkPoints *newPts=0;
  52. vtkCellArray *newVerts=0;
  53. vtkCellArray *newLines=0;
  54. vtkCellArray *newPolys=0;
  55. vtkIdType totPoints, pos;
  56. int offset[3], numPolys;
  57. double x[3];
  58. vtkPointData *pd, *outPD;
  59. vtkDataArray *pointScalars;
  60. vtkCellData *cd, *outCD;
  61. vtkDebugMacro(<< "Extracting structured points geometry");
  62. pd = input->GetPointData();
  63. outPD = output->GetPointData();
  64. cd = input->GetCellData();
  65. outCD = output->GetCellData();
  66. pointScalars=pd->GetScalars();
  67. // this->PointData.CopyNormalsOff();
  68. dims = input->GetDimensions();
  69. if (dims[0] <= 0 || dims[1] <= 0 || dims[2] <= 0)
  70. {
  71. return 1;
  72. }
  73. //
  74. // Based on the dimensions of the structured data, and the extent of the geometry,
  75. // compute the combined extent plus the dimensionality of the data
  76. //
  77. for (dimension=3, i=0; i<3; i++)
  78. {
  79. extent[2*i] = this->Extent[2*i] < 0 ? 0 : this->Extent[2*i];
  80. extent[2*i] = this->Extent[2*i] >= dims[i] ? dims[i]-1 : this->Extent[2*i];
  81. extent[2*i+1] = this->Extent[2*i+1] >= dims[i] ? dims[i]-1 : this->Extent[2*i+1];
  82. if ( extent[2*i+1] < extent[2*i] )
  83. {
  84. extent[2*i+1] = extent[2*i];
  85. }
  86. if ( (extent[2*i+1] - extent[2*i]) == 0 )
  87. {
  88. dimension--;
  89. }
  90. }
  91. //
  92. // Now create polygonal data based on dimension of data
  93. //
  94. startIdx = extent[0] + extent[2]*dims[0] + extent[4]*dims[0]*dims[1];
  95. // The cell index is a bit more complicated at the boundaries
  96. if (dims[0] == 1)
  97. {
  98. startCellIdx = extent[0];
  99. }
  100. else
  101. {
  102. startCellIdx = (extent[0] < dims[0] - 1) ? extent[0]
  103. : extent[0]-1;
  104. }
  105. if (dims[1] == 1)
  106. {
  107. startCellIdx += extent[2]*(dims[0]-1);
  108. }
  109. else
  110. {
  111. startCellIdx += (extent[2] < dims[1] - 1) ? extent[2]*(dims[0]-1)
  112. : (extent[2]-1)*(dims[0]-1);
  113. }
  114. if (dims[2] == 1)
  115. {
  116. startCellIdx += extent[4]*(dims[0]-1)*(dims[1]-1);
  117. }
  118. else
  119. {
  120. startCellIdx += (extent[4] < dims[2] - 1) ? extent[4]*(dims[0]-1)*(dims[1]-1)
  121. : (extent[4]-1)*(dims[0]-1)*(dims[1]-1);
  122. }
  123. switch (dimension)
  124. {
  125. default:
  126. break;
  127. case 0: // --------------------- build point -----------------------
  128. newPts = vtkPoints::New();
  129. newPts->Allocate(1);
  130. newVerts = vtkCellArray::New();
  131. newVerts->Allocate(newVerts->EstimateSize(1,1));
  132. outPD->CopyAllocate(pd,1);
  133. outCD->CopyAllocate(cd,1);
  134. ptIds[0] = newPts->InsertNextPoint(input->GetPoint(startIdx));
  135. outPD->CopyData(pd,startIdx,ptIds[0]);
  136. cellId = newVerts->InsertNextCell(1,ptIds);
  137. outCD->CopyData(cd,startIdx,cellId);
  138. break;
  139. case 1: // --------------------- build line -----------------------
  140. for (dir[0]=dir[1]=dir[2]=totPoints=0, i=0; i<3; i++)
  141. {
  142. if ( (diff[i] = extent[2*i+1] - extent[2*i]) > 0 )
  143. {
  144. dir[0] = i;
  145. totPoints = diff[i] + 1;
  146. break;
  147. }
  148. }
  149. newPts = vtkPoints::New();
  150. newPts->Allocate(totPoints);
  151. newLines = vtkCellArray::New();
  152. newLines->Allocate(newLines->EstimateSize(totPoints-1,2));
  153. outPD->CopyAllocate(pd,totPoints);
  154. outCD->CopyAllocate(cd,totPoints - 1);
  155. //
  156. // Load data
  157. //
  158. if ( dir[0] == 0 )
  159. {
  160. offset[0] = 1;
  161. }
  162. else if (dir[0] == 1)
  163. {
  164. offset[0] = dims[0];
  165. }
  166. else
  167. {
  168. offset[0] = dims[0]*dims[1];
  169. }
  170. for (i=0; i<totPoints; i++)
  171. {
  172. idx = startIdx + i*offset[0];
  173. input->GetPoint(idx, x);
  174. ptIds[0] = newPts->InsertNextPoint(x);
  175. outPD->CopyData(pd,idx,ptIds[0]);
  176. }
  177. if ( dir[0] == 0 )
  178. {
  179. offset[0] = 1;
  180. }
  181. else if (dir[0] == 1)
  182. {
  183. offset[0] = dims[0] - 1;
  184. }
  185. else
  186. {
  187. offset[0] = (dims[0] - 1) * (dims[1] - 1);
  188. }
  189. for (i=0; i<(totPoints-1); i++)
  190. {
  191. idx = startCellIdx + i*offset[0];
  192. ptIds[0] = i;
  193. ptIds[1] = i + 1;
  194. cellId = newLines->InsertNextCell(2,ptIds);
  195. outCD->CopyData(cd,idx,cellId);
  196. }
  197. break;
  198. case 2: // --------------------- build plane -----------------------
  199. //
  200. // Create the data objects
  201. //
  202. for (dir[0]=dir[1]=dir[2]=idx=0,i=0; i<3; i++)
  203. {
  204. if ( (diff[i] = extent[2*i+1] - extent[2*i]) != 0 )
  205. {
  206. dir[idx++] = i;
  207. }
  208. else
  209. {
  210. dir[2] = i;
  211. }
  212. }
  213. totPoints = (diff[dir[0]]+1) * (diff[dir[1]]+1);
  214. numPolys = diff[dir[0]] * diff[dir[1]];
  215. newPts = vtkPoints::New();
  216. newPts->Allocate(totPoints);
  217. newPolys = vtkCellArray::New();
  218. if (this->OutputTriangles)
  219. {
  220. newPolys->Allocate(2*newLines->EstimateSize(numPolys,3));
  221. }
  222. else
  223. {
  224. newPolys->Allocate(newLines->EstimateSize(numPolys,4));
  225. }
  226. outPD->CopyAllocate(pd,totPoints);
  227. outCD->CopyAllocate(cd,numPolys);
  228. //
  229. // Create vertices
  230. //
  231. for (i=0; i<2; i++)
  232. {
  233. if ( dir[i] == 0 )
  234. {
  235. offset[i] = 1;
  236. }
  237. else if ( dir[i] == 1 )
  238. {
  239. offset[i] = dims[0];
  240. }
  241. else if ( dir[i] == 2 )
  242. {
  243. offset[i] = dims[0]*dims[1];
  244. }
  245. }
  246. for (pos=startIdx, j=0; j < (diff[dir[1]]+1); j++)
  247. {
  248. for (i=0; i < (diff[dir[0]]+1); i++)
  249. {
  250. idx = pos + i*offset[0];
  251. input->GetPoint(idx, x);
  252. ptIds[0] = newPts->InsertNextPoint(x);
  253. outPD->CopyData(pd,idx,ptIds[0]);
  254. }
  255. pos += offset[1];
  256. }
  257. //
  258. // Create cells
  259. //
  260. for (i=0; i<2; i++)
  261. {
  262. if ( dir[i] == 0 )
  263. {
  264. offset[i] = 1;
  265. }
  266. else if ( dir[i] == 1 )
  267. {
  268. offset[i] = (dims[0] - 1);
  269. }
  270. else if ( dir[i] == 2 )
  271. {
  272. offset[i] = (dims[0] - 1) * (dims[1] - 1);
  273. }
  274. }
  275. for (pos=startCellIdx, j=0; j < diff[dir[1]]; j++)
  276. {
  277. for (i=0; i < diff[dir[0]]; i++)
  278. {
  279. idx = pos + i*offset[0];
  280. ptIds[0] = i + j*(diff[dir[0]]+1);
  281. ptIds[1] = ptIds[0] + 1;
  282. ptIds[2] = ptIds[1] + diff[dir[0]] + 1;
  283. ptIds[3] = ptIds[2] - 1;
  284. if (this->ThresholdCells)
  285. {
  286. threshok = false;
  287. for (s=0; !threshok && s<4; s++)
  288. {
  289. if (pointScalars->GetComponent(ptIds[s],0)>this->ThresholdValue)
  290. {
  291. threshok = true;
  292. break;
  293. }
  294. }
  295. if (threshok)
  296. {
  297. if (this->OutputTriangles)
  298. {
  299. triIds[0] = ptIds[0];
  300. triIds[1] = ptIds[2];
  301. triIds[2] = ptIds[3];
  302. cellId = newPolys->InsertNextCell(3,ptIds);
  303. outCD->CopyData(cd,idx,cellId);
  304. cellId = newPolys->InsertNextCell(3,triIds);
  305. outCD->CopyData(cd,idx,cellId);
  306. }
  307. else
  308. {
  309. cellId = newPolys->InsertNextCell(4,ptIds);
  310. outCD->CopyData(cd,idx,cellId);
  311. }
  312. }
  313. }
  314. else
  315. {
  316. cellId = newPolys->InsertNextCell(4,ptIds);
  317. outCD->CopyData(cd,idx,cellId);
  318. }
  319. }
  320. pos += offset[1];
  321. }
  322. break;
  323. case 3: // ------------------- grab points in volume --------------
  324. //
  325. // Create data objects
  326. //
  327. for (i=0; i<3; i++)
  328. {
  329. diff[i] = extent[2*i+1] - extent[2*i];
  330. }
  331. totPoints = (diff[0]+1) * (diff[1]+1) * (diff[2]+1);
  332. newPts = vtkPoints::New();
  333. newPts->Allocate(totPoints);
  334. newVerts = vtkCellArray::New();
  335. newVerts->Allocate(newVerts->EstimateSize(totPoints,1));
  336. outPD->CopyAllocate(pd,totPoints);
  337. outCD->CopyAllocate(cd,totPoints);
  338. //
  339. // Create vertices and cells
  340. //
  341. offset[0] = dims[0];
  342. offset[1] = dims[0]*dims[1];
  343. for (k=0; k < (diff[2]+1); k++)
  344. {
  345. for (j=0; j < (diff[1]+1); j++)
  346. {
  347. pos = startIdx + j*offset[0] + k*offset[1];
  348. for (i=0; i < (diff[0]+1); i++)
  349. {
  350. input->GetPoint(pos+i, x);
  351. ptIds[0] = newPts->InsertNextPoint(x);
  352. outPD->CopyData(pd,pos+i,ptIds[0]);
  353. cellId = newVerts->InsertNextCell(1,ptIds);
  354. outCD->CopyData(cd,pos+i,cellId);
  355. }
  356. }
  357. }
  358. break; /* end this case */
  359. } // switch
  360. //
  361. // Update self and release memory
  362. //
  363. if (newPts)
  364. {
  365. output->SetPoints(newPts);
  366. newPts->Delete();
  367. }
  368. if (newVerts)
  369. {
  370. output->SetVerts(newVerts);
  371. newVerts->Delete();
  372. }
  373. if (newLines)
  374. {
  375. output->SetLines(newLines);
  376. newLines->Delete();
  377. }
  378. if (newPolys)
  379. {
  380. output->SetPolys(newPolys);
  381. newPolys->Delete();
  382. }
  383. return 1;
  384. }
  385. void vtkImageDataGeometryFilter::SetExtent(int iMin, int iMax,
  386. int jMin, int jMax,
  387. int kMin, int kMax)
  388. {
  389. int extent[6];
  390. extent[0] = iMin;
  391. extent[1] = iMax;
  392. extent[2] = jMin;
  393. extent[3] = jMax;
  394. extent[4] = kMin;
  395. extent[5] = kMax;
  396. this->SetExtent(extent);
  397. }
  398. // Specify (imin,imax, jmin,jmax, kmin,kmax) indices.
  399. void vtkImageDataGeometryFilter::SetExtent(int extent[6])
  400. {
  401. int i;
  402. if ( extent[0] != this->Extent[0] || extent[1] != this->Extent[1] ||
  403. extent[2] != this->Extent[2] || extent[3] != this->Extent[3] ||
  404. extent[4] != this->Extent[4] || extent[5] != this->Extent[5] )
  405. {
  406. this->Modified();
  407. for (i=0; i<3; i++)
  408. {
  409. if ( extent[2*i] < 0 )
  410. {
  411. extent[2*i] = 0;
  412. }
  413. if ( extent[2*i+1] < extent[2*i] )
  414. {
  415. extent[2*i+1] = extent[2*i];
  416. }
  417. this->Extent[2*i] = extent[2*i];
  418. this->Extent[2*i+1] = extent[2*i+1];
  419. }
  420. }
  421. }
  422. int vtkImageDataGeometryFilter::FillInputPortInformation(int, vtkInformation *info)
  423. {
  424. info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkImageData");
  425. return 1;
  426. }
  427. void vtkImageDataGeometryFilter::PrintSelf(ostream& os, vtkIndent indent)
  428. {
  429. this->Superclass::PrintSelf(os,indent);
  430. os << indent << "Extent: \n";
  431. os << indent << " Jmin,Jmax: (" << this->Extent[2] << ", " << this->Extent[3] << ")\n";
  432. os << indent << " Kmin,Kmax: (" << this->Extent[4] << ", " << this->Extent[5] << ")\n";
  433. os << indent << " Imin,Imax: (" << this->Extent[0] << ", " << this->Extent[1] << ")\n";
  434. os << indent << "OutputTriangles " << this->OutputTriangles << "\n";
  435. os << indent << "ThresholdValue " << this->ThresholdValue << "\n";
  436. os << indent << "ThresholdCells " << this->ThresholdCells << "\n";
  437. }