scaffold: M1 工程骨架(CMake+vcpkg+分层目录+spike冒烟程序)
- 顶层 CMakeLists / CMakePresets / vcpkg.json(全 vcpkg, Qt+VTK[qt] 共用一份 Qt) - .clang-format / .clangd / .editorconfig(AI 编码上下文基础设施, 规约 §10.1) - src 分层目录(core/data/net/render/view/controller/app)+ 各层 README - src/app: Qt+VTK 冒烟程序(锥体), 作 spike#1/#2 起点 - tests: gtest 冒烟 + ctest 接入 - README
This commit is contained in:
parent
fe7737b175
commit
87eba2c5a3
|
|
@ -0,0 +1,24 @@
|
|||
# 统一代码风格(规约 §10.1:约束 AI 输出风格漂移)
|
||||
BasedOnStyle: Google
|
||||
Language: Cpp
|
||||
Standard: c++17
|
||||
ColumnLimit: 100
|
||||
IndentWidth: 4
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
AccessModifierOffset: -4
|
||||
PointerAlignment: Left
|
||||
DerivePointerAlignment: false
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterControlStatement: false
|
||||
SortIncludes: true
|
||||
IncludeBlocks: Regroup
|
||||
NamespaceIndentation: None
|
||||
FixNamespaceComments: true
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# clangd 读取编译数据库,为 IDE / AI 工具提供精确类型上下文(规约 §10.1)
|
||||
CompileFlags:
|
||||
CompilationDatabase: build/debug
|
||||
|
||||
Diagnostics:
|
||||
UnusedIncludes: Strict
|
||||
ClangTidy:
|
||||
Add:
|
||||
- bugprone-*
|
||||
- performance-*
|
||||
- modernize-*
|
||||
Remove:
|
||||
- modernize-use-trailing-return-type
|
||||
|
||||
# 架构铁律(供人 / AI 参阅,设计 §3):
|
||||
# - core 绝不 include Qt/VTK
|
||||
# - VTK actor / RenderWindow 仅由 render 层持有;view 不 new actor
|
||||
# - 信号槽连接集中于 *Controller::wireUp()
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{json,yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
cmake_minimum_required(VERSION 3.21)
|
||||
project(geopro_desktop LANGUAGES CXX)
|
||||
|
||||
# ---- Global C++ settings (规约 §3.2: C++17, 可渐进 C++20) ----
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Qt 自动工具(仅 view/app 层需要 moc/uic/rcc)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
|
||||
if(MSVC)
|
||||
add_compile_options(/utf-8 /MP /W4 /permissive-)
|
||||
endif()
|
||||
|
||||
# ---- Dependencies(全 vcpkg;见 vcpkg.json / docs/ENV_SETUP_Windows.md)----
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Network Sql Concurrent)
|
||||
find_package(VTK REQUIRED) # 含 GUISupportQt(vtk[qt])→ QVTKOpenGLStereoWidget
|
||||
# 以下依赖随分层逐步启用(spike 后接入业务层):
|
||||
# find_package(GDAL CONFIG REQUIRED)
|
||||
# find_package(PROJ CONFIG REQUIRED)
|
||||
# find_package(Eigen3 CONFIG REQUIRED)
|
||||
# find_package(spdlog CONFIG REQUIRED)
|
||||
# find_package(nlohmann_json CONFIG REQUIRED)
|
||||
# find_package(OpenSSL REQUIRED)
|
||||
# find_package(Qt6Keychain CONFIG REQUIRED)
|
||||
# find_package(qtadvanceddocking-qt6 CONFIG REQUIRED) # ADS, spike#2 接入(端口名以实际为准)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"version": 3,
|
||||
"cmakeMinimumRequired": { "major": 3, "minor": 21, "patch": 0 },
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "msvc-debug",
|
||||
"displayName": "MSVC Debug (vcpkg)",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build/debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
|
||||
"VCPKG_TARGET_TRIPLET": "x64-windows",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "msvc-release",
|
||||
"displayName": "MSVC Release (vcpkg)",
|
||||
"inherits": "msvc-debug",
|
||||
"binaryDir": "${sourceDir}/build/release",
|
||||
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{ "name": "debug", "configurePreset": "msvc-debug" },
|
||||
{ "name": "release", "configurePreset": "msvc-release" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
# Geopro 3.0 桌面客户端
|
||||
|
||||
地球物理勘探数据可视化桌面客户端(Qt 6 + VTK 9,C++)。复刻 Geopro 3.0 核心「项目分析视图」。
|
||||
|
||||
> M1 范围、架构与决策见 **[docs/superpowers/specs/2026-06-07-geopro-desktop-m1-design.md](docs/superpowers/specs/2026-06-07-geopro-desktop-m1-design.md)**。
|
||||
> 上位技术基线见 **[docs/Geopro3.0_技术选型与架构规约.md](docs/Geopro3.0_技术选型与架构规约.md)**。
|
||||
> 环境搭建见 **[docs/ENV_SETUP_Windows.md](docs/ENV_SETUP_Windows.md)**。
|
||||
|
||||
## 技术栈
|
||||
|
||||
Qt 6.8 LTS(QtWidgets)+ VTK 9.3+ · CMake + vcpkg(全量,含 Qt)· MSVC 2022 / C++17 · ADS 停靠 · GDAL/PROJ · OpenSSL · QtKeychain。
|
||||
|
||||
## 目录(设计 §3)
|
||||
|
||||
```
|
||||
src/core/ 纯业务,零 Qt/VTK
|
||||
src/data/ Repository + 解析器
|
||||
src/net/ ApiClient / AuthService / Credential
|
||||
src/render/ VTK 场景与 actor(单一场景 + 相机预设)
|
||||
src/view/ QtWidgets 面板
|
||||
src/controller/ 联动编排
|
||||
src/app/ 入口 + 主窗(M1 spike:Qt+VTK 冒烟程序)
|
||||
tests/ gtest / Qt Test
|
||||
tools/ 离线验证脚本(validate_samples.py)
|
||||
docs/ 规约、API、样本数据、设计文档
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
|
||||
前置:VS2022(C++ 桌面开发)、Git、vcpkg(设 `VCPKG_ROOT`)。详见 ENV_SETUP_Windows.md。
|
||||
|
||||
```powershell
|
||||
# x64 Native Tools 命令行,项目根
|
||||
vcpkg x-update-baseline --add-initial-baseline # 锁依赖版本
|
||||
cmake --preset msvc-debug # 首次编译 Qt+VTK,较久
|
||||
cmake --build build/debug
|
||||
.\build\debug\src\app\geopro_desktop.exe # spike 冒烟:应显示一个锥体
|
||||
ctest --test-dir build/debug # 运行单测
|
||||
```
|
||||
|
||||
## 当前状态
|
||||
|
||||
M1 设计完成(v2,经双专家评审)。进入 **spike 预研**(设计 §15):① 全 vcpkg 构建/部署 ② ADS + QVTKOpenGLStereoWidget 停靠稳定 ③ 真实样本跑通 banded contour。spike 通过后展开完整实现计划。
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# 分层(设计 §3)。M1 spike 阶段先只构建 app 冒烟程序;
|
||||
# 随实现推进逐层启用为静态库并由 app 链接:
|
||||
#
|
||||
# add_subdirectory(core) # 纯业务,零 Qt/VTK
|
||||
# add_subdirectory(data) # Repository + 解析器
|
||||
# add_subdirectory(net) # ApiClient / AuthService / Credential
|
||||
# add_subdirectory(render) # VTK 场景与 actor
|
||||
# add_subdirectory(view) # QtWidgets 面板
|
||||
# add_subdirectory(controller) # 联动编排
|
||||
#
|
||||
add_subdirectory(app)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# M1 spike 冒烟程序:QApplication + QMainWindow + QVTKOpenGLStereoWidget(锥体)
|
||||
# 目的:验证「全 vcpkg:Qt + VTK[qt] 共用一份 Qt」可编译、可运行、可渲染(spike#1)。
|
||||
# ADS 停靠(spike#2)在此基础上增量接入。
|
||||
|
||||
add_executable(geopro_desktop WIN32 main.cpp)
|
||||
|
||||
target_link_libraries(geopro_desktop PRIVATE
|
||||
Qt6::Core Qt6::Gui Qt6::Widgets
|
||||
${VTK_LIBRARIES}
|
||||
)
|
||||
|
||||
# VTK 9 模块需 autoinit,否则渲染后端/工厂未注册,运行期黑屏或报错
|
||||
vtk_module_autoinit(TARGETS geopro_desktop MODULES ${VTK_LIBRARIES})
|
||||
|
||||
# 运行期 DLL 自动拷贝(单一 vcpkg 链路,规避双 Qt;设计 §11)
|
||||
if(WIN32)
|
||||
add_custom_command(TARGET geopro_desktop POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_RUNTIME_DLLS:geopro_desktop> $<TARGET_FILE_DIR:geopro_desktop>
|
||||
COMMAND_EXPAND_LISTS)
|
||||
endif()
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
// M1 spike 冒烟程序(设计 §15 spike#1/#2 起点)。
|
||||
//
|
||||
// 验证目标:
|
||||
// 1) 全 vcpkg 下 Qt6 + VTK[qt] 共用同一份 Qt,可编译/链接/运行(无双 Qt 冲突)。
|
||||
// 2) QVTKOpenGLStereoWidget(QOpenGLWidget 系,ADS reparent 友好)能在 Qt 窗口里渲染。
|
||||
//
|
||||
// 跑通后:在此基础上接入 ADS 停靠(spike#2)、再展开 render/view 分层(实现计划)。
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QSurfaceFormat>
|
||||
|
||||
#include <QVTKOpenGLStereoWidget.h>
|
||||
#include <vtkActor.h>
|
||||
#include <vtkConeSource.h>
|
||||
#include <vtkGenericOpenGLRenderWindow.h>
|
||||
#include <vtkNew.h>
|
||||
#include <vtkPolyDataMapper.h>
|
||||
#include <vtkRenderer.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// VTK 要求在创建任何 QVTKOpenGL* 前设置默认 surface format
|
||||
QSurfaceFormat::setDefaultFormat(QVTKOpenGLStereoWidget::defaultFormat());
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QMainWindow window;
|
||||
window.setWindowTitle(QStringLiteral("Geopro 3.0 — spike smoke test (Qt + VTK)"));
|
||||
window.resize(1024, 720);
|
||||
|
||||
auto* vtkWidget = new QVTKOpenGLStereoWidget(&window);
|
||||
window.setCentralWidget(vtkWidget);
|
||||
|
||||
vtkNew<vtkGenericOpenGLRenderWindow> renderWindow;
|
||||
vtkWidget->setRenderWindow(renderWindow);
|
||||
|
||||
vtkNew<vtkConeSource> cone;
|
||||
cone->SetResolution(32);
|
||||
|
||||
vtkNew<vtkPolyDataMapper> mapper;
|
||||
mapper->SetInputConnection(cone->GetOutputPort());
|
||||
|
||||
vtkNew<vtkActor> actor;
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
vtkNew<vtkRenderer> renderer;
|
||||
renderer->AddActor(actor);
|
||||
renderer->SetBackground(0.12, 0.13, 0.16); // 科学软件深色背景
|
||||
renderer->ResetCamera();
|
||||
renderWindow->AddRenderer(renderer);
|
||||
|
||||
window.show();
|
||||
return app.exec();
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# controller — 联动编排层
|
||||
|
||||
按交互闭环拆分(避免 God Object,设计 §3)。信号槽连接集中于各 controller 的 `wireUp()`。
|
||||
|
||||
- `SelectionController` — 勾选 / 选中状态
|
||||
- `RenderSyncController` — 状态 → Scene 渲染同步(勾选 GS/TM → 按 dd 类型筛选 ds → 渲染)
|
||||
- `DetailSyncController` — 列表 ↔ 详情 ↔ 视图定位三向联动(含 render 拾取回流)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# core — 纯业务层
|
||||
|
||||
**铁律:绝不 `#include` 任何 Qt / VTK 头**(含 `IInterpolator`,返回 `core::ScalarVolume`)。可独立单元测试。
|
||||
|
||||
子目录(设计 §3):
|
||||
- `model/` — 领域模型:Project, GsObject, TmObject, DsObject, Anomaly, ColorScale, Grid, ScatterField, ScalarVolume
|
||||
- `geo/` — LocalFrame(原点 + Z 基准 + 轴向)、CrsTransform(PROJ 封装,多 CRS)
|
||||
- `algo/` — IInterpolator 接口 + IdwInterpolator(返回 core 中立的 ScalarVolume)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# data — 数据访问层
|
||||
|
||||
Repository 抽象(**异步契约**:QFuture/回调 + 取消 + 分页),DTO 与领域模型分离。
|
||||
|
||||
子目录(设计 §3、§6):
|
||||
- `repo/` — IProjectRepository, IDatasetRepository
|
||||
- `local/` — LocalSampleRepository(M1,QtConcurrent 跑解析)+ 各格式解析器
|
||||
- `api/` — ApiRepository(M1 骨架,签名对齐 pop-api)
|
||||
- `dto/` — 后端 JSON DTO + → model 映射
|
||||
|
||||
解析约定见设计 §6.1(v 为 [j=y][i=x]、east/north 名值颠倒、影像 EPSG:3857 等)。
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# net — 网络与认证层
|
||||
|
||||
- `ApiClient` — QtNetwork 封装:基址 `http://tenant.geomative.cn/pop-api`、注入 `geomativeauthorization: Geomative <token>` 头、超时、错误码、401 处理。
|
||||
- `AuthService` — 验证码(getImageCode/verifyCodeCheck)+ **JSEncrypt RSA-2048 加密密码** + `login2`(token = `data.accessToken`)。
|
||||
- `Credential` — QtKeychain 凭证存取(严禁明文,规约 §7.4)。
|
||||
|
||||
详见设计 §8(含 §8.3 前置确认项:RSA 公钥常量、token 生命周期)。
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# render — VTK 渲染层
|
||||
|
||||
**独占 `vtkRenderWindow`,统一创建/持有所有 actor**(view 不持有 actor)。单一场景 + 相机预设(设计 §4)。
|
||||
|
||||
子目录:
|
||||
- `Scene` — 场景图、项目世界坐标空间、可见性;持有 RenderWindow
|
||||
- `actors/` — ScatterActor, GridContourActor, VoxelVolumeActor, AnomalyActor, TerrainActor
|
||||
- `color/` — ColorLutBuilder(colorBar → 离散 vtkLookupTable), ScalarBar
|
||||
- `camera/` — CameraPreset(Top2D / Free3D)
|
||||
- `interact/` — InteractionManager + InteractionTool(Measure/Slice/PickSelect);切片用 vtkResliceCursorWidget
|
||||
- `ground/` — IGroundLayer + DemImageGroundLayer(M1);TileGroundLayer(M1.5)
|
||||
|
||||
网格管线:`vtkImageData(+vtkWarpScalar) → vtkDataSetSurfaceFilter → vtkBandedPolyDataContourFilter(GenerateContourEdgesOn)`(设计 §4.3)。
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# view — QtWidgets 视图层
|
||||
|
||||
被动视图。持有 `QVTKOpenGLStereoWidget` 外壳(不 new actor),把交互事件注入 render、把拾取/选择回流给 controller。
|
||||
|
||||
子目录:
|
||||
- `login/` — LoginWindow(样式参考 web 登录页)
|
||||
- `panels/` — ObjectTreePanel, DatasetListPanel, MapViewPanel(QVTKOpenGLStereoWidget), DataDetailPanel, AnomalyPanel, ObjectPropertyPanel, PropertyPanel
|
||||
- `widgets/` — ColorScaleEditor, ToolbarBits
|
||||
|
||||
布局用 ADS 停靠(设计 §9);VTK 面板默认不可浮动(缓解 reparent 上下文丢失)。
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# 单元测试(设计 §12)。M1 spike 阶段先放一个 gtest 冒烟用例,
|
||||
# 验证 gtest 经 vcpkg 接入、ctest 可跑;随 core/data/algo 实现补充真实用例。
|
||||
|
||||
find_package(GTest CONFIG REQUIRED)
|
||||
|
||||
add_executable(geopro_tests smoke_test.cpp)
|
||||
target_link_libraries(geopro_tests PRIVATE GTest::gtest GTest::gtest_main)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(geopro_tests)
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
// gtest 冒烟:验证测试工具链(vcpkg gtest + ctest)已就绪。
|
||||
// 随 core/data/algo 实现,逐步替换为真实用例
|
||||
//(坐标 rebase/轴向、colorBar LUT 映射、v[j][i] 灌点序、IDW 正确性 等,设计 §12)。
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(SmokeTest, ToolchainWorks)
|
||||
{
|
||||
EXPECT_EQ(1 + 1, 2);
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "geopro-desktop",
|
||||
"version": "0.1.0",
|
||||
"description": "Geopro 3.0 desktop client (Qt6 + VTK9) - M1",
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "qtbase",
|
||||
"default-features": false,
|
||||
"features": ["gui", "widgets", "network", "sql", "sql-sqlite", "concurrent", "opengl"]
|
||||
},
|
||||
"qttools",
|
||||
{
|
||||
"name": "vtk",
|
||||
"default-features": false,
|
||||
"features": ["qt", "opengl", "gdal", "proj"]
|
||||
},
|
||||
"gdal",
|
||||
"proj",
|
||||
"eigen3",
|
||||
"spdlog",
|
||||
"fmt",
|
||||
"nlohmann-json",
|
||||
"openssl",
|
||||
"qtkeychain",
|
||||
"qt-advanced-docking-system",
|
||||
"gtest"
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue