ctkTransferFunctionItem.cpp 9.2 KB

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