ctkMaterialPropertyPreviewLabel.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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 <QImage>
  18. #include <QPainter>
  19. #include <QVector3D>
  20. //CTK includes
  21. #include "ctkMaterialPropertyPreviewLabel.h"
  22. // STD includes
  23. #include <cmath>
  24. //ctkMaterialPropertyPreviewLabelPrivate
  25. //-----------------------------------------------------------------------------
  26. class ctkMaterialPropertyPreviewLabelPrivate
  27. {
  28. Q_DECLARE_PUBLIC(ctkMaterialPropertyPreviewLabel);
  29. protected:
  30. ctkMaterialPropertyPreviewLabel* const q_ptr;
  31. public:
  32. ctkMaterialPropertyPreviewLabelPrivate(ctkMaterialPropertyPreviewLabel& object);
  33. QColor Color;
  34. double Opacity;
  35. double Ambient;
  36. double Diffuse;
  37. double Specular;
  38. double SpecularPower;
  39. double GridOpacity;
  40. };
  41. //-----------------------------------------------------------------------------
  42. ctkMaterialPropertyPreviewLabelPrivate::ctkMaterialPropertyPreviewLabelPrivate(ctkMaterialPropertyPreviewLabel& object)
  43. :q_ptr(&object)
  44. {
  45. this->Color = Qt::white;
  46. this->Opacity = 1.;
  47. this->Ambient = 0.0;
  48. this->Diffuse = 1.0;
  49. this->Specular = 0.0;
  50. this->SpecularPower = 1;
  51. this->GridOpacity = 0.6;
  52. }
  53. //ctkMaterialPropertyPreviewLabel
  54. //-----------------------------------------------------------------------------
  55. ctkMaterialPropertyPreviewLabel::ctkMaterialPropertyPreviewLabel(QWidget *newParent)
  56. : QFrame(newParent)
  57. , d_ptr(new ctkMaterialPropertyPreviewLabelPrivate(*this))
  58. {
  59. }
  60. //-----------------------------------------------------------------------------
  61. ctkMaterialPropertyPreviewLabel::ctkMaterialPropertyPreviewLabel(
  62. const QColor& color, double opacity,
  63. double ambient, double diffuse,
  64. double specular, double specularPower,
  65. QWidget *newParent)
  66. : QFrame(newParent)
  67. , d_ptr(new ctkMaterialPropertyPreviewLabelPrivate(*this))
  68. {
  69. Q_D(ctkMaterialPropertyPreviewLabel);
  70. d->Color = color;
  71. d->Opacity = opacity;
  72. d->Ambient = ambient;
  73. d->Diffuse = diffuse;
  74. d->Specular = specular;
  75. d->SpecularPower = specularPower;
  76. }
  77. //-----------------------------------------------------------------------------
  78. ctkMaterialPropertyPreviewLabel::~ctkMaterialPropertyPreviewLabel()
  79. {
  80. }
  81. //-----------------------------------------------------------------------------
  82. void ctkMaterialPropertyPreviewLabel::setAmbient(double newAmbient)
  83. {
  84. Q_D(ctkMaterialPropertyPreviewLabel);
  85. d->Ambient = newAmbient;
  86. this->update();
  87. }
  88. //-----------------------------------------------------------------------------
  89. double ctkMaterialPropertyPreviewLabel::ambient()const
  90. {
  91. Q_D(const ctkMaterialPropertyPreviewLabel);
  92. return d->Ambient;
  93. }
  94. //-----------------------------------------------------------------------------
  95. void ctkMaterialPropertyPreviewLabel::setDiffuse(double newDiffuse)
  96. {
  97. Q_D(ctkMaterialPropertyPreviewLabel);
  98. d->Diffuse = newDiffuse;
  99. this->update();
  100. }
  101. //-----------------------------------------------------------------------------
  102. double ctkMaterialPropertyPreviewLabel::diffuse()const
  103. {
  104. Q_D(const ctkMaterialPropertyPreviewLabel);
  105. return d->Diffuse;
  106. }
  107. //-----------------------------------------------------------------------------
  108. void ctkMaterialPropertyPreviewLabel::setSpecular(double newSpecular)
  109. {
  110. Q_D(ctkMaterialPropertyPreviewLabel);
  111. d->Specular = newSpecular;
  112. this->update();
  113. }
  114. //-----------------------------------------------------------------------------
  115. double ctkMaterialPropertyPreviewLabel::specular()const
  116. {
  117. Q_D(const ctkMaterialPropertyPreviewLabel);
  118. return d->Specular;
  119. }
  120. //-----------------------------------------------------------------------------
  121. void ctkMaterialPropertyPreviewLabel::setSpecularPower(double newSpecularPower)
  122. {
  123. Q_D(ctkMaterialPropertyPreviewLabel);
  124. d->SpecularPower = newSpecularPower;
  125. this->update();
  126. }
  127. //-----------------------------------------------------------------------------
  128. double ctkMaterialPropertyPreviewLabel::specularPower()const
  129. {
  130. Q_D(const ctkMaterialPropertyPreviewLabel);
  131. return d->SpecularPower;
  132. }
  133. //-----------------------------------------------------------------------------
  134. void ctkMaterialPropertyPreviewLabel::setColor(const QColor& newColor)
  135. {
  136. Q_D(ctkMaterialPropertyPreviewLabel);
  137. d->Color = newColor;
  138. this->update();
  139. }
  140. //-----------------------------------------------------------------------------
  141. QColor ctkMaterialPropertyPreviewLabel::color()const
  142. {
  143. Q_D(const ctkMaterialPropertyPreviewLabel);
  144. return d->Color;
  145. }
  146. //-----------------------------------------------------------------------------
  147. void ctkMaterialPropertyPreviewLabel::setOpacity(double newOpacity)
  148. {
  149. Q_D(ctkMaterialPropertyPreviewLabel);
  150. d->Opacity = newOpacity;
  151. this->update();
  152. }
  153. //-----------------------------------------------------------------------------
  154. double ctkMaterialPropertyPreviewLabel::opacity()const
  155. {
  156. Q_D(const ctkMaterialPropertyPreviewLabel);
  157. return d->Opacity;
  158. }
  159. //-----------------------------------------------------------------------------
  160. void ctkMaterialPropertyPreviewLabel::setGridOpacity(double newGridOpacity)
  161. {
  162. Q_D(ctkMaterialPropertyPreviewLabel);
  163. d->GridOpacity = newGridOpacity;
  164. this->update();
  165. }
  166. //-----------------------------------------------------------------------------
  167. double ctkMaterialPropertyPreviewLabel::gridOpacity()const
  168. {
  169. Q_D(const ctkMaterialPropertyPreviewLabel);
  170. return d->GridOpacity;
  171. }
  172. //-----------------------------------------------------------------------------
  173. int ctkMaterialPropertyPreviewLabel::heightForWidth(int w)const
  174. {
  175. return w;
  176. }
  177. //-----------------------------------------------------------------------------
  178. QSize ctkMaterialPropertyPreviewLabel::sizeHint()const
  179. {
  180. return QSize(30,30);
  181. }
  182. //-----------------------------------------------------------------------------
  183. void ctkMaterialPropertyPreviewLabel::paintEvent(QPaintEvent* event)
  184. {
  185. Q_UNUSED(event);
  186. QRect cr = this->contentsRect();
  187. QImage image(cr.size(), QImage::Format_ARGB32_Premultiplied);
  188. this->draw(image);
  189. QPainter widgetPainter(this);
  190. this->drawFrame(&widgetPainter);
  191. widgetPainter.drawImage(cr.left(), cr.top(), image);
  192. }
  193. //-----------------------------------------------------------------------------
  194. //From vtkKWMaterialPropertyWidget::CreateImage
  195. void ctkMaterialPropertyPreviewLabel::draw(QImage& image)
  196. {
  197. Q_D(ctkMaterialPropertyPreviewLabel);
  198. qreal opacity = d->Opacity;
  199. qreal ambient = d->Ambient;
  200. qreal diffuse = d->Diffuse;
  201. qreal specular = d->Specular;
  202. qreal specular_power = d->SpecularPower;
  203. int size = qMin(image.width(), image.height());
  204. int size8 = qMax(size / 8, 1);
  205. qreal size2 = 0.5 * size;
  206. qreal radius2 = size2*size2 - 1;
  207. QRgb rgba;
  208. for (int i = 0; i < image.width(); ++i)
  209. {
  210. for (int j = 0; j < image.height(); ++j)
  211. {
  212. int iGrid = i / size8;
  213. int jGrid = j / size8;
  214. if (((iGrid / 2) * 2 == iGrid &&
  215. (jGrid / 2) * 2 == jGrid) ||
  216. ((iGrid / 2) * 2 != iGrid &&
  217. (jGrid / 2) * 2 != jGrid))
  218. {
  219. rgba = qRgba(0, 0, 0, d->GridOpacity * 255);
  220. }
  221. else
  222. {
  223. rgba = qRgba(255. * d->GridOpacity,
  224. 255. * d->GridOpacity,
  225. 255. * d->GridOpacity,
  226. 255. * d->GridOpacity);
  227. }
  228. qreal dist = static_cast<qreal>((i-size2)*(i-size2) + (j-size2)*(j-size2));
  229. if (dist <= radius2)
  230. {
  231. QVector3D pt;
  232. pt.setX( (i-size2) / (size2-1) );
  233. pt.setY( (j-size2) / (size2-1) );
  234. pt.setZ( sqrt(qMax(1. - pt.x()*pt.x() - pt.y()*pt.y(), 0.)) );
  235. QVector3D normal = pt;
  236. normal.normalize();
  237. QVector3D light;
  238. light.setX(-5 - pt.x());
  239. light.setY(-5 - pt.y());
  240. light.setZ( 5 - pt.z());
  241. light.normalize();
  242. QVector3D view;
  243. view.setX(-pt.x());
  244. view.setY(-pt.y());
  245. view.setZ(5 - pt.z());
  246. view.normalize();
  247. qreal dot = QVector3D::dotProduct(normal, light);
  248. QVector3D ref;
  249. ref.setX( 2.*normal.x()*dot - light.x());
  250. ref.setY( 2.*normal.y()*dot - light.y());
  251. ref.setZ( 2.*normal.z()*dot - light.z());
  252. ref.normalize();
  253. qreal diffuseComp = qMax(diffuse * dot, static_cast<qreal>(0.));
  254. qreal specularDot = qMax(static_cast<qreal>(QVector3D::dotProduct(ref, view)), static_cast<qreal>(0));
  255. qreal specularComp = specular*pow(specularDot, specular_power);
  256. QVector3D intensity;
  257. intensity.setX( qMin(static_cast<qreal>((ambient + diffuseComp)*d->Color.redF() + specularComp), static_cast<qreal>(1.)));
  258. intensity.setY( qMin(static_cast<qreal>((ambient + diffuseComp)*d->Color.greenF() + specularComp), static_cast<qreal>(1.)));
  259. intensity.setZ( qMin(static_cast<qreal>((ambient + diffuseComp)*d->Color.blueF() + specularComp), static_cast<qreal>(1.)));
  260. if (opacity == 1.)
  261. {
  262. rgba = qRgba(static_cast<unsigned char>(255. * intensity.x() * opacity),
  263. static_cast<unsigned char>(255. * intensity.y() * opacity),
  264. static_cast<unsigned char>(255. * intensity.z() * opacity),
  265. static_cast<unsigned char>(255. * opacity));
  266. }
  267. else
  268. {
  269. rgba = qRgba(static_cast<unsigned char>(qMin(255. * intensity.x() * opacity + qRed(rgba)*(1. - opacity), static_cast<qreal>(255.))),
  270. static_cast<unsigned char>(qMin(255. * intensity.y() * opacity + qGreen(rgba)*(1. - opacity), static_cast<qreal>(255.))),
  271. static_cast<unsigned char>(qMin(255. * intensity.z() * opacity + qBlue(rgba)*(1. - opacity), static_cast<qreal>(255.))),
  272. static_cast<unsigned char>(qMin(255. * opacity + qAlpha(rgba)*(1. - opacity), static_cast<qreal>(255.))));
  273. }
  274. }
  275. image.setPixel(i,j,rgba);
  276. }
  277. }
  278. }