From d1bcece8c71d18b0768841e0d81ff6c6f0e5d893 Mon Sep 17 00:00:00 2001 From: YangSn Date: Wed, 4 Nov 2026 10:24:08 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E8=AF=BB=E5=86=99=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E4=BF=9D=E6=8C=81=E4=B8=80=E8=87=B4=EF=BC=8C=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E6=88=B3=EF=BC=8C=E7=BA=BF=E5=8F=B7=E7=B1=BB=E5=9E=8B=E6=94=B9?= =?UTF-8?q?=E4=B8=BAulonglong?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CloudUtils/CloudUtils.pro | 1 - CloudUtils/Inc/LaserDataLoader.h | 9 +-- CloudUtils/Src/LaserDataLoader.cpp | 122 ++++++++++++++--------------- CloudViewApp/resource/logo.ico | Bin 38078 -> 84598 bytes CloudViewApp/resource/logo.png | Bin 6687 -> 4304 bytes 5 files changed, 60 insertions(+), 72 deletions(-) diff --git a/CloudUtils/CloudUtils.pro b/CloudUtils/CloudUtils.pro index 048317e..7801875 100644 --- a/CloudUtils/CloudUtils.pro +++ b/CloudUtils/CloudUtils.pro @@ -15,7 +15,6 @@ win32-msvc { # 鎸囧畾C++鏍囧噯 CONFIG += c++11 -INCLUDEPATH += $$PWD/../../Device/SDK/VzNLSDK/_Inc INCLUDEPATH += $$PWD/../../Device/SDK/VzNLSDK/Inc INCLUDEPATH += $$PWD/../VrCommon/Inc diff --git a/CloudUtils/Inc/LaserDataLoader.h b/CloudUtils/Inc/LaserDataLoader.h index 1551de2..960e5dd 100644 --- a/CloudUtils/Inc/LaserDataLoader.h +++ b/CloudUtils/Inc/LaserDataLoader.h @@ -32,17 +32,14 @@ class LaserDataLoader { public: // lineData is valid only while the callback is running. Copy it to retain it. - using LaserLineLoadCallback = - std::function; + using LaserLineLoadCallback = std::function; // 过滤后仍提供源扫描线点数及每个保留点的原始线内索引。 - using LaserLineLoadIndexedCallback = - std::function; + using LaserLineLoadIndexedCallback = std::function; // Called exactly once when loading succeeds or fails. // Arguments: result, lineNum, scanSpeed, maxTimeStamp, clockPerSecond. - using LaserLoadFinishedCallback = - std::function; + using LaserLoadFinishedCallback = std::function; LaserDataLoader(); ~LaserDataLoader(); diff --git a/CloudUtils/Src/LaserDataLoader.cpp b/CloudUtils/Src/LaserDataLoader.cpp index f603323..c51f95b 100644 --- a/CloudUtils/Src/LaserDataLoader.cpp +++ b/CloudUtils/Src/LaserDataLoader.cpp @@ -91,17 +91,16 @@ struct DatLaserScan3DLinesHeader std::uint64_t scanLineList; }; -struct DatLineScan3DData -{ - int lineIndex; - std::uint32_t timeStamp; - double lineStepping; -}; - -static_assert(sizeof(DatLaserScan3DLinesHeader) == 40, "Unexpected dat header layout"); -static_assert(sizeof(DatLineScan3DData) == 16, "Unexpected dat line layout"); -static_assert(sizeof(Dat3DFeaturePoint) == 112, "Unexpected dat feature point layout"); - +struct DatLineScan3DData +{ + int lineIndex; + std::uint32_t timeStamp; + double lineStepping; +}; + +static_assert(sizeof(DatLaserScan3DLinesHeader) == 40, "Unexpected dat header layout"); +static_assert(sizeof(DatLineScan3DData) == 16, "Unexpected dat line layout"); +static_assert(sizeof(Dat3DFeaturePoint) == 112, "Unexpected dat feature point layout"); template bool ReadBinary(std::ifstream& inputFile, T& value) { @@ -139,9 +138,9 @@ bool LooksLikeTextLaserFile(const std::string& fileName) return inputFile.gcount() == sizeof(header) && std::memcmp(header, "LineNum:", sizeof(header)) == 0; } -bool ReadDatLineRecord(std::ifstream& inputFile, int recordSize, DatLineScan3DData& lineData) -{ - char buffer[40] = {}; +bool ReadDatLineRecord(std::ifstream& inputFile, int recordSize, DatLineScan3DData& lineData) +{ + char buffer[40] = {}; if (recordSize <= 0 || recordSize > static_cast(sizeof(buffer))) { return false; } @@ -151,11 +150,11 @@ bool ReadDatLineRecord(std::ifstream& inputFile, int recordSize, DatLineScan3DDa return false; } - std::memcpy(&lineData.lineIndex, buffer, sizeof(lineData.lineIndex)); - std::memcpy(&lineData.timeStamp, buffer + 4, sizeof(lineData.timeStamp)); - std::memcpy(&lineData.lineStepping, buffer + 8, sizeof(lineData.lineStepping)); - return true; -} + std::memcpy(&lineData.lineIndex, buffer, sizeof(lineData.lineIndex)); + std::memcpy(&lineData.timeStamp, buffer + 4, sizeof(lineData.timeStamp)); + std::memcpy(&lineData.lineStepping, buffer + 8, sizeof(lineData.lineStepping)); + return true; +} void AppendFormattedLine(std::string& output, const char* format, ...) { @@ -493,10 +492,10 @@ int LaserDataLoader::LoadLaserScanData(const std::string& fileName, if (SUCCESS != result) return result; } - int lineIndex = 0; - unsigned int timeStamp = 0; + unsigned long long lineIndex = 0; + unsigned long long timeStamp = 0; int ptNum = 0; - if (3 != sscanf(line.c_str(), "Line_%d_%u_%d", &lineIndex, &timeStamp, &ptNum) || + if (3 != sscanf(line.c_str(), "Line_%llu_%llu_%d", &lineIndex, &timeStamp, &ptNum) || ptNum < 0 || ptNum > VZ_LASER_LINE_PT_MAX_NUM) { return failTextLoad(FILE_ERR_FORMAT, "Invalid laser line header: " + line); } @@ -716,10 +715,10 @@ int LaserDataLoader::LoadLaserScanDataByIndexedCallback( return finish(result); } - int lineIndex = 0; - unsigned int timeStamp = 0; + unsigned long long lineIndex = 0; + unsigned long long timeStamp = 0; int pointCount = 0; - if (sscanf(line.c_str(), "Line_%d_%u_%d", &lineIndex, &timeStamp, &pointCount) != 3 || + if (sscanf(line.c_str(), "Line_%llu_%llu_%d", &lineIndex, &timeStamp, &pointCount) != 3 || pointCount < 0 || pointCount > VZ_LASER_LINE_PT_MAX_NUM) { m_lastError = "Invalid laser line header: " + line; LOG_ERROR("%s\n", m_lastError.c_str()); @@ -738,10 +737,8 @@ int LaserDataLoader::LoadLaserScanDataByIndexedCallback( LOG_ERROR("%s\n", m_lastError.c_str()); return finish(ERR_CODE(DATA_ERR_MEM)); } - std::memset(rgbaPoints.get(), 0, - sizeof(SVzNLPointXYZRGBA) * static_cast(pointCount)); - std::memset(rgba2DPoints.get(), 0, - sizeof(SVzNL2DLRPoint) * static_cast(pointCount)); + std::memset(rgbaPoints.get(), 0, sizeof(SVzNLPointXYZRGBA) * static_cast(pointCount)); + std::memset(rgba2DPoints.get(), 0, sizeof(SVzNL2DLRPoint) * static_cast(pointCount)); lineData.p3DPoint = rgbaPoints.get(); lineData.p2DPoint = rgba2DPoints.get(); } else if (pointCount > 0 && dataType == keResultDataType_Position) { @@ -752,10 +749,8 @@ int LaserDataLoader::LoadLaserScanDataByIndexedCallback( LOG_ERROR("%s\n", m_lastError.c_str()); return finish(ERR_CODE(DATA_ERR_MEM)); } - std::memset(positionPoints.get(), 0, - sizeof(SVzNL3DPosition) * static_cast(pointCount)); - std::memset(position2DPoints.get(), 0, - sizeof(SVzNL2DPosition) * static_cast(pointCount)); + std::memset(positionPoints.get(), 0, sizeof(SVzNL3DPosition) * static_cast(pointCount)); + std::memset(position2DPoints.get(), 0, sizeof(SVzNL2DPosition) * static_cast(pointCount)); lineData.p3DPoint = positionPoints.get(); lineData.p2DPoint = position2DPoints.get(); } @@ -1051,7 +1046,9 @@ bool LaserDataLoader::WriteLaserScanLine(std::ostream& sw, EVzResultDataType dat if (lineData.nPointCount < 0 || (lineData.nPointCount > 0 && !lineData.p3DPoint)) return false; if (dataType != keResultDataType_Position && dataType != keResultDataType_PositionF && dataType != keResultDataType_PointXYZI && dataType != keResultDataType_PointXYZRGBA) return false; - sw << "Line_" << lineData.llFrameIdx << "_" << lineData.llTimeStamp << "_" << lineData.nPointCount << '\n'; + sw << "Line_" << static_cast(lineData.llFrameIdx) + << "_" << static_cast(lineData.llTimeStamp) + << "_" << lineData.nPointCount << '\n'; if (dataType == keResultDataType_Position && lineData.p3DPoint) { const SVzNL3DPosition* points = static_cast(lineData.p3DPoint); @@ -1059,17 +1056,14 @@ bool LaserDataLoader::WriteLaserScanLine(std::ostream& sw, EVzResultDataType dat constexpr int BATCH = 256; constexpr int PER_POINT = 128; for (int base = 0; base < lineData.nPointCount; base += BATCH) { - int end = (base + BATCH < lineData.nPointCount) ? (base + BATCH) : lineData.nPointCount; - std::string buffer; - buffer.reserve(BATCH * PER_POINT); - for (int i = base; i < end; ++i) { - float x = static_cast(points[i].pt3D.x); - float y = static_cast(points[i].pt3D.y); - float z = static_cast(points[i].pt3D.z); - AppendFormattedLine(buffer, "{ %.6f,%.6f,%.6f }-{ %d,%d }-{ %d,%d }\n", - x, y, z, - points2D ? points2D[i].ptLeft2D.x : 0, points2D ? points2D[i].ptLeft2D.y : 0, - points2D ? points2D[i].ptRight2D.x : 0, points2D ? points2D[i].ptRight2D.y : 0); + int end = (base + BATCH < lineData.nPointCount) ? (base + BATCH) : lineData.nPointCount; + std::string buffer; + buffer.reserve(BATCH * PER_POINT); + for (int i = base; i < end; ++i) { + AppendFormattedLine(buffer, "{ %.6f,%.6f,%.6f }-{ %d,%d }-{ %d,%d }\n", + points[i].pt3D.x, points[i].pt3D.y, points[i].pt3D.z, + points2D ? points2D[i].ptLeft2D.x : 0, points2D ? points2D[i].ptLeft2D.y : 0, + points2D ? points2D[i].ptRight2D.x : 0, points2D ? points2D[i].ptRight2D.y : 0); } sw.write(buffer.data(), static_cast(buffer.size())); } @@ -1084,7 +1078,7 @@ bool LaserDataLoader::WriteLaserScanLine(std::ostream& sw, EVzResultDataType dat buffer.reserve(BATCH * PER_POINT); for (int i = base; i < end; ++i) { AppendFormattedLine(buffer, - "{ %.9f, %.9f, %.9f } - { %.6f, %.6f } - { %.6f, %.6f }\n", + "{ %.6f, %.6f, %.6f } - { %.6f, %.6f } - { %.6f, %.6f }\n", points[i].pt3D.x, points[i].pt3D.y, points[i].pt3D.z, points2D ? points2D[i].ptLeft2D.x : 0.0f, points2D ? points2D[i].ptLeft2D.y : 0.0f, @@ -1181,12 +1175,6 @@ int LaserDataLoader::SaveLaserScanDataBinary( m_lastError = "Missing 3D data for binary laser line"; return ERR_CODE(DEV_ARG_INVAILD); } - if (line.llFrameIdx > static_cast((std::numeric_limits::max)()) || - line.llTimeStamp > (std::numeric_limits::max)()) - { - m_lastError = "Frame index or timestamp exceeds legacy binary format range"; - return ERR_CODE(DEV_ARG_INVAILD); - } maxPointCount = std::max(maxPointCount, static_cast(line.nPointCount)); } @@ -1885,22 +1873,22 @@ void LaserDataLoader::FreeConvertedData(std::vector& rgbd int LaserDataLoader::_ParseLaserScanPoint(const std::string& data, SVzNL3DPosition& sData, SVzNL2DPosition& s2DData) { - float X = 0.0f, Y = 0.0f, Z = 0.0f; - float leftX = 0.0f, leftY = 0.0f; - float rightX = 0.0f, rightY = 0.0f; - const int parsed = sscanf(data.c_str(), - " { %f , %f , %f } - { %f , %f } - { %f , %f }", - &X, &Y, &Z, &leftX, &leftY, &rightX, &rightY); + double X = 0.0, Y = 0.0, Z = 0.0; + int leftX = 0, leftY = 0; + int rightX = 0, rightY = 0; + const int parsed = sscanf(data.c_str(), + " { %lf , %lf , %lf } - { %d , %d } - { %d , %d }", + &X, &Y, &Z, &leftX, &leftY, &rightX, &rightY); if (parsed != 7) { return ERR_CODE(FILE_ERR_FORMAT); } sData.pt3D.x = X; sData.pt3D.y = Y; sData.pt3D.z = Z; - s2DData.ptLeft2D.x = leftX; - s2DData.ptLeft2D.y = leftY; - s2DData.ptRight2D.x = rightX; - s2DData.ptRight2D.y = rightY; + s2DData.ptLeft2D.x = leftX; + s2DData.ptLeft2D.y = leftY; + s2DData.ptRight2D.x = rightX; + s2DData.ptRight2D.y = rightY; return SUCCESS; } @@ -2123,9 +2111,13 @@ int LaserDataLoader::_ParseLaserScanPoint(const std::string& data, SVzNLPointXYZ sData.y = Y; sData.z = Z; - int nr = (int)(r * 255); - int ng = (int)(g * 255); - int nb = (int)(b * 255); + const auto toByte = [](float value) { + const float bounded = value < 0.0f ? 0.0f : (value > 1.0f ? 1.0f : value); + return static_cast(std::lround(bounded * 255.0f)); + }; + int nr = static_cast(toByte(r)); + int ng = static_cast(toByte(g)); + int nb = static_cast(toByte(b)); nb <<= 8; nb += ng; nb <<= 8; diff --git a/CloudViewApp/resource/logo.ico b/CloudViewApp/resource/logo.ico index cd0e408c0acea72dee23c29d461324b342bac58f..e85eeaa0161325e75a9dda7bb936b4b8a2f65c6d 100644 GIT binary patch literal 84598 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 yRUp+%hX4(V+RVlfCFep3OOSf!DwD>09=Za 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 literal 6687 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 Z2H>@kp*f#Oyccl