PageRenderTime 80ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Infovis/vtkBivariateLinearTableThreshold.cxx

https://github.com/b3c/VTK-5.8
C++ | 386 lines | 304 code | 62 blank | 20 comment | 40 complexity | 0dd614612a9afbcaf4ec36c2091b4b65 MD5 | raw file
  1. /*=========================================================================
  2. Program: Visualization Toolkit
  3. Module: vtkBivariateLinearTableThreshold.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. /*-------------------------------------------------------------------------
  12. Copyright 2009 Sandia Corporation.
  13. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  14. the U.S. Government retains certain rights in this software.
  15. -------------------------------------------------------------------------*/
  16. #include "vtkBivariateLinearTableThreshold.h"
  17. #include "vtkDataArrayCollection.h"
  18. #include "vtkDataObject.h"
  19. #include "vtkDoubleArray.h"
  20. #include "vtkIdTypeArray.h"
  21. #include "vtkInformation.h"
  22. #include "vtkInformationVector.h"
  23. #include "vtkObjectFactory.h"
  24. #include "vtkTable.h"
  25. #include <vtkstd/map>
  26. vtkStandardNewMacro(vtkBivariateLinearTableThreshold);
  27. class vtkBivariateLinearTableThreshold::Internals
  28. {
  29. public:
  30. vtkstd::vector<vtkIdType> ColumnsToThreshold;
  31. vtkstd::vector<vtkIdType> ColumnComponentsToThreshold;
  32. };
  33. vtkBivariateLinearTableThreshold::vtkBivariateLinearTableThreshold()
  34. {
  35. this->SetNumberOfInputPorts(1);
  36. this->SetNumberOfOutputPorts(2);
  37. this->Implementation = new Internals;
  38. this->Initialize();
  39. }
  40. vtkBivariateLinearTableThreshold::~vtkBivariateLinearTableThreshold()
  41. {
  42. delete this->Implementation;
  43. }
  44. void vtkBivariateLinearTableThreshold::PrintSelf(ostream& os, vtkIndent indent)
  45. {
  46. this->Superclass::PrintSelf(os,indent);
  47. os << "ColumnRanges: " << this->ColumnRanges[0] << " " << this->ColumnRanges[1] << endl;
  48. os << "UseNormalizedDistance: " << this->UseNormalizedDistance << endl;
  49. os << "Inclusive: " << this->Inclusive << endl;
  50. os << "DistanceThreshold: " << this->DistanceThreshold << endl;
  51. os << "LinearThresholdType: " << this->LinearThresholdType << endl;
  52. }
  53. void vtkBivariateLinearTableThreshold::Initialize()
  54. {
  55. this->Inclusive = 0;
  56. this->Implementation->ColumnsToThreshold.clear();
  57. this->Implementation->ColumnComponentsToThreshold.clear();
  58. this->DistanceThreshold = 1.0;
  59. this->ColumnRanges[0] = 1.0;
  60. this->ColumnRanges[1] = 1.0;
  61. this->UseNormalizedDistance = 0;
  62. this->NumberOfLineEquations = 0;
  63. this->LinearThresholdType = BLT_NEAR;
  64. this->LineEquations = vtkSmartPointer<vtkDoubleArray>::New();
  65. this->LineEquations->SetNumberOfComponents(3);
  66. this->Modified();
  67. }
  68. int vtkBivariateLinearTableThreshold::RequestData(vtkInformation* vtkNotUsed(request),
  69. vtkInformationVector** inputVector,
  70. vtkInformationVector* outputVector)
  71. {
  72. vtkTable* inTable = vtkTable::GetData( inputVector[0], 0);
  73. vtkTable* outRowIdsTable = vtkTable::GetData( outputVector, OUTPUT_ROW_IDS );
  74. vtkTable* outRowDataTable = vtkTable::GetData( outputVector, OUTPUT_ROW_DATA );
  75. if (!inTable || this->GetNumberOfColumnsToThreshold() != 2)
  76. {
  77. return 1;
  78. }
  79. if (!outRowIdsTable)
  80. {
  81. vtkErrorMacro(<<"No output table, for some reason.");
  82. return 0;
  83. }
  84. vtkSmartPointer<vtkIdTypeArray> outIds = vtkSmartPointer<vtkIdTypeArray>::New();
  85. if (!ApplyThreshold(inTable,outIds))
  86. {
  87. vtkErrorMacro(<<"Error during threshold application.");
  88. return 0;
  89. }
  90. outRowIdsTable->Initialize();
  91. outRowIdsTable->AddColumn(outIds);
  92. outRowDataTable->Initialize();
  93. int numColumns = inTable->GetNumberOfColumns();
  94. for (int i=0; i<numColumns; i++)
  95. {
  96. vtkDataArray* a = vtkDataArray::CreateDataArray(inTable->GetColumn(i)->GetDataType());
  97. a->SetNumberOfComponents(inTable->GetColumn(i)->GetNumberOfComponents());
  98. a->SetName(inTable->GetColumn(i)->GetName());
  99. outRowDataTable->AddColumn(a);
  100. a->Delete();
  101. }
  102. for (int i=0; i<outIds->GetNumberOfTuples(); i++)
  103. {
  104. outRowDataTable->InsertNextRow(inTable->GetRow(outIds->GetValue(i)));
  105. }
  106. return 1;
  107. }
  108. int vtkBivariateLinearTableThreshold::FillInputPortInformation( int port, vtkInformation* info )
  109. {
  110. if (port == 0)
  111. {
  112. info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTable");
  113. return 1;
  114. }
  115. return 0;
  116. }
  117. int vtkBivariateLinearTableThreshold::FillOutputPortInformation( int port, vtkInformation* info )
  118. {
  119. if ( port == OUTPUT_ROW_IDS ||
  120. port == OUTPUT_ROW_DATA)
  121. {
  122. info->Set( vtkDataObject::DATA_TYPE_NAME(), "vtkTable" );
  123. return 1;
  124. }
  125. return 0;
  126. }
  127. void vtkBivariateLinearTableThreshold::AddColumnToThreshold(vtkIdType column, vtkIdType component)
  128. {
  129. this->Implementation->ColumnsToThreshold.push_back(column);
  130. this->Implementation->ColumnComponentsToThreshold.push_back(component);
  131. this->Modified();
  132. }
  133. int vtkBivariateLinearTableThreshold::GetNumberOfColumnsToThreshold()
  134. {
  135. return (int)this->Implementation->ColumnsToThreshold.size();
  136. }
  137. void vtkBivariateLinearTableThreshold::GetColumnToThreshold(vtkIdType idx, vtkIdType& column, vtkIdType& component)
  138. {
  139. if (idx < 0 || idx >= (int)this->Implementation->ColumnsToThreshold.size())
  140. {
  141. column = -1;
  142. component = -1;
  143. }
  144. else
  145. {
  146. column = this->Implementation->ColumnsToThreshold[idx];
  147. component = this->Implementation->ColumnComponentsToThreshold[idx];
  148. }
  149. }
  150. void vtkBivariateLinearTableThreshold::ClearColumnsToThreshold()
  151. {
  152. this->Implementation->ColumnsToThreshold.clear();
  153. this->Implementation->ColumnComponentsToThreshold.clear();
  154. }
  155. vtkIdTypeArray* vtkBivariateLinearTableThreshold::GetSelectedRowIds(int selection)
  156. {
  157. vtkTable* table = vtkTable::SafeDownCast(this->GetOutput());
  158. if (!table)
  159. return NULL;
  160. return vtkIdTypeArray::SafeDownCast(table->GetColumn(selection));
  161. }
  162. int vtkBivariateLinearTableThreshold::ApplyThreshold(vtkTable* tableToThreshold, vtkIdTypeArray* acceptedIds)
  163. {
  164. // grab the first two arrays (and their components) to threshold
  165. vtkIdType column1,column2,component1,component2;
  166. if (this->GetNumberOfColumnsToThreshold() != 2)
  167. {
  168. vtkErrorMacro(<<"This threshold only works on two columns at a time. Received: "<<this->GetNumberOfColumnsToThreshold());
  169. return 0;
  170. }
  171. this->GetColumnToThreshold(0,column1,component1);
  172. this->GetColumnToThreshold(1,column2,component2);
  173. vtkDataArray* a1 = vtkDataArray::SafeDownCast(tableToThreshold->GetColumn(column1));
  174. vtkDataArray* a2 = vtkDataArray::SafeDownCast(tableToThreshold->GetColumn(column2));
  175. if (!a1 || !a2)
  176. {
  177. vtkErrorMacro(<<"Wrong number of arrays received.");
  178. return 0;
  179. }
  180. if (a1->GetNumberOfTuples() != a2->GetNumberOfTuples())
  181. {
  182. vtkErrorMacro(<<"Two arrays to threshold must have the same number of tuples.");
  183. return 0;
  184. }
  185. int (vtkBivariateLinearTableThreshold::*thresholdFunc)(double,double) = NULL;
  186. switch (this->LinearThresholdType)
  187. {
  188. case vtkBivariateLinearTableThreshold::BLT_ABOVE:
  189. thresholdFunc = &vtkBivariateLinearTableThreshold::ThresholdAbove;
  190. break;
  191. case vtkBivariateLinearTableThreshold::BLT_BELOW:
  192. thresholdFunc = &vtkBivariateLinearTableThreshold::ThresholdBelow;
  193. break;
  194. case vtkBivariateLinearTableThreshold::BLT_NEAR:
  195. thresholdFunc = &vtkBivariateLinearTableThreshold::ThresholdNear;
  196. break;
  197. case vtkBivariateLinearTableThreshold::BLT_BETWEEN:
  198. thresholdFunc = &vtkBivariateLinearTableThreshold::ThresholdBetween;
  199. break;
  200. default:
  201. vtkErrorMacro(<<"Threshold type not defined: "<<this->LinearThresholdType);
  202. return 0;
  203. break;
  204. }
  205. if (!thresholdFunc)
  206. {
  207. vtkErrorMacro(<<"No threshold function specified.");
  208. return 0;
  209. }
  210. acceptedIds->Initialize();
  211. int numTuples = a1->GetNumberOfTuples();
  212. double v1,v2;
  213. for (int i=0; i<numTuples; i++)
  214. {
  215. v1 = a1->GetComponent(i,component1);
  216. v2 = a2->GetComponent(i,component2);
  217. if ((this->*thresholdFunc)(v1,v2))
  218. {
  219. acceptedIds->InsertNextValue(i);
  220. }
  221. }
  222. return 1;
  223. }
  224. void vtkBivariateLinearTableThreshold::AddLineEquation(double* p1, double* p2)
  225. {
  226. double a = p1[1]-p2[1];
  227. double b = p2[0]-p1[0];
  228. double c = p1[0]*p2[1]-p2[0]*p1[1];
  229. this->AddLineEquation(a,b,c);
  230. }
  231. void vtkBivariateLinearTableThreshold::AddLineEquation(double* p, double slope)
  232. {
  233. double p2[2] = {p[0]+1.0,p[1]+slope};
  234. this->AddLineEquation(p,p2);
  235. }
  236. void vtkBivariateLinearTableThreshold::AddLineEquation(double a, double b, double c)
  237. {
  238. double norm = sqrt(a*a+b*b);
  239. a /= norm;
  240. b /= norm;
  241. c /= norm;
  242. this->LineEquations->InsertNextTuple3(a,b,c);
  243. this->NumberOfLineEquations++;
  244. }
  245. void vtkBivariateLinearTableThreshold::ClearLineEquations()
  246. {
  247. this->LineEquations->Initialize();
  248. this->NumberOfLineEquations=0;
  249. }
  250. void vtkBivariateLinearTableThreshold::ComputeImplicitLineFunction(double* p1, double* p2, double* abc)
  251. {
  252. abc[0] = p1[1]-p2[1];
  253. abc[1] = p2[0]-p1[0];
  254. abc[2] = p1[0]*p2[1]-p2[0]*p1[1];
  255. }
  256. void vtkBivariateLinearTableThreshold::ComputeImplicitLineFunction(double* p, double slope, double* abc)
  257. {
  258. double p2[2] = {p[0]+1.0,p[1]+slope};
  259. vtkBivariateLinearTableThreshold::ComputeImplicitLineFunction(p,p2,abc);
  260. }
  261. int vtkBivariateLinearTableThreshold::ThresholdAbove(double x, double y)
  262. {
  263. double* c,v;
  264. for (int i=0; i<this->NumberOfLineEquations; i++)
  265. {
  266. c = this->LineEquations->GetTuple3(i);
  267. v = c[0]*x + c[1]*y + c[2];
  268. if ((this->GetInclusive() && v >= 0) ||
  269. (!this->GetInclusive() && v > 0))
  270. {
  271. return 1;
  272. }
  273. }
  274. return 0;
  275. }
  276. int vtkBivariateLinearTableThreshold::ThresholdBelow(double x, double y)
  277. {
  278. double* c,v;
  279. for (int i=0; i<this->NumberOfLineEquations; i++)
  280. {
  281. c = this->LineEquations->GetTuple3(i);
  282. v = c[0]*x + c[1]*y + c[2];
  283. if ((this->GetInclusive() && v <= 0) ||
  284. (!this->GetInclusive() && v < 0))
  285. {
  286. return 1;
  287. }
  288. }
  289. return 0;
  290. }
  291. int vtkBivariateLinearTableThreshold::ThresholdNear(double x, double y)
  292. {
  293. double* c,v;
  294. for (int i=0; i<this->NumberOfLineEquations; i++)
  295. {
  296. c = this->LineEquations->GetTuple3(i);
  297. if (this->UseNormalizedDistance)
  298. {
  299. double dx = fabs(x-(-c[1]*y-c[2])/c[0]);
  300. double dy = fabs(y-(-c[0]*x-c[2])/c[1]);
  301. double dxn = dx/this->ColumnRanges[0];
  302. double dyn = dy/this->ColumnRanges[1];
  303. v = sqrt(dxn*dxn+dyn*dyn);
  304. }
  305. else
  306. {
  307. v = fabs(c[0]*x + c[1]*y + c[2]);
  308. }
  309. if ((this->GetInclusive() && v <= this->DistanceThreshold) ||
  310. (!this->GetInclusive() && v < this->DistanceThreshold))
  311. {
  312. return 1;
  313. }
  314. }
  315. return 0;
  316. }
  317. int vtkBivariateLinearTableThreshold::ThresholdBetween(double x, double y)
  318. {
  319. return (this->ThresholdAbove(x,y) && this->ThresholdBelow(x,y));
  320. }