ctkVTKColorTransferFunction.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0.txt
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. /// Qt includes
  15. #include <QColor>
  16. #include <QDebug>
  17. /// CTK includes
  18. #include "ctkVTKColorTransferFunction.h"
  19. #include "ctkLogger.h"
  20. /// VTK includes
  21. #include <vtkColorTransferFunction.h>
  22. #include <vtkSmartPointer.h>
  23. //--------------------------------------------------------------------------
  24. static ctkLogger logger("org.commontk.libs.visualization.core.ctkVTKColorTransferFunction");
  25. //--------------------------------------------------------------------------
  26. //-----------------------------------------------------------------------------
  27. class ctkVTKColorTransferFunctionPrivate
  28. {
  29. public:
  30. vtkSmartPointer<vtkColorTransferFunction> ColorTransferFunction;
  31. };
  32. //-----------------------------------------------------------------------------
  33. ctkVTKColorTransferFunction::ctkVTKColorTransferFunction(QObject* parentObject)
  34. :ctkTransferFunction(parentObject)
  35. , d_ptr(new ctkVTKColorTransferFunctionPrivate)
  36. {
  37. }
  38. //-----------------------------------------------------------------------------
  39. ctkVTKColorTransferFunction::ctkVTKColorTransferFunction(vtkColorTransferFunction* colorTransferFunction,
  40. QObject* parentObject)
  41. :ctkTransferFunction(parentObject)
  42. , d_ptr(new ctkVTKColorTransferFunctionPrivate)
  43. {
  44. this->setColorTransferFunction(colorTransferFunction);
  45. }
  46. //-----------------------------------------------------------------------------
  47. ctkVTKColorTransferFunction::~ctkVTKColorTransferFunction()
  48. {
  49. }
  50. //-----------------------------------------------------------------------------
  51. int ctkVTKColorTransferFunction::count()const
  52. {
  53. Q_D(const ctkVTKColorTransferFunction);
  54. if (d->ColorTransferFunction.GetPointer() == 0)
  55. {
  56. return -1;
  57. }
  58. return d->ColorTransferFunction->GetSize();
  59. }
  60. //-----------------------------------------------------------------------------
  61. bool ctkVTKColorTransferFunction::isDiscrete()const
  62. {
  63. return false;
  64. }
  65. //-----------------------------------------------------------------------------
  66. bool ctkVTKColorTransferFunction::isEditable()const
  67. {
  68. return true;
  69. }
  70. //-----------------------------------------------------------------------------
  71. void ctkVTKColorTransferFunction::range(qreal& minRange, qreal& maxRange)const
  72. {
  73. Q_D(const ctkVTKColorTransferFunction);
  74. if (d->ColorTransferFunction.GetPointer() == 0)
  75. {
  76. //Q_ASSERT(d->ColorTransferFunction.GetPointer());
  77. logger.warn("no ColorTransferFunction");
  78. minRange = 1.;
  79. maxRange = 0.;
  80. return;
  81. }
  82. double rangeValues[2];
  83. d->ColorTransferFunction->GetRange(rangeValues);
  84. minRange = rangeValues[0];
  85. maxRange = rangeValues[1];
  86. }
  87. //-----------------------------------------------------------------------------
  88. QVariant ctkVTKColorTransferFunction::minValue()const
  89. {
  90. Q_D(const ctkVTKColorTransferFunction);
  91. if (d->ColorTransferFunction.GetPointer() == 0)
  92. {
  93. //Q_ASSERT(d->ColorTransferFunction.GetPointer());
  94. logger.warn("no ColorTransferFunction");
  95. return -1;
  96. }
  97. double rgb[3];
  98. QColor minValue = QColor::fromRgbF(1.,1.,1.);
  99. for (int i = 0; i < this->count(); ++i)
  100. {
  101. d->ColorTransferFunction->GetColor(i, rgb);
  102. Q_ASSERT(rgb[0] >= 0. && rgb[0] <= 1. &&
  103. rgb[1] >= 0. && rgb[1] <= 1. &&
  104. rgb[2] >= 0. && rgb[2] <= 1.);
  105. QColor color = QColor::fromRgbF(rgb[0], rgb[1], rgb[2]);
  106. if ( qGray(color.red(), color.green(), color.blue()) <
  107. qGray(minValue.red(), minValue.green(), minValue.blue()))
  108. {
  109. minValue = color;
  110. }
  111. }
  112. return minValue;
  113. }
  114. //-----------------------------------------------------------------------------
  115. QVariant ctkVTKColorTransferFunction::maxValue()const
  116. {
  117. Q_D(const ctkVTKColorTransferFunction);
  118. if (d->ColorTransferFunction.GetPointer() == 0)
  119. {
  120. //Q_ASSERT(d->ColorTransferFunction.GetPointer());
  121. logger.warn("no ColorTransferFunction");
  122. return -1;
  123. }
  124. double rgb[3];
  125. QColor minValue = QColor::fromRgbF(0.,0.,0.);
  126. for (int i = 0; i < this->count(); ++i)
  127. {
  128. d->ColorTransferFunction->GetColor(i, rgb);
  129. Q_ASSERT(rgb[0] >= 0. && rgb[0] <= 1. &&
  130. rgb[1] >= 0. && rgb[1] <= 1. &&
  131. rgb[2] >= 0. && rgb[2] <= 1.);
  132. QColor color = QColor::fromRgbF(rgb[0], rgb[1], rgb[2]);
  133. if ( qGray(color.red(), color.green(), color.blue()) >
  134. qGray(minValue.red(), minValue.green(), minValue.blue()))
  135. {
  136. minValue = color;
  137. }
  138. }
  139. return minValue;
  140. }
  141. //-----------------------------------------------------------------------------
  142. ctkControlPoint* ctkVTKColorTransferFunction::controlPoint(int index)const
  143. {
  144. Q_D(const ctkVTKColorTransferFunction);
  145. Q_ASSERT(index >= 0 && index < this->count());
  146. double values[6];
  147. d->ColorTransferFunction->GetNodeValue(index, values);
  148. Q_ASSERT(values[0] >= d->ColorTransferFunction->GetRange()[0] &&
  149. values[0] <= d->ColorTransferFunction->GetRange()[1] &&
  150. values[1] >= 0. && values[1] <= 1. && // Red
  151. values[2] >= 0. && values[2] <= 1. && // Green
  152. values[3] >= 0. && values[3] <= 1. && // Blue
  153. values[4] >= 0. && values[4] <= 1. && // MidPoint
  154. values[5] >= 0. && values[5] <= 1.); // Sharpness
  155. QColor rgb = QColor::fromRgbF(values[1], values[2], values[3]);
  156. if (index + 1 >= this->count())
  157. {
  158. ctkControlPoint* cp = new ctkControlPoint();
  159. cp->P.X = values[0];
  160. cp->P.Value = rgb;
  161. return cp;
  162. }
  163. ctkNonLinearControlPoint* cp = new ctkNonLinearControlPoint();
  164. cp->P.X = values[0];
  165. cp->P.Value = rgb;
  166. double nextValues[6];
  167. d->ColorTransferFunction->GetNodeValue(index + 1, nextValues);
  168. Q_ASSERT(nextValues[0] >= d->ColorTransferFunction->GetRange()[0] &&
  169. nextValues[0] <= d->ColorTransferFunction->GetRange()[1] &&
  170. nextValues[1] >= 0. && nextValues[1] <= 1. && // Red
  171. nextValues[2] >= 0. && nextValues[2] <= 1. && // Green
  172. nextValues[3] >= 0. && nextValues[3] <= 1. && // Blue
  173. nextValues[4] >= 0. && nextValues[4] <= 1. && // MidPoint
  174. nextValues[5] >= 0. && nextValues[5] <= 1.); // Sharpness
  175. // Optimization: don't use SubPoints when the sharpness is 0.
  176. if (values[5] == 0.)
  177. {
  178. cp->SubPoints << ctkPoint(values[0], rgb);
  179. rgb = QColor::fromRgbF(nextValues[1], nextValues[2], nextValues[3]);
  180. cp->SubPoints << ctkPoint(nextValues[0], rgb);
  181. return cp;
  182. }
  183. double subPoints[30];
  184. d->ColorTransferFunction->GetTable(cp->x(), values[0], 10, subPoints);
  185. qreal interval = (values[0] - cp->x()) / 9.;
  186. for(int i = 0; i < 10; ++i)
  187. {
  188. rgb = QColor::fromRgbF(subPoints[3*i],
  189. subPoints[3*i+1],
  190. subPoints[3*i+2]);
  191. cp->SubPoints << ctkPoint(cp->x() + interval*i, rgb);
  192. }
  193. return cp;
  194. }
  195. //-----------------------------------------------------------------------------
  196. QVariant ctkVTKColorTransferFunction::value(qreal pos)const
  197. {
  198. Q_D(const ctkVTKColorTransferFunction);
  199. Q_ASSERT(d->ColorTransferFunction.GetPointer());
  200. double rgb[3];
  201. d->ColorTransferFunction->GetColor(pos, rgb);
  202. QColor color = QColor::fromRgbF(rgb[0], rgb[1], rgb[2]);
  203. return color;
  204. }
  205. //-----------------------------------------------------------------------------
  206. int ctkVTKColorTransferFunction::insertControlPoint(const ctkControlPoint& cp)
  207. {
  208. Q_D(ctkVTKColorTransferFunction);
  209. int index = -1;
  210. if (d->ColorTransferFunction.GetPointer() == 0)
  211. {
  212. return index;
  213. }
  214. QColor rgb = cp.value().value<QColor>();
  215. const ctkNonLinearControlPoint* nonLinearCp = dynamic_cast<const ctkNonLinearControlPoint*>(&cp);
  216. if (nonLinearCp)
  217. {
  218. // TODO retrieve midpoint & sharpness
  219. index = d->ColorTransferFunction->AddRGBPoint(
  220. cp.x(), rgb.redF(), rgb.greenF(), rgb.blueF());
  221. }
  222. else
  223. {
  224. index = d->ColorTransferFunction->AddRGBPoint(
  225. cp.x(), rgb.redF(), rgb.greenF(), rgb.blueF());
  226. }
  227. return index;
  228. }
  229. //-----------------------------------------------------------------------------
  230. int ctkVTKColorTransferFunction::insertControlPoint(qreal pos)
  231. {
  232. Q_D(ctkVTKColorTransferFunction);
  233. int index = -1;
  234. if (d->ColorTransferFunction.GetPointer() == 0)
  235. {
  236. return index;
  237. }
  238. // Get color at the given position
  239. double* rgb = d->ColorTransferFunction->GetColor( pos );
  240. // Add new point with the appropriate color
  241. index = d->ColorTransferFunction->AddRGBPoint(
  242. pos, rgb[0], rgb[1], rgb[2]);
  243. return index;
  244. }
  245. //-----------------------------------------------------------------------------
  246. void ctkVTKColorTransferFunction::setControlPointPos(int index, qreal pos)
  247. {
  248. Q_D(ctkVTKColorTransferFunction);
  249. double values[6];
  250. d->ColorTransferFunction->GetNodeValue(index, values);
  251. values[0] = pos;
  252. // warning, a possible new range is not supported
  253. // SetNodeValue eventually fire the signal changed()
  254. d->ColorTransferFunction->SetNodeValue(index, values);
  255. }
  256. //-----------------------------------------------------------------------------
  257. void ctkVTKColorTransferFunction::setControlPointValue(int index, const QVariant& value)
  258. {
  259. Q_D(ctkVTKColorTransferFunction);
  260. Q_ASSERT(value.value<QColor>().isValid());
  261. QColor rgb = value.value<QColor>();
  262. double values[6];
  263. d->ColorTransferFunction->GetNodeValue(index, values);
  264. values[1] = rgb.redF();
  265. values[2] = rgb.greenF();
  266. values[3] = rgb.blueF();
  267. // setNodeValue should eventually fired the signal changed()
  268. d->ColorTransferFunction->SetNodeValue(index, values);
  269. }
  270. //-----------------------------------------------------------------------------
  271. void ctkVTKColorTransferFunction::setColorTransferFunction(vtkColorTransferFunction* colorTransferFunction)
  272. {
  273. Q_D(ctkVTKColorTransferFunction);
  274. d->ColorTransferFunction = colorTransferFunction;
  275. this->qvtkReconnect(d->ColorTransferFunction,vtkCommand::ModifiedEvent,
  276. this, SIGNAL(changed()));
  277. emit changed();
  278. }
  279. //-----------------------------------------------------------------------------
  280. vtkColorTransferFunction* ctkVTKColorTransferFunction::colorTransferFunction()const
  281. {
  282. Q_D(const ctkVTKColorTransferFunction);
  283. return d->ColorTransferFunction;
  284. }
  285. //-----------------------------------------------------------------------------
  286. void ctkVTKColorTransferFunction::removeControlPoint( qreal pos )
  287. {
  288. Q_D(ctkVTKColorTransferFunction);
  289. d->ColorTransferFunction->RemovePoint( pos );
  290. }