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:
gaozheng 2026-06-07 17:41:10 +08:00
parent fe7737b175
commit 87eba2c5a3
18 changed files with 355 additions and 0 deletions

24
.clang-format Normal file
View File

@ -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

18
.clangd Normal file
View File

@ -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()

15
.editorconfig Normal file
View File

@ -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

35
CMakeLists.txt Normal file
View File

@ -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) # GUISupportQtvtk[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)

29
CMakePresets.json Normal file
View File

@ -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" }
]
}

43
README.md Normal file
View File

@ -0,0 +1,43 @@
# Geopro 3.0 桌面客户端
地球物理勘探数据可视化桌面客户端Qt 6 + VTK 9C++)。复刻 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 LTSQtWidgets+ 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 spikeQt+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 通过后展开完整实现计划。

11
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,11 @@
# §3M1 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)

21
src/app/CMakeLists.txt Normal file
View File

@ -0,0 +1,21 @@
# M1 spike QApplication + QMainWindow + QVTKOpenGLStereoWidget(锥体)
# vcpkgQt + VTK[qt] Qtspike#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()

55
src/app/main.cpp Normal file
View File

@ -0,0 +1,55 @@
// M1 spike 冒烟程序(设计 §15 spike#1/#2 起点)。
//
// 验证目标:
// 1) 全 vcpkg 下 Qt6 + VTK[qt] 共用同一份 Qt可编译/链接/运行(无双 Qt 冲突)。
// 2) QVTKOpenGLStereoWidgetQOpenGLWidget 系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();
}

7
src/controller/README.md Normal file
View File

@ -0,0 +1,7 @@
# controller — 联动编排层
按交互闭环拆分(避免 God Object设计 §3。信号槽连接集中于各 controller 的 `wireUp()`
- `SelectionController` — 勾选 / 选中状态
- `RenderSyncController` — 状态 → Scene 渲染同步(勾选 GS/TM → 按 dd 类型筛选 ds → 渲染)
- `DetailSyncController` — 列表 ↔ 详情 ↔ 视图定位三向联动(含 render 拾取回流)

8
src/core/README.md Normal file
View File

@ -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 基准 + 轴向、CrsTransformPROJ 封装,多 CRS
- `algo/` — IInterpolator 接口 + IdwInterpolator返回 core 中立的 ScalarVolume

11
src/data/README.md Normal file
View File

@ -0,0 +1,11 @@
# data — 数据访问层
Repository 抽象(**异步契约**QFuture/回调 + 取消 + 分页DTO 与领域模型分离。
子目录(设计 §3、§6
- `repo/` — IProjectRepository, IDatasetRepository
- `local/` — LocalSampleRepositoryM1QtConcurrent 跑解析)+ 各格式解析器
- `api/` — ApiRepositoryM1 骨架,签名对齐 pop-api
- `dto/` — 后端 JSON DTO + → model 映射
解析约定见设计 §6.1v 为 [j=y][i=x]、east/north 名值颠倒、影像 EPSG:3857 等)。

7
src/net/README.md Normal file
View File

@ -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 生命周期)。

13
src/render/README.md Normal file
View File

@ -0,0 +1,13 @@
# render — VTK 渲染层
**独占 `vtkRenderWindow`,统一创建/持有所有 actor**view 不持有 actor。单一场景 + 相机预设(设计 §4
子目录:
- `Scene` — 场景图、项目世界坐标空间、可见性;持有 RenderWindow
- `actors/` — ScatterActor, GridContourActor, VoxelVolumeActor, AnomalyActor, TerrainActor
- `color/` — ColorLutBuildercolorBar → 离散 vtkLookupTable, ScalarBar
- `camera/` — CameraPresetTop2D / Free3D
- `interact/` — InteractionManager + InteractionToolMeasure/Slice/PickSelect切片用 vtkResliceCursorWidget
- `ground/` — IGroundLayer + DemImageGroundLayerM1TileGroundLayerM1.5
网格管线:`vtkImageData(+vtkWarpScalar) → vtkDataSetSurfaceFilter → vtkBandedPolyDataContourFilter(GenerateContourEdgesOn)`(设计 §4.3)。

10
src/view/README.md Normal file
View File

@ -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 停靠(设计 §9VTK 面板默认不可浮动(缓解 reparent 上下文丢失)。

10
tests/CMakeLists.txt Normal file
View File

@ -0,0 +1,10 @@
# §12M1 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)

10
tests/smoke_test.cpp Normal file
View File

@ -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);
}

28
vcpkg.json Normal file
View File

@ -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"
]
}