修复崩溃,修复选点序号不对
This commit is contained in:
parent
d6049e7846
commit
36645c6ceb
@ -128,6 +128,12 @@ int LaserDataLoader::LoadLaserScanData(const std::string& fileName,
|
|||||||
return ERR_CODE(DATA_ERR_INVALID);
|
return ERR_CODE(DATA_ERR_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 防止数组越界:跳过超出声明点数的数据行
|
||||||
|
if (nLaserPointIdx >= sLaserData.nPointCount) {
|
||||||
|
LOG_WARN("nLaserPointIdx(%d) >= nPointCount(%d), skip\n", nLaserPointIdx, sLaserData.nPointCount);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (eDataType == keResultDataType_PointXYZRGBA) {
|
if (eDataType == keResultDataType_PointXYZRGBA) {
|
||||||
SVzNLPointXYZRGBA* pRGBAPoints = static_cast<SVzNLPointXYZRGBA*>(sLaserData.p3DPoint);
|
SVzNLPointXYZRGBA* pRGBAPoints = static_cast<SVzNLPointXYZRGBA*>(sLaserData.p3DPoint);
|
||||||
SVzNL2DLRPoint* p2DPoints = static_cast<SVzNL2DLRPoint*>(sLaserData.p2DPoint);
|
SVzNL2DLRPoint* p2DPoints = static_cast<SVzNL2DLRPoint*>(sLaserData.p2DPoint);
|
||||||
|
|||||||
@ -287,6 +287,7 @@ private:
|
|||||||
std::vector<float> colors;
|
std::vector<float> colors;
|
||||||
std::vector<int> lineIndices; // 每个点所属的线索引
|
std::vector<int> lineIndices; // 每个点所属的线索引
|
||||||
std::vector<int> originalIndices; // 每个显示点在原始点云中的索引(用于计算原始index)
|
std::vector<int> originalIndices; // 每个显示点在原始点云中的索引(用于计算原始index)
|
||||||
|
std::vector<int> pointInLineIndices; // 每个显示点在所属线中的索引(预计算,支持不等长线)
|
||||||
bool hasColor;
|
bool hasColor;
|
||||||
bool hasLineInfo; // 是否有线信息
|
bool hasLineInfo; // 是否有线信息
|
||||||
QString name;
|
QString name;
|
||||||
@ -322,6 +323,7 @@ private:
|
|||||||
, colors(std::move(other.colors))
|
, colors(std::move(other.colors))
|
||||||
, lineIndices(std::move(other.lineIndices))
|
, lineIndices(std::move(other.lineIndices))
|
||||||
, originalIndices(std::move(other.originalIndices))
|
, originalIndices(std::move(other.originalIndices))
|
||||||
|
, pointInLineIndices(std::move(other.pointInLineIndices))
|
||||||
, hasColor(other.hasColor)
|
, hasColor(other.hasColor)
|
||||||
, hasLineInfo(other.hasLineInfo)
|
, hasLineInfo(other.hasLineInfo)
|
||||||
, name(std::move(other.name))
|
, name(std::move(other.name))
|
||||||
@ -351,6 +353,7 @@ private:
|
|||||||
colors = std::move(other.colors);
|
colors = std::move(other.colors);
|
||||||
lineIndices = std::move(other.lineIndices);
|
lineIndices = std::move(other.lineIndices);
|
||||||
originalIndices = std::move(other.originalIndices);
|
originalIndices = std::move(other.originalIndices);
|
||||||
|
pointInLineIndices = std::move(other.pointInLineIndices);
|
||||||
hasColor = other.hasColor;
|
hasColor = other.hasColor;
|
||||||
hasLineInfo = other.hasLineInfo;
|
hasLineInfo = other.hasLineInfo;
|
||||||
name = std::move(other.name);
|
name = std::move(other.name);
|
||||||
|
|||||||
@ -255,13 +255,27 @@ void PointCloudGLWidget::addPointCloud(const PointCloudXYZ& cloud, const QString
|
|||||||
data.pointsPerLine = 0;
|
data.pointsPerLine = 0;
|
||||||
|
|
||||||
const float EPSILON = 1e-6f;
|
const float EPSILON = 1e-6f;
|
||||||
|
int prevLineIdx = -1;
|
||||||
|
int ptInLineCounter = 0;
|
||||||
for (size_t i = 0; i < cloud.points.size(); ++i) {
|
for (size_t i = 0; i < cloud.points.size(); ++i) {
|
||||||
|
// 跟踪线内索引(对所有点递增,包括被过滤的零点)
|
||||||
|
int lineIdx = -1;
|
||||||
|
if (data.hasLineInfo && i < cloud.lineIndices.size()) {
|
||||||
|
lineIdx = cloud.lineIndices[i];
|
||||||
|
}
|
||||||
|
if (lineIdx != prevLineIdx) {
|
||||||
|
ptInLineCounter = 0;
|
||||||
|
prevLineIdx = lineIdx;
|
||||||
|
}
|
||||||
|
|
||||||
const auto& pt = cloud.points[i];
|
const auto& pt = cloud.points[i];
|
||||||
if (!std::isfinite(pt.x) || !std::isfinite(pt.y) || !std::isfinite(pt.z)) {
|
if (!std::isfinite(pt.x) || !std::isfinite(pt.y) || !std::isfinite(pt.z)) {
|
||||||
|
ptInLineCounter++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 显示时过滤 (0,0,0) 点
|
// 显示时过滤 (0,0,0) 点
|
||||||
if (std::fabs(pt.x) < EPSILON && std::fabs(pt.y) < EPSILON && std::fabs(pt.z) < EPSILON) {
|
if (std::fabs(pt.x) < EPSILON && std::fabs(pt.y) < EPSILON && std::fabs(pt.z) < EPSILON) {
|
||||||
|
ptInLineCounter++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
data.vertices.push_back(pt.x);
|
data.vertices.push_back(pt.x);
|
||||||
@ -271,14 +285,18 @@ void PointCloudGLWidget::addPointCloud(const PointCloudXYZ& cloud, const QString
|
|||||||
// 保存原始索引
|
// 保存原始索引
|
||||||
data.originalIndices.push_back(static_cast<int>(i));
|
data.originalIndices.push_back(static_cast<int>(i));
|
||||||
|
|
||||||
|
// 保存线内索引(点在所属线中的位置)
|
||||||
|
data.pointInLineIndices.push_back(ptInLineCounter);
|
||||||
|
|
||||||
// 保存线索引
|
// 保存线索引
|
||||||
if (data.hasLineInfo && i < cloud.lineIndices.size()) {
|
if (lineIdx >= 0) {
|
||||||
int lineIdx = cloud.lineIndices[i];
|
|
||||||
data.lineIndices.push_back(lineIdx);
|
data.lineIndices.push_back(lineIdx);
|
||||||
if (lineIdx + 1 > data.totalLines) {
|
if (lineIdx + 1 > data.totalLines) {
|
||||||
data.totalLines = lineIdx + 1;
|
data.totalLines = lineIdx + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ptInLineCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算每线点数(假设网格化点云)
|
// 计算每线点数(假设网格化点云)
|
||||||
@ -328,9 +346,31 @@ void PointCloudGLWidget::addPointCloud(const PointCloudXYZRGB& cloud, const QStr
|
|||||||
// 用于按点大小分组的临时 map
|
// 用于按点大小分组的临时 map
|
||||||
std::map<float, std::vector<size_t>> sizeGroupMap;
|
std::map<float, std::vector<size_t>> sizeGroupMap;
|
||||||
|
|
||||||
|
const float EPSILON = 1e-6f;
|
||||||
|
int prevLineIdx = -1;
|
||||||
|
int ptInLineCounter = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < cloud.points.size(); ++i) {
|
for (size_t i = 0; i < cloud.points.size(); ++i) {
|
||||||
const auto& pt = cloud.points[i];
|
const auto& pt = cloud.points[i];
|
||||||
|
|
||||||
|
// 跟踪线内索引(对所有点递增,包括被过滤的零点)
|
||||||
|
int lineIdx = -1;
|
||||||
|
if (data.hasLineInfo && i < cloud.lineIndices.size()) {
|
||||||
|
lineIdx = cloud.lineIndices[i];
|
||||||
|
}
|
||||||
|
if (lineIdx != prevLineIdx) {
|
||||||
|
ptInLineCounter = 0;
|
||||||
|
prevLineIdx = lineIdx;
|
||||||
|
}
|
||||||
|
|
||||||
if (!std::isfinite(pt.x) || !std::isfinite(pt.y) || !std::isfinite(pt.z)) {
|
if (!std::isfinite(pt.x) || !std::isfinite(pt.y) || !std::isfinite(pt.z)) {
|
||||||
|
ptInLineCounter++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示时过滤 (0,0,0) 点
|
||||||
|
if (std::fabs(pt.x) < EPSILON && std::fabs(pt.y) < EPSILON && std::fabs(pt.z) < EPSILON) {
|
||||||
|
ptInLineCounter++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,9 +387,11 @@ void PointCloudGLWidget::addPointCloud(const PointCloudXYZRGB& cloud, const QStr
|
|||||||
// 保存原始索引
|
// 保存原始索引
|
||||||
data.originalIndices.push_back(static_cast<int>(i));
|
data.originalIndices.push_back(static_cast<int>(i));
|
||||||
|
|
||||||
|
// 保存线内索引(点在所属线中的位置)
|
||||||
|
data.pointInLineIndices.push_back(ptInLineCounter);
|
||||||
|
|
||||||
// 保存线索引
|
// 保存线索引
|
||||||
if (data.hasLineInfo && i < cloud.lineIndices.size()) {
|
if (lineIdx >= 0) {
|
||||||
int lineIdx = cloud.lineIndices[i];
|
|
||||||
data.lineIndices.push_back(lineIdx);
|
data.lineIndices.push_back(lineIdx);
|
||||||
if (lineIdx + 1 > data.totalLines) {
|
if (lineIdx + 1 > data.totalLines) {
|
||||||
data.totalLines = lineIdx + 1;
|
data.totalLines = lineIdx + 1;
|
||||||
@ -360,6 +402,8 @@ void PointCloudGLWidget::addPointCloud(const PointCloudXYZRGB& cloud, const QStr
|
|||||||
if (pt.pointSize > 1.0f) {
|
if (pt.pointSize > 1.0f) {
|
||||||
sizeGroupMap[pt.pointSize].push_back(pointIndex);
|
sizeGroupMap[pt.pointSize].push_back(pointIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ptInLineCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建自定义点大小分组
|
// 构建自定义点大小分组
|
||||||
@ -843,10 +887,9 @@ SelectedPointInfo PointCloudGLWidget::pickPoint(int screenX, int screenY)
|
|||||||
// 计算点在线中的原始索引
|
// 计算点在线中的原始索引
|
||||||
if (bestLineIndex >= 0 && bestCloudIndex >= 0) {
|
if (bestLineIndex >= 0 && bestCloudIndex >= 0) {
|
||||||
const auto& cloudData = m_pointClouds[bestCloudIndex];
|
const auto& cloudData = m_pointClouds[bestCloudIndex];
|
||||||
// 使用原始索引计算:原始索引 % 每线点数
|
// 使用预计算的线内索引(支持不等长线)
|
||||||
if (bestIndex < cloudData.originalIndices.size() && cloudData.pointsPerLine > 0) {
|
if (bestIndex < cloudData.pointInLineIndices.size()) {
|
||||||
int originalIdx = cloudData.originalIndices[bestIndex];
|
result.pointIndexInLine = cloudData.pointInLineIndices[bestIndex];
|
||||||
result.pointIndexInLine = originalIdx % cloudData.pointsPerLine;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user