33 #include <QMdiSubWindow>
34 #include <QMessageBox>
36 #include <QToolButton>
50 m_alignedPoints(
"aligned points"),
51 m_refPoints(
"reference points"),
52 m_refLabels(
"reference labels"),
53 m_alignedLabels(
"aligned labels"),
55 m_pickingHub(pickingHub),
64 settings.beginGroup(
"PointPairAlign");
66 settings.value(
"PickSpheres", useSphereToolButton->isChecked())
69 settings.value(
"SphereRadius", radiusDoubleSpinBox->value())
71 int maxRMS = settings.value(
"MaxRMS", maxRmsSpinBox->value()).toInt();
73 settings.value(
"AdjustScale", adjustScaleCheckBox->isChecked())
76 settings.value(
"AutoUpdateZom", autoZoomCheckBox->isChecked())
80 useSphereToolButton->setChecked(pickSpheres);
81 radiusDoubleSpinBox->setValue(sphereRadius);
82 maxRmsSpinBox->setValue(maxRMS);
83 adjustScaleCheckBox->setChecked(adjustScale);
84 autoZoomCheckBox->setChecked(autoUpdateZoom);
87 connect(showAlignedCheckBox, &QCheckBox::toggled,
this,
89 connect(showReferenceCheckBox, &QCheckBox::toggled,
this,
92 connect(typeAlignToolButton, &QToolButton::clicked,
this,
94 connect(typeRefToolButton, &QToolButton::clicked,
this,
97 connect(unstackAlignToolButton, &QToolButton::clicked,
this,
99 connect(unstackRefToolButton, &QToolButton::clicked,
this,
102 connect(alignToolButton, &QToolButton::clicked,
this,
104 connect(resetToolButton, &QToolButton::clicked,
this,
107 connect(validToolButton, &QToolButton::clicked,
this,
109 connect(cancelToolButton, &QToolButton::clicked,
this,
112 connect(adjustScaleCheckBox, &QCheckBox::toggled,
this,
114 connect(TxCheckBox, &QCheckBox::toggled,
this,
116 connect(TyCheckBox, &QCheckBox::toggled,
this,
118 connect(TzCheckBox, &QCheckBox::toggled,
this,
121 static_cast<void (QComboBox::*)(
int)
>(
122 &QComboBox::currentIndexChanged),
134 wasVisible(entity ? entity->isVisible() : false),
135 wasEnabled(entity ? entity->isEnabled() : false),
136 wasSelected(entity ? entity->isSelected() : false) {}
141 entity->setVisible(wasVisible);
142 entity->setEnabled(wasEnabled);
143 entity->setSelected(wasSelected);
163 if (shiftedEntity && shiftedEntity->
isShifted()) {
165 shift = shiftedEntity
176 alignToolButton->setEnabled(
false);
177 validToolButton->setEnabled(
false);
178 while (alignedPointsTableWidget->rowCount() != 0)
179 alignedPointsTableWidget->removeRow(
180 alignedPointsTableWidget->rowCount() - 1);
181 while (refPointsTableWidget->rowCount() != 0)
182 refPointsTableWidget->removeRow(refPointsTableWidget->rowCount() - 1);
186 it.key()->setSelected(
true);
187 it.key()->showSF(
false);
191 it.key()->setSelected(
true);
192 it.key()->showSF(
false);
249 "Picking mechanism is already in use! Close the other tool "
250 "first, and then restart this one.");
289 if (
abs(dx) > 0 ||
abs(dy) > 0) {
290 alignLabel->
move2D(x * retinaScale, y * retinaScale,
291 dx * retinaScale, dy * retinaScale,
312 if (
abs(dx) > 0 ||
abs(dy) > 0) {
313 refLabel->
move2D(x * retinaScale, y * retinaScale,
314 dx * retinaScale, dy * retinaScale,
344 if (alignedEntities.empty()) {
346 "[PointPairRegistration] Need at least one aligned entity!");
351 if (referenceEntities) {
363 bool hasOriginViewportParams =
false;
368 hasOriginViewportParams =
true;
383 hasOriginViewportParams =
true;
395 showAlignedCheckBox->setChecked(
true);
402 "(you can add points 'manually' if necessary)",
405 QString(
"Pick equivalent points on both clouds (at least %1 pairs "
411 if (hasOriginViewportParams) {
423 "Whether the point is expressed in the entity original coordinate "
424 "system (before being shifted by CV) or not");
432 "Add aligned point",
this);
440 if (!ptsDlg.exec())
return;
443 s_last_ax = ptsDlg.doubleSpinBox1->value();
444 s_last_ay = ptsDlg.doubleSpinBox2->value();
445 s_last_az = ptsDlg.doubleSpinBox3->value();
464 "Add reference point",
this);
474 if (!ptsDlg.exec())
return;
477 s_last_rx = ptsDlg.doubleSpinBox1->value();
478 s_last_ry = ptsDlg.doubleSpinBox2->value();
479 s_last_rz = ptsDlg.doubleSpinBox3->value();
499 if (!entity || !useSphereToolButton->isChecked() ||
508 double searchRadius = radiusDoubleSpinBox->value();
509 double maxRMSPercentage = maxRmsSpinBox->value() / 100.0;
519 bool success =
false;
520 if (part && part->
size() > 16) {
527 part, 0.5, C, radius, rms, &pDlg, 0.9) ==
529 if (radius / searchRadius < 0.5 || radius / searchRadius > 2.0) {
531 QString(
"[ccPointPairRegistrationDlg] Detected sphere "
532 "radius (%1) is too far from search radius!")
545 part = cloud->
crop(box,
true);
546 if (part && part->
size() > 16)
551 CVLog::Print(QString(
"[ccPointPairRegistrationDlg] Detected "
552 "sphere radius = %1 (rms = %2)")
555 if (radius / searchRadius < 0.5 ||
556 radius / searchRadius > 2.0) {
558 "[ccPointPairRegistrationDlg] Sphere radius is too "
559 "far from search radius!");
560 }
else if (rms / searchRadius >= maxRMSPercentage) {
562 "[ccPointPairRegistrationDlg] RMS is too high!");
564 sphereRadius = radius;
571 "[ccPointPairRegistrationDlg] Failed to fit a sphere "
572 "around the picked point!");
577 "[ccPointPairRegistrationDlg] Failed to crop points around the "
581 if (part)
delete part;
605 QString(
"pick wrong entity : [%1]").arg(pi.
entity->
getName()));
613 alignToolButton->setEnabled(canAlign);
614 validToolButton->setEnabled(
false);
623 QToolButton* delButton =
new QToolButton();
624 delButton->setIcon(QIcon(
":/Resources/images/smallCancel.png"));
650 QObject* senderButton = sender();
653 bool alignedPoint =
true;
657 for (
int i = 0; i < alignedPointsTableWidget->rowCount(); ++i) {
666 if (pointIndex < 0) {
668 alignedPoint =
false;
669 for (
int i = 0; i < refPointsTableWidget->rowCount(); ++i) {
678 if (pointIndex < 0) {
694 if (!tableWidget)
return;
697 tableWidget->setRowCount(
698 std::max<int>(rowIndex + 1, tableWidget->rowCount()));
699 tableWidget->setVerticalHeaderItem(rowIndex,
700 new QTableWidgetItem(pointName));
703 for (
int d = 0; d < 3; ++d) {
704 QTableWidgetItem* item =
new QTableWidgetItem();
705 item->setData(Qt::EditRole, QString::number(P.
u[d],
'f', 6));
716 connect(delButton, &QToolButton::clicked,
this,
746 bool shiftEnabled =
false;
752 if (alignedCloud && alignedCloud->
isShifted()) {
759 shiftEnabled, Pshift,
nullptr, &scale)) {
771 if (shifted && cloud) {
782 "Point already picked or too close to an already selected "
800 QString pointName = QString(
"R%1").arg(newPointIndex);
806 if (sphereRadius <= 0) {
855 "Point already picked or too close to an already selected "
872 QString pointName = QString(
"A%1").arg(newPointIndex);
875 addPointToTable(alignedPointsTableWidget, newPointIndex, Pin, pointName);
878 if (sphereRadius <= 0) {
903 assert(alignedPointsTableWidget->rowCount() > 0);
904 alignedPointsTableWidget->removeRow(alignedPointsTableWidget->rowCount() -
921 if (pointCount == 0)
return;
923 assert(refPointsTableWidget->rowCount() > 0);
924 refPointsTableWidget->removeRow(refPointsTableWidget->rowCount() - 1);
936 if (pointCount == 0) {
946 int index,
bool autoRemoveDualPoint ) {
949 "[ccPointPairRegistrationDlg::removeAlignedPoint] Invalid "
961 alignedPointsTableWidget->removeRow(index);
964 for (
int i = index + 1; i < pointCount; ++i) {
969 QString pointName = QString(
"A%1").arg(i - 1);
977 static_cast<unsigned>(i - 1), pointName);
986 alignedPointsTableWidget->setVerticalHeaderItem(
987 i - 1,
new QTableWidgetItem(pointName));
992 assert(pointCount >= 0);
1004 if (autoRemoveDualPoint && index <
static_cast<int>(
m_refPoints.
size()) &&
1005 QMessageBox::question(0,
"Remove dual point",
1006 "Remove the equivalent reference point as well?",
1008 QMessageBox::No) == QMessageBox::Yes) {
1014 int index,
bool autoRemoveDualPoint ) {
1017 "[ccPointPairRegistrationDlg::removeRefPoint] Invalid index!");
1027 refPointsTableWidget->removeRow(index);
1030 for (
int i = index + 1; i < pointCount; ++i) {
1035 QString pointName = QString(
"R%1").arg(i - 1);
1053 refPointsTableWidget->setVerticalHeaderItem(
1054 i - 1,
new QTableWidgetItem(pointName));
1059 assert(pointCount >= 0);
1071 if (autoRemoveDualPoint &&
1073 QMessageBox::question(0,
"Remove dual point",
1074 "Remove the equivalent aligned point as well?",
1076 QMessageBox::No) == QMessageBox::Yes) {
1084 bool forceRedraw = !remove;
1086 context.forceRedraw = forceRedraw;
1142 it.key()->setVisible(state);
1158 if (autoZoomCheckBox->isChecked()) {
1170 it.key()->setVisible(state);
1186 if (autoZoomCheckBox->isChecked()) {
1196 bool autoUpdateTab) {
1205 CVLog::Error(QString(
"Need at least %1 points for each entity (and the "
1206 "same number of points in both subsets)!")
1212 bool adjustScale = adjustScaleCheckBox->isChecked();
1217 CVLog::Error(
"Registration failed! (points are aligned?)");
1224 switch (rotComboBox->currentIndex()) {
1239 if (!TxCheckBox->isChecked())
1241 if (!TyCheckBox->isChecked())
1243 if (!TzCheckBox->isChecked())
1257 if (autoUpdateTab) {
1267 QTableWidgetItem* itemA =
new QTableWidgetItem();
1268 itemA->setData(Qt::EditRole,
dist);
1270 QTableWidgetItem* itemR =
new QTableWidgetItem();
1271 itemR->setData(Qt::EditRole,
dist);
1284 for (
int i = 0; alignedPointsTableWidget->rowCount(); ++i)
1286 new QTableWidgetItem());
1287 for (
int i = 0; refPointsTableWidget->rowCount(); ++i)
1288 refPointsTableWidget->setItem(i,
RMS_COL_INDEX,
new QTableWidgetItem());
1296 "[Point-pair registration]",
1311 QString rmsString = QString(
"Achievable RMS: %1").arg(rms);
1315 resetToolButton->setEnabled(
true);
1316 validToolButton->setEnabled(
true);
1318 resetToolButton->setEnabled(
false);
1319 validToolButton->setEnabled(
false);
1339 QString rmsString = QString(
"Current RMS: %1").arg(rms);
1340 CVLog::Print(QString(
"[PointPairRegistration] ") + rmsString);
1346 "[PointPairRegistration] Internal error (negative RMS?!)");
1351 bool adjustScale = adjustScaleCheckBox->isChecked();
1355 QString scaleString = QString(
"Scale: %1").arg(trans.
s);
1356 CVLog::Print(QString(
"[PointPairRegistration] ") + scaleString);
1358 CVLog::Print(QString(
"[PointPairRegistration] Scale: fixed (1.0)"));
1361 ccGLMatrix transMat = FromCCLibMatrix<double, float>(trans.
R, trans.
T);
1369 it.key()->setRedrawFlagRecursive(
true);
1383 if (!showAlignedCheckBox->isChecked())
1384 showAlignedCheckBox->setChecked(
true);
1385 if (!showReferenceCheckBox->isChecked())
1386 showReferenceCheckBox->setChecked(
true);
1390 if (autoZoomCheckBox->isChecked()) {
1400 resetToolButton->setEnabled(
true);
1401 alignToolButton->setEnabled(
false);
1402 validToolButton->setEnabled(
true);
1412 static_cast<cc2DLabel*
>(child)->setRelativeMarkerScale(markerSize);
1414 static_cast<cc2DLabel*
>(child)->updateLabel();
1425 static_cast<cc2DLabel*
>(child)->setRelativeMarkerScale(markerSize);
1427 static_cast<cc2DLabel*
>(child)->updateLabel();
1446 it.key()->applyGLTransformation_recursive(
apply ? &transMat :
nullptr);
1475 it.key()->setRedrawFlagRecursive(
true);
1478 if (autoZoomCheckBox->isChecked()) {
1488 alignToolButton->setEnabled(
true);
1489 resetToolButton->setEnabled(
false);
1522 QStringList summary;
1524 QString rmsString = QString(
"Final RMS: %1").arg(rms);
1525 CVLog::Print(QString(
"[PointPairRegistration] ") + rmsString);
1526 summary << rmsString;
1527 summary <<
"----------------";
1531 bool adjustScale = adjustScaleCheckBox->isChecked();
1532 if (adjustScale && trans.
R.
isValid()) {
1535 ccGLMatrix transMat = FromCCLibMatrix<double, float>(trans.
R, trans.
T);
1540 summary << QString(
"Transformation matrix");
1543 summary <<
"----------------";
1545 CVLog::Print(
"[PointPairRegistration] Applied transformation matrix:");
1549 QString scaleString =
1550 QString(
"Scale: %1 (already integrated in above matrix!)")
1552 CVLog::Warning(QString(
"[PointPairRegistration] ") + scaleString);
1553 summary << scaleString;
1555 CVLog::Print(QString(
"[PointPairRegistration] Scale: fixed (1.0)"));
1556 summary <<
"Scale: fixed (1.0)";
1558 summary <<
"----------------";
1561 summary <<
"Refer to Console (F8) for more details";
1562 QMessageBox::information(
this,
"Align info", summary.join(
"\n"));
1565 bool alwaysDropShift =
false;
1566 bool firstQuestion =
true;
1578 "global shift has been updated to match "
1579 "the reference: (%1,%2,%3) [x%4]")
1589 if (firstQuestion) {
1591 (QMessageBox::question(
1592 this, tr(
"Drop shift information?"),
1593 tr(
"Aligned cloud is shifted but "
1594 "reference cloud is not: drop "
1595 "global shift information?"),
1597 QMessageBox::No) == QMessageBox::Yes);
1598 firstQuestion =
false;
1601 if (alwaysDropShift) {
1605 "global shift has been reset to "
1606 "match the reference!")
1614 "[PointPairRegistration] Failed to register entities?!"));
1620 settings.beginGroup(
"PointPairAlign");
1621 settings.setValue(
"PickSpheres", useSphereToolButton->isChecked());
1622 settings.setValue(
"SphereRadius", radiusDoubleSpinBox->value());
1623 settings.setValue(
"MaxRMS", maxRmsSpinBox->value());
1624 settings.setValue(
"AdjustScale", adjustScaleCheckBox->isChecked());
1625 settings.setValue(
"AutoUpdateZom", autoZoomCheckBox->isChecked());
1626 settings.endGroup();
1635 it.key()->enableGLTransformation(
false);
1641 it.key()->setRedrawFlagRecursive(
true);
constexpr PointCoordinateType PC_ONE
'1' as a PointCoordinateType value
Vector3Tpl< double > CCVector3d
Double 3D Vector.
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
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.
Vector3Tpl< double > toDouble() const
Cast operator to a double vector (explicit call version)
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
2D label (typically attached to points)
bool addPickedPoint(ccGenericPointCloud *cloud, unsigned pointIndex, bool entityCenter=false)
Adds a point to this label.
void clear(bool ignoreDependencies=false, bool ignoreCaption=true)
Clears label.
virtual bool move2D(int x, int y, int dx, int dy, int screenWidth, int screenHeight) override
Called on mouse move (for 2D interactors)
void setDisplayedIn2D(bool state)
Whether to display the label in 2D.
void update2DLabelView(CC_DRAW_CONTEXT &context, bool updateScreen=true)
void clearLabel(bool ignoreCaption=true)
void displayPointLegend(bool state)
Whether to display the point(s) legend (title only)
Generic dialog to query 3 (double) values.
bool getCheckboxState() const
Returns.
void showCheckbox(const QString &label, bool state, QString tooltip=QString())
Enable the checkbox (bottom-left)
virtual void setTempColor(const ecvColor::Rgb &col, bool autoActivate=true)
Sets current temporary (unique)
virtual void setVisible(bool state)
Sets entity visibility.
virtual void showNameIn3D(bool state)
Sets whether name should be displayed in 3D.
QString toString(int precision=12, QChar separator=' ') const
Returns matrix as a string.
ccGLMatrixTpl< T > inverse() const
Returns inverse transformation.
void setTranslation(const Vector3Tpl< float > &Tr)
Sets translation (float version)
virtual void toIdentity()
Sets matrix to identity.
Float version of ccGLMatrixTpl.
A 3D cloud interface with associated features (color, normals, octree, etc.)
virtual cloudViewer::ReferenceCloud * crop(const ccBBox &box, bool inside=true)=0
Crops the cloud inside (or outside) a bounding box.
static ccShiftedObject * ToShifted(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccShiftedObject.
static cc2DLabel * To2DLabel(ccHObject *obj)
Converts current object to cc2DLabel (if possible)
static ccGenericPointCloud * ToGenericPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccGenericPointCloud.
Hierarchical CLOUDVIEWER Object.
void draw(CC_DRAW_CONTEXT &context) override
Draws entity and its children.
void removeAllChildren()
Removes all children.
virtual ccBBox getDisplayBB_recursive(bool relative)
Returns the bounding-box of this entity and it's children WHEN DISPLAYED.
QString getViewId() const
void applyGLTransformation_recursive(const ccGLMatrix *trans=nullptr)
Applies the active OpenGL transformation to the entity (recursive)
unsigned getChildrenNumber() const
Returns the number of children.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
void setRedrawFlagRecursive(bool redraw=false)
void updateNameIn3DRecursive()
ccHObject * getParent() const
Returns parent object.
void removeChild(ccHObject *child)
std::vector< ccHObject * > Container
Standard instances container (for children, etc.)
ccHObject * getChild(unsigned childPos) const
Returns the ith child.
virtual QString getName() const
Returns object name.
bool isA(CV_CLASS_ENUM type) const
virtual void setName(const QString &name)
Sets object name.
virtual void setEnabled(bool state)
Sets the "enabled" property.
bool isKindOf(CV_CLASS_ENUM type) const
Generic overlay dialog interface.
virtual void stop(bool accepted)
Stops process/dialog.
virtual bool start()
Starts process.
QWidget * m_associatedWin
Associated (MDI) window.
virtual bool linkWith(QWidget *win)
Links the overlay dialog with a MDI window.
Point/triangle picking hub.
void removeListener(ccPickingListener *listener, bool autoStopPickingIfLast=true)
Removes a listener.
bool addListener(ccPickingListener *listener, bool exclusive=false, bool autoStartPicking=true, ecvDisplayTools::PICKING_MODE mode=ecvDisplayTools::POINT_OR_TRIANGLE_PICKING)
Adds a listener.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void invalidateBoundingBox() override
Invalidates bounding box.
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
bool resize(unsigned numberOfPoints) override
Resizes all the active features arrays.
CCVector3 computeGravityCenter()
Returns the cloud gravity center.
bool start() override
Starts process.
void updateAlignedMarkers(int index)
void label2DMove(int x, int y, int dx, int dy)
EntityContexts m_alignedEntities
Aligned entity.
void updateAllMarkers(float markerSize)
bool m_paused
Whether the dialog is paused or not.
void stop(bool state) override
Stops process/dialog.
EntityContexts m_referenceEntities
Reference entity (if any)
void updateRefMarkers(int index)
void onItemPicked(const PickedItem &pi) override
Inherited from ccPickingListener.
void unstackAligned()
Slot called to remove the last point on the 'align' stack.
ccHObject m_alignedLabels
void removeRefPoint(int index, bool autoRemoveDualPoint=true)
Removes a point from the 'reference' set.
bool convertToSphereCenter(CCVector3d &P, ccHObject *entity, PointCoordinateType &sphereRadius)
Converts a picked point to a sphere center (if necessary)
bool linkWith(QWidget *win) override
Links the overlay dialog with a MDI window.
void addManualRefPoint()
Slot called to add a manual point to the 'reference' set.
void unstackRef()
Slot called to remove the last point on the 'reference' stack.
void updateAlignInfo()
Updates the registration info and buttons states.
ccPickingHub * m_pickingHub
Picking hub.
void onDelButtonPushed()
Slot called when a "delete" button is pushed.
void resetTitle()
Resets the displayed title (3D view)
void addPointToTable(QTableWidget *tableWidget, int rowIndex, const CCVector3d &P, QString pointLabel)
Adds a point to one of the table (ref./aligned)
bool addAlignedPoint(CCVector3d &P, ccHObject *entity=nullptr, bool shifted=true)
Adds a point to the 'align' set.
ccGLMatrix m_transMatHistory
bool callHornRegistration(cloudViewer::PointProjectionTools::Transformation &trans, double &rms, bool autoUpdateTab)
Calls Horn registration (cloudViewer::HornRegistrationTools)
void updateSphereMarks(ccHObject *obj, bool remove)
void onPointCountChanged()
Enables (or not) buttons depending on the number of points in both lists.
ccPointPairRegistrationDlg(ccPickingHub *pickingHub, ecvMainAppInterface *app, QWidget *parent=nullptr)
Default constructor.
void removeAlignedPoint(int index, bool autoRemoveDualPoint=true)
Removes a point from the 'align' set.
void clearRMSColumns()
Clears the RMS rows.
ecvMainAppInterface * m_app
Main application interface.
void addManualAlignedPoint()
Slot called to add a manual point to the 'align' set.
void transformAlignedEntity(const ccGLMatrix &transMat, bool apply=true)
void showAlignedEntities(bool)
Slot called to change aligned cloud visibility.
ccPointCloud m_alignedPoints
Aligned points set.
bool init(QWidget *win, const ccHObject::Container &alignedEntities, const ccHObject::Container *referenceEntities=nullptr)
Inits dialog.
ccPointCloud m_refPoints
Reference points set.
void clear()
Clears dialog.
bool addReferencePoint(CCVector3d &P, ccHObject *entity=nullptr, bool shifted=true)
Adds a point to the 'reference' set.
void zoomGlobalOnRegistrationEntities()
void showReferenceEntities(bool)
Slot called to change reference cloud visibility.
void pause(bool state)
Pauses the dialog.
Shifted entity interface.
virtual void setGlobalScale(double scale)
CCVector3d toGlobal3d(const Vector3Tpl< T > &Plocal) const
Returns the point back-projected into the original coordinates system.
CCVector3 toLocal3pc(const Vector3Tpl< T > &Pglobal) const
Returns the point projected into the local (shifted) coordinates system.
bool isShifted() const
Returns whether the cloud is shifted 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.
virtual double getGlobalScale() const
Returns the scale applied to original coordinates.
void clear()
Resets the bounding box.
bool isValid() const
Returns whether bounding box is valid or not.
void add(const Vector3Tpl< T > &P)
'Enlarges' the bounding box with a point
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
unsigned size() const override
unsigned capacity() const
Returns cloud capacity (i.e. reserved size)
const CCVector3 * getPoint(unsigned index) const override
A very simple point cloud (no point duplication)
unsigned size() const override
Returns the number of points.
bool isValid() const
Returns matrix validity.
void scale(Scalar coef)
Scales matrix (all elements are multiplied by the same coef.)
static bool Handle(const CCVector3d &P, double diagonal, Mode mode, bool useInputCoordinatesShiftIfPossible, CCVector3d &coordinatesShift, bool *preserveCoordinateShift, double *coordinatesScale, bool *applyAll=0)
Main application interface (for plugins)
virtual void putObjectBackIntoDBTree(ccHObject *obj, const ccHObjectContext &context)=0
Adds back object to DB tree.
virtual ccHObjectContext removeObjectTemporarilyFromDBTree(ccHObject *obj)=0
Removes object temporarily from DB tree.
Graphical progress indicator (thread-safe)
Standard parameters for GL displays/viewports.
__host__ __device__ int2 abs(int2 v)
static cc2DLabel * CreateLabel(cc2DLabel *label, ccPointCloud *cloud, unsigned pointIndex, QString pointName)
static void SetEnabled_recursive(ccHObject *ent)
static QToolButton * CreateDeleteButton()
static bool s_lastAlignePointIsGlobal
static const unsigned MIN_PAIRS_COUNT
static const int RMS_COL_INDEX
static const int DEL_BUTTON_COL_INDEX
static const int XYZ_COL_INDEX
static bool s_lastRefPointisGlobal
static QString s_aligned_tooltip
static double dist(double x1, double y1, double x2, double y2)
bool LessThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
constexpr Rgb red(MAX, 0, 0)
constexpr Rgb yellow(MAX, MAX, 0)
void restore()
Restores cloud original state.
EntityContext(ccHObject *ent)
Default constructor.
void fill(const ccHObject::Container &entities)
Backup "context" for an object.