From 74072f9620db2481085c54ddbde011ee5b87497a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=B0=E4=BB=94?= Date: Wed, 12 Aug 2026 14:48:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A03D=E6=95=B0=E6=8D=AE=E7=9A=84?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 16 ++++++++++ CloudView3D/CMakeLists.txt | 42 ++++++++++++++++++++++++++ CloudView3D/CloudView3D.pro | 2 +- CloudView3D/Src/PointCloudGLWidget.cpp | 36 ++++++++++++---------- 4 files changed, 79 insertions(+), 17 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 CloudView3D/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..558c96d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.14) + +project(WoodCamUtils LANGUAGES CXX) + +option(WOODCAM_BUILD_CLOUDVIEW3D "Build the Qt/OpenGL CloudView3D utility" ON) + +# VrCommon is a header-oriented compatibility module. Keep it as an interface +# target so consumers get the canonical VZNL_Types.h include path. +add_library(VrCommon INTERFACE) +target_include_directories(VrCommon INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}/VrCommon/Inc +) + +if(WOODCAM_BUILD_CLOUDVIEW3D) + add_subdirectory(CloudView3D) +endif() diff --git a/CloudView3D/CMakeLists.txt b/CloudView3D/CMakeLists.txt new file mode 100644 index 0000000..e4a4178 --- /dev/null +++ b/CloudView3D/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.14) + +find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets OpenGL) + +if(NOT TARGET VrCommon) + add_library(VrCommon INTERFACE) + target_include_directories(VrCommon INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}/../VrCommon/Inc + ) +endif() + +add_library(CloudView3D STATIC + Src/PointCloudGLWidget.cpp + Inc/CloudView3D.h + Inc/CloudView3DTypes.h + Inc/PointCloudGLWidget.h +) + +set_target_properties(CloudView3D PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON + AUTOMOC ON +) + +target_include_directories(CloudView3D PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/Inc + ${CMAKE_CURRENT_SOURCE_DIR}/../VrCommon/Inc +) + +target_link_libraries(CloudView3D PUBLIC + VrCommon + Qt5::Core + Qt5::Gui + Qt5::Widgets + Qt5::OpenGL +) + +if(WIN32) + target_link_libraries(CloudView3D PUBLIC opengl32 glu32) +elseif(UNIX AND NOT APPLE) + target_link_libraries(CloudView3D PUBLIC GL GLU) +endif() diff --git a/CloudView3D/CloudView3D.pro b/CloudView3D/CloudView3D.pro index 514a324..9d5fea8 100644 --- a/CloudView3D/CloudView3D.pro +++ b/CloudView3D/CloudView3D.pro @@ -12,7 +12,7 @@ win32-msvc { INCLUDEPATH += $$PWD/Inc INCLUDEPATH += $$PWD/../VrUtils/Inc INCLUDEPATH += $$PWD/../VrCommon/Inc -INCLUDEPATH += $$PWD/../../Device/SDK/VzNLSDK/Inc +# VZNL_Types.h is maintained in the shared Utils module. HEADERS += \ Inc/CloudView3D.h \ diff --git a/CloudView3D/Src/PointCloudGLWidget.cpp b/CloudView3D/Src/PointCloudGLWidget.cpp index fb56b81..72b9452 100644 --- a/CloudView3D/Src/PointCloudGLWidget.cpp +++ b/CloudView3D/Src/PointCloudGLWidget.cpp @@ -1,10 +1,14 @@ #include "PointCloudGLWidget.h" -#include +#include #include #include #include #include -#include "VrLog.h" + +#define CLOUD_LOG_INFO(...) \ + qInfo().noquote() << QString::asprintf(__VA_ARGS__).trimmed() +#define CLOUD_LOG_WARN(...) \ + qWarning().noquote() << QString::asprintf(__VA_ARGS__).trimmed() // OpenGL/GLU 头文件 #ifdef _WIN32 @@ -105,7 +109,7 @@ void PointCloudGLWidget::initializeGL() { initializeOpenGLFunctions(); - LOG_INFO("[CloudView] OpenGL initialized, version: %s\n", reinterpret_cast(glGetString(GL_VERSION))); + CLOUD_LOG_INFO("[CloudView] OpenGL initialized, version: %s\n", reinterpret_cast(glGetString(GL_VERSION))); glClearColor(0.15f, 0.15f, 0.15f, 1.0f); glEnable(GL_DEPTH_TEST); @@ -142,7 +146,7 @@ void PointCloudGLWidget::paintGL() if (++frameCount % 100 == 0) { // 从四元数转换为欧拉角用于显示 QVector3D euler = m_rotation.toEulerAngles(); - LOG_INFO("[CloudView] Current rotation: pitch=%.1f, yaw=%.1f, roll=%.1f\n", + CLOUD_LOG_INFO("[CloudView] Current rotation: pitch=%.1f, yaw=%.1f, roll=%.1f\n", euler.x(), euler.y(), euler.z()); } @@ -242,10 +246,10 @@ void PointCloudGLWidget::paintGL() void PointCloudGLWidget::addPointCloud(const PointCloudXYZ& cloud, const QString& name) { - LOG_INFO("[CloudView] addPointCloud called, cloud size: %zu\n", cloud.size()); + CLOUD_LOG_INFO("[CloudView] addPointCloud called, cloud size: %zu\n", cloud.size()); if (cloud.empty()) { - LOG_WARN("[CloudView] Cloud is empty, returning\n"); + CLOUD_LOG_WARN("[CloudView] Cloud is empty, returning\n"); return; } @@ -309,7 +313,7 @@ void PointCloudGLWidget::addPointCloud(const PointCloudXYZ& cloud, const QString data.pointsPerLine = static_cast(cloud.size()) / data.totalLines; } - LOG_INFO("[CloudView] Valid vertices count: %zu, colorIndex: %d, totalLines: %d, pointsPerLine: %d\n", + CLOUD_LOG_INFO("[CloudView] Valid vertices count: %zu, colorIndex: %d, totalLines: %d, pointsPerLine: %d\n", data.vertices.size() / 3, data.colorIndex, data.totalLines, data.pointsPerLine); m_pointClouds.push_back(std::move(data)); @@ -320,10 +324,10 @@ void PointCloudGLWidget::addPointCloud(const PointCloudXYZ& cloud, const QString doneCurrent(); computeBoundingBox(); - LOG_INFO("[CloudView] BoundingBox min: (%.3f, %.3f, %.3f) max: (%.3f, %.3f, %.3f)\n", + CLOUD_LOG_INFO("[CloudView] BoundingBox min: (%.3f, %.3f, %.3f) max: (%.3f, %.3f, %.3f)\n", m_minBound.x(), m_minBound.y(), m_minBound.z(), m_maxBound.x(), m_maxBound.y(), m_maxBound.z()); - LOG_INFO("[CloudView] Center: (%.3f, %.3f, %.3f) Distance: %.3f\n", + CLOUD_LOG_INFO("[CloudView] Center: (%.3f, %.3f, %.3f) Distance: %.3f\n", m_center.x(), m_center.y(), m_center.z(), m_distance); resetView(); @@ -420,7 +424,7 @@ void PointCloudGLWidget::addPointCloud(const PointCloudXYZRGB& cloud, const QStr group.indices = std::move(pair.second); data.customPointSizeGroups.push_back(std::move(group)); } - LOG_INFO("[CloudView] Found %zu custom point size groups\n", data.customPointSizeGroups.size()); + CLOUD_LOG_INFO("[CloudView] Found %zu custom point size groups\n", data.customPointSizeGroups.size()); } // 计算每线点数 @@ -493,7 +497,7 @@ void PointCloudGLWidget::resetView() m_rotation = QQuaternion::fromEulerAngles(m_rotationX, m_rotationY, m_rotationZ); m_pan = QVector3D(0, 0, 0); - LOG_INFO("[CloudView] resetView: size=(%.3f, %.3f, %.3f) maxSize=%.3f distance=%.3f\n", + CLOUD_LOG_INFO("[CloudView] resetView: size=(%.3f, %.3f, %.3f) maxSize=%.3f distance=%.3f\n", size.x(), size.y(), size.z(), maxSize, m_distance); emit viewAnglesChanged(m_rotationX, m_rotationY, m_rotationZ); @@ -530,7 +534,7 @@ void PointCloudGLWidget::setViewAngles(float rotX, float rotY, float rotZ) // 从欧拉角转换为四元数(ZYX顺序) m_rotation = QQuaternion::fromEulerAngles(rotX, rotY, rotZ); - LOG_INFO("[CloudView] setViewAngles: rotX=%.1f, rotY=%.1f, rotZ=%.1f\n", rotX, rotY, rotZ); + CLOUD_LOG_INFO("[CloudView] setViewAngles: rotX=%.1f, rotY=%.1f, rotZ=%.1f\n", rotX, rotY, rotZ); emit viewAnglesChanged(m_rotationX, m_rotationY, m_rotationZ); update(); @@ -646,7 +650,7 @@ void PointCloudGLWidget::updateSelectedPointCoord(int index, float x, float y, f m_selectedPoints[index].y = y; m_selectedPoints[index].z = z; - LOG_INFO("[CloudView] Updated selected point %d to (%.3f, %.3f, %.3f)\n", index, x, y, z); + CLOUD_LOG_INFO("[CloudView] Updated selected point %d to (%.3f, %.3f, %.3f)\n", index, x, y, z); // 刷新显示 update(); @@ -671,7 +675,7 @@ void PointCloudGLWidget::setSelectedPointCoord(int index, float x, float y, floa m_selectedPoints[index].lineIndex = -1; m_selectedPoints[index].pointIndexInLine = -1; - LOG_INFO("[CloudView] Set selected point %d to (%.3f, %.3f, %.3f)\n", index, x, y, z); + CLOUD_LOG_INFO("[CloudView] Set selected point %d to (%.3f, %.3f, %.3f)\n", index, x, y, z); // 刷新显示 update(); @@ -1032,10 +1036,10 @@ SelectedPointInfo PointCloudGLWidget::pickPoint(int screenX, int screenY) } } - LOG_INFO("[CloudView] Point selected: (%.3f, %.3f, %.3f) lineIndex=%d pointIndexInLine=%d screenDist=%.1f\n", + CLOUD_LOG_INFO("[CloudView] Point selected: (%.3f, %.3f, %.3f) lineIndex=%d pointIndexInLine=%d screenDist=%.1f\n", bestX, bestY, bestZ, bestLineIndex, result.pointIndexInLine, std::sqrt(minScreenDist)); } else { - LOG_INFO("[CloudView] No point selected, minScreenDist=%.1f\n", std::sqrt(minScreenDist)); + CLOUD_LOG_INFO("[CloudView] No point selected, minScreenDist=%.1f\n", std::sqrt(minScreenDist)); } return result;