#include "CloudViewSettings.h" #include #include #include #include #include namespace { QString settingsFilePath() { QString settingsDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); if (settingsDir.isEmpty()) { settingsDir = QDir::homePath() + "/CloudView"; } QDir().mkpath(settingsDir); return QDir(settingsDir).filePath("CloudView.ini"); } } CloudViewSettingsData CloudViewSettings::load() { CloudViewSettingsData result; QSettings settings(settingsFilePath(), QSettings::IniFormat); // 模式独立于启用状态保存;缺失或非法配置默认采用“替换为全 0”。 const QVariant savedModeValue = settings.contains("PointCloudRange/filterMode") ? settings.value("PointCloudRange/filterMode") : settings.value("PointCloudRange/mode", static_cast(PointCloudXYZRangeFilterMode::ReplaceWithZero)); const int savedFilterMode = savedModeValue.toInt(); const PointCloudXYZRangeFilterMode filterMode = savedFilterMode == static_cast(PointCloudXYZRangeFilterMode::Remove) ? PointCloudXYZRangeFilterMode::Remove : PointCloudXYZRangeFilterMode::ReplaceWithZero; const float poseAxisLength = settings.value("Display/poseAxisLength", result.poseAxisLength).toFloat(); if (std::isfinite(poseAxisLength) && poseAxisLength > 0.0f) { result.poseAxisLength = poseAxisLength; } result.pseudoColorEnabled = settings.value("PseudoColor/enabled", result.pseudoColorEnabled).toBool(); const bool hasPaletteSetting = settings.contains("PseudoColor/defaultPalette"); result.pseudoColorDefaultPalette = hasPaletteSetting ? settings.value("PseudoColor/defaultPalette").toBool() : result.pseudoColorDefaultPalette; const float period = settings.value("PseudoColor/period", result.pseudoColorPeriod).toFloat(); if (std::isfinite(period) && period > 0.0f) { result.pseudoColorPeriod = period; } const QColor startColor(settings.value("PseudoColor/startColor", "#0000ff").toString()); const QColor endColor(settings.value("PseudoColor/endColor", "#ff0000").toString()); if (startColor.isValid()) { result.pseudoColorStartColor = QVector3D(startColor.redF(), startColor.greenF(), startColor.blueF()); } if (endColor.isValid()) { result.pseudoColorEndColor = QVector3D(endColor.redF(), endColor.greenF(), endColor.blueF()); } if (!hasPaletteSetting && settings.contains("PseudoColor/period")) { const QColor legacyStartColor(settings.value("PseudoColor/startColor", "#0000ff").toString()); const QColor legacyEndColor(settings.value("PseudoColor/endColor", "#ff0000").toString()); const bool legacyDefaults = qFuzzyCompare(result.pseudoColorPeriod, 100.0f) && legacyStartColor == QColor("#0000ff") && legacyEndColor == QColor("#ff0000"); if (legacyDefaults) { // 旧版周期色环配置迁移为 Z 范围蓝→红梯度。 result.pseudoColorPeriod = 500.0f; result.pseudoColorStartColor = QVector3D(0.0f, 0.0f, 1.0f); result.pseudoColorEndColor = QVector3D(1.0f, 0.0f, 0.0f); result.pseudoColorDefaultPalette = true; } else { // 非默认旧配置继续使用原有的自定义起止色渐变。 result.pseudoColorDefaultPalette = false; } } const bool rangeEnabled = settings.value("PointCloudRange/enabled", false).toBool(); PointCloudXYZRange range; range.enabled = rangeEnabled; range.filterMode = filterMode; if (rangeEnabled) { const auto readBound = [&settings](const char* key, double fallback) { bool ok = false; const double value = settings.value(key).toDouble(&ok); return ok && std::isfinite(value) ? value : fallback; }; // Missing bounds retain the range object's implicit unbounded side. range.minX = readBound("PointCloudRange/minX", range.minX); range.maxX = readBound("PointCloudRange/maxX", range.maxX); range.minY = readBound("PointCloudRange/minY", range.minY); range.maxY = readBound("PointCloudRange/maxY", range.maxY); range.minZ = readBound("PointCloudRange/minZ", range.minZ); range.maxZ = readBound("PointCloudRange/maxZ", range.maxZ); if (range.isValid()) { result.pointCloudRange = range; } } else { result.pointCloudRange = range; } // Keep the mode even when a persisted enabled range is invalid and is // therefore reset to the disabled default range. result.pointCloudRange.filterMode = filterMode; return result; } bool CloudViewSettings::save(const CloudViewSettingsData& value) { QSettings settings(settingsFilePath(), QSettings::IniFormat); if (std::isfinite(value.poseAxisLength) && value.poseAxisLength > 0.0f) { settings.setValue("Display/poseAxisLength", value.poseAxisLength); } settings.setValue("PseudoColor/enabled", value.pseudoColorEnabled); settings.setValue("PseudoColor/defaultPalette", value.pseudoColorDefaultPalette); settings.setValue("PseudoColor/period", qMax(1.0f, value.pseudoColorPeriod)); settings.setValue("PseudoColor/startColor", QColor::fromRgbF(value.pseudoColorStartColor.x(), value.pseudoColorStartColor.y(), value.pseudoColorStartColor.z()).name(QColor::HexRgb)); settings.setValue("PseudoColor/endColor", QColor::fromRgbF(value.pseudoColorEndColor.x(), value.pseudoColorEndColor.y(), value.pseudoColorEndColor.z()).name(QColor::HexRgb)); const PointCloudXYZRange& range = value.pointCloudRange; const bool saveRange = range.enabled && range.isValid(); settings.setValue("PointCloudRange/enabled", saveRange); const int filterModeValue = range.filterMode == PointCloudXYZRangeFilterMode::Remove ? static_cast(PointCloudXYZRangeFilterMode::Remove) : static_cast(PointCloudXYZRangeFilterMode::ReplaceWithZero); settings.setValue("PointCloudRange/filterMode", filterModeValue); settings.setValue("PointCloudRange/mode", filterModeValue); if (saveRange) { const auto saveBound = [&settings](const char* key, double bound) { if (std::isfinite(bound)) { settings.setValue(key, bound); } else { settings.remove(key); } }; saveBound("PointCloudRange/minX", range.minX); saveBound("PointCloudRange/maxX", range.maxX); saveBound("PointCloudRange/minY", range.minY); saveBound("PointCloudRange/maxY", range.maxY); saveBound("PointCloudRange/minZ", range.minZ); saveBound("PointCloudRange/maxZ", range.maxZ); } else { // Disabled ranges use implicit infinite bounds; do not persist infinities. settings.remove("PointCloudRange/minX"); settings.remove("PointCloudRange/maxX"); settings.remove("PointCloudRange/minY"); settings.remove("PointCloudRange/maxY"); settings.remove("PointCloudRange/minZ"); settings.remove("PointCloudRange/maxZ"); } // Remove keys from the former min/max/stop based implementation so old // values cannot reappear in the user configuration file. settings.remove("PseudoColor/autoRange"); settings.remove("PseudoColor/minZ"); settings.remove("PseudoColor/maxZ"); settings.remove("PseudoColor/divisionCount"); settings.remove("PseudoColor/gradient"); settings.remove("PseudoColor/stops"); settings.sync(); return settings.status() == QSettings::NoError; }