/qtgui/lenseffectswidget.cpp

https://bitbucket.org/luxrender/lux · C++ · 451 lines · 313 code · 104 blank · 34 comment · 25 complexity · 29fbb3c17060eba3fb8f03c6b483bae9 MD5 · raw file

  1. /***************************************************************************
  2. * Copyright (C) 1998-2013 by authors (see AUTHORS.txt) *
  3. * *
  4. * This file is part of LuxRender. *
  5. * *
  6. * Lux Renderer is free software; you can redistribute it and/or modify *
  7. * it under the terms of the GNU General Public License as published by *
  8. * the Free Software Foundation; either version 3 of the License, or *
  9. * (at your option) any later version. *
  10. * *
  11. * Lux Renderer is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * You should have received a copy of the GNU General Public License *
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  18. * *
  19. * This project is based on PBRT ; see http://www.pbrt.org *
  20. * Lux Renderer website : http://www.luxrender.net *
  21. ***************************************************************************/
  22. #include <cmath>
  23. #include <QFont>
  24. #include <QFileDialog>
  25. #include <QFileInfo>
  26. #include "api.h"
  27. #include "lenseffectswidget.hxx"
  28. #include "mainwindow.hxx"
  29. #include "ui_lenseffects.h"
  30. LensEffectsWidget::LensEffectsWidget(QWidget *parent) : QWidget(parent), ui(new Ui::LensEffectsWidget)
  31. {
  32. ui->setupUi(this);
  33. // Bloom
  34. connect(ui->slider_gaussianAmount, SIGNAL(valueChanged(int)), this, SLOT(gaussianAmountChanged(int)));
  35. connect(ui->spinBox_gaussianAmount, SIGNAL(valueChanged(double)), this, SLOT(gaussianAmountChanged(double)));
  36. connect(ui->slider_gaussianRadius, SIGNAL(valueChanged(int)), this, SLOT(gaussianRadiusChanged(int)));
  37. connect(ui->spinBox_gaussianRadius, SIGNAL(valueChanged(double)), this, SLOT(gaussianRadiusChanged(double)));
  38. connect(ui->button_gaussianComputeLayer, SIGNAL(clicked()), this, SLOT(computeBloomLayer()));
  39. connect(ui->button_gaussianDeleteLayer, SIGNAL(clicked()), this, SLOT(deleteBloomLayer()));
  40. // Vignetting
  41. connect(ui->slider_vignettingAmount, SIGNAL(valueChanged(int)), this, SLOT(vignettingAmountChanged(int)));
  42. connect(ui->spinBox_vignettingAmount, SIGNAL(valueChanged(double)), this, SLOT(vignettingAmountChanged(double)));
  43. connect(ui->checkBox_vignettingEnabled, SIGNAL(stateChanged(int)), this, SLOT(vignettingEnabledChanged(int)));
  44. // Chromatic abberration
  45. connect(ui->slider_caAmount, SIGNAL(valueChanged(int)), this, SLOT(caAmountChanged(int)));
  46. connect(ui->spinBox_caAmount, SIGNAL(valueChanged(double)), this, SLOT(caAmountChanged(double)));
  47. connect(ui->checkBox_caEnabled, SIGNAL(stateChanged(int)), this, SLOT(caEnabledChanged(int)));
  48. // Glare
  49. connect(ui->slider_glareAmount, SIGNAL(valueChanged(int)), this, SLOT(glareAmountChanged(int)));
  50. connect(ui->spinBox_glareAmount, SIGNAL(valueChanged(double)), this, SLOT(glareAmountChanged(double)));
  51. connect(ui->slider_glareRadius, SIGNAL(valueChanged(int)), this, SLOT(glareRadiusChanged(int)));
  52. connect(ui->spinBox_glareRadius, SIGNAL(valueChanged(double)), this, SLOT(glareRadiusChanged(double)));
  53. connect(ui->spinBox_glareBlades, SIGNAL(valueChanged(int)), this, SLOT(glareBladesChanged(int)));
  54. connect(ui->slider_glareThreshold, SIGNAL(valueChanged(int)), this, SLOT(glareThresholdSliderChanged(int)));
  55. connect(ui->spinBox_glareThreshold, SIGNAL(valueChanged(double)), this, SLOT(glareThresholdSpinBoxChanged(double)));
  56. connect(ui->button_glareComputeLayer, SIGNAL(clicked()), this, SLOT(computeGlareLayer()));
  57. connect(ui->button_glareDeleteLayer, SIGNAL(clicked()), this, SLOT(deleteGlareLayer()));
  58. connect(ui->checkBox_glareMap, SIGNAL(stateChanged(int)), this, SLOT(glareMapChanged(int)));
  59. connect(ui->button_browsePupilMap, SIGNAL(clicked()), this, SLOT(glareBrowsePupilMap()));
  60. connect(ui->button_browseLashesMap, SIGNAL(clicked()), this, SLOT(glareBrowseLashesMap()));
  61. #if defined(__APPLE__) // for better design on OSX
  62. ui->tab_gaussianBloom->setFont(QFont ("Lucida Grande", 11));
  63. ui->tab_vignetting->setFont(QFont ("Lucida Grande", 11));
  64. ui->tab_chromaticAbberationTab->setFont(QFont ("Lucida Grande", 11));
  65. ui->tab_glare->setFont(QFont ("Lucida Grande", 11));
  66. #endif
  67. }
  68. LensEffectsWidget::~LensEffectsWidget()
  69. {
  70. }
  71. void LensEffectsWidget::changeEvent(QEvent *event)
  72. {
  73. if (event->type() == QEvent::EnabledChange) {
  74. updateParam(LUX_FILM, LUX_FILM_VIGNETTING_ENABLED, m_Vignetting_Enabled && this->isEnabled());
  75. updateParam(LUX_FILM, LUX_FILM_ABERRATION_ENABLED, m_Aberration_enabled && this->isEnabled());
  76. updateParam(LUX_FILM, LUX_FILM_GLARE_AMOUNT, this->isEnabled() ? m_Glare_amount : 0.0);
  77. updateParam(LUX_FILM, LUX_FILM_BLOOMWEIGHT, this->isEnabled() ? m_bloomweight : 0.0);
  78. if (!this->isEnabled())
  79. // prevent bloom update
  80. updateParam(LUX_FILM, LUX_FILM_UPDATEBLOOMLAYER, 0.0);
  81. emit valuesChanged ();
  82. }
  83. }
  84. void LensEffectsWidget::updateWidgetValues()
  85. {
  86. int sliderval;
  87. // Bloom widgets
  88. updateWidgetValue (ui->slider_gaussianAmount, (int)((FLOAT_SLIDER_RES / BLOOMWEIGHT_RANGE) * m_bloomweight));
  89. updateWidgetValue (ui->spinBox_gaussianAmount, m_bloomweight);
  90. updateWidgetValue (ui->slider_gaussianRadius, (int)((FLOAT_SLIDER_RES / BLOOMRADIUS_RANGE) * m_bloomradius));
  91. updateWidgetValue (ui->spinBox_gaussianRadius, m_bloomradius);
  92. // Vignetting
  93. if (m_Vignetting_Scale >= 0.f)
  94. sliderval = (int) (FLOAT_SLIDER_RES/2) + (( (FLOAT_SLIDER_RES/2) / VIGNETTING_SCALE_RANGE ) * (m_Vignetting_Scale));
  95. else
  96. sliderval = (int)(( FLOAT_SLIDER_RES/2 * VIGNETTING_SCALE_RANGE ) * (1.f - std::fabs(m_Vignetting_Scale)));
  97. updateWidgetValue (ui->slider_vignettingAmount, sliderval);
  98. updateWidgetValue (ui->spinBox_vignettingAmount, m_Vignetting_Scale);
  99. // Chromatic aberration
  100. updateWidgetValue(ui->slider_caAmount, (int) (( FLOAT_SLIDER_RES / ABERRATION_AMOUNT_RANGE ) * (m_Aberration_amount)));
  101. updateWidgetValue(ui->spinBox_caAmount, m_Aberration_amount);
  102. // Glare
  103. updateWidgetValue(ui->slider_glareAmount, (int)((FLOAT_SLIDER_RES / GLARE_AMOUNT_RANGE) * m_Glare_amount));
  104. updateWidgetValue(ui->spinBox_glareAmount, m_Glare_amount);
  105. updateWidgetValue(ui->slider_glareRadius, (int)((FLOAT_SLIDER_RES / GLARE_RADIUS_RANGE) * m_Glare_radius));
  106. updateWidgetValue(ui->spinBox_glareRadius, m_Glare_radius);
  107. updateWidgetValue(ui->spinBox_glareBlades, m_Glare_blades);
  108. updateWidgetValue(ui->slider_glareThreshold, (int)((FLOAT_SLIDER_RES / GLARE_THRESHOLD_RANGE) * m_Glare_threshold));
  109. updateWidgetValue(ui->spinBox_glareThreshold, m_Glare_threshold);
  110. updateWidgetValue(ui->checkBox_glareMap, m_Glare_map);
  111. updateWidgetValue(ui->lineEdit_pupilMap, m_Glare_pupil);
  112. updateWidgetValue(ui->lineEdit_lashesMap, m_Glare_lashes);
  113. }
  114. void LensEffectsWidget::resetValues()
  115. {
  116. m_bloomradius = 0.07f;
  117. m_bloomweight = 0.25f;
  118. m_Vignetting_Enabled = false;
  119. m_Vignetting_Scale = 0.4;
  120. m_Aberration_enabled = false;
  121. m_Aberration_amount = 0.5;
  122. m_Glare_amount = 0.03f;
  123. m_Glare_radius = 0.03f;
  124. m_Glare_blades = 3;
  125. m_Glare_threshold = 0.5f;
  126. m_Glare_map = false;
  127. m_Glare_pupil = "";
  128. m_Glare_lashes = "";
  129. }
  130. void LensEffectsWidget::resetFromFilm (bool useDefaults)
  131. {
  132. double t;
  133. m_bloomradius = retrieveParam( useDefaults, LUX_FILM, LUX_FILM_BLOOMRADIUS);
  134. m_bloomweight = retrieveParam( useDefaults, LUX_FILM, LUX_FILM_BLOOMWEIGHT);
  135. t = retrieveParam( useDefaults, LUX_FILM, LUX_FILM_VIGNETTING_ENABLED);
  136. m_Vignetting_Enabled = t != 0.0;
  137. m_Vignetting_Scale = retrieveParam( useDefaults, LUX_FILM, LUX_FILM_VIGNETTING_SCALE);
  138. t = retrieveParam( useDefaults, LUX_FILM, LUX_FILM_ABERRATION_ENABLED);
  139. m_Aberration_enabled = t != 0.0;
  140. m_Aberration_amount = retrieveParam( useDefaults, LUX_FILM, LUX_FILM_ABERRATION_AMOUNT);
  141. m_Glare_amount = retrieveParam( useDefaults, LUX_FILM, LUX_FILM_GLARE_AMOUNT);
  142. m_Glare_radius = retrieveParam( useDefaults, LUX_FILM, LUX_FILM_GLARE_RADIUS);
  143. m_Glare_blades = (int)retrieveParam( useDefaults, LUX_FILM, LUX_FILM_GLARE_BLADES);
  144. m_Glare_map = retrieveParam(useDefaults, LUX_FILM, LUX_FILM_GLARE_MAP) != 0;
  145. m_Glare_pupil = retrieveStringParam(useDefaults, LUX_FILM, LUX_FILM_GLARE_PUPIL);
  146. m_Glare_lashes = retrieveStringParam(useDefaults, LUX_FILM, LUX_FILM_GLARE_LASHES);
  147. luxSetParameterValue(LUX_FILM, LUX_FILM_BLOOMRADIUS, m_bloomradius);
  148. luxSetParameterValue(LUX_FILM, LUX_FILM_BLOOMWEIGHT, m_bloomweight);
  149. luxSetParameterValue(LUX_FILM, LUX_FILM_VIGNETTING_ENABLED, m_Vignetting_Enabled);
  150. luxSetParameterValue(LUX_FILM, LUX_FILM_VIGNETTING_SCALE, m_Vignetting_Scale);
  151. luxSetParameterValue(LUX_FILM, LUX_FILM_ABERRATION_ENABLED, m_Aberration_enabled);
  152. luxSetParameterValue(LUX_FILM, LUX_FILM_ABERRATION_AMOUNT, m_Aberration_amount);
  153. luxSetParameterValue(LUX_FILM, LUX_FILM_GLARE_AMOUNT, m_Glare_amount);
  154. luxSetParameterValue(LUX_FILM, LUX_FILM_GLARE_RADIUS, m_Glare_radius);
  155. luxSetParameterValue(LUX_FILM, LUX_FILM_GLARE_BLADES, m_Glare_blades);
  156. luxSetParameterValue(LUX_FILM, LUX_FILM_GLARE_MAP, m_Glare_map);
  157. luxSetStringParameterValue(LUX_FILM, LUX_FILM_GLARE_PUPIL, m_Glare_pupil.toAscii().data());
  158. luxSetStringParameterValue(LUX_FILM, LUX_FILM_GLARE_LASHES, m_Glare_lashes.toAscii().data());
  159. }
  160. void LensEffectsWidget::gaussianAmountChanged (int value)
  161. {
  162. gaussianAmountChanged ( (double)value / ( FLOAT_SLIDER_RES / BLOOMWEIGHT_RANGE ) );
  163. }
  164. void LensEffectsWidget::gaussianAmountChanged (double value)
  165. {
  166. m_bloomweight = value;
  167. int sliderval = (int)((FLOAT_SLIDER_RES / BLOOMWEIGHT_RANGE) * m_bloomweight);
  168. updateWidgetValue(ui->slider_gaussianAmount, sliderval);
  169. updateWidgetValue(ui->spinBox_gaussianAmount, m_bloomweight);
  170. updateParam (LUX_FILM, LUX_FILM_BLOOMWEIGHT, m_bloomweight);
  171. emit valuesChanged ();
  172. }
  173. void LensEffectsWidget::gaussianRadiusChanged (int value)
  174. {
  175. gaussianRadiusChanged ( (double)value / ( FLOAT_SLIDER_RES / BLOOMRADIUS_RANGE ) );
  176. }
  177. void LensEffectsWidget::gaussianRadiusChanged (double value)
  178. {
  179. m_bloomradius = value;
  180. int sliderval = (int)((FLOAT_SLIDER_RES / BLOOMRADIUS_RANGE) * m_bloomradius);
  181. updateWidgetValue(ui->slider_gaussianRadius, sliderval);
  182. updateWidgetValue(ui->spinBox_gaussianRadius, m_bloomradius);
  183. updateParam (LUX_FILM, LUX_FILM_BLOOMRADIUS, m_bloomradius);
  184. }
  185. void LensEffectsWidget::computeBloomLayer()
  186. {
  187. // Signal film to update bloom layer at next tonemap
  188. updateParam(LUX_FILM, LUX_FILM_UPDATEBLOOMLAYER, 1.0f);
  189. ui->button_gaussianDeleteLayer->setEnabled (true);
  190. ui->slider_gaussianAmount->setEnabled(true);
  191. ui->spinBox_gaussianAmount->setEnabled(true);
  192. emit forceUpdate ();
  193. }
  194. void LensEffectsWidget::deleteBloomLayer()
  195. {
  196. // Signal film to delete bloom layer
  197. updateParam(LUX_FILM, LUX_FILM_DELETEBLOOMLAYER, 1.0f);
  198. ui->button_gaussianDeleteLayer->setEnabled (false);
  199. ui->slider_gaussianAmount->setEnabled(false);
  200. ui->spinBox_gaussianAmount->setEnabled(false);
  201. emit forceUpdate ();
  202. }
  203. void LensEffectsWidget::vignettingAmountChanged(int value)
  204. {
  205. double dvalue = -1.0f + (2.0f * (double)value / FLOAT_SLIDER_RES);
  206. vignettingAmountChanged ( dvalue );
  207. }
  208. void LensEffectsWidget::vignettingAmountChanged(double value)
  209. {
  210. m_Vignetting_Scale = value;
  211. int sliderval;
  212. sliderval = (int)(0.5f * (value + 1.0f) * FLOAT_SLIDER_RES);
  213. updateWidgetValue(ui->slider_vignettingAmount, sliderval);
  214. updateWidgetValue(ui->spinBox_vignettingAmount, m_Vignetting_Scale);
  215. updateParam (LUX_FILM, LUX_FILM_VIGNETTING_SCALE, m_Vignetting_Scale);
  216. if (m_Vignetting_Enabled)
  217. emit valuesChanged();
  218. }
  219. void LensEffectsWidget::vignettingEnabledChanged(int value)
  220. {
  221. if (value == Qt::Checked)
  222. m_Vignetting_Enabled = true;
  223. else
  224. m_Vignetting_Enabled = false;
  225. updateParam (LUX_FILM, LUX_FILM_VIGNETTING_ENABLED, m_Vignetting_Enabled);
  226. emit valuesChanged();
  227. }
  228. void LensEffectsWidget::caAmountChanged (int value)
  229. {
  230. caAmountChanged ( (double)value / ( FLOAT_SLIDER_RES / ABERRATION_AMOUNT_RANGE ) );
  231. }
  232. void LensEffectsWidget::caAmountChanged (double value)
  233. {
  234. m_Aberration_amount = value;
  235. if (m_Aberration_amount > ABERRATION_AMOUNT_RANGE)
  236. m_Aberration_amount = ABERRATION_AMOUNT_RANGE;
  237. else if (m_Aberration_amount < 0.0f)
  238. m_Aberration_amount = 0.0f;
  239. int sliderval = (int) (( FLOAT_SLIDER_RES / ABERRATION_AMOUNT_RANGE ) * (m_Aberration_amount));
  240. updateWidgetValue(ui->slider_caAmount, sliderval);
  241. updateWidgetValue(ui->spinBox_caAmount, m_Aberration_amount);
  242. updateParam(LUX_FILM, LUX_FILM_ABERRATION_AMOUNT, ABERRATION_AMOUNT_FACTOR * m_Aberration_amount);
  243. if (m_Aberration_enabled)
  244. emit valuesChanged();
  245. }
  246. void LensEffectsWidget::caEnabledChanged(int value)
  247. {
  248. if (value == Qt::Checked)
  249. m_Aberration_enabled = true;
  250. else
  251. m_Aberration_enabled = false;
  252. updateParam (LUX_FILM, LUX_FILM_ABERRATION_ENABLED, m_Aberration_enabled);
  253. emit valuesChanged();
  254. }
  255. void LensEffectsWidget::glareAmountChanged (int value)
  256. {
  257. glareAmountChanged ( (double)value / ( FLOAT_SLIDER_RES / GLARE_AMOUNT_RANGE ) );
  258. }
  259. void LensEffectsWidget::glareAmountChanged (double value)
  260. {
  261. m_Glare_amount = value;
  262. int sliderval = (int)((FLOAT_SLIDER_RES / GLARE_AMOUNT_RANGE) * m_Glare_amount);
  263. updateWidgetValue(ui->slider_glareAmount, sliderval);
  264. updateWidgetValue(ui->spinBox_glareAmount, m_Glare_amount);
  265. updateParam (LUX_FILM, LUX_FILM_GLARE_AMOUNT, m_Glare_amount);
  266. emit valuesChanged();
  267. }
  268. void LensEffectsWidget::glareRadiusChanged (int value)
  269. {
  270. glareRadiusChanged ( (double)value / ( FLOAT_SLIDER_RES / GLARE_RADIUS_RANGE ) );
  271. }
  272. void LensEffectsWidget::glareRadiusChanged (double value)
  273. {
  274. m_Glare_radius = value;
  275. int sliderval = (int)((FLOAT_SLIDER_RES / GLARE_RADIUS_RANGE) * m_Glare_radius);
  276. updateWidgetValue(ui->slider_glareRadius, sliderval);
  277. updateWidgetValue(ui->spinBox_glareRadius, m_Glare_radius);
  278. updateParam (LUX_FILM, LUX_FILM_GLARE_RADIUS, m_Glare_radius);
  279. }
  280. void LensEffectsWidget::glareBladesChanged(int value)
  281. {
  282. m_Glare_blades = value;
  283. if (m_Glare_blades > GLARE_BLADES_MAX)
  284. m_Glare_blades = GLARE_BLADES_MAX;
  285. else if (m_Glare_blades < GLARE_BLADES_MIN)
  286. m_Glare_blades = GLARE_BLADES_MIN;
  287. updateParam (LUX_FILM, LUX_FILM_GLARE_BLADES, m_Glare_blades);
  288. emit valuesChanged();
  289. }
  290. void LensEffectsWidget::glareThresholdSliderChanged(int value)
  291. {
  292. glareThresholdSpinBoxChanged( (double)value / FLOAT_SLIDER_RES * GLARE_THRESHOLD_RANGE );
  293. }
  294. void LensEffectsWidget::glareThresholdSpinBoxChanged(double value)
  295. {
  296. m_Glare_threshold = value;
  297. int sliderval = (int)(FLOAT_SLIDER_RES / GLARE_THRESHOLD_RANGE * m_Glare_threshold);
  298. updateWidgetValue(ui->slider_glareThreshold, sliderval);
  299. updateWidgetValue(ui->spinBox_glareThreshold, m_Glare_threshold);
  300. updateParam (LUX_FILM, LUX_FILM_GLARE_THRESHOLD, m_Glare_threshold);
  301. }
  302. void LensEffectsWidget::computeGlareLayer()
  303. {
  304. // Signal film to update glare layer at next tonemap
  305. updateParam(LUX_FILM, LUX_FILM_UPDATEGLARELAYER, 1.0f);
  306. ui->button_glareDeleteLayer->setEnabled (true);
  307. ui->slider_glareAmount->setEnabled(true);
  308. ui->spinBox_glareAmount->setEnabled(true);
  309. emit forceUpdate ();
  310. }
  311. void LensEffectsWidget::deleteGlareLayer()
  312. {
  313. // Signal film to delete glare layer
  314. updateParam(LUX_FILM, LUX_FILM_DELETEGLARELAYER, 1.0f);
  315. ui->button_glareDeleteLayer->setEnabled (false);
  316. ui->slider_glareAmount->setEnabled(false);
  317. ui->spinBox_glareAmount->setEnabled(false);
  318. emit forceUpdate ();
  319. }
  320. void LensEffectsWidget::glareMapChanged(int value)
  321. {
  322. if (value == Qt::Checked)
  323. m_Glare_map = true;
  324. else
  325. m_Glare_map = false;
  326. updateParam (LUX_FILM, LUX_FILM_GLARE_MAP, m_Glare_map);
  327. }
  328. void LensEffectsWidget::glareBrowsePupilMap()
  329. {
  330. m_Glare_pupil = QFileDialog::getOpenFileName(this, tr("Choose a pupil/aperture map"), m_lastOpendir, tr("Image files (*.png *.jpg)"));
  331. if (m_Glare_pupil.isEmpty())
  332. return;
  333. ui->lineEdit_pupilMap->setText(m_Glare_pupil);
  334. updateParam(LUX_FILM, LUX_FILM_GLARE_PUPIL, m_Glare_pupil.toAscii().data());
  335. QFileInfo info(m_Glare_pupil);
  336. m_lastOpendir = info.absolutePath();
  337. }
  338. void LensEffectsWidget::glareBrowseLashesMap()
  339. {
  340. m_Glare_lashes = QFileDialog::getOpenFileName(this, tr("Choose an eyelashes/obstacle map"), m_lastOpendir, tr("Image files (*.png *.jpg)"));
  341. if (m_Glare_lashes.isEmpty())
  342. return;
  343. ui->lineEdit_lashesMap->setText(m_Glare_lashes);
  344. updateParam(LUX_FILM, LUX_FILM_GLARE_LASHES, m_Glare_lashes.toAscii().data());
  345. QFileInfo info(m_Glare_lashes);
  346. m_lastOpendir = info.absolutePath();
  347. }