ctkTransferFunctionItem.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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. #include <QLinearGradient>
  18. #include <QGraphicsSceneMouseEvent>
  19. #include <QPainter>
  20. #include <QtGlobal>
  21. #include <QVariant>
  22. /// CTK includes
  23. #include "ctkTransferFunction.h"
  24. #include "ctkTransferFunctionItem.h"
  25. #include "ctkTransferFunctionScene.h"
  26. //-----------------------------------------------------------------------------
  27. class ctkTransferFunctionItemPrivate
  28. {
  29. public:
  30. ctkTransferFunctionItemPrivate();
  31. void init();
  32. QRectF Rect;
  33. ctkTransferFunction* TransferFunction;
  34. };
  35. //-----------------------------------------------------------------------------
  36. ctkTransferFunctionItemPrivate::ctkTransferFunctionItemPrivate()
  37. {
  38. this->TransferFunction = 0;
  39. this->Rect = QRectF(0.,0.,1.,1.);
  40. }
  41. //-----------------------------------------------------------------------------
  42. void ctkTransferFunctionItemPrivate::init()
  43. {
  44. //Q_Q(ctkTransferFunctionItem);
  45. }
  46. //-----------------------------------------------------------------------------
  47. ctkTransferFunctionItem::ctkTransferFunctionItem(QGraphicsItem* parentGraphicsItem)
  48. :QGraphicsObject(parentGraphicsItem)
  49. , d_ptr(new ctkTransferFunctionItemPrivate)
  50. {
  51. Q_D(ctkTransferFunctionItem);
  52. d->init();
  53. }
  54. //-----------------------------------------------------------------------------
  55. ctkTransferFunctionItem::ctkTransferFunctionItem(
  56. ctkTransferFunction* transferFunction, QGraphicsItem* parentItem)
  57. :QGraphicsObject(parentItem)
  58. , d_ptr(new ctkTransferFunctionItemPrivate)
  59. {
  60. Q_D(ctkTransferFunctionItem);
  61. d->init();
  62. this->setTransferFunction(transferFunction);
  63. }
  64. //-----------------------------------------------------------------------------
  65. ctkTransferFunctionItem::~ctkTransferFunctionItem()
  66. {
  67. }
  68. //-----------------------------------------------------------------------------
  69. void ctkTransferFunctionItem::setTransferFunction(ctkTransferFunction* transferFunction)
  70. {
  71. Q_D(ctkTransferFunctionItem);
  72. d->TransferFunction = transferFunction;
  73. if (this->scene())
  74. {
  75. connect(d->TransferFunction,SIGNAL(changed()),
  76. this->scene(), SLOT(update()),Qt::UniqueConnection);
  77. }
  78. }
  79. //-----------------------------------------------------------------------------
  80. ctkTransferFunction* ctkTransferFunctionItem::transferFunction() const
  81. {
  82. Q_D(const ctkTransferFunctionItem);
  83. return d->TransferFunction;
  84. }
  85. //-----------------------------------------------------------------------------
  86. void ctkTransferFunctionItem::setRect(const QRectF& newRect)
  87. {
  88. Q_D(ctkTransferFunctionItem);
  89. if (d->Rect == newRect)
  90. {
  91. return;
  92. }
  93. d->Rect = newRect;
  94. this->update();
  95. }
  96. //-----------------------------------------------------------------------------
  97. QRectF ctkTransferFunctionItem::rect() const
  98. {
  99. Q_D(const ctkTransferFunctionItem);
  100. return d->Rect;
  101. }
  102. //-----------------------------------------------------------------------------
  103. QRectF ctkTransferFunctionItem::boundingRect()const
  104. {
  105. Q_D(const ctkTransferFunctionItem);
  106. return d->Rect;
  107. }
  108. /*
  109. //-----------------------------------------------------------------------------
  110. QList<ctkPoint> ctkTransferFunctionItem::bezierParams(
  111. ctkControlPoint* start, ctkControlPoint* end) const
  112. {
  113. Q_ASSERT(start);
  114. Q_ASSERT(end);
  115. QList<ctkPoint> points;
  116. ctkBezierControlPoint* bezierCP = dynamic_cast<ctkBezierControlPoint*>(start);
  117. if (!bezierCP)
  118. {// just duplicate start and end into p1 and p2
  119. points << start->P;
  120. points << start->P;
  121. points << end->P;
  122. points << end->P;
  123. return points;
  124. }
  125. points << start->P;
  126. points << bezierCP->P1;
  127. points << bezierCP->P2;
  128. points << end->P;
  129. return points;
  130. }
  131. //-----------------------------------------------------------------------------
  132. QList<ctkPoint> ctkTransferFunctionItem::nonLinearPoints(
  133. ctkControlPoint* start, ctkControlPoint* end) const
  134. {
  135. Q_ASSERT(start);
  136. ctkNonLinearControlPoint* nonLinearCP =
  137. dynamic_cast<ctkNonLinearControlPoint*>(start);
  138. if (!nonLinearCP)
  139. {
  140. QList<ctkPoint> points;
  141. points << start->P;
  142. points << end->P;
  143. return points;
  144. }
  145. return nonLinearCP->SubPoints;
  146. }
  147. //-----------------------------------------------------------------------------
  148. qreal ctkTransferFunctionItem::y(const QVariant& v) const
  149. {
  150. Q_ASSERT(v.canConvert<qreal>() || v.canConvert<QColor>());
  151. if (v.canConvert<QColor>())
  152. {
  153. return v.value<QColor>().alphaF();
  154. }
  155. return v.toReal();
  156. }
  157. //-----------------------------------------------------------------------------
  158. QColor ctkTransferFunctionItem::color(const QVariant& v) const
  159. {
  160. //Q_ASSERT(v.canConvert<QColor>());
  161. if (v.canConvert<QColor>())
  162. {
  163. return v.value<QColor>();
  164. }
  165. else
  166. {
  167. //black background
  168. QColor defaultColor(0., 0., 0.);
  169. return defaultColor;
  170. }
  171. return QColor();
  172. }
  173. //-----------------------------------------------------------------------------
  174. qreal ctkTransferFunctionItem::rangeXDiff()
  175. {
  176. // pointer to private class
  177. Q_D(ctkTransferFunctionItem);
  178. qreal rangeX[2];
  179. d->TransferFunction->range(rangeX);
  180. return this->rect().width() / (rangeX[1] - rangeX[0]);
  181. }
  182. //-----------------------------------------------------------------------------
  183. qreal ctkTransferFunctionItem::rangeXOffSet()
  184. {
  185. // pointer to private class
  186. Q_D(ctkTransferFunctionItem);
  187. qreal rangeX[2];
  188. d->TransferFunction->range(rangeX);
  189. return rangeX[0];
  190. }
  191. //-----------------------------------------------------------------------------
  192. qreal ctkTransferFunctionItem::rangeYDiff()
  193. {
  194. // pointer to private class
  195. Q_D(ctkTransferFunctionItem);
  196. QVariant rangeY[2];
  197. rangeY[0] = d->TransferFunction->minValue();
  198. rangeY[1] = d->TransferFunction->maxValue();
  199. qreal rangeYDiff = this->rect().height();
  200. if (rangeY[0].canConvert<qreal>())
  201. {
  202. if (rangeY[1].toReal() == rangeY[0].toReal())
  203. {
  204. rangeYDiff /= rangeY[0].toReal();
  205. return rangeYDiff;
  206. }
  207. else
  208. {
  209. rangeYDiff /= rangeY[1].toReal() - rangeY[0].toReal();
  210. return rangeYDiff;
  211. }
  212. }
  213. else if (rangeY[0].canConvert<QColor>())
  214. {
  215. if ( rangeY[1].value<QColor>().alphaF() == rangeY[0].value<QColor>().alphaF())
  216. {
  217. rangeYDiff /= rangeY[0].value<QColor>().alphaF();
  218. return rangeYDiff;
  219. }
  220. else
  221. {
  222. rangeYDiff /= rangeY[1].value<QColor>().alphaF() - rangeY[0].value<QColor>().alphaF();
  223. return rangeYDiff;
  224. }
  225. }
  226. else
  227. {
  228. Q_ASSERT(rangeY[0].canConvert<qreal>() ||
  229. rangeY[0].canConvert<QColor>());
  230. }
  231. return rangeYDiff;
  232. }
  233. //-----------------------------------------------------------------------------
  234. qreal ctkTransferFunctionItem::rangeYOffSet()
  235. {
  236. // pointer to private class
  237. Q_D(ctkTransferFunctionItem);
  238. QVariant rangeY[2];
  239. rangeY[0] = d->TransferFunction->minValue();
  240. rangeY[1] = d->TransferFunction->maxValue();
  241. if (rangeY[0].canConvert<qreal>())
  242. {
  243. if (rangeY[1].toReal() == rangeY[0].toReal())
  244. {
  245. return 0.;
  246. }
  247. else
  248. {
  249. return rangeY[0].toReal();
  250. }
  251. }
  252. else if (rangeY[0].canConvert<QColor>())
  253. {
  254. if ( rangeY[1].value<QColor>().alphaF() == rangeY[0].value<QColor>().alphaF())
  255. {
  256. return 0.;
  257. }
  258. else
  259. {
  260. return rangeY[0].value<QColor>().alphaF();
  261. }
  262. }
  263. else
  264. {
  265. Q_ASSERT(rangeY[0].canConvert<qreal>() ||
  266. rangeY[0].canConvert<QColor>());
  267. }
  268. return 0;
  269. }
  270. //-----------------------------------------------------------------------------
  271. QPointF ctkTransferFunctionItem::transferFunction2ScreenCoordinates( qreal x, qreal y)
  272. {
  273. QPointF screenCoordinates((x - this->rangeXOffSet() ) * this->rangeXDiff(),
  274. this->rect().height() - (y - this->rangeYOffSet() ) * this->rangeYDiff() );
  275. return screenCoordinates;
  276. }
  277. //-----------------------------------------------------------------------------
  278. QPointF ctkTransferFunctionItem::screen2TransferFunctionCoordinates( qreal x, qreal y)
  279. {
  280. QPointF transferFunctionCoordinates((x / this->rangeXDiff() ) + this->rangeXOffSet(),
  281. ( - y + this->rect().height() )/this->rangeYDiff() + this->rangeYOffSet());
  282. return transferFunctionCoordinates;
  283. }
  284. */
  285. //-----------------------------------------------------------------------------
  286. QVariant ctkTransferFunctionItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value)
  287. {
  288. QVariant res = this->QGraphicsObject::itemChange(change, value);
  289. if (change == QGraphicsItem::ItemSceneHasChanged && this->scene())
  290. {
  291. connect(this->transferFunction(),SIGNAL(changed()),
  292. this->scene(), SLOT(update()),Qt::UniqueConnection);
  293. }
  294. return res;
  295. }