37 #include <QApplication>
38 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
39 #include <QDesktopWidget>
42 #include <QMainWindow>
43 #include <QMessageBox>
44 #include <QPushButton>
62 ecvDisplayTools::INTERACTION_FLAGS flags =
72 ecvDisplayTools::INTERACTION_FLAGS flags =
111 s_tools.instance = displayTools;
115 s_tools.instance->m_timer.start();
119 s_tools.instance->registerVisualizer(win, stereoMode);
122 s_tools.instance->m_lastMousePos = QPoint(-1, -1);
123 s_tools.instance->m_lastMouseMovePos = QPoint(-1, -1);
124 s_tools.instance->m_validModelviewMatrix =
false;
125 s_tools.instance->m_validProjectionMatrix =
false;
126 s_tools.instance->m_cameraToBBCenterDist = 0.0;
127 s_tools.instance->m_shouldBeRefreshed =
false;
128 s_tools.instance->m_mouseMoved =
false;
129 s_tools.instance->m_mouseButtonPressed =
false;
130 s_tools.instance->m_widgetClicked =
false;
132 s_tools.instance->m_bbHalfDiag = 0.0;
135 s_tools.instance->m_pickingModeLocked =
false;
136 s_tools.instance->m_lastClickTime_ticks = 0;
138 s_tools.instance->m_sunLightEnabled =
true;
139 s_tools.instance->m_customLightEnabled =
false;
140 s_tools.instance->m_clickableItemsVisible =
false;
141 s_tools.instance->m_alwaysUseFBO =
false;
142 s_tools.instance->m_updateFBO =
true;
143 s_tools.instance->m_winDBRoot =
nullptr;
144 s_tools.instance->m_globalDBRoot =
nullptr;
145 s_tools.instance->m_removeFlag =
false;
146 s_tools.instance->m_font = QFont();
148 s_tools.instance->m_pivotSymbolShown =
false;
149 s_tools.instance->m_allowRectangularEntityPicking =
false;
150 s_tools.instance->m_rectPickingPoly =
nullptr;
151 s_tools.instance->m_overridenDisplayParametersEnabled =
false;
152 s_tools.instance->m_displayOverlayEntities =
true;
153 s_tools.instance->m_bubbleViewModeEnabled =
false;
154 s_tools.instance->m_bubbleViewFov_deg = 90.0f;
155 s_tools.instance->m_touchInProgress =
false;
156 s_tools.instance->m_touchBaseDist = 0.0;
157 s_tools.instance->m_scheduledFullRedrawTime = 0;
158 s_tools.instance->m_exclusiveFullscreen =
false;
159 s_tools.instance->m_showDebugTraces =
false;
161 s_tools.instance->m_autoRefresh =
false;
162 s_tools.instance->m_hotZone =
nullptr;
163 s_tools.instance->m_showCursorCoordinates =
false;
164 s_tools.instance->m_autoPickPivotAtCenter =
false;
165 s_tools.instance->m_ignoreMouseReleaseEvent =
false;
166 s_tools.instance->m_rotationAxisLocked =
false;
171 QString(
"DB.3DView_%1").arg(
s_tools.instance->m_uniqueID));
174 s_tools.instance->m_viewportParams.viewMat.toIdentity();
178 s_tools.instance->m_viewMatd.toIdentity();
179 s_tools.instance->m_projMatd.toIdentity();
191 bool perspectiveView =
196 bool objectCenteredView =
198 int pivotVisibility =
204 switch (pivotVisibility) {
220 s_tools.instance->m_deferredPickingTimer.setSingleShot(
true);
221 s_tools.instance->m_deferredPickingTimer.setInterval(100);
226 Qt::DirectConnection);
231 connect(&
s_tools.instance->m_scheduleTimer, &QTimer::timeout,
233 connect(&
s_tools.instance->m_deferredPickingTimer, &QTimer::timeout,
272 std::list<MessageToDisplay>::iterator it =
274 qint64 currentTime_sec =
m_timer.elapsed() / 1000;
280 if (it->messageValidity_sec < currentTime_sec) {
307 const std::string&
id) {
312 CVLog::Print(QString(
"current selected index is %1").arg(index));
315 CVLog::Print(QString(
"current selected point coord is [%1, %2, %3]")
322 PICKING_MODE pickingMode = PICKING_MODE::ENTITY_PICKING;
337 "[ecvDisplayTools::doPicking] Skipping picking because "
338 "VTK widget was clicked");
346 if (
x < 0 ||
y < 0) {
361 emit
s_tools.instance->entitySelectionChanged(label);
362 QApplication::processEvents();
375 (QApplication::keyboardModifiers() & Qt::AltModifier)) {
378 (QApplication::keyboardModifiers() &
379 Qt::ControlModifier)) {
396 wheelDelta_deg / 3.6f);
400 double delta = deg2PixConversion *
401 static_cast<double>(wheelDelta_deg) *
416 static const float c_defaultDeg2Zoom = 20.0f;
417 float zoomFactor = std::pow(1.1f, wheelDelta_deg / c_defaultDeg2Zoom);
425 if (
s_tools.instance->m_clickableItems.empty()) {
435 for (std::vector<ClickableItem>::const_iterator it =
436 s_tools.instance->m_clickableItems.begin();
437 it !=
s_tools.instance->m_clickableItems.end(); ++it) {
438 if (it->area.contains(
x,
y)) {
439 clickedItem = it->role;
444 switch (clickedItem) {
489 emit
s_tools.instance->exclusiveFullScreenToggled(
false);
507 CVLog::Print(QString(
"New point size: %1").arg(newSize));
510 if (
s_tools.instance->m_viewportParams.defaultPointSize != newSize) {
511 s_tools.instance->m_viewportParams.defaultPointSize = newSize;
516 QString(
"New default point size: %1").arg(newSize),
528 if (
s_tools.instance->m_globalDBRoot) {
529 s_tools.instance->m_globalDBRoot->setPointSizeRecursive(
size);
532 if (
s_tools.instance->m_winDBRoot) {
533 s_tools.instance->m_winDBRoot->setPointSizeRecursive(
size);
541 CVLog::Print(QString(
"New line with: %1").arg(newWidth));
544 if (
s_tools.instance->m_viewportParams.defaultLineWidth != newWidth) {
545 s_tools.instance->m_viewportParams.defaultLineWidth = newWidth;
549 QString(
"New default line width: %1").arg(newWidth),
561 if (
s_tools.instance->m_globalDBRoot) {
562 s_tools.instance->m_globalDBRoot->setLineWidthRecursive(with);
565 if (
s_tools.instance->m_winDBRoot) {
566 s_tools.instance->m_winDBRoot->setLineWidthRecursive(with);
576 if (!
s_tools.instance->m_globalDBRoot && !
s_tools.instance->m_winDBRoot) {
599 const std::unordered_set<int>* selectedIDs ) {
602 emit
s_tools.instance->entitySelectionChanged(pickedEntity);
607 emit
s_tools.instance->entitiesSelectionChanged(*selectedIDs);
614 assert(pickedEntity ==
nullptr || pickedItemIndex >= 0);
615 assert(nearestPoint);
617 emit
s_tools.instance->itemPicked(
618 pickedEntity,
static_cast<unsigned>(pickedItemIndex),
623 emit
s_tools.instance->itemPickedFast(pickedEntity, pickedItemIndex,
626 if (
s_tools.instance->m_globalDBRoot && pickedEntity &&
627 pickedItemIndex >= 0) {
662 static_cast<float>(params.
centerX + 20) /
663 s_tools.instance->m_glViewport.width(),
664 static_cast<float>(params.
centerY + 20) /
665 s_tools.instance->m_glViewport.height());
667 QApplication::processEvents();
674 if (coef <= 0.0 || coef >= 1.0) {
675 CVLog::Warning(
"[ecvDisplayTools::setZNearCoef] Invalid coef. value!");
679 if (
s_tools.instance->m_viewportParams.zNearCoef != coef) {
681 s_tools.instance->m_viewportParams.zNearCoef = coef;
683 if (
s_tools.instance->m_viewportParams.perspectiveView) {
689 s_tools.instance->m_viewportParams.zFar);
694 QString(
"Near clipping = %1% of max depth (= %2)")
695 .arg(
s_tools.instance->m_viewportParams.zNearCoef *
698 .arg(
s_tools.instance->m_viewportParams.zNear),
706 emit
s_tools.instance->zNearCoefChanged(coef);
707 emit
s_tools.instance->cameraParamChanged();
722 switch (params.
mode) {
738 assert(!
s_tools.instance->m_captureMode.enabled);
741 std::unordered_set<int> selectedIDs;
742 int pickedItemIndex = -1;
749 if (
s_tools.instance->m_last_point_index >= 0) {
753 selectedIDs.insert(selectedID);
754 pickedItemIndex =
s_tools.instance->m_last_point_index;
758 if (pickedEntity && pickedItemIndex >= 0 &&
762 int pNum =
static_cast<int>(tempEntity->
size());
763 if (pickedItemIndex >= pNum) {
764 P =
s_tools.instance->m_last_picked_point;
766 QString(
"[ecvDisplayTools::StartOpenGLPicking] Picking "
767 "Error, %1 is more than picked entity size %2")
768 .arg(pickedItemIndex)
769 .arg(tempEntity->
size()));
770 pickedItemIndex = pNum - 1;
773 ->getPoint(pickedItemIndex));
776 if (temp.
norm() > 1) {
780 QString(
"[ecvDisplayTools::StartOpenGLPicking] droped "
781 "selected point coord is [%1, %2, %3]")
806 int nearestElementIndex = -1;
807 double nearestElementSquareDist = -1.0;
809 static const unsigned MIN_POINTS_FOR_OCTREE_COMPUTATION = 128;
813 bool autoComputeOctree =
false;
814 bool firstCloudWithoutOctree =
true;
820 int pickedIndex = -1;
822 if (
s_tools.instance->m_last_point_index >= 0) {
823 pickedIndex =
s_tools.instance->m_last_point_index;
827 if (pickedEntity && pickedIndex >= 0) {
842 nearestElementIndex = pickedIndex;
843 int pNum =
static_cast<int>(tempEntity->
size());
844 if (pickedIndex >= pNum) {
845 nearestPoint =
s_tools.instance->m_last_picked_point;
847 QString(
"[ecvDisplayTools::StartCPUBasedPointPicking] "
848 "Picking Error, %1 is more than picked entity "
851 .arg(tempEntity->
size()));
852 nearestElementIndex = pNum;
854 nearestPoint = *(tempEntity->
getPoint(pickedIndex));
857 nearestPoint -
s_tools.instance->m_last_picked_point;
858 if (temp.
norm() > 1) {
862 QString(
"[ecvDisplayTools::"
863 "StartCPUBasedPointPicking] droped "
864 "selected point coord is [%1, %2, %3]")
867 .arg(nearestPoint.
z));
873 nearestEntity = pickedEntity;
878 if (
s_tools.instance->m_globalDBRoot)
879 toProcess.push_back(
s_tools.instance->m_globalDBRoot);
880 if (
s_tools.instance->m_winDBRoot)
881 toProcess.push_back(
s_tools.instance->m_winDBRoot);
883 while (!toProcess.empty()) {
886 toProcess.pop_back();
890 bool ignoreSubmeshes =
false;
897 if (firstCloudWithoutOctree && !cloud->
getOctree() &&
899 MIN_POINTS_FOR_OCTREE_COMPUTATION)
911 behavior = autoComputeOctreeThisSession;
916 autoComputeOctree =
true;
920 QMessageBox question(
921 QMessageBox::Question,
922 "Picking acceleration",
923 "Automatically compute octree(s) to "
924 "accelerate the picking "
925 "process?\n(this behavior can be "
926 "changed later in the Display "
928 QMessageBox::NoButton,
931 QPushButton* yes =
new QPushButton(
"Yes");
932 question.addButton(yes,
933 QMessageBox::AcceptRole);
934 QPushButton* no =
new QPushButton(
"No");
935 question.addButton(no, QMessageBox::RejectRole);
936 QPushButton* always =
new QPushButton(
"Always");
937 question.addButton(always,
938 QMessageBox::AcceptRole);
939 QPushButton* never =
new QPushButton(
"Never");
940 question.addButton(never,
941 QMessageBox::RejectRole);
944 QAbstractButton* clickedButton =
945 question.clickedButton();
946 if (clickedButton == yes) {
947 autoComputeOctree =
true;
948 autoComputeOctreeThisSession =
950 }
else if (clickedButton == no) {
952 "now only support octree picking, "
953 "please don't select no!");
955 autoComputeOctree =
false;
956 autoComputeOctreeThisSession =
958 }
else if (clickedButton == always ||
959 clickedButton == never) {
961 (clickedButton == always);
977 autoComputeOctree =
false;
981 firstCloudWithoutOctree =
false;
984 int nearestPointIndex = -1;
985 double nearestSquareDist = 0.0;
987 clickedPos, camera, nearestPointIndex,
992 MIN_POINTS_FOR_OCTREE_COMPUTATION)) {
993 if (nearestElementIndex < 0 ||
994 (nearestPointIndex >= 0 &&
995 nearestSquareDist < nearestElementSquareDist)) {
996 nearestElementSquareDist = nearestSquareDist;
997 nearestElementIndex = nearestPointIndex;
999 *(cloud->
getPoint(nearestPointIndex));
1000 nearestEntity = cloud;
1015 ignoreSubmeshes =
true;
1023 int nearestTriIndex = -1;
1024 double nearestSquareDist = 0.0;
1028 nearestSquareDist, P)) {
1029 if (nearestElementIndex < 0 ||
1030 (nearestTriIndex >= 0 &&
1031 nearestSquareDist < nearestElementSquareDist)) {
1032 nearestElementSquareDist = nearestSquareDist;
1033 nearestElementIndex = nearestTriIndex;
1035 nearestEntity = mesh;
1038 }
else if (params.
mode ==
1044 int nearestPointIndex = -1;
1045 double nearestSquareDist = 0.0;
1049 nearestSquareDist)) {
1050 if (nearestElementIndex < 0 ||
1051 (nearestPointIndex >= 0 &&
1052 nearestSquareDist < nearestElementSquareDist)) {
1053 nearestElementSquareDist = nearestSquareDist;
1054 assert(nearestPointIndex <
1055 static_cast<int>(label->
size()));
1056 nearestElementIndex = nearestPointIndex;
1060 nearestEntity = label;
1070 ignoreSubmeshes =
true;
1074 if (!cameraSensor &&
1083 if (
id.toInt() != -1 &&
1086 nearestElementIndex =
id.toInt();
1088 nearestEntity = cameraSensor;
1098 if (ignoreSubmeshes &&
1105 toProcess.push_back(ent->
getChild(i));
1108 }
catch (
const std::bad_alloc&) {
1117 s_tools.instance->m_last_point_index = nearestElementIndex;
1118 s_tools.instance->m_last_picked_point = nearestPoint;
1119 if (nearestEntity) {
1130 if (
s_tools.instance->m_last_picked_id.isEmpty())
return nullptr;
1133 unsigned int selectedID =
s_tools.instance->m_last_picked_id.toUInt();
1135 pickedEntity =
s_tools.instance->m_globalDBRoot->find(selectedID);
1138 s_tools.instance->m_winDBRoot) {
1139 pickedEntity =
s_tools.instance->m_winDBRoot->find(selectedID);
1142 return pickedEntity;
1146 return QPointF(
x -
Width() / 2,
1167 s_tools.instance->m_pivotVisibility = vis;
1169 if (vis == PivotVisibility::PIVOT_HIDE) {
1182 settings.endGroup();
1193 if (
s_tools.instance->m_hotZone) {
1194 s_tools.instance->m_hotZone->topCorner = QPoint(0, 0);
1198 .arg(
s_tools.instance->m_glViewport.width())
1199 .arg(
s_tools.instance->m_glViewport.height()),
1204 if (dx != 0.0f || dy != 0.0f)
1208 emit
s_tools.instance->cameraDisplaced(dx, dy);
1215 if (!
s_tools.instance->m_viewportParams.objectCenteredView) {
1216 s_tools.instance->m_viewportParams.viewMat.transposed().applyRotation(
1224 int x,
int y,
bool extendToSelectedLabels ) {
1225 s_tools.instance->m_activeItems.clear();
1231 if (
s_tools.instance->m_activeItems.size() == 1) {
1235 if (!label->
isSelected() || !extendToSelectedLabels) {
1242 if (
s_tools.instance->m_globalDBRoot)
1243 s_tools.instance->m_globalDBRoot->filterChildren(
1245 if (
s_tools.instance->m_winDBRoot)
1246 s_tools.instance->m_winDBRoot->filterChildren(
1249 for (
auto& label : labels) {
1257 s_tools.instance->m_activeItems.push_back(l);
1267 int pickedItemIndex,
1290 double xc =
static_cast<double>(
Width() / 2);
1291 double yc =
static_cast<double>(
1295 if (
s_tools.instance->m_viewportParams.objectCenteredView) {
1300 if (!camera.
project(
s_tools.instance->m_viewportParams.getPivotPoint(),
1308 Q2D.
x = std::min(Q2D.
x, 3.0 *
Width() / 4.0);
1309 Q2D.
x = std::max(Q2D.
x,
Width() / 4.0);
1311 Q2D.
y = std::min(Q2D.
y, 3.0 *
Height() / 4.0);
1312 Q2D.
y = std::max(Q2D.
y,
Height() / 4.0);
1323 v.
x = std::max(std::min(v.
x / xc, 1.0), -1.0);
1324 v.
y = std::max(std::min(v.
y / yc, 1.0), -1.0);
1327 double d2 = v.
x * v.
x + v.
y * v.
y;
1331 double d = std::sqrt(d2);
1335 v.
z = std::sqrt(1.0 - d2);
1352 viewParams.
up = upDir;
1356 viewParams.
focal = camC - viewDir;
1362 emit
s_tools.instance->baseViewMatChanged(
1363 s_tools.instance->m_viewportParams.viewMat);
1372 switch (orientation) {
1419 switch (orientation) {
1458 bool forceRedraw ) {
1460 bool wasViewerBased =
1461 !
s_tools.instance->m_viewportParams.objectCenteredView;
1462 if (wasViewerBased) {
1467 if (wasViewerBased) {
1472 emit
s_tools.instance->baseViewMatChanged(
1473 s_tools.instance->m_viewportParams.viewMat);
1474 emit
s_tools.instance->cameraParamChanged();
1478 double currentPos[3], currentFocal[3];
1482 CCVector3d currentCameraPos(currentPos[0], currentPos[1], currentPos[2]);
1483 CCVector3d currentFocalPoint(currentFocal[0], currentFocal[1],
1488 CCVector3d currentViewDir = currentFocalPoint - currentCameraPos;
1489 double currentDistance = currentViewDir.
norm();
1492 if (currentDistance < 1
e-6) {
1493 currentDistance = 1.0;
1501 switch (orientation) {
1557 CCVector3d newCameraPos = currentFocalPoint - newViewDir * currentDistance;
1561 currentFocalPoint.
x, currentFocalPoint.
y,
1562 currentFocalPoint.
z, top.
x, top.
y, top.
z);
1578 int k =
static_cast<int>(
1579 std::floor(std::log(equivalentWidth) / std::log(10.0f)));
1580 float granularity = std::pow(10.0f,
static_cast<float>(k)) / 2.0f;
1582 return std::floor(std::max(equivalentWidth / granularity, 1.0f)) *
1593 float currentFov_deg =
GetFov();
1594 if (currentFov_deg < FLT_EPSILON)
return 1.0f;
1597 double zoomEquivalentDist =
1598 (
s_tools.instance->m_viewportParams.getCameraCenter() -
1599 s_tools.instance->m_viewportParams.getPivotPoint())
1603 float screenSize = std::min(
s_tools.instance->m_glViewport.width(),
1604 s_tools.instance->m_glViewport.height()) *
1605 s_tools.instance->m_viewportParams
1609 zoomEquivalentDist *
1616 return s_tools.instance->m_viewMatd;
1622 return s_tools.instance->m_projMatd;
1626 bool withGLfeatures,
1628 double* eyeOffset ) {
1629 double bbHalfDiag = 1.0;
1633 if (
s_tools.instance->m_globalDBRoot ||
s_tools.instance->m_winDBRoot) {
1646 s_tools.instance->m_viewportParams.getCameraCenter() - bbCenter;
1647 double cameraToBBCenterDist = cameraCenterToBBCenter.
normd();
1656 s_tools.instance->m_viewportParams.getRotationCenter();
1660 double rotationCenterToFarthestObjectDist = 0.0;
1664 rotationCenterToFarthestObjectDist =
1665 (bbCenter - rotationCenter).norm() + bbHalfDiag;
1669 if (
s_tools.instance->m_pivotSymbolShown &&
1672 s_tools.instance->m_viewportParams.objectCenteredView) {
1673 double pivotActualRadius =
1675 std::min(
s_tools.instance->m_glViewport.width(),
1676 s_tools.instance->m_glViewport.height()) /
1678 double pivotSymbolScale =
1680 rotationCenterToFarthestObjectDist = std::max(
1681 rotationCenterToFarthestObjectDist, pivotSymbolScale);
1684 if (withGLfeatures &&
s_tools.instance->m_customLightEnabled) {
1686 double distToCustomLight =
1690 rotationCenterToFarthestObjectDist = std::max(
1691 rotationCenterToFarthestObjectDist, distToCustomLight);
1694 rotationCenterToFarthestObjectDist *= 1.01;
1697 double cameraCenterToRotationCentertDist = 0;
1698 if (
s_tools.instance->m_viewportParams.objectCenteredView) {
1699 cameraCenterToRotationCentertDist =
1700 s_tools.instance->m_viewportParams.getFocalDistance();
1704 double zNear = cameraCenterToRotationCentertDist -
1705 rotationCenterToFarthestObjectDist;
1706 double zFar = cameraCenterToRotationCentertDist +
1707 rotationCenterToFarthestObjectDist;
1710 double ar =
static_cast<double>(
s_tools.instance->m_glViewport.height()) /
1711 s_tools.instance->m_glViewport.width();
1714 if (
s_tools.instance->m_viewportParams.perspectiveView) {
1719 zNear = bbHalfDiag *
s_tools.instance->m_viewportParams
1725 double xMax = zNear *
s_tools.instance->m_viewportParams
1726 .computeDistanceToHalfWidthRatio();
1727 double yMax = xMax * ar;
1731 double frustumAsymmetry = 0.0;
1733 xMax - frustumAsymmetry,
1734 -yMax, yMax, zNear, zFar);
1742 double xMax = std::abs(cameraCenterToRotationCentertDist) *
1743 s_tools.instance->m_viewportParams
1744 .computeDistanceToHalfWidthRatio();
1745 double yMax = xMax * ar;
1756 s_tools.instance->m_projMatd =
1760 s_tools.instance->m_viewportParams.zNear = metrics.
zNear;
1761 s_tools.instance->m_viewportParams.zFar = metrics.
zFar;
1765 s_tools.instance->m_validProjectionMatrix =
true;
1770 if (
s_tools.instance->m_viewportParams.perspectiveView) {
1771 return s_tools.instance->m_viewportParams.getCameraCenter();
1780 s_tools.instance->m_viewportParams.getCameraCenter().y,
1786 s_tools.instance->m_viewportParams.computeViewMatrix();
1789 s_tools.instance->m_viewportParams.computeScaleMatrix(
1790 s_tools.instance->m_glViewport);
1792 return scaleMatd * viewMatd;
1799 s_tools.instance->m_validModelviewMatrix =
true;
1803 s_tools.instance->m_viewportParams.viewMat = mat;
1808 emit
s_tools.instance->baseViewMatChanged(
1809 s_tools.instance->m_viewportParams.viewMat);
1810 emit
s_tools.instance->cameraParamChanged();
1815 bool perspectiveWasEnabled =
1816 s_tools.instance->m_viewportParams.perspectiveView;
1817 bool viewWasObjectCentered =
1818 s_tools.instance->m_viewportParams.objectCenteredView;
1821 s_tools.instance->m_viewportParams.perspectiveView = state;
1822 s_tools.instance->m_viewportParams.objectCenteredView = objectCenteredView;
1826 s_tools.instance->m_viewportParams.getPivotPoint();
1828 if (
s_tools.instance->m_viewportParams.perspectiveView) {
1829 if (!perspectiveWasEnabled)
1834 double currentFov_deg =
static_cast<double>(
GetFov());
1838 std::min(
s_tools.instance->m_glViewport.width(),
1839 s_tools.instance->m_glViewport.height()) *
1840 s_tools.instance->m_viewportParams.pixelSize;
1841 if (screenSize > 0.0) {
1842 PC.
z = screenSize / (
s_tools.instance->m_viewportParams.zoom *
1850 :
"Viewer-based perspective ON",
1855 s_tools.instance->m_viewportParams.objectCenteredView =
true;
1857 if (perspectiveWasEnabled)
1871 if (viewWasObjectCentered &&
1872 !
s_tools.instance->m_viewportParams.objectCenteredView) {
1873 s_tools.instance->m_viewportParams.viewMat.transposed().apply(
1875 }
else if (!viewWasObjectCentered &&
1876 s_tools.instance->m_viewportParams.objectCenteredView) {
1877 s_tools.instance->m_viewportParams.viewMat.apply(PC);
1882 emit
s_tools.instance->perspectiveStateChanged();
1883 emit
s_tools.instance->cameraParamChanged();
1891 s_tools.instance->m_viewportParams.perspectiveView);
1894 s_tools.instance->m_viewportParams.objectCenteredView);
1895 settings.endGroup();
1898 s_tools.instance->m_bubbleViewModeEnabled =
false;
1906 bool perspectiveWasEnabled =
1907 s_tools.instance->m_viewportParams.perspectiveView;
1908 bool viewWasObjectCentered =
1909 s_tools.instance->m_viewportParams.objectCenteredView;
1910 return perspectiveWasEnabled && viewWasObjectCentered;
1914 bool perspectiveWasEnabled =
1915 s_tools.instance->m_viewportParams.perspectiveView;
1916 bool viewWasObjectCentered =
1917 s_tools.instance->m_viewportParams.objectCenteredView;
1918 return perspectiveWasEnabled && !viewWasObjectCentered;
1923 if (
s_tools.instance->m_bubbleViewModeEnabled) {
1925 "[updateConstellationCenterAndZoom] Not when bubble-view is "
1936 zoomedBox = (*aBox);
1954 double bbDiag =
static_cast<double>(zoomedBox.
getDiagNorm());
1957 CVLog::Warning(
"[ecvDisplayTools] Entity/DB has a null bounding-box!");
1963 const double margin = 1.1;
1966 Eigen::Vector3d center(centerVec.
x, centerVec.
y, centerVec.
z);
1967 zoomedBox.
Scale(margin, center);
1975 int minScreenSize = std::min(
s_tools.instance->m_glViewport.width(),
1976 s_tools.instance->m_glViewport.height());
1978 ?
static_cast<float>(bbDiag / minScreenSize)
1989 s_tools.instance->Update2DLabel(
true);
2010 if (
s_tools.instance->m_globalDBRoot) {
2012 box =
s_tools.instance->m_globalDBRoot->getDisplayBB_recursive(
false);
2016 if (
s_tools.instance->m_winDBRoot) {
2018 s_tools.instance->m_winDBRoot->getDisplayBB_recursive(
false);
2082 s_tools.instance->m_displayOverlayEntities = state;
2089 s_tools.instance->m_globalDBRoot = root;
2099 if (
s_tools.instance->m_winDBRoot) {
2100 s_tools.instance->m_winDBRoot->addChild(
2104 CVLog::Error(
"[ecvDisplayTools::addToOwnDB] Window has no DB!");
2109 if (
s_tools.instance->m_winDBRoot)
2110 s_tools.instance->m_winDBRoot->removeChild(obj);
2114 if (removeinfos.size() > 0) {
2115 s_tools.instance->m_removeInfos = removeinfos;
2116 s_tools.instance->m_removeFlag =
true;
2118 s_tools.instance->m_removeFlag =
false;
2131 s_tools.instance->m_interactionFlags = flags;
2135 #ifdef CV_GL_WINDOW_USE_QWINDOW
2136 if (m_parentWidget) {
2137 m_parentWidget->setMouseTracking(
2147 s_tools.instance->m_clickableItemsVisible =
false;
2152 return s_tools.instance->m_interactionFlags;
2158 const double* M =
s_tools.instance->m_viewportParams.viewMat.data();
2167 const double* M =
s_tools.instance->m_viewportParams.viewMat.data();
2175 return (
s_tools.instance->m_bubbleViewModeEnabled
2176 ?
s_tools.instance->m_bubbleViewFov_deg
2177 :
s_tools.instance->m_viewportParams.fov_deg);
2184 bool viewerBasedPerspective ,
2185 bool bubbleViewMode ) {
2187 if (bubbleViewMode) {
2194 if (fov_deg > 0.0f) {
2195 if (
s_tools.instance->m_viewportParams.perspectiveView) {
2213 if (viewerBasedPerspective &&
s_tools.instance->m_autoPickPivotAtCenter) {
2229 CVLog::Warning(
"[ecvDisplayTools::setAspectRatio] Invalid AR value!");
2233 if (
s_tools.instance->m_viewportParams.cameraAspectRatio != ar) {
2235 s_tools.instance->m_viewportParams.cameraAspectRatio = ar;
2251 if (
s_tools.instance->m_bubbleViewModeEnabled) {
2253 }
else if (
s_tools.instance->m_viewportParams.fov_deg != fov_deg) {
2255 s_tools.instance->m_viewportParams.fov_deg = fov_deg;
2264 QString(
"F.O.V. = %1 deg.").arg(fov_deg, 0,
'f', 1),
2270 emit
s_tools.instance->fovChanged(
2271 s_tools.instance->m_viewportParams.fov_deg);
2272 emit
s_tools.instance->cameraParamChanged();
2279 int displayMaxDelay_sec ,
2281 if (message.isEmpty()) {
2283 std::list<MessageToDisplay>::iterator it =
2284 s_tools.instance->m_messagesToDisplay.begin();
2285 while (it !=
s_tools.instance->m_messagesToDisplay.end()) {
2287 if (it->position == pos) {
2290 it =
s_tools.instance->m_messagesToDisplay.erase(it);
2296 "[ecvDisplayTools::DisplayNewMessage] Appending an empty "
2297 "message has no effect!");
2306 for (std::list<MessageToDisplay>::iterator it =
2307 s_tools.instance->m_messagesToDisplay.begin();
2308 it !=
s_tools.instance->m_messagesToDisplay.end();) {
2310 if (it->type ==
type) {
2313 it =
s_tools.instance->m_messagesToDisplay.erase(it);
2321 "[ecvDisplayTools::DisplayNewMessage] Append is not "
2322 "supported for center screen messages!");
2329 s_tools.instance->m_timer.elapsed() / 1000 + displayMaxDelay_sec;
2332 s_tools.instance->m_messagesToDisplay.push_back(mess);
2338 bool autoUpdateCameraPos ,
2340 if (autoUpdateCameraPos &&
2341 (!
s_tools.instance->m_viewportParams.perspectiveView ||
2342 s_tools.instance->m_viewportParams.objectCenteredView)) {
2346 s_tools.instance->m_viewportParams.viewMat.applyRotation(MdP);
2348 s_tools.instance->m_viewportParams.getCameraCenter() + MdP - dP;
2352 s_tools.instance->m_viewportParams.setPivotPoint(P,
true);
2356 emit
s_tools.instance->pivotPointChanged(
2357 s_tools.instance->m_viewportParams.getPivotPoint());
2358 emit
s_tools.instance->cameraParamChanged();
2361 const unsigned& precision =
2366 .arg(P.
x, 0,
'f', precision)
2367 .arg(P.
y, 0,
'f', precision)
2368 .arg(P.
z, 0,
'f', precision),
2374 s_tools.instance->m_autoPivotCandidate = P;
2380 if (
s_tools.instance->m_autoPickPivotAtCenter != state) {
2381 s_tools.instance->m_autoPickPivotAtCenter = state;
2393 s_tools.instance->m_rotationAxisLocked = state;
2394 s_tools.instance->m_lockedRotationAxis = axis;
2395 s_tools.instance->m_lockedRotationAxis.normalize();
2400 CONTEXT.
glW =
s_tools.instance->m_glViewport.width();
2401 CONTEXT.
glH =
s_tools.instance->m_glViewport.height();
2453 bool dontScaleFeatures ,
2454 bool renderOverlayItems ) {
2455 if (
filename.isEmpty() || zoomFactor < 1.0e-2f) {
2459 QImage outputImage =
RenderToImage(
static_cast<int>(zoomFactor),
2460 renderOverlayItems,
false, 0);
2462 if (outputImage.isNull()) {
2470 outputImage = outputImage.convertToFormat(QImage::Format_RGB32);
2474 outputImage.convertToFormat(QImage::Format_RGB32).save(
filename);
2476 CVLog::Print(QString(
"[Snapshot] File '%1' saved! (%2 x %3 pixels)")
2478 .arg(outputImage.width())
2479 .arg(outputImage.height()));
2482 QString(
"[Snapshot] Failed to save file '%1'!").arg(
filename));
2489 if ((
s_tools.instance->m_viewportParams.getCameraCenter() - P).norm2d() !=
2491 s_tools.instance->m_viewportParams.setCameraCenter(P,
true);
2493 emit
s_tools.instance->cameraPosChanged(
2494 s_tools.instance->m_viewportParams.getCameraCenter());
2495 emit
s_tools.instance->cameraParamChanged();
2503 if (
s_tools.instance->m_overridenDisplayParametersEnabled) {
2504 s_tools.instance->m_overridenDisplayParameters.initFontSizesIfNeeded();
2505 return s_tools.instance->m_overridenDisplayParameters;
2523 s_tools.instance->m_viewportParams.viewMat = rotationMat;
2529 s_tools.instance->m_viewportParams.setPivotPoint(pivot);
2531 s_tools.instance->m_viewportParams.zNear = nearFar[0];
2532 s_tools.instance->m_viewportParams.zFar = nearFar[1];
2533 s_tools.instance->m_viewportParams.fov_deg =
2548 s_tools.instance->m_overridenDisplayParametersEnabled =
true;
2549 s_tools.instance->m_overridenDisplayParameters = params;
2550 s_tools.instance->m_overridenDisplayParameters.initFontSizesIfNeeded();
2558 s_tools.instance->m_viewportParams.zNear = nearFar[0];
2559 s_tools.instance->m_viewportParams.zFar = nearFar[1];
2565 s_tools.instance->m_viewportParams.viewMat = rotationMat;
2569 s_tools.instance->m_viewportParams.setPivotPoint(pivot);
2572 if (
s_tools.instance->m_viewportParams.perspectiveView) {
2574 s_tools.instance->m_viewportParams.fov_deg =
2577 s_tools.instance->m_viewportParams.fov_deg =
static_cast<float>(
2584 s_tools.instance->m_viewportParams.setCameraCenter(
2601 s_tools.instance->m_viewportParams = params;
2613 s_tools.instance->m_viewportParams.perspectiveView =
2625 emit
s_tools.instance->baseViewMatChanged(
2626 s_tools.instance->m_viewportParams.viewMat);
2627 emit
s_tools.instance->pivotPointChanged(
2628 s_tools.instance->m_viewportParams.getPivotPoint());
2629 emit
s_tools.instance->cameraPosChanged(
2630 s_tools.instance->m_viewportParams.getCameraCenter());
2631 emit
s_tools.instance->fovChanged(
2632 s_tools.instance->m_viewportParams.fov_deg);
2633 emit
s_tools.instance->cameraParamChanged();
2638 return s_tools.instance->m_viewportParams;
2643 bool bubbleViewModeWasEnabled =
s_tools.instance->m_bubbleViewModeEnabled;
2644 if (!
s_tools.instance->m_bubbleViewModeEnabled && state) {
2645 s_tools.instance->m_preBubbleViewParameters =
2646 s_tools.instance->m_viewportParams;
2655 s_tools.instance->m_bubbleViewModeEnabled =
true;
2658 s_tools.instance->m_bubbleViewFov_deg =
2661 }
else if (bubbleViewModeWasEnabled) {
2662 s_tools.instance->m_bubbleViewModeEnabled =
false;
2664 s_tools.instance->m_preBubbleViewParameters.perspectiveView,
2665 s_tools.instance->m_preBubbleViewParameters.objectCenteredView);
2673 if (fov_deg < FLT_EPSILON || fov_deg > 180.0f)
return;
2675 if (fov_deg !=
s_tools.instance->m_bubbleViewFov_deg) {
2676 s_tools.instance->m_bubbleViewFov_deg = fov_deg;
2678 if (
s_tools.instance->m_bubbleViewModeEnabled) {
2682 emit
s_tools.instance->fovChanged(
2683 s_tools.instance->m_bubbleViewFov_deg);
2684 emit
s_tools.instance->cameraParamChanged();
2690 if (
s_tools.instance->m_viewportParams.pixelSize != pixelSize) {
2691 s_tools.instance->m_viewportParams.pixelSize = pixelSize;
2700 assert(!
s_tools.instance->m_bubbleViewModeEnabled);
2707 if (
s_tools.instance->m_viewportParams.zoom != value) {
2708 s_tools.instance->m_viewportParams.zoom = value;
2717 assert(!
s_tools.instance->m_viewportParams.perspectiveView);
2719 if (zoomFactor > 0.0f && zoomFactor != 1.0f) {
2726 if (
s_tools.instance->m_pickingModeLocked) {
2727 if ((mode !=
s_tools.instance->m_pickingMode) &&
2730 "[ecvDisplayTools::setPickingMode] Picking mode is locked! "
2731 "Can't change it...");
2752 s_tools.instance->m_pickingMode = mode;
2759 return s_tools.instance->m_pickingMode;
2763 s_tools.instance->m_pickingModeLocked = state;
2767 return s_tools.instance->m_pickingModeLocked;
2771 if (!
s_tools.instance->m_viewportParams.perspectiveView) {
2772 return static_cast<double>(
2773 s_tools.instance->m_viewportParams.pixelSize /
2774 s_tools.instance->m_viewportParams.zoom);
2777 int minScreenDim = std::min(
s_tools.instance->m_glViewport.width(),
2778 s_tools.instance->m_glViewport.height());
2779 if (minScreenDim <= 0)
return 1.0;
2782 double zoomEquivalentDist =
2783 (
s_tools.instance->m_viewportParams.getCameraCenter() -
2784 s_tools.instance->m_viewportParams.getPivotPoint())
2787 double currentFov_deg =
static_cast<double>(
GetFov());
2788 return zoomEquivalentDist *
2790 std::min(currentFov_deg, 75.0))) /
2795 return s_tools.instance->m_allowRectangularEntityPicking;
2799 s_tools.instance->m_allowRectangularEntityPicking = state;
2804 if (state && !
s_tools.instance->m_pivotSymbolShown &&
2805 s_tools.instance->m_viewportParams.objectCenteredView &&
2811 s_tools.instance->m_pivotSymbolShown = state;
2816 s_tools.instance->m_captureMode.enabled
2819 s_tools.instance->m_captureMode.zoomFactor)
2825 s_tools.instance->m_captureMode.enabled
2828 s_tools.instance->m_captureMode.zoomFactor)
2833 QFont font =
s_tools.instance->m_font;
2842 QPoint globalOldPoint = QCursor::pos();
2843 oldlpPoint.x = globalOldPoint.x();
2844 oldlpPoint.y = globalOldPoint.y();
2847 QPoint clickPos = screenRect.center();
2848 lpPoint.x = clickPos.x();
2849 lpPoint.y = clickPos.y();
2851 SetCursorPos(lpPoint.x, lpPoint.y);
2853 MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE, 0,
2856 SetCursorPos(oldlpPoint.x, oldlpPoint.y);
2870 s_tools.instance->m_shouldBeRefreshed =
true;
2877 bool forceRedraw ) {
2878 if (
s_tools.instance->m_shouldBeRefreshed) {
2884 bool forceRedraw ) {
2886 if (
s_tools.instance->m_showDebugTraces) {
2890 if (!
s_tools.instance->m_diagStrings.isEmpty()) {
2891 QStringList::iterator it =
s_tools.instance->m_diagStrings.begin();
2892 while (it !=
s_tools.instance->m_diagStrings.end()) {
2895 it =
s_tools.instance->m_diagStrings.erase(it);
2899 s_tools.instance->m_diagStrings
2900 << QString(
"only2D : %1").arg(only2D ?
"true" :
"false");
2901 s_tools.instance->m_diagStrings
2902 << QString(
"ForceRedraw : %1")
2903 .arg(forceRedraw ?
"true" :
"false");
2907 if (!
s_tools.instance->m_diagStrings.isEmpty()) {
2908 QStringList::iterator it =
s_tools.instance->m_diagStrings.begin();
2909 while (it !=
s_tools.instance->m_diagStrings.end()) {
2912 it =
s_tools.instance->m_diagStrings.erase(it);
2918 if (
s_tools.instance->m_removeAllFlag) {
2931 bool drawBackground =
false;
2932 bool draw3DPass =
false;
2933 bool drawForeground =
true;
2938 if (
s_tools.instance->m_updateFBO ||
2939 s_tools.instance->m_captureMode.enabled) {
2941 drawBackground =
true;
2951 std::list<MessageToDisplay>::iterator it =
2952 s_tools.instance->m_messagesToDisplay.begin();
2953 qint64 currentTime_sec =
s_tools.instance->m_timer.elapsed() / 1000;
2957 while (it !=
s_tools.instance->m_messagesToDisplay.end()) {
2959 if (it->messageValidity_sec < currentTime_sec) {
2962 it =
s_tools.instance->m_messagesToDisplay.erase(it);
2970 QRect originViewport =
s_tools.instance->m_glViewport;
2971 bool modifiedViewport =
false;
2977 if (drawBackground) {
2978 if (
s_tools.instance->m_showDebugTraces) {
2979 s_tools.instance->m_diagStrings <<
"draw background";
2991 if (
s_tools.instance->m_showDebugTraces) {
2992 s_tools.instance->m_diagStrings <<
"draw 3D";
3000 if (
s_tools.instance->m_showDebugTraces) {
3001 if (!
s_tools.instance->m_diagStrings.isEmpty()) {
3003 int font_size = font.pointSize();
3004 QFontMetrics fm(font);
3006 int x =
s_tools.instance->m_glViewport.width() / 2 - 100;
3007 int margin = font_size / 2;
3013 (fm.height() + margin);
3024 for (
const QString& str :
s_tools.instance->m_diagStrings) {
3027 y += fm.height() + margin;
3033 if (modifiedViewport) {
3036 CONTEXT.
glW = originViewport.width();
3037 CONTEXT.
glH = originViewport.height();
3038 modifiedViewport =
false;
3041 if (drawBackground || draw3DCross) {
3042 s_tools.instance->m_updateFBO =
false;
3048 if (drawForeground) {
3052 s_tools.instance->m_shouldBeRefreshed =
false;
3054 if (
false &&
s_tools.instance->m_autoPickPivotAtCenter &&
3055 !
s_tools.instance->m_mouseMoved &&
3056 s_tools.instance->m_autoPivotCandidate.norm2d() != 0.0) {
3066 s_tools.instance->m_glViewport =
3067 QRect(rect.left() * retinaScale, rect.top() * retinaScale,
3068 rect.width() * retinaScale, rect.height() * retinaScale);
3085 if (
s_tools.instance->m_customLightEnabled ||
3086 s_tools.instance->m_sunLightEnabled) {
3090 if (
s_tools.instance->m_sunLightEnabled) {
3096 if (
s_tools.instance->m_globalDBRoot) {
3097 s_tools.instance->m_globalDBRoot->draw(CONTEXT);
3100 if (
s_tools.instance->m_winDBRoot) {
3101 s_tools.instance->m_winDBRoot->draw(CONTEXT);
3106 if (
s_tools.instance->m_autoPickPivotAtCenter)
3111 s_tools.instance->m_autoPivotCandidate = P;
3116 if (
s_tools.instance->m_globalDBRoot &&
3117 s_tools.instance->m_globalDBRoot->getChildrenNumber()) {
3127 context.hideShowEntityType = hideShowEntityType;
3129 for (
const QString& removeViewId : viewIDs) {
3130 context.viewID = removeViewId;
3161 context.removeEntityType = removeEntityType;
3162 for (
const QString& removeViewId : viewIDs) {
3163 context.removeViewID = removeViewId;
3203 s_tools.instance->setBackgroundColor(CONTEXT);
3219 if (
s_tools.instance->m_globalDBRoot)
3220 s_tools.instance->m_globalDBRoot->draw(CONTEXT);
3221 if (
s_tools.instance->m_winDBRoot)
3222 s_tools.instance->m_winDBRoot->draw(CONTEXT);
3227 s_tools.instance->m_clickableItems.clear();
3230 if (
s_tools.instance->m_displayOverlayEntities) {
3234 if (!
s_tools.instance->m_captureMode.enabled ||
3235 s_tools.instance->m_captureMode.renderOverlayItems) {
3237 if (!
s_tools.instance->m_viewportParams.perspectiveView) {
3245 if (!
s_tools.instance->m_captureMode.enabled) {
3249 if (!
s_tools.instance->m_messagesToDisplay.empty()) {
3250 QFont font =
s_tools.instance->m_font;
3251 QFontMetrics fm(font);
3252 int margin = fm.height() / 4;
3253 int ll_currentHeight =
3254 s_tools.instance->m_glViewport.height() - 10;
3255 int uc_currentHeight = 10;
3257 for (
const auto& message :
3258 s_tools.instance->m_messagesToDisplay) {
3259 switch (message.position) {
3261 RenderText(10, ll_currentHeight, message.message,
3263 int messageHeight = fm.height();
3264 ll_currentHeight -= (messageHeight + margin);
3267 QRect rect = fm.boundingRect(message.message);
3268 int x = (
s_tools.instance->m_glViewport.width() -
3271 int y = uc_currentHeight + rect.height();
3273 uc_currentHeight += (rect.height() + margin);
3276 QFont newFont(font);
3278 newFont.setPointSize(fontSize);
3279 QRect rect = QFontMetrics(newFont).boundingRect(
3282 (
s_tools.instance->m_glViewport.width() -
3285 (
s_tools.instance->m_glViewport.height() -
3288 message.message, newFont);
3295 {
s_tools.instance->DrawClickableItems(0, yStart); }
3305 for (
auto& label : labels) {
3322 s_tools.instance->m_activeItems.clear();
3326 for (
auto& label : labels) {
3333 s_tools.instance->m_activeItems.push_back(l);
3334 if (immediateUpdate) {
3348 QString
id =
s_tools.instance->pick2DLabel(
x,
y);
3351 s_tools.instance->m_activeItems.clear();
3352 if (!
id.isEmpty()) {
3355 for (
auto& label : labels) {
3361 s_tools.instance->m_activeItems.push_back(l);
3370 if (
s_tools.instance->m_globalDBRoot)
3371 s_tools.instance->m_globalDBRoot->filterChildren(labels,
true,
type);
3372 if (
s_tools.instance->m_winDBRoot)
3373 s_tools.instance->m_winDBRoot->filterChildren(labels,
true,
type);
3382 const QString&
id) {
3392 context.textParam.display3D =
false;
3393 context.textParam.font = font;
3394 context.textParam.font.setPointSize(font.pointSize());
3398 if (
context.textParam.display3D) {
3403 context.textParam.textPos.x = output2D.
x;
3404 context.textParam.textPos.y = output2D.
y;
3405 context.textParam.textPos.z = output2D.
z;
3409 s_tools.instance->m_glViewport.height() -
y;
3410 context.textParam.textPos.z = 0;
3422 const QString&
id) {
3431 Q2D.
y =
s_tools.instance->m_glViewport.height() - 1 - Q2D.
y;
3439 const QFont& font ) {
3446 const QString& text,
3449 unsigned char align ,
3451 const unsigned char* rgbColor ,
3453 const QString&
id ) {
3455 int y2 =
s_tools.instance->m_glViewport.height() - 1 -
y;
3458 const unsigned char* col =
3461 QFont realFont = (font ? *font :
s_tools.instance->m_font);
3462 QFont textFont = realFont;
3463 QFontMetrics fm(textFont);
3464 int margin = fm.height() / 4;
3467 QRect rect = fm.boundingRect(text);
3471 x2 -= rect.width() / 2;
3475 y2 += rect.height() / 2;
3477 y2 += rect.height();
3480 if (bkgAlpha != 0.0f) {
3482 const float invertedCol[4] = {(255 - col[0]) / 255.0f,
3483 (255 - col[0]) / 255.0f,
3484 (255 - col[0]) / 255.0f, bkgAlpha};
3491 int yB =
s_tools.instance->m_glViewport.height() - y2;
3501 param.
color.
r = invertedCol[0];
3502 param.
color.
g = invertedCol[1];
3503 param.
color.
b = invertedCol[2];
3504 param.
color.
a = invertedCol[3];
3506 QRect(xB - margin, yB - margin, rect.width() + 2 * margin,
3507 static_cast<int>(rect.height() + 1.5 * margin));
3511 param.
rect.setWidth(param.
rect.width() * 2);
3514 param.
rect.moveTop(std::min(
s_tools.instance->m_glViewport.height(),
3515 param.
rect.y() + 2 * margin));
3528 RenderText(x2, y2, text, realFont, textColor,
id);
3537 unsigned char alpha ) {
3540 param.
opacity = alpha / 255.0f;
3541 param.
rect = QRect(
x,
y, w, h);
3547 s_tools.instance->m_hotZone->bbv_label));
3549 s_tools.instance->m_hotZone->fs_label));
3551 s_tools.instance->m_hotZone->psi_label));
3553 s_tools.instance->m_hotZone->lsi_label));
3559 const static char* CLICKED_ITEMS =
"clicked_items";
3561 if (!
s_tools.instance->m_hotZone) {
3570 s_tools.instance->m_hotZone->updateInternalVariables(
3575 s_tools.instance->m_hotZone->topCorner =
3576 QPoint(xStart0, yStart) +
3577 QPoint(
s_tools.instance->m_hotZone->margin,
3578 s_tools.instance->m_hotZone->margin);
3582 if (!
s_tools.instance->m_clickableItemsVisible &&
3583 !
s_tools.instance->m_bubbleViewModeEnabled && !fullScreenEnabled) {
3592 int fullW =
s_tools.instance->m_glViewport.width();
3593 int fullH =
s_tools.instance->m_glViewport.height();
3600 QRect areaRect =
s_tools.instance->m_hotZone->rect(
3601 s_tools.instance->m_clickableItemsVisible,
3602 s_tools.instance->m_bubbleViewModeEnabled, fullScreenEnabled);
3603 areaRect.translate(
s_tools.instance->m_hotZone->topCorner);
3608 param.
color.
a = 210 / 255.0f;
3609 int x0 = areaRect.x();
3610 int y0 = fullH - areaRect.y() - areaRect.height();
3611 param.
rect = QRect(x0, y0, areaRect.width(), areaRect.height());
3615 yStart =
s_tools.instance->m_hotZone->topCorner.y();
3621 int iconSize =
s_tools.instance->m_hotZone->iconSize;
3623 if (fullScreenEnabled) {
3624 int xStart =
s_tools.instance->m_hotZone->topCorner.x();
3629 s_tools.instance->m_hotZone->yTextBottomLineShift,
3630 s_tools.instance->m_hotZone->fs_label,
3631 s_tools.instance->m_hotZone->font,
3635 xStart +=
s_tools.instance->m_hotZone->fs_labelRect.width() +
3636 s_tools.instance->m_hotZone->margin;
3640 xStart +=
s_tools.instance->m_hotZone->margin * 4;
3645 int y0 = fullH - (yStart + iconSize);
3649 param.rect = QRect(x0, y0, iconSize +
offset, iconSize);
3654 texParam.
text =
"Exit";
3656 QRect(x0, fullH - (yStart +
offset / 2 + 3 * iconSize / 4),
3657 iconSize, iconSize);
3660 s_tools.instance->m_clickableItems.emplace_back(
3662 QRect(xStart, yStart, iconSize, iconSize));
3667 yStart +=
s_tools.instance->m_hotZone->margin;
3670 if (
s_tools.instance->m_bubbleViewModeEnabled) {
3671 int xStart =
s_tools.instance->m_hotZone->topCorner.x();
3676 s_tools.instance->m_hotZone->yTextBottomLineShift,
3677 s_tools.instance->m_hotZone->bbv_label,
3678 s_tools.instance->m_hotZone->font);
3681 xStart +=
s_tools.instance->m_hotZone->bbv_labelRect.width() +
3682 s_tools.instance->m_hotZone->margin;
3685 xStart +=
s_tools.instance->m_hotZone->margin * 4;
3690 s_tools.instance->m_clickableItems.emplace_back(
3692 QRect(xStart, yStart,
s_tools.instance->m_hotZone->iconSize,
3693 s_tools.instance->m_hotZone->iconSize));
3694 xStart +=
s_tools.instance->m_hotZone->iconSize;
3697 yStart +=
s_tools.instance->m_hotZone->iconSize;
3698 yStart +=
s_tools.instance->m_hotZone->margin;
3701 if (
s_tools.instance->m_clickableItemsVisible) {
3714 int xStart =
s_tools.instance->m_hotZone->topCorner.x();
3719 s_tools.instance->m_hotZone->yTextBottomLineShift,
3720 s_tools.instance->m_hotZone->psi_label,
3721 s_tools.instance->m_hotZone->font, textColor,
3725 xStart +=
s_tools.instance->m_hotZone->psi_labelRect.width() +
3726 s_tools.instance->m_hotZone->margin;
3729 xStart +=
s_tools.instance->m_hotZone->margin * 4;
3737 int y0 = fullH - (yStart + iconSize / 2);
3738 widgetParam.
rect = QRect(x0, y0, iconSize, iconSize / 4);
3740 s_tools.instance->m_clickableItems.emplace_back(
3742 QRect(xStart, yStart, iconSize, iconSize));
3749 s_tools.instance->m_viewportParams.defaultPointSize / 2;
3755 int y0 = fullH - (yStart + iconSize / 2);
3756 sepParam.
rect = QRect(x0, y0, iconSize, iconSize);
3758 xStart +=
s_tools.instance->m_hotZone->margin * 2;
3764 int y0 = fullH - (yStart + iconSize / 2);
3765 widgetParam.
rect = QRect(x0, y0, iconSize, iconSize / 4);
3767 x0 = xStart + 3 * iconSize / 8;
3768 y0 = fullH - (yStart + 7 * iconSize / 8);
3769 widgetParam.
rect = QRect(x0, y0, iconSize / 4, iconSize);
3772 s_tools.instance->m_clickableItems.emplace_back(
3774 QRect(xStart, yStart, iconSize, iconSize));
3779 yStart +=
s_tools.instance->m_hotZone->margin;
3784 int xStart =
s_tools.instance->m_hotZone->topCorner.x();
3789 s_tools.instance->m_hotZone->yTextBottomLineShift,
3790 s_tools.instance->m_hotZone->lsi_label,
3791 s_tools.instance->m_hotZone->font, textColor,
3795 xStart +=
s_tools.instance->m_hotZone->lsi_labelRect.width() +
3796 s_tools.instance->m_hotZone->margin;
3799 xStart +=
s_tools.instance->m_hotZone->margin * 4;
3807 int y0 = fullH - (yStart + iconSize / 2);
3808 widgetParam.
rect = QRect(x0, y0, iconSize, iconSize / 4);
3811 s_tools.instance->m_clickableItems.emplace_back(
3813 QRect(xStart, yStart, iconSize, iconSize));
3820 s_tools.instance->m_viewportParams.defaultLineWidth / 2;
3826 int y0 = fullH - (yStart + iconSize / 2);
3827 sepParam.
rect = QRect(x0, y0, iconSize, iconSize);
3829 xStart +=
s_tools.instance->m_hotZone->margin * 2;
3835 int y0 = fullH - (yStart + iconSize / 2);
3836 widgetParam.
rect = QRect(x0, y0, iconSize, iconSize / 4);
3838 x0 = xStart + 3 * iconSize / 8;
3839 y0 = fullH - (yStart + 7 * iconSize / 8);
3840 widgetParam.
rect = QRect(x0, y0, iconSize / 4, iconSize);
3843 s_tools.instance->m_clickableItems.emplace_back(
3845 QRect(xStart, yStart, iconSize, iconSize));
3850 yStart +=
s_tools.instance->m_hotZone->margin;
3856 if (
s_tools.instance->m_removeAllFlag) {
3861 }
else if (
s_tools.instance->m_removeFlag) {
3876 s_tools.instance->m_removeFlag =
false;
3888 context.removeViewID = viewId;
3894 if (propertyParam.
entity) {
3903 s_tools.instance->changeEntityProperties(propertyParam);
3914 switch (param.
type) {
3922 QFont textFont =
s_tools.instance->m_font;
3924 textFont.pointSize();
3926 s_tools.instance->drawWidgets(param);
3936 s_tools.instance->drawWidgets(param);
3940 s_tools.instance->drawWidgets(param);
3954 if (
s_tools.instance->m_interactionFlags &
3959 poly->
draw(CONTEXT);
3962 s_tools.instance->drawWidgets(param);
3965 s_tools.instance->drawWidgets(param);
3981 switch (param.
type) {
4095 context.removeViewID = view_id;
4105 y =
s_tools.instance->m_glViewport.height() - 1 -
y;
4108 if (glDepth == 1.0) {
4116 if (!
s_tools.instance->m_viewportParams.objectCenteredView ||
4119 !
s_tools.instance->m_pivotSymbolShown)) {
4126 s_tools.instance->m_viewportParams.getPivotPoint().y,
4127 s_tools.instance->m_viewportParams.getPivotPoint().z);
4131 std::min(
s_tools.instance->m_glViewport.width(),
4132 s_tools.instance->m_glViewport.height()) /
4147 sphere.
draw(CONTEXT);
4152 s_tools.instance->m_currentScreen = widget;
constexpr float MIN_POINT_SIZE_F
static constexpr float CC_GL_MIN_ZOOM_RATIO
static constexpr float CC_GL_MAX_ZOOM_RATIO
constexpr float MIN_LINE_WIDTH_F
constexpr float MAX_LINE_WIDTH_F
CC_VIEW_ORIENTATION
View orientation.
constexpr double ZERO_TOLERANCE_D
constexpr float MAX_POINT_SIZE_F
Vector3Tpl< double > CCVector3d
Double 3D Vector.
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
float PointCoordinateType
Type of the coordinates of a (N-D) point.
int64_t CV_CLASS_ENUM
Type of object type flags (64 bits)
std::shared_ptr< core::Tensor > image
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 PrintVerbose(const char *format,...)
Prints out a verbose formatted message in console.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
void normalize()
Sets vector norm to unity.
double normd() const
Returns vector norm (forces double precision output)
Type norm() const
Returns vector norm.
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.
const PickedPoint & getPickedPoint(unsigned index) const
Returns a given point.
bool isPointLegendDisplayed() const
Returns whether the point(s) legend is displayed.
unsigned size() const
Returns current size.
void setPosition(float x, float y)
Sets relative position.
bool pointPicking(const CCVector2d &clickPos, const ccGLCameraParameters &camera, int &nearestPointIndex, double &nearestSquareDist) const
Point (marker) picking.
void update2DLabelView(CC_DRAW_CONTEXT &context, bool updateScreen=true)
bool isDisplayedIn2D() const
Returns whether the label is displayed in 2D.
virtual ccBBox & Scale(const double s, const Eigen::Vector3d ¢er) override
Apply scaling to the geometry coordinates. Given a scaling factor , and center , a given point is tr...
Camera (projective) sensor.
const cloudViewer::geometry::LineSet & getNearPlane() const
void setClickedPoint(int x, int y, int screenWidth, int screenHeight, const ccGLMatrixd &viewMatrix)
Sets last clicked point (on screen)
void setActiveComponent(int id)
Sets currently active component.
virtual bool isVisible() const
Returns whether entity is visible or not.
virtual void setVisible(bool state)
Sets entity visibility.
virtual bool isSelected() const
Returns whether entity is selected or not.
virtual void showColors(bool state)
Sets colors visibility.
Vector3Tpl< T > getTranslationAsVec3D() const
Returns a copy of the translation as a CCVector3.
void applyRotation(Vector3Tpl< float > &vec) const
Applies rotation only to a 3D vector (in place) - float version.
T * data()
Returns a pointer to internal data.
void clearTranslation()
Clears translation.
static ccGLMatrixTpl< double > FromViewDirAndUpDir(const Vector3Tpl< double > &forward, const Vector3Tpl< double > &up)
Generates a 'viewing' matrix from a looking vector and a 'up' direction.
void invert()
Inverts transformation.
void setRotation(const float Rt[9])
Sets Rotation from a float array.
Vector3Tpl< T > getColumnAsVec3D(unsigned index) const
Returns a copy of a given column as a CCVector3.
static Eigen::Matrix< double, 3, 3 > ToEigenMatrix3(const ccGLMatrixTpl< float > &mat)
Double version of ccGLMatrixTpl.
virtual bool isShownAsWire() const
Returns whether the mesh is displayed as wired or with plain facets.
virtual ccGenericPointCloud * getAssociatedCloud() const =0
Returns the vertices cloud.
virtual bool trianglePicking(const CCVector2d &clickPos, const ccGLCameraParameters &camera, int &nearestTriIndex, double &nearestSquareDist, CCVector3d &nearestPoint, CCVector3d *barycentricCoords=nullptr) const
Brute force triangle picking.
A 3D cloud interface with associated features (color, normals, octree, etc.)
virtual ccOctree::Shared getOctree() const
Returns the associated octree (if any)
bool pointPicking(const CCVector2d &clickPos, const ccGLCameraParameters &camera, int &nearestPointIndex, double &nearestSquareDist, double pickWidth=2.0, double pickHeight=2.0, bool autoComputeOctree=false)
Point picking (brute force or octree-driven)
virtual void setColor(const ecvColor::Rgb &col)
Sets primitive color (shortcut)
static ccPolyline * ToPolyline(ccHObject *obj)
Converts current object to ccPolyline (if possible)
static cc2DViewportLabel * To2DViewportLabel(ccHObject *obj)
Converts current object to cc2DViewportLabel (if possible)
static ccGenericMesh * ToGenericMesh(ccHObject *obj)
Converts current object to ccGenericMesh (if possible)
static ccGenericPointCloud * ToGenericPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccGenericPointCloud.
static cc2DLabel * To2DLabel(ccHObject *obj)
Converts current object to cc2DLabel (if possible)
Hierarchical CLOUDVIEWER Object.
void draw(CC_DRAW_CONTEXT &context) override
Draws entity and its children.
ENTITY_TYPE getEntityType() const
QString getViewId() const
unsigned getChildrenNumber() const
Returns the number of children.
void setRedrawFlagRecursive(bool redraw=false)
void updateNameIn3DRecursive()
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
std::vector< ccHObject * > Container
Standard instances container (for children, etc.)
ccHObject * getChild(unsigned childPos) const
Returns the ith child.
CV_CLASS_ENUM getClassID() const override
Returns class ID.
Interactor interface (entity that can be dragged or clicked in a 3D view)
virtual unsigned getUniqueID() const
Returns object unique ID.
bool isA(CV_CLASS_ENUM type) const
virtual void setEnabled(bool state)
Sets the "enabled" property.
virtual bool isEnabled() const
Returns whether the object is enabled or not.
bool isKindOf(CV_CLASS_ENUM type) const
bool is2DMode() const
Returns whether the polyline is considered as 2D or 3D.
ccMesh * getAssociatedMesh()
Returns the associated mesh.
double getDiagNormd() const
Returns diagonal length (double precision)
Vector3Tpl< T > getCenter() const
Returns center.
T getDiagNorm() const
Returns diagonal length.
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.
virtual VerticesIndexes * getTriangleVertIndexes(unsigned triangleIndex)=0
Returns the indexes of the vertices of a given triangle.
virtual bool IsEmpty() const override
void interactorPointPickedEvent(const CCVector3 &p, int index, const std::string &id)
static void Set(const ParamStruct ¶ms)
Sets GUI parameters.
static const ParamStruct & Parameters()
Returns the stored values of each parameter.
static void UpdateParameters()
Standard parameters for GL displays/viewports.
bool perspectiveView
Perspective view state.
float fov_deg
Camera F.O.V. (field of view) in degrees.
float pixelSize
Current pixel size (in 'current unit'/pixel)
double zFar
Actual perspective 'zFar' value.
const CCVector3d & getCameraCenter() const
Returns the camera center.
void setPivotPoint(const CCVector3d &P, bool autoUpdateFocal=true)
Sets the pivot point (for object-centered view mode)
const CCVector3d & getPivotPoint() const
Returns the pivot point (for object-centered view mode)
ccGLMatrixd viewMat
Visualization matrix (rotation only)
void setCameraCenter(const CCVector3d &C, bool autoUpdateFocal=true)
Sets the camera center.
double zNear
Actual perspective 'zNear' value.
@ CC_VIRTUAL_TRANS_ENABLED
void Sleep(int milliseconds)
MiniVec< float, N > floor(const MiniVec< float, N > &a)
float RadiansToDegrees(int radians)
Convert radians to degrees.
bool GreaterThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
float DegreesToRadians(int degrees)
Convert degrees to radians.
bool LessThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
RgbTpl< ColorCompType > Rgb
3 components, default type
constexpr Rgba odarkGrey(MAX/2, MAX/2, MAX/2, OPACITY)
constexpr Rgbaf night(0.00f, 0.00f, 0.00f, 1.00F)
constexpr Rgba ored(MAX, 0, 0, OPACITY)
Rgbaf FromRgba(const Rgba &color)
constexpr Rgbaf bright(1.00f, 1.00f, 1.00f, 1.00f)
constexpr Rgb yellow(MAX, MAX, 0)
constexpr Rgba ogreen(0, MAX, 0, OPACITY)
constexpr Rgbub defaultLabelBkgColor(MAX, MAX, MAX)
constexpr Rgbaf dark(0.34f, 0.34f, 0.34f, 1.00f)
QString viewId
Display scalar field (prioritary on colors)
CCVector3 getPointPosition() const
Returns the point position (3D)
OpenGL camera parameters.
float fov_deg
F.O.V. (in degrees) - perspective mode only.
ccGLMatrixd projectionMat
Projection matrix (GL_PROJECTION)
ccGLMatrixd modelViewMat
Model view matrix (GL_MODELVIEW)
bool unproject(const CCVector3d &input2D, CCVector3d &output3D) const
Unprojects a 2D point (+ normalized 'z' coordinate) in 3D.
float pixelSize
Pixel size (i.e. zoom) - non perspective mode only.
bool perspective
Perspective mode.
bool project(const CCVector3d &input3D, CCVector3d &output2D, bool *inFrustum=nullptr) const
Projects a 3D point in 2D (+ normalized 'z' coordinate)
int viewport[4]
Viewport (GL_VIEWPORT)
ecvColor::Rgbub pointsDefaultCol
Default point color.
bool drawBackgroundGradient
ecvColor::Rgbub bbDefaultCol
Default bounding-box color.
float devicePixelRatio
Device pixel ratio (general 1, 2 on HD displays)
float labelMarkerSize
Label marker size (radius)
int drawingFlags
Drawing options (see below)
bool higherLODLevelsAvailable
Wheter higher levels are available or not.
unsigned labelOpacity
Label background opacity.
unsigned minLODPointCount
Minimum number of points for activating LOD display.
ecvColor::Rgbub labelDefaultBkgCol
Default label background color.
ecvColor::Rgbub backgroundCol2
bool moreLODPointsAvailable
Wheter more points are available or not at the current level.
unsigned dispNumberPrecision
Numerical precision (for displaying text)
ecvColor::Rgbub labelDefaultMarkerCol
Default label marker color.
ecvColor::Rgbub backgroundCol
unsigned char currentLODLevel
Current level for LOD display.
float labelMarkerTextShift_pix
Shift for 3D label marker display (around the marker, in pixels)
ccMaterial::Shared defaultMat
Default material.
int glW
GL screen widthecvColor.
unsigned minLODTriangleCount
Minimum number of triangles for activating LOD display.
ccScalarField * sfColorScaleToDisplay
Currently displayed color scale (the corresponding scalar field in fact)
ecvColor::Rgbub textDefaultCol
Default text color.
bool useVBOs
Use VBOs for faster display.
bool decimateCloudOnMove
Whether to decimate big clouds when updating the 3D view.
bool drawRoundedPoints
Whether to draw rounded points (instead of sqaures)
Triangle described by the indexes of its 3 vertices.
ComputeOctreeForPicking
Octree computation (for picking) behaviors.
ecvColor::Rgbaf meshSpecular
Default mesh specular color.
unsigned labelMarkerSize
Label marker size.
ecvColor::Rgbub backgroundCol
Background color.
unsigned displayedNumPrecision
Displayed numbers precision.
ComputeOctreeForPicking autoComputeOctree
Octree computation (for picking) behavior.
ecvColor::Rgbub labelMarkerCol
Labels marker color.
ecvColor::Rgbub textDefaultCol
Default text color.
bool drawRoundedPoints
Whether to draw rounded points (slower) or not.
unsigned minLoDCloudSize
Min cloud size for decimation.
ecvColor::Rgbub labelBackgroundCol
Labels background color.
ecvColor::Rgbub bbDefaultCol
Bounding-boxes color.
bool displayCross
Display cross in the middle of the screen.
void toPersistentSettings() const
Saves to persistent DB.
unsigned minLoDMeshSize
Min mesh size for decimation.
ecvColor::Rgbaf meshFrontDiff
Default mesh diffuse color (front)
bool drawBackgroundGradient
Use background gradient.
bool useVBOs
Whether to use VBOs for faster display.
unsigned labelOpacity
Labels background opcaity.
ecvColor::Rgbaf meshBackDiff
Default mesh diffuse color (back)
double zoomSpeed
Zoom speed (1.0 by default)
bool decimateCloudOnMove
Decimate clouds when moved.
ecvColor::Rgbub pointsDefaultCol
Default 3D points color.
Generic singleton encapsulation structure.
ENTITY_TYPE removeType
Remove type.
QString removeId
Remove viewId.