|
| 1 | +#include "normalsplan.h" |
| 2 | +#include "qlabelbutton.h" |
| 3 | +#include "helpbutton.h" |
| 4 | +#include "relightapp.h" |
| 5 | + |
| 6 | +#include <QButtonGroup> |
| 7 | +#include <QPushButton> |
| 8 | +#include <QLineEdit> |
| 9 | +#include <QHBoxLayout> |
| 10 | +#include <QDoubleSpinBox> |
| 11 | +#include <QMessageBox> |
| 12 | +#include <QFileDialog> |
| 13 | + |
| 14 | +NormalsPlanRow::NormalsPlanRow(NormalsParameters &_parameters, QFrame *parent): |
| 15 | + PlanRow(parent), parameters(_parameters) { |
| 16 | + |
| 17 | +} |
| 18 | + |
| 19 | + |
| 20 | +NormalsSourceRow::NormalsSourceRow(NormalsParameters &_parameters, QFrame *parent): |
| 21 | + NormalsPlanRow(_parameters, parent) { |
| 22 | + label->label->setText("Source:"); |
| 23 | + label->help->setId("normals/normalmap"); |
| 24 | + |
| 25 | + compute = new QLabelButton("Compute", "Compute normals from images"); |
| 26 | + file = new QLabelButton("Normalmap", "Loat a normalmap image."); |
| 27 | + buttons->addWidget(compute, 0, Qt::AlignCenter); |
| 28 | + |
| 29 | + QVBoxLayout *button_layout =new QVBoxLayout; |
| 30 | + button_layout->addWidget(file); |
| 31 | + |
| 32 | + QHBoxLayout *loader_layout = new QHBoxLayout; |
| 33 | + loader_layout->addWidget(path = new QLineEdit); |
| 34 | + loader_layout->addWidget(open = new QPushButton("...")); |
| 35 | + |
| 36 | + button_layout->addLayout(loader_layout); |
| 37 | + |
| 38 | + |
| 39 | + buttons->addLayout(button_layout, 0); //, Qt::AlignCenter); |
| 40 | + |
| 41 | + connect(compute, &QAbstractButton::clicked, this, [this](){ setComputeSource(true); }); |
| 42 | + connect(file, &QAbstractButton::clicked, this, [this](){ setComputeSource(false); }); |
| 43 | + //connect(rbf, &QAbstractButton::clicked, this, [this](){ setBasis(Rti::RBF, true); }); |
| 44 | + //connect(bln, &QAbstractButton::clicked, this, [this](){ setBasis(Rti::BILINEAR, true); }); |
| 45 | + |
| 46 | + QButtonGroup *group = new QButtonGroup(this); |
| 47 | + |
| 48 | + group->addButton(compute); |
| 49 | + group->addButton(file); |
| 50 | +} |
| 51 | + |
| 52 | + |
| 53 | +void NormalsSourceRow::setComputeSource(bool compute) { |
| 54 | + parameters.compute = compute; |
| 55 | +} |
| 56 | + |
| 57 | + |
| 58 | + |
| 59 | +NormalsFlattenRow::NormalsFlattenRow(NormalsParameters &_parameters, QFrame *parent): |
| 60 | + NormalsPlanRow(_parameters, parent) { |
| 61 | + label->label->setText("Flatten:"); |
| 62 | + label->help->setId("normals/flattening"); |
| 63 | + |
| 64 | + none = new QLabelButton("None", "Do not flatten the surface"); |
| 65 | + radial = new QLabelButton("Radial", "Polynomial radial fitting."); |
| 66 | + fourier = new QLabelButton("Fourier", "Remove low frequencies"); |
| 67 | + |
| 68 | + buttons->addWidget(none, 1, Qt::AlignCenter); |
| 69 | + buttons->addWidget(radial, 1, Qt::AlignCenter); |
| 70 | + |
| 71 | + QVBoxLayout *button_layout =new QVBoxLayout; |
| 72 | + button_layout->addWidget(fourier); |
| 73 | + |
| 74 | + QHBoxLayout *loader_layout = new QHBoxLayout; |
| 75 | + loader_layout->addWidget(new QLabel("Fourier low pass frequency.")); |
| 76 | + loader_layout->addWidget(max_frequency = new QDoubleSpinBox); |
| 77 | + max_frequency->setRange(0.01, 1); |
| 78 | + |
| 79 | + button_layout->addLayout(loader_layout); |
| 80 | + |
| 81 | + |
| 82 | + buttons->addLayout(button_layout, 1); //, Qt::AlignCenter); |
| 83 | + |
| 84 | + connect(none, &QAbstractButton::clicked, this, [this](){ setFlattenMethod(FLAT_NONE); }); |
| 85 | + connect(radial, &QAbstractButton::clicked, this, [this](){ setFlattenMethod(FLAT_RADIAL); }); |
| 86 | + connect(fourier, &QAbstractButton::clicked, this, [this](){ setFlattenMethod(FLAT_FOURIER); }); |
| 87 | + |
| 88 | +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) |
| 89 | + connect(max_frequency, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, [this](double v) { parameters.m_FlatRadius = v; }); |
| 90 | +#else |
| 91 | + connect(max_frequency, qOverload<double>(&QDoubleSpinBox::valueChanged), this, [this](double v) { parameters.m_FlatRadius = v; }); |
| 92 | +#endif |
| 93 | + |
| 94 | + |
| 95 | + QButtonGroup *group = new QButtonGroup(this); |
| 96 | + |
| 97 | + group->addButton(none); |
| 98 | + group->addButton(radial); |
| 99 | + group->addButton(fourier); |
| 100 | +} |
| 101 | + |
| 102 | +void NormalsFlattenRow::setFlattenMethod(FlatMethod method) { |
| 103 | + parameters.flatMethod = method; |
| 104 | + none->setChecked(method == FLAT_NONE); |
| 105 | + radial->setChecked(method == FLAT_RADIAL); |
| 106 | + fourier->setChecked(method == FLAT_FOURIER); |
| 107 | +} |
| 108 | + |
| 109 | +void NormalsFlattenRow::setFourierFrequency(double f) { |
| 110 | + parameters.m_FlatRadius = f; |
| 111 | + max_frequency->setValue(f); |
| 112 | +} |
| 113 | + |
| 114 | + |
| 115 | + |
| 116 | +NormalsSurfaceRow::NormalsSurfaceRow(NormalsParameters &_parameters, QFrame *parent): |
| 117 | + NormalsPlanRow(_parameters, parent) { |
| 118 | + label->label->setText("Flatten:"); |
| 119 | + label->help->setId("normals/flattening"); |
| 120 | + |
| 121 | + none = new QLabelButton("None", "Do generate a mesh."); |
| 122 | + bni = new QLabelButton("Bilateral Normal Integration", "Dense, allows discontinuity"); |
| 123 | + assm = new QLabelButton("Adaptive Surface Meshing.", "Adaptive, no discontinuities."); |
| 124 | + |
| 125 | + buttons->addWidget(none, 0, Qt::AlignCenter); |
| 126 | + |
| 127 | + { |
| 128 | + QVBoxLayout *bni_layout =new QVBoxLayout; |
| 129 | + bni_layout->addWidget(bni); |
| 130 | + { |
| 131 | + QHBoxLayout *bni_parameter = new QHBoxLayout; |
| 132 | + bni_parameter->addWidget(new QLabel("Discontinuity propensity.")); |
| 133 | + bni_parameter->addWidget(bni_k = new QDoubleSpinBox); |
| 134 | + bni_k->setRange(0.01, 50); |
| 135 | + bni_k->setValue(parameters.bni_k); |
| 136 | + |
| 137 | + bni_layout->addLayout(bni_parameter); |
| 138 | + } |
| 139 | + buttons->addLayout(bni_layout, 0); //, Qt::AlignCenter); |
| 140 | + } |
| 141 | + |
| 142 | + { |
| 143 | + QVBoxLayout *assm_layout =new QVBoxLayout; |
| 144 | + assm_layout->addWidget(assm); |
| 145 | + |
| 146 | + { |
| 147 | + QHBoxLayout *assm_parameter = new QHBoxLayout; |
| 148 | + assm_parameter->addWidget(new QLabel("Mesh error in pixels..")); |
| 149 | + assm_parameter->addWidget(assm_error = new QDoubleSpinBox); |
| 150 | + assm_error->setRange(0.001, 100); |
| 151 | + assm_error->setValue(parameters.assm_error); |
| 152 | + |
| 153 | + assm_layout->addLayout(assm_parameter); |
| 154 | + } |
| 155 | + buttons->addLayout(assm_layout, 0); //, Qt::AlignCenter); |
| 156 | + } |
| 157 | + |
| 158 | + connect(none, &QAbstractButton::clicked, this, [this](){ setSurfaceMethod(SURFACE_NONE); }); |
| 159 | + connect(bni, &QAbstractButton::clicked, this, [this](){ setSurfaceMethod(SURFACE_BNI); }); |
| 160 | + connect(assm, &QAbstractButton::clicked, this, [this](){ setSurfaceMethod(SURFACE_ASSM); }); |
| 161 | + |
| 162 | +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) |
| 163 | + connect(bni_k, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, [this](double v) { parameters.bni_k = v; }); |
| 164 | + connect(assm_error, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, [this](double v) { parameters.assm_error = v; }); |
| 165 | +#else |
| 166 | + connect(bni_k, qOverload<double>(&QDoubleSpinBox::valueChanged), this, [this](double v) { parameters.bni_k = v; }); |
| 167 | + connect(assm_error, qOverload<double>(&QDoubleSpinBox::valueChanged), this, [this](double v) { parameters.assm_error = v; }); |
| 168 | +#endif |
| 169 | + |
| 170 | + QButtonGroup *group = new QButtonGroup(this); |
| 171 | + group->addButton(none); |
| 172 | + group->addButton(bni); |
| 173 | + group->addButton(assm); |
| 174 | +} |
| 175 | + |
| 176 | +void NormalsSurfaceRow::setSurfaceMethod(SurfaceIntegration surface) { |
| 177 | + parameters.surface_integration = surface; |
| 178 | + none->setChecked(surface == SURFACE_NONE); |
| 179 | + bni->setChecked(surface == SURFACE_BNI); |
| 180 | + assm->setChecked(surface == SURFACE_ASSM); |
| 181 | +} |
| 182 | + |
| 183 | + |
| 184 | + |
| 185 | +NormalsExportRow::NormalsExportRow(NormalsParameters ¶meters, QFrame *parent): NormalsPlanRow(parameters, parent) { |
| 186 | + label->label->setText("Directory/File:"); |
| 187 | + label->help->setId("normals/export"); |
| 188 | + |
| 189 | + path_edit = new QLineEdit; |
| 190 | + connect(path_edit, &QLineEdit::editingFinished,this, &NormalsExportRow::verifyPath); |
| 191 | + buttons->addWidget(path_edit); |
| 192 | + QPushButton *path_button = new QPushButton("..."); |
| 193 | + buttons->addWidget(path_button); |
| 194 | + connect(path_button, &QPushButton::clicked, this, &NormalsExportRow::selectOutput); |
| 195 | +} |
| 196 | + |
| 197 | +void NormalsExportRow::setPath(QString path, bool emitting) { |
| 198 | + path_edit->setText(path); |
| 199 | + parameters.path = path; |
| 200 | +} |
| 201 | + |
| 202 | +void NormalsExportRow::verifyPath() { |
| 203 | + parameters.path = QString(); |
| 204 | + QString path = path_edit->text(); |
| 205 | + QDir path_dir(path); |
| 206 | + path_dir.cdUp(); |
| 207 | + if(!path_dir.exists()) { |
| 208 | + QMessageBox::warning(this, "Invalid output path", "The specified path is not valid"); |
| 209 | + return; |
| 210 | + } |
| 211 | + if(!path.endsWith(".jpg") && !path.endsWith(".png")) { |
| 212 | + path += ".jpg"; |
| 213 | + path_edit->setText(path); |
| 214 | + } |
| 215 | + parameters.path = path; |
| 216 | +} |
| 217 | + |
| 218 | +void NormalsExportRow::selectOutput() { |
| 219 | + //get folder if not legacy. |
| 220 | + QString output_parent = qRelightApp->lastOutputDir(); |
| 221 | + |
| 222 | + QString output = QFileDialog::getSaveFileName(this, "Select a file name", output_parent); |
| 223 | + if(output.isNull()) return; |
| 224 | + |
| 225 | + if(!output.endsWith(".jpg") && !output.endsWith(".png")) |
| 226 | + output += ".jpg"; |
| 227 | + |
| 228 | + QDir output_parent_dir(output); |
| 229 | + output_parent_dir.cdUp(); |
| 230 | + qRelightApp->setLastOutputDir(output_parent_dir.absolutePath()); |
| 231 | + setPath(output); |
| 232 | +} |
| 233 | + |
| 234 | +void NormalsExportRow::suggestPath() { |
| 235 | + QDir input = qRelightApp->project().dir; |
| 236 | + input.cdUp(); |
| 237 | + QString filename = input.filePath("normals"); |
| 238 | + setPath(filename); |
| 239 | +} |
0 commit comments