11 #include <QMessageBox>
12 #include <QPushButton>
29 "add",
"sub",
"mult",
"div",
"sqrt",
"pow2",
30 "pow3",
"exp",
"log",
"log10",
"cos",
"sin",
31 "tan",
"acos",
"asin",
"atan",
"int",
"inverse"};
40 : QDialog(parent, Qt::Tool),
Ui::SFArithmeticsDlg() {
48 sf1ComboBox->setEnabled(
false);
49 sf2ComboBox->setEnabled(
false);
50 buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
false);
52 for (
unsigned i = 0; i < sfCount; ++i) {
56 sf1ComboBox->addItems(sfLabels);
57 sf1ComboBox->setCurrentIndex(0);
59 sfLabels <<
"[Constant value]";
60 sf2ComboBox->addItems(sfLabels);
61 sf2ComboBox->setCurrentIndex(std::min<unsigned>(1, sfCount - 1));
65 connect(operationComboBox,
66 static_cast<void (QComboBox::*)(
int)
>(
67 &QComboBox::currentIndexChanged),
70 static_cast<void (QComboBox::*)(
int)
>(
71 &QComboBox::currentIndexChanged),
80 sf2ComboBox->setEnabled(index <=
DIVIDE);
86 constantDoubleSpinBox->setEnabled(sf2ComboBox->currentIndex() + 1 ==
87 sf2ComboBox->count());
91 return sf1ComboBox->currentIndex();
95 return sf2ComboBox->currentIndex();
100 int opIndex = operationComboBox->currentIndex();
101 if (opIndex <
static_cast<int>(
s_opCount)) {
110 QString sf1, QString sf2 )
const {
120 for (
unsigned i = 0; i <
s_opCount; ++i) {
130 Operation op, QString sf1, QString sf2 ) {
133 return QString(
"%1 + %2").arg(sf1, sf2);
135 return QString(
"%1 - %2").arg(sf1, sf2);
137 return QString(
"%1 * %2").arg(sf1, sf2);
139 return QString(
"%1 / %2").arg(sf1, sf2);
142 return QString(
"%1(%2)").arg(
s_opNames[op], sf1);
179 "[ccScalarFieldArithmeticsDlg::apply] No input cloud, or cloud "
187 "[ccScalarFieldArithmeticsDlg::apply] Invalid/unhandled "
196 if (sf1Idx >=
static_cast<int>(sfCount)) {
198 "[ccScalarFieldArithmeticsDlg::apply] Invalid SF1 index!");
209 sf2Desc->
sfIndex >=
static_cast<int>(sfCount))) {
211 "[ccScalarFieldArithmeticsDlg::apply] Invalid SF2 "
212 "index/descriptor!");
217 CVLog::Error(
"Invalid constant value (can't divide by zero)");
230 QString sf1Name(sf1->
getName());
235 if (sfName.length() > 24) {
238 sf1Name = QString(
"(SF#%1)").arg(sf1Idx);
239 sf2Name = QString(
"(SF#%1)").arg(sf2Desc->
sfIndex);
246 if (sfIdx == sf1Idx || sfIdx == sf2Desc->
sfIndex) {
248 "Resulting scalar field would have the "
249 "same name as one of the operand (%1)! "
250 "Rename it first...")
255 QMessageBox::warning(
256 parent,
"Same scalar field name",
257 "Resulting scalar field already exists! Overwrite it?",
258 QMessageBox::Ok | QMessageBox::Cancel,
259 QMessageBox::Ok) != QMessageBox::Ok) {
269 "[ccScalarFieldArithmeticsDlg::apply] Failed to create "
270 "destination SF! (not enough memory?)");
285 "[ccScalarFieldArithmeticsDlg::apply] Not enough memory!");
292 for (
unsigned i = 0; i < valCount; ++i) {
296 const ScalarType& val1 = sf1->
getValue(i);
304 const ScalarType& val2 = sf2->
getValue(i);
313 const ScalarType& val2 = sf2->
getValue(i);
322 const ScalarType& val2 = sf2->
getValue(i);
331 const ScalarType& val2 = sf2->
getValue(i);
338 if (val1 >= 0) val = std::sqrt(val1);
344 val = val1 * val1 * val1;
347 val = std::exp(val1);
350 if (val1 >= 0) val = std::log(val1);
353 if (val1 >= 0) val = std::log10(val1);
356 val = std::cos(val1);
359 val = std::sin(val1);
362 val = std::tan(val1);
365 if (val1 >= -1 && val1 <= 1) val = std::acos(val1);
368 if (val1 >= -1 && val1 <= 1) val = std::asin(val1);
371 val = std::atan(val1);
374 val =
static_cast<ScalarType
>(
static_cast<int>(
381 :
static_cast<ScalarType
>(1.0f / val1);
constexpr ScalarType NAN_VALUE
NaN as a ScalarType value.
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void setCurrentDisplayedScalarField(int index)
Sets the currently displayed scalar field.
int addScalarField(const char *uniqueName) override
Creates a new scalar field and registers it.
void deleteScalarField(int index) override
Deletes a specific scalar field.
bool hasScalarFields() const override
Returns whether one or more scalar fields are instantiated.
int getSF1Index()
Returns first selected SF index.
static Operation GetOperationByName(QString name)
Returns the operation enumerator based on its name.
Operation getOperation() const
Returns selected operation.
QString getOperationName(QString sf1, QString sf2=QString()) const
Returns selected operation name.
void onOperationIndexChanged(int index)
Called when the operation combo-box is modified.
int getSF2Index()
Returns second selected SF index.
static bool Apply(ccPointCloud *cloud, Operation op, int sf1Idx, bool inplace, SF2 *sf2=0, QWidget *parent=0)
Applies operation on a given cloud.
ccScalarFieldArithmeticsDlg(ccPointCloud *cloud, QWidget *parent=0)
Default constructor.
Operation
Arithmetic operations.
void onSF2IndexChanged(int index)
Called when the SF2 combo-box is modified.
bool apply(ccPointCloud *cloud)
Applies operation on a given cloud.
static QString GetOperationName(Operation op, QString sf1, QString sf2=QString())
Returns operation name.
int getScalarFieldIndexByName(const char *name) const
Returns the index of a scalar field represented by its name.
ScalarField * getScalarField(int index) const
Returns a pointer to a specific scalar field.
unsigned getNumberOfScalarFields() const
Returns the number of associated (and active) scalar fields.
const char * getScalarFieldName(int index) const
Returns the name of a specific scalar field.
A simple scalar field (to be associated to a point cloud)
virtual void computeMinAndMax()
Determines the min and max values.
ScalarType & getValue(std::size_t index)
void setValue(std::size_t index, ScalarType value)
const char * getName() const
Returns scalar field name.
bool resizeSafe(std::size_t count, bool initNewElements=false, ScalarType valueForNewElements=0)
Resizes memory (no exception thrown)
static bool ValidValue(ScalarType value)
Returns whether a scalar value is valid or not.
unsigned currentSize() const
__host__ __device__ int2 abs(int2 v)
static const char s_opNames[s_opCount][12]
static double s_previousConstValue
static int s_previouslySelectedOperationIndex
static const unsigned s_opCount
static bool s_applyInPlace
bool GreaterThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
bool LessThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).