PageRenderTime 23ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/Filters/General/vtkReflectionFilter.cxx

https://github.com/dgobbi/VTK
C++ | 471 lines | 398 code | 36 blank | 37 comment | 58 complexity | 4ef4ab1eafa61bd5516ecf13b68734c6 MD5 | raw file
  1. /*=========================================================================
  2. Program: Visualization Toolkit
  3. Module: vtkReflectionFilter.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 "vtkReflectionFilter.h"
  12. #include "vtkBoundingBox.h"
  13. #include "vtkCellData.h"
  14. #include "vtkCompositeDataIterator.h"
  15. #include "vtkGenericCell.h"
  16. #include "vtkIdList.h"
  17. #include "vtkInformation.h"
  18. #include "vtkInformationVector.h"
  19. #include "vtkMultiBlockDataSet.h"
  20. #include "vtkObjectFactory.h"
  21. #include "vtkPointData.h"
  22. #include "vtkSmartPointer.h"
  23. #include "vtkUnstructuredGrid.h"
  24. vtkStandardNewMacro(vtkReflectionFilter);
  25. //---------------------------------------------------------------------------
  26. vtkReflectionFilter::vtkReflectionFilter()
  27. {
  28. this->Plane = USE_X_MIN;
  29. this->Center = 0.0;
  30. this->CopyInput = 1;
  31. }
  32. //---------------------------------------------------------------------------
  33. vtkReflectionFilter::~vtkReflectionFilter()
  34. {
  35. }
  36. //---------------------------------------------------------------------------
  37. void vtkReflectionFilter::FlipVector(double tuple[3], int mirrorDir[3])
  38. {
  39. for(int j=0; j<3; j++)
  40. {
  41. tuple[j] *= mirrorDir[j];
  42. }
  43. }
  44. //---------------------------------------------------------------------------
  45. int vtkReflectionFilter::ComputeBounds(vtkDataObject* input, double bounds[6])
  46. {
  47. // get the input and output
  48. vtkDataSet *inputDS = vtkDataSet::SafeDownCast(input);;
  49. vtkCompositeDataSet* inputCD = vtkCompositeDataSet::SafeDownCast(input);
  50. if (inputDS)
  51. {
  52. inputDS->GetBounds(bounds);
  53. return 1;
  54. }
  55. if (inputCD)
  56. {
  57. vtkBoundingBox bbox;
  58. vtkSmartPointer<vtkCompositeDataIterator> iter;
  59. iter.TakeReference(inputCD->NewIterator());
  60. for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
  61. {
  62. vtkDataSet* ds = vtkDataSet::SafeDownCast(iter->GetCurrentDataObject());
  63. if (!ds)
  64. {
  65. vtkErrorMacro("Input composite dataset must be comprised for vtkDataSet "
  66. "subclasses alone.");
  67. return 0;
  68. }
  69. bbox.AddBounds(ds->GetBounds());
  70. }
  71. if (bbox.IsValid())
  72. {
  73. bbox.GetBounds(bounds);
  74. return 1;
  75. }
  76. }
  77. return 0;
  78. }
  79. //---------------------------------------------------------------------------
  80. int vtkReflectionFilter::RequestData(
  81. vtkInformation *vtkNotUsed(request),
  82. vtkInformationVector **inputVector,
  83. vtkInformationVector *outputVector)
  84. {
  85. // get the input and output
  86. vtkDataSet *inputDS = vtkDataSet::GetData(inputVector[0], 0);
  87. vtkUnstructuredGrid *outputUG = vtkUnstructuredGrid::GetData(outputVector, 0);
  88. vtkCompositeDataSet* inputCD = vtkCompositeDataSet::GetData(inputVector[0], 0);
  89. vtkCompositeDataSet *outputCD = vtkCompositeDataSet::GetData(outputVector, 0);
  90. if (inputDS && outputUG)
  91. {
  92. double bounds[6];
  93. this->ComputeBounds(inputDS, bounds);
  94. return this->RequestDataInternal(inputDS, outputUG, bounds);
  95. }
  96. if (inputCD && outputCD)
  97. {
  98. outputCD->CopyStructure(inputCD);
  99. double bounds[6];
  100. if (this->ComputeBounds(inputCD, bounds))
  101. {
  102. vtkSmartPointer<vtkCompositeDataIterator> iter;
  103. iter.TakeReference(inputCD->NewIterator());
  104. for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
  105. {
  106. vtkDataSet* ds = vtkDataSet::SafeDownCast(iter->GetCurrentDataObject());
  107. vtkSmartPointer<vtkUnstructuredGrid> ug =
  108. vtkSmartPointer<vtkUnstructuredGrid>::New();
  109. if (!this->RequestDataInternal(ds, ug, bounds))
  110. {
  111. return 0;
  112. }
  113. outputCD->SetDataSet(iter, ug);
  114. }
  115. }
  116. return 1;
  117. }
  118. return 0;
  119. }
  120. //---------------------------------------------------------------------------
  121. int vtkReflectionFilter::RequestDataInternal(
  122. vtkDataSet* input, vtkUnstructuredGrid* output,
  123. double bounds[6])
  124. {
  125. vtkIdType i;
  126. vtkPointData *inPD = input->GetPointData();
  127. vtkPointData *outPD = output->GetPointData();
  128. vtkCellData *inCD = input->GetCellData();
  129. vtkCellData *outCD = output->GetCellData();
  130. vtkIdType numPts = input->GetNumberOfPoints();
  131. vtkIdType numCells = input->GetNumberOfCells();
  132. double tuple[3];
  133. vtkPoints *outPoints;
  134. double point[3];
  135. double constant[3] = {0.0, 0.0, 0.0};
  136. int mirrorDir[3] = { 1, 1, 1};
  137. int ptId, cellId, j;
  138. vtkGenericCell *cell = vtkGenericCell::New();
  139. vtkIdList *ptIds = vtkIdList::New();
  140. outPoints = vtkPoints::New();
  141. if (this->CopyInput)
  142. {
  143. outPoints->Allocate(2* numPts);
  144. output->Allocate(numCells * 2);
  145. }
  146. else
  147. {
  148. outPoints->Allocate(numPts);
  149. output->Allocate(numCells);
  150. }
  151. outPD->CopyAllocate(inPD);
  152. outCD->CopyAllocate(inCD);
  153. vtkDataArray *inPtVectors, *outPtVectors, *inPtNormals, *outPtNormals;
  154. vtkDataArray *inCellVectors, *outCellVectors, *inCellNormals;
  155. vtkDataArray *outCellNormals;
  156. inPtVectors = inPD->GetVectors();
  157. outPtVectors = outPD->GetVectors();
  158. inPtNormals = inPD->GetNormals();
  159. outPtNormals = outPD->GetNormals();
  160. inCellVectors = inCD->GetVectors();
  161. outCellVectors = outCD->GetVectors();
  162. inCellNormals = inCD->GetNormals();
  163. outCellNormals = outCD->GetNormals();
  164. // Copy first points.
  165. if (this->CopyInput)
  166. {
  167. for (i = 0; i < numPts; i++)
  168. {
  169. input->GetPoint(i, point);
  170. ptId = outPoints->InsertNextPoint(point);
  171. outPD->CopyData(inPD, i, ptId);
  172. }
  173. }
  174. // Copy reflected points.
  175. switch (this->Plane)
  176. {
  177. case USE_X_MIN:
  178. constant[0] = 2*bounds[0];
  179. mirrorDir[0] = -1;
  180. break;
  181. case USE_X_MAX:
  182. constant[0] = 2*bounds[1];
  183. mirrorDir[0] = -1;
  184. break;
  185. case USE_X:
  186. constant[0] = 2*this->Center;
  187. mirrorDir[0] = -1;
  188. break;
  189. case USE_Y_MIN:
  190. constant[1] = 2*bounds[2];
  191. mirrorDir[1] = -1;
  192. break;
  193. case USE_Y_MAX:
  194. constant[1] = 2*bounds[3];
  195. mirrorDir[1] = -1;
  196. break;
  197. case USE_Y:
  198. constant[1] = 2*this->Center;
  199. mirrorDir[1] = -1;
  200. break;
  201. case USE_Z_MIN:
  202. constant[2] = 2*bounds[4];
  203. mirrorDir[2] = -1;
  204. break;
  205. case USE_Z_MAX:
  206. constant[2] = 2*bounds[5];
  207. mirrorDir[2] = -1;
  208. break;
  209. case USE_Z:
  210. constant[2] = 2*this->Center;
  211. mirrorDir[2] = -1;
  212. break;
  213. }
  214. for (i = 0; i < numPts; i++)
  215. {
  216. input->GetPoint(i, point);
  217. ptId =
  218. outPoints->InsertNextPoint( mirrorDir[0]*point[0] + constant[0],
  219. mirrorDir[1]*point[1] + constant[1],
  220. mirrorDir[2]*point[2] + constant[2] );
  221. outPD->CopyData(inPD, i, ptId);
  222. if (inPtVectors)
  223. {
  224. inPtVectors->GetTuple(i, tuple);
  225. this->FlipVector(tuple, mirrorDir);
  226. outPtVectors->SetTuple(ptId, tuple);
  227. }
  228. if (inPtNormals)
  229. {
  230. inPtNormals->GetTuple(i, tuple);
  231. this->FlipVector(tuple, mirrorDir);
  232. outPtNormals->SetTuple(ptId, tuple);
  233. }
  234. }
  235. int numCellPts, cellType;
  236. vtkIdType *newCellPts;
  237. vtkIdList *cellPts;
  238. // Copy original cells.
  239. if (this->CopyInput)
  240. {
  241. for (i = 0; i < numCells; i++)
  242. {
  243. // special handling for polyhedron cells
  244. if (vtkUnstructuredGrid::SafeDownCast(input) &&
  245. input->GetCellType(i) == VTK_POLYHEDRON)
  246. {
  247. vtkUnstructuredGrid::SafeDownCast(input)->GetFaceStream(i, ptIds);
  248. output->InsertNextCell(VTK_POLYHEDRON, ptIds);
  249. }
  250. else
  251. {
  252. input->GetCellPoints(i, ptIds);
  253. output->InsertNextCell(input->GetCellType(i), ptIds);
  254. }
  255. outCD->CopyData(inCD, i, i);
  256. }
  257. }
  258. // Generate reflected cells.
  259. for (i = 0; i < numCells; i++)
  260. {
  261. input->GetCell(i, cell);
  262. numCellPts = cell->GetNumberOfPoints();
  263. cellType = cell->GetCellType();
  264. // Triangle strips with even number of triangles have
  265. // to be handled specially. A degenerate triangle is
  266. // introduce to flip all the triangles properly.
  267. if (cellType == VTK_TRIANGLE_STRIP && numCellPts % 2 == 0)
  268. {
  269. cellPts = cell->GetPointIds();
  270. numCellPts++;
  271. newCellPts = new vtkIdType[numCellPts];
  272. newCellPts[0] = cellPts->GetId(0);
  273. newCellPts[1] = cellPts->GetId(2);
  274. newCellPts[2] = cellPts->GetId(1);
  275. newCellPts[3] = cellPts->GetId(2);
  276. for (j = 4; j < numCellPts; j++)
  277. {
  278. newCellPts[j] = cellPts->GetId(j-1);
  279. if (this->CopyInput)
  280. {
  281. newCellPts[j] += numPts;
  282. }
  283. }
  284. cellId = output->InsertNextCell(cellType, numCellPts, newCellPts);
  285. delete [] newCellPts;
  286. }
  287. else if (cellType == VTK_POLYHEDRON &&
  288. vtkUnstructuredGrid::SafeDownCast(input))
  289. {
  290. cellPts = vtkIdList::New();
  291. vtkUnstructuredGrid::SafeDownCast(input)->GetFaceStream(i, cellPts);
  292. vtkIdType* idPtr = cellPts->GetPointer(0);;
  293. int nfaces = static_cast<int>(*idPtr++);
  294. for (j = 0; j < nfaces; j++)
  295. {
  296. vtkIdType npts = *idPtr++;
  297. for (vtkIdType k = 0; k < (npts+1)/2; k++)
  298. {
  299. vtkIdType temp = idPtr[k];
  300. idPtr[k] = idPtr[npts-1-k];
  301. idPtr[npts-1-k] = temp;
  302. }
  303. if (this->CopyInput)
  304. {
  305. for (vtkIdType k = 0; k < npts; k++)
  306. {
  307. idPtr[k] += numPts;
  308. }
  309. }
  310. idPtr += npts;
  311. }
  312. cellId = output->InsertNextCell(cellType, cellPts);
  313. cellPts->Delete();
  314. }
  315. else if (cellType == VTK_PYRAMID && vtkUnstructuredGrid::SafeDownCast(input))
  316. {
  317. if(numCellPts != 5)
  318. {
  319. vtkErrorMacro("Pyramid cell must have exactly 5 points")
  320. }
  321. int four = numCellPts-1;
  322. cellPts = cell->GetPointIds();
  323. newCellPts = new vtkIdType[numCellPts];
  324. for (j = four-1; j >= 0; j--)
  325. {
  326. newCellPts[four-1-j] = cellPts->GetId(j);
  327. if (this->CopyInput)
  328. {
  329. newCellPts[four-1-j] += numPts;
  330. }
  331. }
  332. newCellPts[four] = cellPts->GetId(four);
  333. if (this->CopyInput)
  334. {
  335. newCellPts[four] += numPts;
  336. }
  337. cellId = output->InsertNextCell(cellType, numCellPts, newCellPts);
  338. delete [] newCellPts;
  339. }
  340. else
  341. {
  342. cellPts = cell->GetPointIds();
  343. newCellPts = new vtkIdType[numCellPts];
  344. for (j = numCellPts-1; j >= 0; j--)
  345. {
  346. newCellPts[numCellPts-1-j] = cellPts->GetId(j);
  347. if (this->CopyInput)
  348. {
  349. newCellPts[numCellPts-1-j] += numPts;
  350. }
  351. }
  352. cellId = output->InsertNextCell(cellType, numCellPts, newCellPts);
  353. delete [] newCellPts;
  354. }
  355. outCD->CopyData(inCD, i, cellId);
  356. if (inCellVectors)
  357. {
  358. inCellVectors->GetTuple(i, tuple);
  359. this->FlipVector(tuple, mirrorDir);
  360. outCellVectors->SetTuple(cellId, tuple);
  361. }
  362. if (inCellNormals)
  363. {
  364. inCellNormals->GetTuple(i, tuple);
  365. this->FlipVector(tuple, mirrorDir);
  366. outCellNormals->SetTuple(cellId, tuple);
  367. }
  368. }
  369. cell->Delete();
  370. ptIds->Delete();
  371. output->SetPoints(outPoints);
  372. outPoints->Delete();
  373. output->CheckAttributes();
  374. return 1;
  375. }
  376. //---------------------------------------------------------------------------
  377. int vtkReflectionFilter::FillInputPortInformation(int, vtkInformation *info)
  378. {
  379. // Input can be a dataset or a composite of datasets.
  380. info->Remove(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE());
  381. info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkCompositeDataSet");
  382. info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
  383. return 1;
  384. }
  385. //---------------------------------------------------------------------------
  386. int vtkReflectionFilter::RequestDataObject(
  387. vtkInformation*,
  388. vtkInformationVector** inputVector ,
  389. vtkInformationVector* outputVector)
  390. {
  391. vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  392. if (!inInfo)
  393. {
  394. return 0;
  395. }
  396. vtkDataObject *input = vtkDataObject::GetData(inInfo);
  397. vtkInformation* outInfo = outputVector->GetInformationObject(0);
  398. if (input)
  399. {
  400. vtkDataObject *output = vtkDataObject::GetData(outInfo);
  401. // If input is composite dataset, output is a vtkMultiBlockDataSet of
  402. // unstructrued grids.
  403. // If input is a dataset, output is an unstructured grid.
  404. if (!output ||
  405. (input->IsA("vtkCompositeDataSet") && !output->IsA("vtkMultiBlockDataSet")) ||
  406. (input->IsA("vtkDataSet") && !output->IsA("vtkUnstructuredGrid")))
  407. {
  408. vtkDataObject* newOutput = 0;
  409. if (input->IsA("vtkCompositeDataSet"))
  410. {
  411. newOutput = vtkMultiBlockDataSet::New();
  412. }
  413. else // if (input->IsA("vtkDataSet"))
  414. {
  415. newOutput = vtkUnstructuredGrid::New();
  416. }
  417. outInfo->Set(vtkDataSet::DATA_OBJECT(), newOutput);
  418. newOutput->Delete();
  419. }
  420. return 1;
  421. }
  422. return 0;
  423. }
  424. //---------------------------------------------------------------------------
  425. void vtkReflectionFilter::PrintSelf(ostream &os, vtkIndent indent)
  426. {
  427. this->Superclass::PrintSelf(os, indent);
  428. os << indent << "Plane: " << this->Plane << endl;
  429. os << indent << "Center: " << this->Center << endl;
  430. os << indent << "CopyInput: " << this->CopyInput << endl;
  431. }