Files
envi-code/CODEBUDDY.md
T
company-desktop-computer 3ba658ffc5 refactor: MakeTempSatPath 并入已有的 SAT 相关 namespace
- 不再为单个函数新建 namespace 块:把 SAT 相关的
  find_nth_occurrence_reverse / fixACISFormat 整块上移到 RegionToString 之前,
  MakeTempSatPath 并入同一块,文件内 namespace 块数由 7 回到 6
- 编码规范补充:优先复用已有 namespace,整个文件没有时才新建
2026-10-21 09:24:21 +08:00

166 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CODEBUDDY.md
This file provides guidance to CodeBuddy Code when working with code in this repository.
> 本文件是仓库内唯一的项目说明(原 `ai.memory/` 已合并至此)。与代码不一致时以 `cmake/` 脚本和当前代码为准。
## 项目概览
- **产品**:上海华软 **Envi3D 2026(环境设计)** —— CAD/BIM **机电(MEP)插件套件**。
- **形态**:ObjectARX / ZRX 插件(DLL,后缀 `.arx` / `.zrx`),运行在 CAD 宿主内,含大量 MFC 界面与自定义图元实体。
- **CMake 项目名**:`SHS_Code2026`(version 1.0.0)。
- **主代码目录**:`SourceCode/Code2026/`(约 2900 `.cpp` + 3100 `.h`;另有天正 `tg_shs/` 系列库)。
- **远端**:`origin` = `ssh://git@39.107.55.179:222/gjm/envi-code.git`(Gitea),主分支 `main`。
目标平台(由 preset 与编译宏区分):
| 平台 | SDK | 版本 | 对应 CAD |
| --- | --- | --- | --- |
| AutoCAD | ObjectARX | R18 ~ R26 | CAD 2010 ~ 2027 |
| 中望CAD | ZRX | Z2023 ~ Z2026 | ZWCAD 2023 ~ 2026 |
## 构建
**统一使用 CMake,不再使用 Visual Studio 工程文件(`.vcxproj` / `.sln` 已全部删除)。唯一例外:`SourceCode/Code2026/StartApp/StartApp.sln`(C# 启动器,独立于 CMake)。**
所有命令在 `SourceCode/Code2026/` 下执行(`cmakelists.txt` 与 `cmakepresets.json` 同目录):
```bash
cd SourceCode/Code2026
cmake --preset R250 # 配置(AutoCAD 2025-2026)
cmake --build --preset R250 --config Release # 编译
cmake --build --preset R250 --config Debug
cmake --build --preset R250 --config Release --target HvacCmd # 单模块
cmake --build --preset R250 --config Release --target Build_SH_CORE # 聚合目标
```
- 要求 CMake ≥ 3.21;生成器 `Visual Studio 18 2026`,架构 `x64`,`/MP` 多进程编译。
- preset 文件名是小写 `cmakepresets.json`(Windows 文件系统大小写不敏感,等价 `CMakePresets.json`)。
- 工具集随 CAD 版本变化:`v143`(R24x/R25x/R26x、Z202x)、`v142`、`v141`、`v140`、`v110`、`v100`、`v90`。
- C++ 标准在顶层 `cmakelists.txt` 中按 SDK 版本自动切换:ARX >25 → C++20;ARX 20~25 与 ZRX >2021 → C++14;ARX >19 → C++03;更老 → C++98。
- 输出目录:`bin/Code2026/{Debug|Release}-x64-<标签>`、`lib/Code2026/...`,标签为 `R<版本><子版本>` 或 `Z<版本>`。
- 加密模块的产物再落到子目录 `<PRODUCT>-<MODE>`(如 `ENV_2025_V6_S0-BAL_REMOTE`)。
- Debug 构建通过 post-build 调用 `copyarx.exe`,按 `sh_output_path.json`(ACAD)/ `zw_output_path.json`(中望)把产物部署到 `c:\ShangHuaSoft\Envi3D-2026-M`。**Release 不部署**。
### 预设(`cmakepresets.json`,13 套 + 3 个 base)
| 分组 | preset |
| --- | --- |
| AutoCAD | `R180 R190 R200 R210 R220 R230 R240 R243 R250 R260` |
| 中望CAD | `Z2023 Z2024 Z2025 Z2026` |
继承链:`base` → `acad_base` / `zwcad_base` → 各版本 preset。关键 cache 变量:`CAD_SDK_ROOT`(`../../arx/` 或 `../../zrx/`)、`DEP_LIB_ROOT` / `DEP_INC_ROOT`(`../dep_lib` / `../dep_inc`)、`PRODUCT=ENV_2025_V6_S0`、`TRIAL_YEAR=2026`、`GENERATE_BIN_DIR` / `GENERATE_LIB_DIR`。
### 顶层聚合目标
- `Build_TG` → `wfA wfB wfS wfAnotate wfoutdoor`
- `Build_SH_CORE` → `AecRxBase` + `CoreCommand_TRIAL_YEAR` + `CoreCommand_BAL_REMOTE`
- `Build_SH_GLOBAL` → `MFCCtrl sqliteserver AdsXRx ThunderProof`
### 批量编译与打包(`autoCompile/WF2026/`)
- `batch_build.bat` → `python cmake_batch_build.py`,读 `cmake_batch_build.json` 中的包定义,逐 preset 执行 `cmake --preset` + `cmake --build --preset --config release -j 8`,日志写 `<preset>.log`。
- 打包:Inno Setup(`*.iss`)+ Python(`SHSCompile.py`)+ 多个 `.bat`,覆盖 ACAD/中望、1 年期/加密版,以及客户专版(中广核、国能集团)。如 `环境设计-ACAD-加密自动打包.bat`、`环境设计-中望-1年期自动打包.bat`。
### CMake 封装(`cmake/functions.cmake`)
- `add_custom_module(dir folder)`:`add_subdirectory` + 以目录名作为 target 名并设 FOLDER;`add_custom_module_2(dir target folder)` 用于目录名 ≠ target 名(如 `ISODraft` → `ISODraftCmd`、`tg_shs/shs_kernal` → `wfK`)。
- `target_link_objectarx(target EXT)`:链接 CAD SDK + 全局头 `ShsGlobalIncludes`(`inc/`、`inc/implement/`),定义 `CMAKE`、`ARX=<版本>` 与模块导出宏(如 `HVACCMD_EXPORT`)。
- `simple_link_cad_sdk`:按 `IsZWCAD()` 选择 `ThirdParty::ARX` / `ThirdParty::ZRX`。
- `add_def_file_name(SOURCES <Name>)`:向源列表追加 `<Name>.def` / `<Name>_zrx.def`(导出 `acrxEntryPoint`、`acrxGetApiVersion`)。
- `target_set_name_and_suffix(target <Name> ".arx")`:设置 `OUTPUT_NAME`/`SUFFIX`,中望平台自动改 `.zrx`。
- `set_encryption_definitions_and_output_path(target MODE)`:**授权模式**,见下节。
- `set_debug_post_build`:调用 `copyarx.exe` 部署(仅 Debug)。
- `cmake/ThirdPartyDeps.cmake`:定义 `ShsGlobalIncludes` 与 `ThirdParty::ARX` / `ZRX` / `SQLite3` / `cURL` / `TG` / `modernGlue` / `BitAnswer` 等接口目标;按 SDK 版本条件追加库(`acdrawbridge` 需 >19,`acpal`/`acgeoment` 需 >23)。
- 顶层 `cmakelists.txt` 用 `add_custom_module` 注册全部模块并组织 `FOLDER`(`SH/Core`、`SH/Pipe` …);`CoreLibrary`、`CoreCommand` 走各自的 `add_subdirectory`(因内部有双版本逻辑)。
## 授权 / 加密
- `CoreLibrary`、`CoreCommand` 通过 `get_encryption_modes()` 由**同一套源码编译出两个目标**:
- `CoreCommand_BAL_REMOTE` / `CoreLibrary_BAL_REMOTE`(网络锁 / 正式版)
- `CoreCommand_TRIAL_YEAR` / `CoreLibrary_TRIAL_YEAR`(1 年期试用版,Release 下定义 `TRIAL_YEAR=<年份>`)
- 其它业务模块**只链接 `CoreCommand_BAL_REMOTE`**;`CoreLibrary_${MODE}` 由加密模块内部引用。
- 依赖 **BitAnswer**(加密狗库);加密表由 `utility/generateEncryptionTable` 生成。
## 架构
分三层:
1. **实体层**:`CoreLibrary` 定义海量自定义图元 `AecDbXxx`(继承 `AcDbEntity`),是数据模型核心;同时含绘图/分解/布尔等基础能力。
2. **命令层**:各 `*Cmd` 模块实现 MFC 对话框 + Jig 交互 + ARX 命令注册(`acrxEntryPoint` → `acedRegCmds->addCommand`,命令组名各模块自定)。
3. **链接关系**:业务模块 → `AecRxBase` / `CoreCommand` / `sqliteserver` / `MFCCtrl`。
模块在顶层 `cmakelists.txt` 中按 FOLDER 分组:
| FOLDER | 模块 | 职责 |
| --- | --- | --- |
| `SH/Global_Libraries` | `MFCCtrl`, `sqliteserver` | MFC 控件库;SQLite 数据服务 |
| `SH/ThunderProof` | `AdsXRx`, `ThunderProof` | 防雷接地设计 |
| `SH/Core` | `AecRxBase`, `CoreImplement`, `CoreLibrary`, `CoreCommand` | 核心基类、自定义实体、主命令 |
| `SH/Pipe` | `PipelineCmd`, `PipelineSpecCmd`, `PIDLineCmd`, `ISODraft`(→`ISODraftCmd`), `PipeHanger`(→`PipeHangerCmd`), `PlumbingCmd`, `pool3dcmd` | 管道/工艺/ISO 图/支吊架/给排水/水池 |
| `SH/Structures` | `ArchCmd`, `ElecCmd`, `HvacCmd`, `SPLDCmd` | 建筑/电气/暖通/道路 |
| `SH/Other` | `shsTK`, `Dimension`, `EarthWormMain`, `EarthWormCmd` | 通用工具、标注、主程序 |
| `TG/*` | `tg_shs/*` | 天正系列库 |
关键模块:
- **CoreLibrary**:数据模型核心(自定义实体 `AecDbXxx`),头文件在 `inc/` 与 `inc/implement/`,被所有模块共享。
- **AecRxBase**:ARX 基类库(`AecDbEntityBase`、`AecDbCurveBase`、Grip、双击编辑等)。
- **CoreCommand**:主命令集 + MFC 主界面/面板(BIM 面板、AI 助手 `sh_ai.cpp` / `askaipaletteset.cpp`)、PCF 导入导出(`pcf.cpp`、`PcfIso.cpp`);**生成两种加密版本**。
- **CoreImplement**:仅在 Debug 下链接(自定义实体的实现层)。
- **StartApp**:C# (.NET WinForms) 启动器,不走 CMake,保留独立 `StartApp.sln`。
- **tg_shs/**:天正系列(`shs_kernal`→`wfK`、`shs_twtkernal`→`wfKernal`、`shs_GeLib`、`shs_annotate`→`wfA`、`shs_twtanotate`→`wfAnotate`、`shs_blklib`→`wfB`、`shs_siteplan`→`wfS`、`shs_pipewire`→`wfpipew`、`shs_outdoor`→`wfoutdoor`、`shs_ximage/*` 图像库、`shs_dbf`、`shs_sqlite` 等)。
## 新增模块约定
在模块目录放 `CMakeLists.txt`,并在顶层 `SourceCode/Code2026/cmakelists.txt` 用 `add_custom_module(<相对目录> <FOLDER分组>)` 注册。模板参考 `HvacCmd/CMakeLists.txt`:
```cmake
add_library(<target> SHARED ${SOURCES})
add_def_file_name(SOURCES "<Name>")
target_set_name_and_suffix(<target> "<Name>" ".arx")
target_link_objectarx(<target> <XXX_EXPORT>)
target_precompile_headers(<target> PRIVATE StdAfx.h)
set_debug_post_build(<target> "<Name>" ".arx")
```
需要授权双版本时,参考 `CoreCommand/cmakelists.txt` 的 `get_encryption_modes` + `foreach(MODE ...)` + `set_encryption_definitions_and_output_path` 写法。
## 平台差异与注意事项
- 用 `IsZWCAD()` 判断目标平台;ZRX 产物后缀自动变 `.zrx`,链接 `ThirdParty::ZRX`;ARX 链接 `ThirdParty::ARX`。
- 编译宏:`ARX=<版本号>` 或 `ZWCAD`;模块导出宏(`*_EXPORT`)由 `target_link_objectarx` 注入。
- 部分库仅在特定 SDK 版本可用(如 `acdrawbridge` 需 >19,`acpal`/`acgeoment` 需 >23),已在 `ThirdPartyDeps.cmake` 处理。
- **禁止**新增或依赖 `.vcxproj` / `.sln`(`StartApp` 除外)。`cmake_output/` 下 CMake 生成的临时 `*.vcxproj` 是构建产物、已被 gitignore,**不要**误提交。
- `.gitignore` 忽略:`Arx/`、`ZRX/`、`cmake_output/`、`bin/`、`lib/`,以及 `*.obj/*.pdb/*.user/.vs/` 等 VS 中间产物。
## 源码编码(重要)
**全部 `SourceCode/Code2026/**/*.cpp|*.h` 已统一为 UTF-8 with BOM**(2026-10 一次性重编码,约 6000 个文件)。新增或修改的 `.cpp/.h` 必须保存为 **UTF-8 BOM**:
- 例外:`cmakelists.txt` / `CMakeLists.txt` 保持 ASCII、无 BOM。
- 改完自检:`python -c "print(open('f.cpp','rb').read(3))"` 应为 `b'\xef\xbb\xbf'`;再查 `raw.count(b'\xef\xbf\xbd')`,非 0 说明中文已被写坏(不可逆),用 `git checkout HEAD -- <file>` 还原重做。
- 若遇到仍是 GBK/UTF-16 的老文件(从旧分支检出),先探明编码再改,不要假设。
## 编码规范
- **文件内私有函数用匿名 `namespace`**:只在一个 `.cpp` 内使用的函数,直接实现在该文件**已有的**匿名 `namespace { }` 中;只有整个文件没有匿名 namespace 时才新建一块。不要为每个函数单独开一块,也不要写成文件级 `static` 或放进头文件。
```cpp
namespace {
CString MakeTempSatPath() { ... }
}
```
## 测试 / 静态检查
本仓库**没有单元测试框架**(无 gtest/Catch2),也没有 lint 配置。验证方式是编译对应 preset,并在 CAD 中加载 `.arx` / `.zrx` 实测。
## Git 协作
- 提交信息用中文。
- 远端是 Gitea,走 222 端口 SSH;各机器私钥不同,在本机 `~/.ssh/config` 指定,**不要把私钥文件名写进仓库**。
- 推送到 `main` 需经 PR:`git push origin HEAD:refs/for/main/<分支名>` 触发评审,不要直接推 `main`。