ctkTransferFunctionItem.cpp 8.6 KB

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