27 #include <QApplication>
28 #include <QElapsedTimer>
29 #include <QInputDialog>
30 #include <QMessageBox>
41 double densityKernelSize = 0.0) {
45 switch (densityType) {
60 sfName += QString(
" (r=%2)").arg(densityKernelSize);
62 if (approx) sfName +=
" [approx]";
70 if (cloud && cloud->
size() != 0) {
86 return sqrt(surfacePerPoint * knn);
96 size_t selNum = entities.size();
98 for (
size_t i = 0; i < selNum; ++i) {
103 if (sigma < 0 || sigmaCloud < sigma) sigma = sigmaCloud;
115 if (characteristics.empty()) {
122 if (characteristics.size() == 1) {
124 characteristics.front().subOption,
125 radius, entities, roughnessUpDir,
130 QScopedPointer<ecvProgressDialog> pDlg;
133 pDlg->setAutoClose(
false);
138 roughnessUpDir, parent, pDlg.
data())) {
154 size_t selNum = entities.size();
155 if (selNum < 1)
return false;
164 sfName =
"Eigenvalues sum";
167 sfName =
"Omnivariance";
170 sfName =
"Eigenentropy";
173 sfName =
"Anisotropy";
176 sfName =
"Planarity";
179 sfName =
"Linearity";
188 sfName =
"Surface variation";
191 sfName =
"Sphericity";
194 sfName =
"Verticality";
197 sfName =
"1st eigenvalue";
200 sfName =
"2nd eigenvalue";
203 sfName =
"3rd eigenvalue";
208 "Internal error: invalid sub option for Feature "
213 sfName += QString(
" (%1)").arg(radius);
230 "Internal error: invalid sub option for Curvature "
234 sfName += QString(
" (%1)").arg(radius);
265 if (!pDlg && parent) {
267 pDlg->setAutoClose(
false);
270 for (
size_t i = 0; i < selNum; ++i) {
287 QString(
"Failed to create scalar field on cloud "
288 "'%1' (not enough memory?)")
302 QString(
"Couldn't compute octree for cloud '%1'!")
311 roughnessUpDir, pDlg,
315 if (pc && sfIdx >= 0) {
320 roughnessUpDir !=
nullptr) {
333 QString errorMessage;
336 errorMessage =
"Internal error (invalid input)";
339 errorMessage =
"Not enough points";
344 "Failed to compute octree (not enough memory?)";
347 errorMessage =
"Process failed";
352 "Internal error (unhandled characteristic)";
355 errorMessage =
"Not enough memory";
359 errorMessage =
"Process cancelled by user";
363 errorMessage =
"Unknown error";
368 QString(
"Failed to apply processing to cloud '%1'")
372 if (pc && sfIdx >= 0) {
377 if (pDlg != progressDialog) {
387 if (pDlg != progressDialog) {
398 void** additionalParameters ) {
399 size_t selNum = entities.size();
400 if (selNum < 1)
return false;
406 bool euclidean =
false;
412 if (additionalParameters) {
413 euclidean = *
static_cast<bool*
>(additionalParameters[0]);
416 euclidean = (QMessageBox::question(
418 "Is the scalar field composed of "
419 "(euclidean) distances?",
420 QMessageBox::Yes | QMessageBox::No,
421 QMessageBox::No) == QMessageBox::Yes);
430 for (
size_t i = 0; i < selNum; ++i) {
439 if (lockedVertices) {
441 entities[i]->getName(), selNum == 1);
456 sfName = QString(
"%1(%2)").arg(
487 QString(
"Failed to create scalar field on cloud "
488 "'%1' (not enough memory?)")
494 QScopedPointer<ecvProgressDialog> pDlg;
507 QString(
"Couldn't compute octree for cloud '%1'!")
514 QElapsedTimer eTimer;
523 euclidean,
false, pDlg.data(),
531 qint64 elapsedTime_ms = eTimer.elapsed();
534 if (pc && sfIdx >= 0) {
541 static_cast<double>(elapsedTime_ms) / 1000.0);
544 QString(
"Failed to apply processing to cloud '%1'")
546 if (pc && sfIdx >= 0) {
561 unsigned refEntityIndex ,
563 if (entities.size() < 2 || refEntityIndex >= entities.size()) {
565 "[ApplyScaleMatchingAlgorithm] Invalid input parameter(s)");
569 std::vector<double> scales;
571 scales.resize(entities.size(), -1.0);
572 }
catch (
const std::bad_alloc&) {
578 ccHObject* refEntity = entities[refEntityIndex];
582 "[Scale Matching] The reference entity must be a cloud or a "
587 unsigned count =
static_cast<unsigned>(entities.size());
595 QApplication::processEvents();
597 for (
unsigned i = 0; i <
count; ++i) {
603 if (cloud && !lockedVertices) {
613 "has an invalid bounding-box!")
621 "perform PCA on entity '%1'!")
631 for (
unsigned j = 0; j < cloud->
size(); ++j) {
640 scales[i] = maxX - minX;
646 double finalError = 0.0;
647 double finalScale = 1.0;
648 unsigned finalPointCount = 0;
669 finalScale, finalError,
670 finalPointCount, parameters,
671 false,
false, parent)) {
672 scales[i] = finalScale;
675 "register entity '%1'!")
685 }
else if (cloud && lockedVertices) {
691 "rescaled this way!")
696 if (scales[i] <= 0 && i == refEntityIndex) {
698 "Reference entity has an invalid scale! Can't proceed.");
708 CVLog::Print(QString(
"[Scale Matching] Reference entity scale: %1")
709 .arg(scales[refEntityIndex]));
715 for (
unsigned i = 0; i <
count; ++i) {
716 if (i == refEntityIndex)
continue;
717 if (scales[i] < 0)
continue;
719 CVLog::Print(QString(
"[Scale Matching] Entity '%1' scale: %2")
720 .arg(entities[i]->getName())
732 if (!cloud || lockedVertices)
continue;
738 scaled = scales[refEntityIndex] / scales[i];
754 cloud->
scale(scale_pc, scale_pc, scale_pc, C);
762 toBeRescaleEntities.push_back(cloud);
768 for (
unsigned i = 0; i < toBeRescaleEntities.size(); ++i) {
constexpr PointCoordinateType PC_ONE
'1' as a PointCoordinateType value
constexpr double ZERO_TOLERANCE_D
float PointCoordinateType
Type of the coordinates of a (N-D) point.
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Print(const char *format,...)
Prints out a formatted message in console.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
ccHObjectContext removeObjectTemporarilyFromDBTree(ccHObject *obj) override
Removes object temporarily from DB tree.
void putObjectBackIntoDBTree(ccHObject *obj, const ccHObjectContext &context) override
Adds back object to DB tree.
virtual void setRedraw(bool state)
Sets entity redraw mode.
virtual void showSF(bool state)
Sets active scalarfield visibility.
Float version of ccGLMatrixTpl.
A 3D cloud interface with associated features (color, normals, octree, etc.)
virtual void scale(PointCoordinateType fx, PointCoordinateType fy, PointCoordinateType fz, CCVector3 center=CCVector3(0, 0, 0))=0
Multiplies all coordinates by constant factors (one per dimension)
virtual ccOctree::Shared computeOctree(cloudViewer::GenericProgressCallback *progressCb=nullptr, bool autoAddChild=true)
Computes the cloud octree.
ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
virtual ccOctree::Shared getOctree() const
Returns the associated octree (if any)
static ccPointCloud * ToPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccPointCloud.
static ccGenericPointCloud * ToGenericPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccGenericPointCloud.
Hierarchical CLOUDVIEWER Object.
virtual ccBBox getOwnBB(bool withGLFeatures=false)
Returns the entity's own bounding-box.
QString getViewId() const
std::vector< ccHObject * > Container
Standard instances container (for children, etc.)
virtual QString getName() const
Returns object name.
bool isA(CV_CLASS_ENUM type) const
bool isKindOf(CV_CLASS_ENUM type) const
QSharedPointer< ccOctree > Shared
Shared pointer.
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.
int getCurrentDisplayedScalarFieldIndex() const
Returns the currently displayed scalar field index (or -1 if none)
void deleteScalarField(int index) override
Deletes a specific scalar field.
A scalar field associated to display-related parameters.
void setSymmetricalScale(bool state)
Sets whether the color scale should be symmetrical or not.
virtual void setGlobalShift(double x, double y, double z)
Sets shift applied to original coordinates (information storage only)
virtual const CCVector3d & getGlobalShift() const
Returns the shift applied to original coordinates.
Vector3Tpl< T > getDiagVec() const
Returns diagonal vector.
Vector3Tpl< T > getCenter() const
Returns center.
double computeVolume() const
Returns the bounding-box volume.
T getMaxBoxDim() const
Returns maximal box dimension.
bool isValid() const
Returns whether bounding box is valid or not.
virtual unsigned size() const =0
Returns the number of points.
virtual const CCVector3 * getPoint(unsigned index) const =0
Returns the ith point.
const PointCoordinateType * getLSPlane()
Returns best interpolating plane equation (Least-square)
const CCVector3 * getGravityCenter()
Returns gravity center.
const CCVector3 * getLSPlaneX()
Returns best interpolating plane (Least-square) 'X' base vector.
bool oneStep()
Increments total progress value of a single unit.
int getScalarFieldIndexByName(const char *name) const
Returns the index of a scalar field represented by its name.
void setCurrentOutScalarField(int index)
Sets the OUTPUT scalar field.
void setCurrentScalarField(int index)
Sets both the INPUT & OUTPUT scalar field.
const char * getScalarFieldName(int index) const
Returns the name of a specific scalar field.
void setCurrentInScalarField(int index)
Sets the INPUT scalar field.
ScalarField * getCurrentInScalarField() const
Returns the scalar field currently associated to the cloud input.
virtual void computeMinAndMax()
Determines the min and max values.
Graphical progress indicator (thread-safe)
virtual void start() override
virtual void setInfo(const char *infoStr) override
Notifies some information about the ongoing process.
virtual void setMethodTitle(const char *methodTitle) override
Notifies the algorithm title.
__host__ __device__ float dot(float2 a, float2 b)
#define CC_LOCAL_VOL_DENSITY_FIELD_NAME
#define CC_MOMENT_ORDER1_FIELD_NAME
#define CC_CURVATURE_NORM_CHANGE_RATE_FIELD_NAME
#define CC_GRADIENT_NORMS_FIELD_NAME
#define CC_CURVATURE_GAUSSIAN_FIELD_NAME
#define CC_CURVATURE_MEAN_FIELD_NAME
#define CC_LOCAL_KNN_DENSITY_FIELD_NAME
#define CC_LOCAL_SURF_DENSITY_FIELD_NAME
#define CC_ROUGHNESS_FIELD_NAME
static QString GetDensitySFName(cloudViewer::GeometricalAnalysisTools::Density densityType, bool approx, double densityKernelSize=0.0)
bool ApplyScaleMatchingAlgorithm(ScaleMatchingAlgorithm algo, ccHObject::Container &entities, double icpRmsDiff, int icpFinalOverlap, unsigned refEntityIndex, QWidget *parent)
bool ApplyCCLibAlgorithm(CC_LIB_ALGORITHM algo, ccHObject::Container &entities, QWidget *parent, void **additionalParameters)
bool ComputeGeomCharacteristics(const GeomCharacteristicSet &characteristics, PointCoordinateType radius, ccHObject::Container &entities, const CCVector3 *roughnessUpDir, QWidget *parent)
ScaleMatchingAlgorithm
Scale matching algorithms.
std::vector< GeomCharacteristic > GeomCharacteristicSet
Set of GeomCharacteristic instances.
bool ComputeGeomCharacteristic(cloudViewer::GeometricalAnalysisTools::GeomCharacteristic c, int subOption, PointCoordinateType radius, ccHObject::Container &entities, const CCVector3 *roughnessUpDir, QWidget *parent, ecvProgressDialog *progressDialog)
PointCoordinateType GetDefaultCloudKernelSize(ccGenericPointCloud *cloud, unsigned knn)
Returns a default first guess for algorithms kernel size (one cloud)
void DisplayLockedVerticesWarning(const QString &meshName, bool displayAsError)
Display a warning or error for locked verts.
Geometric characteristic (with sub option)
Backup "context" for an object.