执行摘要
本报告基于 CityEngine 2025 官方发布的 ESRI.lib、CityEngine2025Tutorial、CityEngine2025Example 三套工程文件(合计约 4.7 GB 压缩包,解压后约 11 GB,含 780 个 .cga 规则文件),结合官方 CGA Reference 与 Python API 文档,对 CGA(Computer Generated Architecture)形状语法进行了系统性学习。
核心发现
CGA 是一种声明式、基于形状替换(Shape Replacement)的领域特定语言。任何复杂三维模型都被抽象为 Shape = Geometry + Scope + Pivot + Symbol,通过 extrude、split、comp 等操作递归展开为几何体。
数据规模
- ESRI.lib:140 个 CGA(基础库)
- Tutorial:99 个 CGA(教学案例)
- Example:541 个 CGA(实战案例)
- 解压后总大小:约 11 GB
技术路线
不建议让 LLM 直接端到端生成 CGA。最可行的路径是:自然语言 → 语义中间表示(Semantic IR)→ 规则中间表示(Rule IR)→ CGA 代码 → 几何执行,以建筑为起点,逐步扩展到植物、城市家具、交通等领域。
一、CityEngine 与 CGA 概览
1.1 什么是 CityEngine
ArcGIS CityEngine 是 Esri 推出的三维城市建模软件,核心能力是基于二维矢量数据(地块、道路、建筑 footprint)或三维初始形状,通过程序化规则批量生成大规模、参数化的三维城市场景。它被广泛用于城市规划、建筑设计、游戏、影视特效和数字孪生等领域。
CityEngine 的关键特性包括:
- 程序化建模(Procedural Modeling):用规则描述建筑、道路、植被等,而非手动建模。
- GIS 集成:支持 Shapefile、FileGDB、OSM、KML 等 GIS 数据作为输入。
- Python API:支持 Jython 2.7 与 Python 3.x,可自动化场景操作、规则分配、模型导出。
- 多格式导出:OBJ、FBX、glTF/GLB、DAE、USD、IFC、SLPK 等。
1.2 什么是 CGA
CGA(Computer Generated Architecture)是 CityEngine 的领域特定语言(DSL),属于 Shape Grammar 的变体。CGA 程序由一组规则组成,每个规则定义如何将一个形状(Shape)替换为新的形状或几何操作。
@StartRule
Lot --> extrude(height) Mass
Mass --> comp(f) { front: Facade | side: Wall | top: Roof }
Facade --> split(y) { ~1: Floor }*
Floor --> split(x) { 1: Wall | ~2: Window | 1: Wall }*
Window --> color("#00BFFF") primitiveCube()
上述代码展示了典型的建筑生成流程:地块(Lot)拉伸为体块(Mass),体块按面拆分,正立面按楼层和窗户网格细分,最终生成带颜色的窗户立方体。
1.3 本次分析的数据来源
| 数据源 | 大小 | CGA 数量 | 主要内容 |
|---|---|---|---|
| ESRI.lib | 652 MB / 749 MB | 140 | CityEngine 自带基础库:植物、街道、围栏、屋顶、材质等通用规则 |
| CityEngine2025Tutorial | 271 MB / 570 MB | 99 | 官方教程案例:从基础 extrude 到立面建模、Python 脚本、WebScene 发布 |
| CityEngine2025Example | 3.5 GB / 4.7 GB | 541 | 官方实战案例:完整街道、城市规划、景观设计、中世纪城市、沙漠城市、 damage 评估等 |
这些数据覆盖了建筑、道路、植物、城市家具、地形、材质、屋顶、立面等绝大多数城市场景,为设计通用解析器提供了充足的语法和结构样本。
二、CGA 语法深度解析
2.1 文件结构与组成
一个典型的 .cga 文件由以下部分组成:
| 组成部分 | 关键字 | 说明 |
|---|---|---|
| 版本声明 | version "2025.0" | 指定规则兼容的 CityEngine 版本 |
| 导入 | import lib: "path.cga" | 引入其他 CGA 文件,可带前缀、覆盖属性 |
| 属性 | attr height = 20 | 可在 Inspector 中修改的外部参数 |
| 常量 | const PI = 3.14159 | 内部不可修改的常量 |
| 函数 | getColor(t) = case t=="res": ... | 返回值的表达式函数 |
| 规则 | Lot --> extrude(10) Mass | 核心:形状替换与操作 |
| 起始规则 | @StartRule | 标记初始规则入口 |
| 样式 | style MyStyle { ... } | 同一文件内的多风格切换 |
| 注解 | @Group @Order @Range @Enum | UI 分组、排序、参数限制 |
2.2 Shape、Scope 与 Pivot
CGA 的执行基于一个核心数据模型:Shape = 几何(Geometry)+ 作用域(Scope)+ 枢轴(Pivot)+ 符号(Symbol)。
2.2.1 Shape(形状)
Shape 是 CGA 执行过程中的基本单元。每个 Shape 包含:
- Symbol:形状名称,用于匹配规则,如
Lot、Facade、Window。 - Geometry:实际网格(顶点、边、面)与材质。
- Scope:形状的局部坐标系和包围盒,决定位置、方向、尺寸。
- Pivot:局部坐标系原点,通常与 Scope 原点对齐。
2.2.2 Scope(作用域)
Scope 定义了形状的局部坐标系,所有变换操作(s()、t()、r())都基于当前 Scope。常用属性:
| 属性 | 说明 |
|---|---|
scope.sx / sy / sz | Scope 在三个轴上的尺寸 |
scope.tx / ty / tz | Scope 原点的平移 |
scope.rx / ry / rz | Scope 的旋转(欧拉角,度) |
scope.elevation | 海拔高度(只读) |
2.2.3 Pivot(枢轴)
Pivot 是 Shape 的坐标参考点。setPivot()、center()、alignScopeToGeometry() 等操作会改变 Pivot,从而影响后续 split 和 extrude 的方向。
2.3 核心操作符
CGA 的操作符分为几何创建、几何切分、几何变换、材质纹理、流程控制等类别。
2.3.1 几何创建
| 操作符 | 示例 | 说明 |
|---|---|---|
extrude | extrude(20) | 将 2D 面沿法线拉伸为 3D 体 |
primitiveCube | primitiveCube() | 生成立方体 |
primitiveCylinder | primitiveCylinder() | 生成圆柱体 |
primitiveSphere | primitiveSphere() | 生成球体 |
i() | i("tree.obj") | 插入外部模型资产 |
roofGable | roofGable(30) | 生成人字屋顶 |
roofHip | roofHip() | 生成四坡屋顶 |
2.3.2 几何切分
| 操作符 | 示例 | 说明 |
|---|---|---|
split | split(x){ 3: A | ~1: B }* | 沿某轴切分,支持绝对、相对、浮动、重复 |
comp | comp(f){ front: F | top: R } | 按拓扑组件(面/边/顶点)拆分 |
offset | offset(1) | 面内外偏移 |
setback | setback(2) | 沿边后退 |
innerRectangle | innerRectangle(scope) | 提取内部最大矩形 |
2.3.3 几何变换
| 操作符 | 示例 | 说明 |
|---|---|---|
t() | t(0, 5, 0) | 平移 |
s() | s('1, '2, '1) | 缩放(带 ' 表示相对当前 scope) |
r() | r(0, 90, 0) | 旋转 |
center() | center(xyz) | 将 scope 中心对齐几何中心 |
alignScopeToGeometry | alignScopeToGeometry(yUp, any, world.lowest) | 对齐 scope 到几何 |
2.3.4 split 尺寸前缀
split 是 CGA 中最强大的操作之一,其尺寸前缀决定分配逻辑:
| 前缀 | 示例 | 含义 |
|---|---|---|
| 无 | 3: A | 绝对尺寸(米) |
' | '0.3: A | 相对尺寸(占当前 scope 的比例) |
~ | ~1: A | 浮动尺寸(自动分配剩余空间) |
* | { ... }* | 重复切分直到无法容纳 |
2.3.5 comp 组件选择器
comp 按拓扑组件拆分形状。常见组件类型与选择器:
| 组件类型 | 选择器 | 说明 |
|---|---|---|
f(面) | front / back / left / right / top / bottom / side | 按朝向选择面 |
e(边) | vertical / horizontal / aslant / nutant | 按方向选择边 |
v(顶点) | all | 所有顶点 |
g(组) | border / inside | 边界或内部 |
m(材质) | 索引/名称 | 按材质拆分 |
2.4 内置函数库
CGA 内置函数按功能分为十余类。下表列出与解析器实现最相关的类别与代表函数。
2.4.1 数学与概率函数
| 函数 | 说明 | 典型用途 |
|---|---|---|
sin / cos / tan / atan2 | 三角函数 | 弧形、朝向计算 |
sqrt / pow / ln / exp | 幂指对函数 | 面积、距离、曲线 |
ceil / floor / clamp / min / max | 取整与范围限制 | 楼层数、尺寸约束 |
rand(min, max) | 随机数 | 随机高度、旋转、种子 |
p(probability) | 概率布尔 | 按概率分支 |
seedian | 形状随机种子 | 可复现的随机序列 |
2.4.2 几何查询函数
| 函数 | 说明 | 典型用途 |
|---|---|---|
geometry.area | 表面积 | 按面积决定高度 |
geometry.angle | 坡度/方位角 | 屋顶、朝向分析 |
geometry.boundaryLength | 边界总长 | 周长计算 |
geometry.height | 世界高度 | 高程判断 |
geometry.volume | 体积 | 容积率 |
geometry.isPlanar / isRectangular | 几何性质判断 | 形状适配规则 |
geometry.nFaces / nEdges / nVertices | 拓扑统计 | 复杂度评估 |
2.4.3 资源与文件函数
| 函数 | 说明 | 典型用途 |
|---|---|---|
fileSearch / filesSearch | 文件查找 | 批量加载纹理/模型 |
fileExists | 文件存在性 | 条件加载 |
fileRandom | 随机文件 | 随机纹理/资产 |
assetInfo | 查询资产尺寸 | 模型适配 |
assetMetadata | 读取资产元数据 | 语义信息 |
imageInfo | 图片宽高 | 纹理比例 |
2.4.4 上下文与遮挡函数
| 函数 | 说明 | 典型用途 |
|---|---|---|
inside / overlaps / touches | 遮挡关系 | 建筑退让、绿地避让 |
contextCompare | 上下文排名 | 按位置/面积排序 |
contextCount | 统计邻居 | 密度控制 |
minimumDistance | 最近距离 | 避让分析 |
2.4.5 材质与颜色函数
材质属性可通过 set(material.name, ...) 设置,颜色可通过 color("#rrggbb") 设置。PBR 属性包括 material.roughness、material.metallic、material.opacity 等。
三、真实案例研究
本节从三套工程文件中选取具有代表性的 CGA 规则,分析其实际结构与设计思路。
3.1 建筑:Building.cga
文件:CityEngine2025Example/Example_Complete_Streets__2025_0/rules/Buildings_Standard/Building.cga(460 行)
该规则是一个典型的参数化建筑生成器,展示了如何用 @Group、@Order、@Enum 等注解组织大量属性。
@StartRule
Building -->
alignScopeToAxes(y)
s('1,0,'1)
cleanupGeometry(edges, 0.1)
report("Building_FID", buildingFID)
report("Parcel_FID", parcelFID)
BuildingReference.Usage_Typology.ReportUsages(Total_GFA, 1)
FootprintModelDispatch
FootprintModelDispatch -->
case modelFileExists: ModelLoader
else: BuildingShell
BuildingShell -->
extrude(totalHeight) Mass
关键设计:
- 通过
typology枚举支持 17 种建筑类型(农业、教育、工业、办公、住宅、交通等)。 - 优先加载外部 geospecific 模型(
modelFile),否则程序化生成BuildingShell。 - 使用
report()输出建筑 FID、地块 FID、GFA 等指标,用于 Dashboard。 - 纹理通过
fileRandom和Three_Part_Texturing库动态选择。
3.2 街道:Standard_Street.cga
文件:CityEngine2025Example/Example_Planning_04_Landscape_Design__2025_0/rules/Streets_Standard/Standard_Street.cga
街道规则是 CityEngine 中复杂度最高的规则类型之一,涉及车道、人行道、绿化带、路灯、交通标志等多元素协同。
Street -->
split(z) { ~1: Sidewalk
| streetWidth: Roadway
| ~1: Sidewalk }
Roadway -->
comp(f) { top: RoadSurface
| side: Curb }
Sidewalk -->
split(x) { ~1: Pavement
| furnitureWidth: FurnitureStrip
| ~1: Pavement }
FurnitureStrip -->
split(x) { ~2: NIL
| lampWidth: Lamp
| ~2: NIL }*
关键设计:
- 街道沿 Z 轴切分为人行道、车行道、人行道三段。
- 车行道按
comp(f)提取顶面和侧面,分别生成路面和路缘。 - 人行道家具带通过重复
split规则放置路灯、长椅、垃圾桶等城市家具。 - 大量参数(车道宽度、人行道宽度、树种、路灯间距)通过
attr暴露给用户。
3.3 植物:Trees.cga / Plant_Mixer
文件:CityEngine2025Tutorial/Tutorial_15_Publish_WebScenes__2025_0/rules/Trees.cga(41 行)
该规则展示了 CityEngine 中植物生成的典型模式:通过 import 调用 ESRI.lib 的通用 Plant_Loader.cga,实现植物模型的统一加载。
import Plant_Loader:"/ESRI.lib/rules/Plants/Plant_Loader.cga"
(Name=Plant_Name, Height=HEIGHT, Representation=Representation)
@Group("Plant Model", 0)
@Order(1)
attr Plant_Name =
case GENUS == "Eucalyptus": "Blue Gum Eucalyptus"
case GENUS == "Ulmus": "Field Elm"
case GENUS == "Washingtonia": "California Palm"
case GENUS == "Acer": "Sugar Maple"
case GENUS == "Quercus": "White Oak"
case GENUS == "Juglans": "California Walnut"
else: NAME
@Order(2) @Enum("Realistic", "Schematic", "Fan")
attr Representation = "Fan"
Tree --> Plant_Loader.Generate
关键设计:
- 通过
GENUS属名映射到具体植物模型名称(如 Acer → Sugar Maple)。 - 支持三种表达方式:Realistic(真实模型)、Schematic(示意)、Fan(扇形简化)。
Plant_Loader封装了模型查找、缩放、LOD 切换等复杂逻辑,上层规则只需传入参数。- 这种“参数 + 通用加载器”模式非常适合向植物、城市家具、交通车辆等领域扩展。
3.4 城市家具:Bench.cga
文件:CityEngine2025Example/Example_Planning_04_Landscape_Design__2025_0/rules/Landscape_Design_Hardscape/Bench.cga(37 行)
这是一个极简的城市家具规则,展示了如何用少量 CGA 操作表达一个可参数化的长椅。
@Order(1) @Distance
attr Thickness = 0.06
@Order(2) @Color
attr Bench_Color = "#999999"
@StartRule
Bench -->
color(Bench_Color)
innerRectangle(scope) { shape: BenchFootprint }
BenchFootprint -->
extrude(0.3)
split(y) { ~1: BenchLegs | Thickness: X. }
BenchLegs -->
split(x) { Thickness: X.
| ~1: NIL
| Thickness: X. }
关键设计:
- 通过
innerRectangle(scope)获取放置长椅的内部矩形。 - 用
split(y)分离椅面与椅腿区域。 - 用
split(x)在两端生成椅腿,中间留空。 - 仅暴露
Thickness和Bench_Color两个属性,简洁易用。
案例研究的启示
四类规则虽然领域不同,但遵循共同模式:
- 参数化入口:用
attr暴露少量关键参数。 - 层次化分解:通过
split/comp将整体拆分为局部。 - 资产与程序化结合:简单几何用 CGA 生成,复杂对象用
i()或加载器引入。 - 可复用库:复杂逻辑封装在通用库(如
Plant_Loader、Building_Reference)中。
四、自研 CGA 解析器技术方案
4.1 总体目标
为 peyep 项目设计并实现一个纯自研的 CGA 解析器体系,具备以下能力:
- 自然语言转 CGA:用户用中文/英文描述建筑或城市元素,系统自动生成合法、可执行的 CGA 规则。
- CGA 解析生成几何体:不依赖 CityEngine 桌面软件,自主解析 CGA 并输出三维几何(mesh)。
- 通用性与可扩展性:以建筑为起点,逐步支持植物、城市家具、交通运输、道路网络等任意三维模型。
- Web 化与服务化:通过 FastAPI 提供 REST/ WebSocket 接口,支持在线编辑、实时预览与版本管理。
4.2 四层架构
直接让 LLM 输出 CGA 代码的成功率很低(CGA 是低资源 DSL)。因此采用分层架构,每层各司其职:
| 层级 | 职责 | 输出 | 关键技术 |
|---|---|---|---|
| NL 理解层 | 解析意图、抽取实体、补全缺失参数 | Semantic JSON/YAML | LLM + NER + 风格本体库 |
| 语义中间表示 | 统一描述“是什么、在哪里、多大、什么风格” | Semantic IR | JSON Schema + 约束定义 |
| 规则中间表示 | 生成领域相关的规则推导树 | Rule IR(AST) | 模板引擎 + 约束求解 |
| CGA 代码层 | 生成合法 CGA 代码 | .cga 文件 | 模板引擎 + 语法校验 |
| 几何执行层 | 解析 CGA 并输出 Mesh | GLB / OBJ / CityJSON | 自研解释器 + Three.js |
4.3 自然语言理解层
NL 理解层负责把用户的自然语言描述转换为结构化的 Semantic IR。需要处理的典型输入:
"建一个 5 层高的现代办公楼,底层是商业,入口朝南,屋顶是平的,立面有大面积玻璃窗。"
输出示例:
{
"category": "building",
"type": "office",
"style": "modern",
"floors": 5,
"floor_height": 3.5,
"ground_floor": { "usage": "retail", "height": 4.5 },
"entrance": { "direction": "south" },
"roof": { "type": "flat" },
"facade": { "window_ratio": 0.7, "pattern": "grid" }
}
核心模块:
- 意图分类器:判断是建筑、植物、道路、家具还是城市场景。
- 实体抽取:抽取楼层数、高度、风格、材质、朝向、位置等。
- 单位归一化:将“5 层”、“20 米”、“约占 1/3”统一为数值。
- 缺失参数补全:用户提供不完整时,用默认值或反问确认。
- 风格本体库:将“现代”、“欧式”、“Art Deco”映射为规则模板与参数范围。
4.4 语义 / 规则中间表示
Semantic IR 是领域无关的,Rule IR 是领域相关的。中间表示的设计直接影响系统的可扩展性。
4.4.1 Semantic IR 示例
entity:
id: building_01
category: building
type: office
location: { x: 0, y: 0, z: 0 }
footprint: [[0,0], [20,0], [20,15], [0,15]]
parameters:
floors: 5
floor_height: 3.5
ground_floor_height: 4.5
roof_type: flat
facade_window_ratio: 0.7
style: modern
context:
entrance_direction: south
adjacent_to: [road_01]
4.4.2 Rule IR 示例
{
"rule": "Building",
"operations": [
{ "op": "alignScopeToAxes", "axis": "y" },
{ "op": "extrude", "height": "totalHeight" },
{ "op": "comp", "selector": "f", "branches": [
{ "case": "front", "rule": "Facade" },
{ "case": "top", "rule": "Roof" }
]},
{ "op": "split", "axis": "y", "repeat": true, "parts": [
{ "size": "ground_floor_height", "rule": "GroundFloor" },
{ "size": "floor_height", "rule": "UpperFloor" }
]}
]
}
4.4.3 约束求解
几何约束需要在 Rule IR 层求解,例如:
- 楼层高度总和 ≤ 总高度
- 窗户不超出立面范围
- 入口朝南时,立面需对应 front 面
- 退界距离、容积率等城市设计规范
可选用 OR-Tools、Z3 或自定义约束求解器处理硬约束。
4.5 CGA 代码生成层
CGA 代码层将 Rule IR 编译为合法 CGA。采用模板引擎(如 Jinja2)+ 语法校验的组合。
4.5.1 模板策略
先不追求 LLM 直接写完整 CGA,而是为每个领域预置模板:
BuildingTemplate:住宅 / 办公 / 商业 / 混合StreetTemplate:标准街道 / 林荫道 / 商业步行街PlantTemplate:乔木 / 灌木 / 地被FurnitureTemplate:长椅 / 路灯 / 垃圾桶 / 公交站台
4.5.2 CGA 子集
为降低实现难度,先支持 CGA 核心子集:
| 类别 | 支持的操作符 / 函数 |
|---|---|
| 几何创建 | extrude、primitiveCube、primitiveCylinder、primitiveSphere、i() |
| 几何切分 | split、comp、offset、innerRectangle |
| 几何变换 | t()、s()、r()、center、alignScopeToAxes |
| 材质纹理 | color、texture、setupProjection |
| 流程控制 | case/else、NIL、概率 % |
| 数学函数 | sin/cos/sqrt/pow/rand/clamp/min/max |
| 几何查询 | geometry.area/height/volume/nFaces |
4.5.3 语法校验
生成 CGA 后立即进行静态检查:
- 语法树是否完整
- 规则是否存在循环依赖
- 引用的规则是否已定义
- split 尺寸是否合理(总尺寸不超过 scope)
- shape 名称是否唯一
4.6 CGA 解析与几何执行层
这是自研解析器的核心,需要独立完成 CityEngine 的解释器功能。
4.6.1 核心数据结构
class Shape:
symbol: str
geometry: Mesh
scope: Scope # 局部坐标系 + 尺寸
pivot: Transform
material: Material
attributes: dict
class Scope:
origin: Vector3
axes: Matrix3 # X/Y/Z 局部轴
size: Vector3
class Operation:
name: str
params: list
branches: list # 用于 split / comp / case
4.6.2 解释器执行流程
- 解析:用 ANTLR/TextX 生成 CGA AST。
- 实例化初始 Shape:从 footprint 或基本体开始。
- 规则匹配:根据 Symbol 查找规则。
- 操作执行:对 Shape 应用操作,生成新 Shape 列表。
- 递归展开:直到没有匹配规则或到达终端。
- 几何合并:收集所有叶节点几何,合并为最终 Mesh。
4.6.3 关键算法
| 操作 | 算法思路 |
|---|---|
extrude | 将多边形面沿法线/指定方向拉伸,生成侧壁和顶底面。 |
split | 沿 axis 的 scope 轴计算切割平面,用 BSP 或 clip 拆分几何。 |
comp(f) | 识别几何体的面法线,按朝向(front/back/top/...)分组。 |
s() / t() / r() | 修改当前 Shape 的 scope 变换矩阵。 |
i() | 加载外部 OBJ/glb 模型,缩放到当前 scope。 |
color/texture | 更新 Shape 的材质属性。 |
4.6.4 输出格式
- Web 预览:glTF/GLB 供 Three.js / Cesium 加载。
- 标准模型:OBJ、FBX、DAE。
- 城市数据:CityJSON(需额外转换)。
4.7 多领域扩展设计
CGA 本身以建筑为核心,但通过统一 Semantic IR + 多后端编译器,可扩展到其他领域。
| 领域 | 规则范式 | 目标 DSL / 引擎 | 关键参数 |
|---|---|---|---|
| 建筑 | CGA Shape Grammar | 自研 CGA 解释器 | 楼层、立面、屋顶、材质 |
| 植物 | L-system / 参数化 B-spline | 自研植物生成器 | 分枝规则、叶序、高度、冠幅 |
| 道路网络 | 生长图 / OSM 图 | 道路图 + CGA 道路规则 | 车道宽度、街区大小、道路等级 |
| 城市家具 | 模板实例化 + scatter | CGA i() / 自研 scatter | 类型、间距、朝向、密度 |
| 交通/车辆 | 行为规则 + 路径约束 | SUMO / 自定义模拟 | 流量、车道、信号灯 |
| 地形/水系 | 噪声 + 水文模拟 | 自定义生成器 | 高程、侵蚀、河流 |
4.7.1 领域编译器接口
class DomainCompiler(ABC):
@abstractmethod
def compile(self, semantic_ir: SemanticIR) -> RuleIR:
pass
class BuildingCompiler(DomainCompiler): ...
class PlantCompiler(DomainCompiler): ...
class StreetCompiler(DomainCompiler): ...
class FurnitureCompiler(DomainCompiler): ...
4.7.2 场景级组合
最终城市场景生成借鉴 CityEngine / CityX 的多阶段流水线:
道路网络生成
→ 地块划分(parcelization)
→ 建筑生成(per-lot CGA)
→ 绿化/家具 scatter(基于道路与建筑上下文)
→ 交通/行人层(可选)
→ 地形/水系融合
4.8 实施路线图
| 阶段 | 周期 | 目标 | 交付物 |
|---|---|---|---|
| Phase 1: MVP | 4–6 周 | 建筑单体生成 | NL → Semantic IR → CGA → Web GLB 预览 |
| Phase 2: 约束与风格 | 6–8 周 | 约束求解、风格库、参数编辑 | 风格模板库 + 约束求解器 + 用户反馈闭环 |
| Phase 3: 多领域扩展 | 8–10 周 | 植物、家具、街道 | PlantCompiler / FurnitureCompiler / StreetCompiler |
| Phase 4: 城市场景 | 10–12 周 | 完整城市场景生成 | 道路 → 地块 → 建筑 → 绿化 → 交通全链路 |
| Phase 5: 产品化 | 持续 | 性能优化、SaaS 化、协作 | 多租户、版本管理、API 开放 |
Phase 1 详细任务
- 完成 CGA 词法/语法解析器(ANTLR4 文法)。
- 实现 Shape、Scope、Pivot 核心数据结构。
- 实现 extrude、split、comp、s/t/r、color、texture 等核心操作。
- 设计 Semantic IR 与 Rule IR Schema。
- 基于 LLM 实现 NL → Semantic IR(Prompt + Few-shot)。
- 为建筑领域预置 3–5 个模板(现代办公楼、住宅、商业综合体)。
- FastAPI 后端:上传 footprint、生成 CGA、执行几何、返回 GLB。
- 前端 Three.js 预览 + 参数面板。
五、系统架构与工程实施详案
本节把第四章的技术方案进一步落地,给出可直接指导开发的系统架构图、子系统职责、数据流、子域名规划、立即执行的任务清单以及里程碑排期。
5.1 总体架构图
flowchart TB
subgraph User["用户层"]
U1[Web 浏览器 / 移动设备]
U2[第三方 API 调用方]
end
subgraph CDN["边缘层"]
C1[Caddy 反向代理
80/443 + on-demand TLS]
end
subgraph App["应用层 (FastAPI + Web)"]
A1[Web 前端
Three.js / React]
A2[FastAPI 主服务
REST + WebSocket]
A3[认证 / 租户 / 项目管理]
end
subgraph Core["核心引擎层"]
N1[NL 理解模块
LLM + NER + 风格本体]
S1[Semantic IR
领域无关语义描述]
R1[Rule IR
结构化规则推导树]
CGA1[CGA 生成器
模板引擎 + 语法校验]
INT1[CGA 解释器
Shape / Scope / Operation]
GEO1[几何引擎
Extrude / Split / Comp]
OUT1[输出器
GLB / OBJ / CityJSON]
end
subgraph Domain["领域编译器"]
D1[BuildingCompiler]
D2[PlantCompiler]
D3[StreetCompiler]
D4[FurnitureCompiler]
D5[TransportCompiler]
end
subgraph Asset["资产与数据层"]
DB1[(PostgreSQL
项目 / 用户 / 版本)]
DB2[(Redis
缓存 / 队列)]
FS1[文件存储
CGA / GLB / Texture]
LIB1[规则模板库]
LIB2[模型资产库]
end
U1 --> C1
U2 --> C1
C1 --> A1
C1 --> A2
A1 --> A2
A2 --> N1
A2 --> S1
A2 --> R1
A2 --> CGA1
A2 --> INT1
A2 --> GEO1
A2 --> OUT1
A2 --> A3
N1 --> S1
S1 --> R1
R1 --> CGA1
CGA1 --> INT1
INT1 --> GEO1
GEO1 --> OUT1
R1 --> D1
R1 --> D2
R1 --> D3
R1 --> D4
R1 --> D5
D1 --> CGA1
D2 --> CGA1
D3 --> CGA1
D4 --> CGA1
D5 --> CGA1
A2 --> DB1
A2 --> DB2
A2 --> FS1
A2 --> LIB1
A2 --> LIB2
5.2 子系统职责与数据流
| 子系统 | 技术栈 | 核心职责 | 输入 / 输出 |
|---|---|---|---|
| Web 前端 | React / Three.js / WebGL | 自然语言输入、参数面板、3D 预览、项目列表 | 输入:用户文本 / 草图;输出:HTTP 请求 |
| FastAPI 主服务 | Python / FastAPI / Pydantic | 路由、认证、租户隔离、任务调度、文件服务 | 输入:HTTP/WebSocket;输出:JSON / GLB / CGA |
| NL 理解模块 | OpenAI / Claude / 自研 NER | 意图分类、实体抽取、单位归一化、缺失补全 | 输入:自然语言;输出:Semantic IR |
| Semantic IR | JSON Schema / Pydantic | 领域无关的实体描述(是什么、在哪里、多大、什么风格) | 输入:语义 JSON;输出:Rule IR |
| Rule IR | 自定义 AST / YAML | 结构化规则推导树、约束求解、模板选择 | 输入:Semantic IR;输出:AST |
| 领域编译器 | Python 策略模式 | 将 Semantic IR 映射为建筑 / 植物 / 街道 / 家具规则 | 输入:Semantic IR;输出:Rule IR |
| CGA 生成器 | Jinja2 / 模板引擎 | Rule IR → CGA 代码、语法校验、注释生成 | 输入:Rule IR;输出:.cga |
| CGA 解释器 | ANTLR4 / Python | 词法/语法解析、规则匹配、操作执行 | 输入:.cga;输出:Shape Tree |
| 几何引擎 | Python / Trimesh / PyMesh / 自研 | extrude / split / comp / transform / boolean | 输入:Shape Tree;输出:Mesh |
| 输出器 | pygltf / trimesh | 导出 GLB / OBJ / CityJSON / 截图 | 输入:Mesh;输出:文件 |
| 数据层 | PostgreSQL / Redis / MinIO/S3 | 持久化项目、用户、版本、缓存、队列 | — |
标准请求数据流
- 用户在前端输入自然语言描述并上传 footprint(可选)。
- FastAPI 接收请求,调用 NL 理解模块生成 Semantic IR。
- 根据
category选择对应 DomainCompiler(如 BuildingCompiler)。 - DomainCompiler 生成 Rule IR,并通过约束求解器校验尺寸、比例、退界。
- CGA 生成器将 Rule IR 编译为
.cga文件,同时进行语法校验。 - CGA 解释器加载 CGA,从初始 Shape 开始递归执行规则。
- 几何引擎执行每个操作,生成 Shape Tree 的叶节点几何。
- 输出器合并几何并导出 GLB,返回前端渲染。
5.3 子域名规划与分配
Caddy 已配置 on-demand TLS,任意子域名首次访问都会自动申请 Let's Encrypt 证书。以下是推荐用途:
| 子域名 | 用途 | 当前状态 | 备注 |
|---|---|---|---|
peyep.com | 主站 / 产品首页 | 已可访问 | 重定向到 HTTPS |
www.peyep.com | 主站 / 文档与报告 | 已可访问 | 当前报告页面 |
app.peyep.com | Web 应用主入口 | 已泛解析,待开发 | 用户工作台 |
api.peyep.com | REST / WebSocket API | 已泛解析,待开发 | 第三方接入 |
docs.peyep.com | 开发文档 / API 文档 | 已泛解析,待部署 | MkDocs / Swagger |
static.peyep.com | 静态资源 / CDN | 已泛解析,可选 | 后期配合 CDN |
test.peyep.com | 测试 / 演示环境 | 已泛解析,待部署 | 预发验证 |
status.peyep.com | 服务状态页 | 已泛解析,可选 | 运维监控 |
注意:目前所有子域名都通过同一套 Caddy 配置反向代理到 FastAPI。后续可按需在 Caddyfile 中拆分:例如 docs.peyep.com 指向静态文档目录,static.peyep.com 开启缓存。
5.4 马上可以开展的任务
以下任务无需等待额外资源,可立即启动:
任务 1:项目结构初始化
- 在
/root/peyep下创建cga_parserPython 包。 - 新增
app/routers/cga.py、app/services/。 - 安装依赖:
pip install antlr4-python3-runtime jinja2 trimesh pygltf python-multipart。
任务 2:CGA 子集词法/语法解析
- 定义 ANTLR4 文法
CgaSubset.g4,覆盖 attr/const/import/rule/extrude/split/comp/t/s/r/color/texture/case/else/NIL。 - 生成 Python 解析器,输出 AST。
- 用真实 CGA 文件做回归测试。
任务 3:核心数据结构
- 实现
Shape、Scope、Pivot、Material。 - 实现
Geometry抽象,基于 Trimesh 或自研 Mesh。 - 实现
Operation抽象类与注册表。
任务 4:核心几何操作
extrude:多边形拉伸生成体块。split:沿 axis 切割,支持绝对/相对/浮动/重复。comp(f):按面朝向分组。t/s/r:scope 变换。color / texture:材质设置。
任务 5:Semantic IR + 建筑模板
- 定义
Building、Facade、Floor、Roof的 JSON Schema。 - 预置 3 个模板:现代办公楼、低层住宅、商业裙楼。
- 打通:
JSON → Rule IR → CGA → GLB。
任务 6:NL 理解 MVP
- 基于 LLM Prompt + Few-shot 把中文建筑描述转为 Semantic IR。
- 示例:"5 层现代办公楼,底层商业,玻璃幕墙" → JSON。
- 新增 FastAPI 接口
POST /api/v1/nl/generate。
5.5 工程实施里程碑
| 里程碑 | 周期 | 目标 | 验收标准 |
|---|---|---|---|
| M1:CGA 引擎 MVP | 3–4 周 | 解析并执行简化版 CGA | 输入 .cga 文件,输出可渲染 GLB |
| M2:建筑模板闭环 | 3–4 周 | Semantic IR → CGA → Geometry | 支持 3 种建筑模板,前端可预览 |
| M3:自然语言入口 | 2–3 周 | NL → Semantic IR | 中文描述生成可用 CGA,成功率 >70% |
| M4:多领域扩展 | 4–6 周 | 植物、城市家具、街道 | 3 个新 DomainCompiler 上线 |
| M5:城市场景 | 4–6 周 | 道路 → 地块 → 建筑 → 绿化 | 可生成完整街区 GLB |
| M6:产品化 | 持续 | 多租户、付费、API 开放 | 注册用户可保存项目、导出资产 |
六、商业化产品架构与核心技术路线
本节从商业化生产角度出发,将平台拆分为 NL2CGA、cgajs、CGARuntime、viewer、全球数据底座 五大核心子产品,分别给出技术路线对比、持续进化策略以及与其他模块的接口契约。
6.1 产品定位与商业模式
peyep 的最终产品形态是 “AI 驱动的程序化三维城市建模平台”,面向城市规划、建筑设计、游戏地编、数字孪生、影视特效等行业。核心价值在于:用自然语言或简单参数快速生成可生产、可编辑、可导出的大规模三维模型。
| 子产品 | 对外形态 | 目标客户 | 商业化模式 |
|---|---|---|---|
| NL2CGA | API / Web 文本输入 | 设计师、开发者、AI 应用 | 按调用量、按模型复杂度、企业授权 |
| cgajs | 解析器 SDK / 库 | 三维工具开发商、GIS 厂商 | SDK 授权、按席位、按部署量 |
| CGARuntime | 几何生成引擎 | 游戏、数字孪生、城市规划 | 按计算时长、按输出资产数量 |
| viewer | Web 3D 预览组件 | 所有线上客户 | 免费 / 增值插件 |
| 全球数据底座 | GIS 底图服务 | 城市规划、国土、仿真 | 数据订阅、私有化部署 |
6.2 NL2CGA:自然语言转 CGA
核心问题:CGA 是 Esri 专有 DSL,LLM 预训练语料极少;直接端到端生成失败率高,无法用于生产。
6.2.1 技术路线对比
| 路线 | 核心思想 | 优点 | 缺点 | 商业化成熟度 |
|---|---|---|---|---|
| LLM 直接生成 | Prompt + Few-shot 直接输出 CGA | 上手快、表达自由 | 幻觉严重、语法错误多、难控 | 低 |
| 模板填充 | 预定义模板,NL 只选型和填参 | 可控、可解释、生产稳定 | 表达能力受限 | 高 |
| Semantic IR 中间层 | NL → 语义 IR → CGA | 解耦语义与代码、易验证迁移 | 需设计 IR schema、工程量大 | 中 |
| RAG + 样例 | 向量检索相关 CGA 片段后生成 | 降低幻觉、复用私有规则库 | 检索质量决定上限 | 中-高 |
| Agent + Critic 循环 | 生成 → 编译 → 评估 → 修复 | 自纠错、执行成功率高 | 延迟高、成本高 | 中(快速上升) |
| 多模态 | 文本 + 草图/图片共同输入 | 直观、可捕捉风格 | 数据稀缺、评估难 | 低-中 |
6.2.2 推荐架构:分层混合式 NL2CGA
flowchart LR
A[用户输入
文本/图片/草图/Footprint] --> B[多模态编码 + NLU]
B --> C[Semantic IR
建筑程序图]
C --> D[规划器 + RAG 检索]
D --> E[约束化 CGA 生成器]
E --> F[CGA 编译与执行]
F --> G[Critic / 评估器]
G -->|失败| E
G --> H[输出 .cga / .rpk + 3D 模型 + 说明]
6.2.3 持续进化与数据飞轮
flowchart LR
A[用户输入] --> B[生成 CGA]
B --> C[编译/渲染]
C --> D[用户验收/反馈]
D --> E[Bad Case 回收]
E --> F[微调/RLHF/SFT]
F --> A
- 显式/隐式反馈:点赞、星级、重生成次数、参数调整轨迹、最终是否导出。
- 评估指标:Compile Pass Rate、Runtime Success Rate、Geometry Validity、语义约束满足率、用户满意度。
- Bad Case 回收:按失败类型分桶,人工审核高价值案例,修正后入库。
- 模型迭代:收集高质量 (NL, IR, CGA) 三元组做 SFT;用编译/渲染结果作为奖励做 RLHF/DPO。
6.2.4 是否需要更多 CGA 文件?
结论:需要大量、合法、结构化的 CGA 语料。
| 来源 | 方式 | 授权注意 |
|---|---|---|
| 官方教程与示例 | CityEngine / PyPRT Examples | 多数 Apache 2.0,运行时需 CityEngine 许可 |
| 开源 GitHub 集合 | natowi/cga-collection 等 | 需严格审查 LICENSE |
| 购买/授权 | Esri Marketplace、vrbn studios | 按项目/席位授权 |
| 用户贡献 | 让客户上传 CGA/RPK 换取积分 | 必须签署 IP 授权 |
| 合成数据 | 基于模板变异 + LLM 反向描述 | 成本低,多样性受限于种子库 |
6.3 cgajs:CGA 解析器
核心目标:纯自研、不依赖 CityEngine 桌面软件,完整解析并执行 CGA 规则。
6.3.1 解析器架构
flowchart TB
A[CGA Source .cga] --> B[Lexer]
B --> C[Parser]
C --> D[AST Builder + Semantic Analyzer]
D --> E[IR / Bytecode Generator]
E --> F[Executor / Interpreter]
F --> G[Shape Tree / Mesh / GLB]
6.3.2 解析器工具对比
| 工具 | 优点 | 缺点 | 推荐阶段 |
|---|---|---|---|
| Lark | 纯 Python、语法直观、快速迭代 | 性能比 ANTLR 低 2~5 倍 | MVP 推荐 |
| ANTLR4 | 生态成熟、多目标生成 | 需维护 .g4 与运行时 | 中长期跨语言 SDK |
| PLY | 底层可控 | 手写工作量大、错误信息差 | 不推荐主力 |
| 手写递归下降 | 最高灵活性 | 开发慢、维护成本高 | 表达式求值补充 |
6.3.3 函数库分层覆盖策略
| 层级 | 覆盖内容 | 说明 |
|---|---|---|
| Tier 0 核心 | extrude、split、comp、s/t/r、color、texture、NIL、case/else、rand | 必须先实现,支撑 80% 建筑规则 |
| Tier 1 扩展 | roofGable、roofHip、offset、setback、innerRectangle、asset 函数、数组/字符串 | 支撑立面、屋顶、家具、植物 |
| Tier 2 高级 | inside/overlaps/touches、context 函数、geometry.area/volume、report、颜色工具 | 城市级约束与报告 |
6.3.4 如何持续完成解析 CityEngine 所有函数
- 以 780 个官方
.cga文件为“活规范”,建立解析回归测试。 - 每个函数实现为
OperationHandler,注册到 Executor。 - 建立函数覆盖矩阵,每实现一个函数就补充单元测试和 golden 测试。
- 对缺失函数实现“软失败”:打印警告、返回 NIL 或保持原 shape,保证解析器能跑通更多文件。
- 用 PyPRT 作为 golden 参考:对同一 CGA + 同一 footprint,对比顶点/面片/面积/体积/Hausdorff 距离。
6.4 CGARuntime:几何运行时
核心目标:将 CGA 规则执行结果转换为可渲染 Mesh,达到或接近 CityEngine 的生成效果。
6.4.1 几何内核路线对比
| 路线 | 优点 | 缺点 | 适合 CGA 吗? |
|---|---|---|---|
| CSG | 布尔可靠 | 无法处理 split/comp/UV | 不推荐 |
| BREP(OpenCASCADE) | 精度高、拓扑闭合 | 重、慢、split/comp 复杂 | 高精度后端 |
| 半边结构 | 拓扑清晰、适合面片编辑 | 布尔/offset 需自研或嫁接 | 推荐主核 |
| Trimesh + Manifold | 生态成熟、输出方便 | split/comp 需重建拓扑 | 推荐最终网格后端 |
| CGAL | 数值鲁棒、算法完备 | API 重、与 CGA 语义不完全对齐 | 推荐关键算法库 |
6.4.2 推荐方案:混合内核
flowchart TB
A[CGARuntime Geometry Kernel] --> B[Shape Tree + Scope + Half-edge Mesh]
B --> C[CGAL 2D Offset
Straight Skeleton
Arrangement]
B --> D[Manifold Boolean
Watertight]
B --> E[OpenCASCADE
BRep 高精度]
6.4.3 关键操作实现要点
- extrude:多边形面沿法向拉伸,生成侧面和顶底面,维护 hole 拓扑。
- split:处理绝对、相对(')、浮动(~)、重复(*)四种尺寸,用平面裁剪几何。
- comp(f):按面法线在 scope/对象/世界坐标系下的象限分组。
- offset / setback / innerRectangle:嫁接 CGAL 2D 偏移与直骨架算法。
- boolean:闭合流形体用 Manifold;高精度场景用 OpenCASCADE。
6.4.4 如何达到 CityEngine 效果
| 维度 | CityEngine | CGARuntime 对标 |
|---|---|---|
| 精度 | double,容差 1e-7 | 全程 double,顶点合并容差 1e-6~1e-7 |
| 拓扑 | 保持 firstEdge、面顺序、孔方向 | 记录并传播 firstEdge,维护半边/面邻接 |
| UV | 多 UV set、scope/world 投影、tile 平铺 | 实现 setupProjection/projectUV/tileUV 全链路 |
| 材质 | PBR + 多通道纹理 | GLB 2.0 PBR 材质,face → material 索引 |
| 标签/报告 | tag、report、自动标签 | 在 face/edge/vertex 维护 tag 属性 |
6.4.5 输出格式
- GLB/glTF 2.0:Web 预览首选,支持 PBR、Draco、实例化。
- OBJ:快速 DCC 互操作。
- FBX:导入 Maya/3ds Max/UE。
- CityJSON:与 GIS/CIM 平台对接。
- 3D Tiles:大场景 Web 发布(Cesium)。
6.5 viewer:三维渲染引擎
核心问题:自研渲染器还是使用当下通用引擎?
6.5.1 渲染引擎对比
| 引擎 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| Three.js | 生态最大、包体小、与 React/Vue 集成好 | 城市级性能需自行优化 | 单体建筑预览首选 |
| CesiumJS | GIS/城市级 3D Tiles 标准、地形影像原生 | 单模型精致度不如 Three.js | 城市级 GIS 首选 |
| Babylon.js | 功能全、开箱即用 | 包体较大 | 复杂交互场景 |
| Filament | PBR 质量顶尖 | 缺乏 scene graph 和 Web 生态 | 高端移动 PBR |
| PlayCanvas | 运行时极小、移动端优化好 | GIS/3D Tiles 弱 | 移动端/低端设备 |
| Unity WebGL | 功能完整 | 包体大、授权成本高 | 已有 Unity 资产 |
| Unreal Pixel Streaming | 画质天花板 | 云端 GPU 成本高、延迟大 | 高端展示 |
6.5.2 推荐方案
flowchart TB
A[viewer 分层架构] --> B[单体建筑预览
Three.js WebGPU + GLB PBR]
A --> C[城市级 GIS 预览
CesiumJS + 3D Tiles]
A --> D[移动端降级
PlayCanvas / Three.js WebGL]
B --> E[统一交换格式:glTF 2.0 / GLB]
C --> E
D --> E
结论:不要自研通用底层渲染器。 peyep 的核心价值在 CGA 解析与生成,viewer 应基于成熟引擎做应用层(相机控制、LOD、材质映射、城市流送)。
6.6 全球数据底座集成
核心目标:将 CGA 生成的建筑/城市模型放入真实的全球地理环境中,支持遥感影像、DEM、全球矢量数据。
6.6.1 数据源对比
| 数据类型 | 开放数据源 | 商业数据源 | 推荐 |
|---|---|---|---|
| 遥感影像 | Sentinel-2、Landsat | Mapbox Satellite、Bing/Azure、Google Earth Engine | 开放 + 商业城市级补充 |
| DEM | SRTM、AW3D30、NASADEM | Cesium World Terrain、Mapbox Terrain | 开放 30m + 商业高精度 |
| 矢量 | OpenStreetMap、Natural Earth | Mapbox/Here/Google 矢量瓦片 | OSM + Protomaps 自托管 |
| 3D 建筑 | Cesium OSM Buildings | Google Photorealistic 3D Tiles | OSM 白模 + Google Premium |
6.6.2 集成方案:分阶段混合架构
flowchart TB
A[CGA 输出局部坐标] --> B[Footprint 中心 → WGS84]
B --> C[ENU 原点]
C --> D[建筑顶点 ENU → ECEF]
D --> E[CesiumJS 渲染]
F[遥感影像] --> E
G[DEM 地形] --> E
H[OSM 矢量] --> E
6.6.3 坐标系统处理
- WGS84(EPSG:4326):数据存储与交换标准。
- Web Mercator(EPSG:3857):Web 瓦片显示。
- ECEF(EPSG:4978):CesiumJS 内部 3D 渲染坐标。
- ENU:以 footprint 中心为原点的局部工程坐标,适合 CGA 建模。
6.6.4 商业化成本与合规
- Cesium ion:Community 仅限非商业;商业产品需 Commercial/Enterprise。
- Mapbox v2+:闭源商业许可,商业部署需购买授权。
- Google 3D Tiles:按 root tile 计费,注意刷新页面会重复计费。
- OSM:ODbL 协议,可商用但需署名;作为 Produced Work 展示通常只需署名。
6.7 子域名与微服务规划
基于商业化拆分,建议子域名按子产品/环境分配:
| 子域名 | 用途 | 对应模块 | 当前状态 |
|---|---|---|---|
peyep.com | 主站 / 产品首页 | 营销页 | 已上线 |
www.peyep.com | 文档与报告 | Static / FastAPI | 已上线 |
app.peyep.com | Web 应用主入口 | viewer + 工作台 | 待开发 |
api.peyep.com | REST / WebSocket API | FastAPI 主服务 | 待开发 |
nl2cga.peyep.com | 自然语言转 CGA 服务 | NL2CGA 微服务 | 待开发 |
cgajs.peyep.com | CGA 解析器服务/API | cgajs 微服务 | 待开发 |
runtime.peyep.com | 几何生成引擎 | CGARuntime 微服务 | 待开发 |
viewer.peyep.com | 三维渲染组件与示例 | viewer SDK | 待开发 |
data.peyep.com | 全球数据底座服务 | GIS 数据代理 | 待开发 |
docs.peyep.com | 开发文档 / API 文档 | MkDocs / Swagger | 待部署 |
test.peyep.com | 测试 / 演示环境 | Staging | 待部署 |
status.peyep.com | 服务状态页 | 运维监控 | 可选 |
6.8 近期可实施任务清单
以下任务可立即启动,不依赖外部资源:
任务 1:项目结构初始化
- 创建
/root/peyep/cgajs、/root/peyep/nl2cga、/root/peyep/cga_runtime、/root/peyep/viewer目录。 - 新增
app/routers/{nl2cga,cgajs,runtime,viewer}.py。 - 安装依赖:
lark antlr4-python3-runtime jinja2 trimesh manifold3d pygltf。
任务 2:cgajs MVP
- 用 Lark 编写
CgaGrammar.lark,能解析 780 个官方 CGA 文件并生成 AST。 - 实现 Shape/Scope/Pivot 与 extrude/comp/split/s/t/r/color。
- 跑通第一个案例:
Tutorial_06_简单建筑 → GLB。
任务 3:NL2CGA MVP
- 定义 Semantic IR JSON Schema(Building/Facade/Floor/Roof)。
- 用 LLM Prompt + Few-shot 把中文描述转为 Semantic IR。
- 预置 3 个建筑模板,实现 Semantic IR → CGA。
任务 4:viewer MVP
- 用 Three.js WebGPU 搭建 GLB 加载与 PBR 预览页面。
- 提供参数面板,可调整高度、层数、材质。
- 部署到
viewer.peyep.com。
任务 5:全球数据底座原型
- 用 CesiumJS + Cesium ion 搭建最小地球场景。
- 将 CGA 生成建筑通过 ENU→ECEF 放置到地形上。
- 部署到
data.peyep.com或app.peyep.com/earth。
6.9 完整开发路线图
| 阶段 | 周期 | 核心目标 | 关键交付 |
|---|---|---|---|
| Phase 0:基础设施 | 2–3 周 | 域名、SSL、CI/CD、项目结构、依赖 | 子域名规划完成,模块目录建立,FastAPI 路由拆分 |
| Phase 1:cgajs 核心 | 6–8 周 | 解析并执行 CGA 核心子集 | 780 个官方 CGA 可解析,简单建筑可生成 GLB |
| Phase 2:CGARuntime 几何 | 6–8 周 | 几何内核与 CityEngine 效果对标 | extrude/split/comp/offset/roof/boolean 齐全,golden 测试通过 |
| Phase 3:NL2CGA | 4–6 周 | 自然语言生成可用 CGA | 3 类建筑模板 + LLM 语义抽取,成功率 >70% |
| Phase 4:viewer | 3–4 周 | Web 3D 预览组件 | Three.js + CesiumJS 双 viewer,支持 GLB/3D Tiles |
| Phase 5:全球底座 | 4–6 周 | CesiumJS + 开放数据底座 | 建筑可放置到真实地形,支持 OSM 道路/水系 |
| Phase 6:多领域扩展 | 6–8 周 | 植物、家具、街道、交通 | 4 个新 DomainCompiler 上线 |
| Phase 7:商业化 | 持续 | 多租户、付费、API、SLA | SaaS 平台上线,对外开放 API |
七、Golden 测试、CGA 语料消耗与产品界面方案
在前两章确定商业化架构与技术路线后,本章给出三个关键落地问题的具体方案:① 如何用 Esri PyPRT 作为 cgajs 的 golden 参考进行几何对比;② 如何系统地消耗 CityEngine 官方 780 个 CGA 文件,并建立基于 LLM 的自我迭代学习系统;③ 为 10 个子域名产品细化菜单、功能模块与界面布局。
7.1 PyPRT 作为 cgajs Golden 参考
7.1.1 PyPRT 与 PRT 关系及授权
PyPRT 是 Esri CityEngine 底层 PRT(Procedural Runtime) 的 Python 绑定,它调用 CityEngine 真正的 CGA 执行引擎生成三维模型。关键点:
- PyPRT 只能消费
.rpk规则包,不能直接读取原始.cga文本;.rpk内部包含编译后的.cgb、纹理与资产。 - CityEngine 版本必须与 PyPRT 版本匹配,否则会出现
CGAC version不兼容警告。 - 授权:个人/教育/非商业免费;商业用途需要组织至少持有一份最新 CityEngine 商业许可。禁止将 PyPRT 再分发或以 Web 服务形式对外提供,除非获得 Esri 书面许可。
对 cgajs 的启示
PyPRT 只能用于内部 golden 测试与 CI 验证,绝不能成为 cgajs / CGARuntime 产品的运行时依赖或对外服务依赖。 golden 几何文件可保留在测试仓库,但生产镜像中不得包含 PyPRT 与 PRT 二进制。
7.1.2 从 .cga 到 .rpk
使用 CityEngine Python API 将官方 .cga 打包为 .rpk:
from scripting import *
ce = CE()
settings = RPKExportSettings()
settings.setRuleFile("/my_project/rules/building.cga")
settings.setFile(ce.toFSPath("/my_project/output/building.rpk"))
settings.setAddFilesAutomatically(True) # 自动收集引用资产
settings.setIncludeSourceFiles(True) # 保留 .cga 源文件
settings.setCompatibility(RPKExportSettings.DEFAULT)
ce.exportRPK(settings)
打包后,将 .rpk 放入 tests/fixtures/rules/,作为 golden 对比的权威输入。
7.1.3 InitialShape 与 generate_model API
PyPRT 的核心调用链为:InitialShape → ModelGenerator → generate_model。
import pyprt, os
# 1. footprint:y-up,逆时针
footprint = [0,0,0, 10,0,0, 10,0,10, 0,0,10]
shape = pyprt.InitialShape(footprint)
# 2. 查询 RPK 暴露的属性
info = pyprt.get_rpk_attributes_info(os.path.abspath("building.rpk"))
print(info.keys())
# 3. 配置属性与起始规则
attrs = {
"shapeName": "golden_building",
"seed": 42,
"buildingHeight": 15.0,
"ruleFile": "bin/rule.cgb",
"startRule": "Default$Init"
}
# 4. 生成模型
m = pyprt.ModelGenerator([shape])
models = m.generate_model(
[attrs],
os.path.abspath("building.rpk"),
"com.esri.pyprt.PyEncoder",
{"emitGeometry": True, "emitReport": False, "triangulate": True}
)
model = models[0]
print(len(model.get_vertices()), len(model.get_faces()))
7.1.4 导出 OBJ/GLB 参考模型
通过内置 OBJEncoder / GLTFEncoder 导出完整材质、UV、法线:
out_dir = os.path.abspath("output/golden")
os.makedirs(out_dir, exist_ok=True)
# OBJ
m.generate_model(
[attrs], os.path.abspath("building.rpk"),
"com.esri.prt.codecs.OBJEncoder",
{"outputPath": out_dir, "baseName": "golden", "triangulateMeshes": True}
)
# GLB
m.generate_model(
[attrs], os.path.abspath("building.rpk"),
"com.esri.prt.codecs.GLTFEncoder",
{
"outputPath": out_dir, "baseName": "golden",
"outputFormat": "GLTF_GLB_WITH_SINGLE_BUFFER",
"includeMaterials": True
}
)
7.1.5 几何对比指标与代码示例
对同一 footprint + 同一 CGA,同时用 cgajs 与 PyPRT 生成模型,计算以下指标:
| 指标 | 用途 | 工具 |
|---|---|---|
| 顶点数 / 面数 | 快速发现拓扑差异 | trimesh |
| 表面积 | 验证 extrude / split 尺度 | trimesh.area |
| 体积(封闭体) | 验证实体布尔与封闭性 | trimesh.volume |
| AABB 包围盒 | 验证坐标系与平移缩放 | trimesh.bounds |
| 对称 Hausdorff | 形状最大偏差 | scipy.spatial.distance.directed_hausdorff |
| Chamfer 距离 | 表面平均偏差 | scipy.spatial.cKDTree |
| SSIM / PSNR | 同视角渲染图对比 | pyrender + skimage |
import trimesh, numpy as np
from scipy.spatial import cKDTree
from scipy.spatial.distance import directed_hausdorff
def sample_surface(mesh, n=20000):
return mesh.sample(n)
def hausdorff_distance(a, b, n=20000):
pa, pb = sample_surface(a, n), sample_surface(b, n)
return max(directed_hausdorff(pa, pb)[0], directed_hausdorff(pb, pa)[0])
def chamfer_distance(a, b, n=20000):
pa, pb = sample_surface(a, n), sample_surface(b, n)
return (cKDTree(pb).query(pa)[0].mean() + cKDTree(pa).query(pb)[0].mean()) / 2
golden = trimesh.load("golden_0.obj", force="mesh")
ours = trimesh.load("cgajs_building.obj", force="mesh")
print("hausdorff:", hausdorff_distance(golden, ours))
print("chamfer:", chamfer_distance(golden, ours))
print("area ratio:", ours.area / golden.area)
阈值建议:Hausdorff < 0.05 m、面积误差 < 1%、顶点数偏差 < 5%(triangulate 策略差异可导致面数不同,需结合 Hausdorff 判断)。
7.1.6 CI 集成与授权隔离
推荐把 PyPRT golden 测试限定在 tests/golden/ 与 self-hosted CI runner:
- runner 必须持有 CityEngine 商业许可。
- RPK 与 golden OBJ 版本锁定,文件名带 PyPRT / CityEngine 版本号。
- 生产 Docker 镜像不安装 PyPRT,避免授权违规。
- 当版本不匹配时,用 CityEngine CLI 批量导出静态 OBJ 作为临时 golden。
7.2 官方 780 CGA 文件的全流程消耗
7.2.1 语料画像与分类
对 780 个官方 CGA 建立 Capability Profile:
{
"file": "Building.cga",
"domain": "Building",
"version": "2017.1",
"lines": 460,
"rules": 35,
"ops": {"extrude": 5, "split": 40, "comp": 12, "setupProjection": 80},
"builtin_funcs": {"rand": 20, "floor": 5},
"imports": ["Referenced/Three_Part_Texturing.cga"],
"assets": ["*.jpg", "facades/..."]
}
分类维度包括:
- 领域:建筑 ~271、街道 ~75、植物 ~27、家具 ~5、其他 ~396。
- 复杂度:L1 入门(<100 行)、L2 标准(100–500 行)、L3 复杂(500–2000 行)、L4 专家(>2000 行)。
- 操作签名:高频操作为
setupProjection(10,563 次)、projectUV(10,558 次)、split(6,054 次)、comp(1,359 次)、extrude(902 次)。 - 版本:2010.3 ~ 2025.1,约 290 个文件未声明 version。
7.2.2 四级测试流水线
flowchart LR
A[Raw CGA] --> B[L0 解析测试
生成 AST]
B --> C[L1 语义测试
符号表完整]
C --> D[L2 执行测试
生成几何]
D --> E[L3 对比测试
与 PyPRT 对比]
| 级别 | 目标 | 关键断言 |
|---|---|---|
| L0 | 解析器能生成 AST | 无语法错误、无未识别 token |
| L1 | 语义完整 | attr/const/规则引用可解析、import 成功、无循环依赖 |
| L2 | 能生成几何 | 顶点数 > 0、无 NaN、无崩溃 |
| L3 | 与官方输出一致 | Hausdorff / 面积 / 体积在阈值内 |
7.2.3 AI 自我迭代闭环
flowchart TD
A[扫描 780 CGA 生成画像] --> B[批量跑 L0/L1/L2/L3]
B --> C[失败分类器]
C --> D[LLM 根因分析]
D --> E[LLM 生成修复]
E --> F[应用 patch 到沙盒分支]
F --> G[重跑四级测试]
G -->|通过| H[A/B 对比与人工审核]
G -->|失败| D
H --> I[合并到主分支]
LLM 接收的上下文包括:失败文件路径、错误行、错误类别、相关代码片段、能力画像、类似成功案例、解析/执行日志。LLM 输出修复提案(JSON patch),由脚本自动 apply 并在临时 worktree 中验证。
7.2.4 失败分类与根因分析
| 类别 | 示例 | 修复方向 |
|---|---|---|
| 语法错误 | version "2025.1" 未识别、概率语法 60% : | 扩展 Lark grammar |
| 语义错误 | import 路径解析失败、规则未定义 | 语义分析器 / import 解析 |
| 几何错误 | split 产生零面积面、comp(f) 在非流形几何失败 | 实现 OperationHandler |
| 资产缺失 | 纹理/OBJ 引用不存在 | 资产索引、占位材质 |
| 版本不兼容 | 旧版语法或废弃操作 | 版本适配层 |
| 随机差异 | rand() 导致与参考不一致 | 固定种子、概率可重复 |
7.2.5 A/B 回归保护
任何 AI 生成的修复必须通过 A/B 对比:
- 新通过文件数 > 0。
- 原通过文件无新增失败。
- 总体解析成功率不下降。
- grammar 核心改动必须人工 approve;新增 OperationHandler 抽样 review;测试用例/文档可自动合并。
python scripts/ab_compare.py \
--baseline main \
--candidate fix-branch \
--report reports/ab_2026_06_19.json
7.2.6 CGA 知识图谱
从语料中提取三层知识库:
- 函数依赖图:操作 → 文件、规则 → 规则、import → 被引用规则。
- 模板模式库:Box-Extrude-Facade-Split、Massing-LU-Shape、Texture-Projection-Paint、Street-Lane-Marking、Plant-Loader。
- 错误模式库:正则 + 修复提示,用于快速分类失败。
7.2.7 商用可行性评估
仅依靠官方 780 个文件,能够做到:
- 语法覆盖:90%+ 核心语法,但边缘语法(
@Handle、inline、extension)不足。 - 操作覆盖:78 个 CGA 操作中约 40 个有真实用例;未出现的操作需按文档补全。
- 函数覆盖:约 42 个 builtin 函数有真实用例;CGA 总 builtin 函数 100+,需文档驱动实现。
- 领域覆盖:建筑/街道较强,植物/家具/交通较弱。
结论:780 个官方文件是极佳种子语料,可支撑 L0 60–70% 文件通过、L2 30–40% 文件通过 的 MVP;要达到商业化可用,必须扩展至数千真实项目文件、补充官方文档作为 ground truth、引入用户反馈闭环。
7.3 子域名菜单与界面设计方案
为 10 个子域名产品统一设计深色科技风界面,主色 #0A84FF、背景 #0F1419、表面 #1A1F26,桌面端左侧 240px 侧边栏 + 右侧主内容,移动端折叠为抽屉或底部 Tab。
7.3.1 全局设计系统
| 角色 | 色值 | 用途 |
|---|---|---|
| 品牌主色 | #0A84FF | 按钮、链接、高亮 |
| 背景主色 | #0F1419 | 页面背景、画布外框 |
| 表面色 | #1A1F26 | 卡片、面板、输入框 |
| 成功 | #28C76F | 运行成功 |
| 警告 | #F5A623 | 参数异常 |
| 错误 | #EA4E43 | 报错、失败 |
通用快捷键:Ctrl+K 全局搜索、Ctrl+Enter 运行/生成/解析、Ctrl+S 保存。状态栏统一显示服务健康、版本、坐标、操作提示。
7.3.2 peyep.com / www.peyep.com
- 定位:品牌门户、产品总览、技术报告与博客入口。
- 顶部导航:产品 · 解决方案 · 文档 · 报告 · 定价 · 博客 · 关于我们 · 登录/试用。
- 首页模块:Hero 大标题、6 大产品矩阵卡片、能力展示三段式、最新报告入口、应用场景、页脚。
- 报告页:左侧目录树 + 右侧 Markdown 渲染 + 顶部工具栏(字体/主题/分享/打印)。
7.3.3 app.peyep.com
- 定位:统一工作台,管理项目、资产、任务与团队协作。
- 顶部导航:工作台 · 项目 · 资产 · 团队 · 应用市场 · 设置。
- 侧边栏:我的项目 / 最近打开 / 收藏 / 回收站;全部项目 / 与我共享 / 模板库;模型 / 材质 / CGA 规则 / 数据源。
- 工作台:快捷入口(新建项目 / 导入 CGA / NL2CGA / 打开 viewer)、最近项目卡片、数据看板、活动流、推荐模板。
- 项目详情页:左侧资源树、中部编辑器/预览标签页、右侧属性检查器 + 参数面板、底部状态栏。
7.3.4 api.peyep.com
- 定位:REST / WebSocket API 文档、SDK 下载、开发者控制台。
- 顶部导航:文档 · 参考 · 控制台 · SDK · 定价 · 状态。
- 侧边栏:快速开始(认证 / 基础 URL / 错误码);API 参考(NL2CGA / CGA 解析 / 几何生成 / Viewer / 数据底座);WebSocket;SDK(Python / JS / CLI);控制台(应用 / Key / 用量 / 账单)。
- API 参考页:左侧端点目录、中部请求说明 + 参数表、右侧代码示例 + “在控制台测试”按钮。
7.3.5 nl2cga.peyep.com
- 定位:自然语言生成 CGA,降低程序化建模门槛。
- 顶部导航:生成器 · 我的规则 · 模板 · 语法检查 · 定价。
- 布局:左侧模板/历史侧边栏;中部大输入区 + 生成按钮 + CGA 输出区;右侧参数面板(模型、风格、复杂度、输出语言)。
- 交互:输入框支持
/唤起模板;生成后可一键“运行到 Runtime”;语法错误红色下划线 + 修复建议。
7.3.6 cgajs.peyep.com
- 定位:在线 CGA 解析、调试、AST 可视化与规则游乐场。
- 顶部导航:游乐场 · 解析器 · AST · 函数库 · 测试套件 · 文档。
- 布局:左侧文件树;中部 Monaco/CodeMirror 编辑器 + 控制台;右侧解析结果面板(AST JSON / 语法错误 / 符号表 / 性能)。
- 交互:
Ctrl+Enter触发解析;错误行点击跳转;AST 节点悬停显示源码位置;一键导出 Lark/JSON。
7.3.7 runtime.peyep.com
- 定位:CGA 规则执行与几何生成服务,输出 GLB/OBJ/USD 等格式。
- 顶部导航:执行 · 流水线 · 模型库 · 性能 · 文档。
- 布局:左侧任务队列;中部输入区(CGA 代码 / Shapefile)+ 输出日志 + 模型预览;右侧参数面板(种子、LOD、格式、纹理开关)。
- 交互:运行中实时刷新日志;输出模型一键下载或发送到 viewer;失败任务显示错误堆栈。
7.3.8 viewer.peyep.com
- 定位:Web 端三维模型预览、场景搭建、渲染组件展示。
- 顶部导航:示例 · 组件 · 场景 · 文档 · 打开模型。
- 布局:左侧场景树;中部 WebGL/WebGPU 3D 画布;右侧属性面板 + 渲染设置。
- 交互:悬停显示属性、双击聚焦、右键菜单(隐藏/孤立/重置)、截图导出 PNG、嵌入代码生成。
7.3.9 data.peyep.com
- 定位:全球地形、影像、矢量、OSM 等开放数据聚合与瓦片服务。
- 顶部导航:数据目录 · 瓦片服务 · 数据集 · API · 控制台。
- 布局:左侧数据目录;中部 CesiumJS / MapLibre 全球地图 + 瓦片预览;右侧图层/属性面板。
- 交互:框选区域下载数据、复制瓦片 URL、将建筑数据一键发送到 runtime 生成模型。
7.3.10 docs.peyep.com
- 定位:peyep 全产品线开发文档、教程与 FAQ。
- 顶部导航:快速开始 · 教程 · API · 示例 · 更新日志 · 搜索。
- 布局:标准文档三栏(左侧目录树、中部 Markdown 正文、右侧当前页面大纲)。
- 内容:环境搭建、第一个 CGA、NL2CGA / cgajs / CGARuntime / viewer / 数据底座教程、API 参考、CGA 语法、函数库、错误码、FAQ。
7.3.11 test.peyep.com
- 定位:内部测试、功能演示、A/B 测试、客户沙盒。
- 顶部导航:演示 · 沙盒 · 测试集 · 报告 · 状态。
- 布局:环境状态看板、各子产品演示入口、沙盒列表、最近测试任务、快速操作(清空缓存 / 重置数据 / 生成报告)。
- 沙盒页:顶部环境信息 banner、左侧功能菜单、中部嵌入对应子产品简化版、右侧操作说明与参数。
八、最终整体方案与分阶段实施路线图
本章从整体网站结构、产品逻辑、运维部署三个维度进行诊断,给出最终整体架构,并细化每个阶段的具体任务、交付物与验收标准,供决策后按优先级实施。
8.1 当前架构问题诊断
8.1.1 网站与部署层
- 子域名无感知路由:Caddy 把所有子域名都反代到同一个 FastAPI 进程,但应用层未根据 Host 头区分产品,所有子域名显示同一首页。
- 首页与落地页缺失:
web/index.html只是占位标题;没有与报告第六章、第七章设计对应的子产品落地页。 - 开发模式不适合生产:
scripts/start.sh使用--reload单 worker;缺少生产启动脚本、systemd 服务文件、日志轮转与进程守护。 - 缺少统一配置管理:没有环境变量/配置模块来区分 development / staging / production。
- 安全与性能基线缺失:未配置安全响应头、CORS、请求限流、静态资源缓存策略。
8.1.2 产品功能层
- API 空白:当前只有
/health、/ask、/updata.html,没有面向 NL2CGA / cgajs / Runtime / Viewer / Data 的实际 API。 - 路由与服务目录空转:
app/routers/、app/services/目录存在但为空,产品边界未在代码中落地。 - 缺少统一 API 前缀规范:各子产品接口若随意命名,后续拆分微服务时集成成本极高。
- 缺少子产品间调用链:NL2CGA → cgajs → Runtime → Viewer 的数据流尚未抽象为内部 API 调用。
- 缺少数据模型:没有用户、项目、资产、场景、模型版本等核心数据实体设计。
8.1.3 数据与运维层
- 持久化未设计:没有数据库、对象存储、缓存、消息队列的选型与接入。
- 可观测性不足:无结构化日志、指标监控、告警、分布式追踪。
- CI/CD 缺失:没有自动化测试、构建、部署流水线。
- 服务运行方式临时:FastAPI 当前跑在 tmux,未使用 systemd 等持久化机制。
- 备份与容灾:未定义数据备份、灾难恢复、回滚策略。
8.2 最终整体架构
8.2.1 分层架构
flowchart TB
subgraph EDGE["边缘层"]
C[Caddy
TLS / gzip / 限流 / 缓存]
end
subgraph GATE["网关层"]
F[FastAPI Main
子域名识别 / Auth / 健康聚合]
end
subgraph PROD["产品层(模块化单体,可拆分)"]
W[www]
A[app]
AP[api]
N[nl2cga]
CJ[cgajs]
R[runtime]
V[viewer]
D[data]
DO[docs]
T[test]
end
subgraph SHARED["共享服务层"]
AUTH[Auth / SSO]
DB[(PostgreSQL)]
OBJ[(S3 / MinIO)]
CACHE[(Redis)]
Q[[Celery / RQ]]
end
subgraph FE["前端层"]
CSS[统一设计系统 CSS]
LP[子域名落地页]
SPA[产品 SPA]
end
C --> F
F --> W & A & AP & N & CJ & R & V & D & DO & T
W & A & AP & N & CJ & R & V & D & DO & T --> SHARED
W & A & AP & N & CJ & R & V & D & DO & T --> FE
8.2.2 子域名路由策略
采用「Caddy 统一接入 + FastAPI 应用层识别 Host」的渐进式方案:
- Caddy 为
*.peyep.com提供自动 HTTPS 并反代到127.0.0.1:8000;peyep.com裸域 301 永久重定向到www.peyep.com。 - FastAPI 中间件读取
Host头,解析当前子域名并写入request.state.subdomain。 /根据子域名返回对应落地页(web/{subdomain}/index.html,www与根域共用web/index.html)。- 所有子产品 API 统一前缀
/api/v1/{product}/...,未来拆分微服务时只需把前缀代理到新后端。 /api/v1/status聚合所有子产品健康状态,供test.peyep.com与监控使用。
8.2.3 核心数据流
sequenceDiagram
participant U as 用户
participant A as app.peyep.com
participant N as nl2cga
participant C as cgajs
participant R as runtime
participant V as viewer
participant D as data
U->>A: 创建项目 / 选择地块
A->>D: 获取 OSM / DEM / 建筑轮廓
A->>N: 自然语言描述 → CGA
N->>C: 校验 / 解析 CGA
C-->>N: AST / 语义结果
A->>R: 执行 CGA + footprint
R-->>A: GLB / 报告
A->>V: 预览模型 / 放置到地形
V-->>U: 交互式三维场景
8.3 已修复的基础问题
在本次整体审视中,已先对最明显的基础设施问题进行修复,形成后续开发的可扩展骨架:
| 问题 | 修复内容 | 文件 |
|---|---|---|
| 子域名无识别 | 新增 app/config.py 子域名注册表与解析函数;app/main.py 增加 Host 中间件 | app/config.py, app/main.py |
| API 空白 | 创建 10 个子产品 FastAPI Router 骨架,挂载到 /api/v1/{product} | app/routers/*.py |
| 首页占位 | 重写 web/index.html 为品牌门户,包含产品矩阵、最新报告入口、健康检测 | web/index.html, web/static/style.css |
| 落地页缺失 | 新增子域名落地页生成器 scripts/generate_landings.py,自动生成 9 个产品落地页 | scripts/generate_landings.py, web/*/index.html |
| 无生产启动 | 新增 scripts/start.prod.sh,使用多 worker 与 production 环境变量 | scripts/start.prod.sh |
| 依赖未规划 | 整理 requirements.txt,区分 Web 框架与后续可选依赖 | requirements.txt |
| 全局健康缺失 | 新增 /api/v1/status 聚合接口,返回所有子产品状态 | app/main.py |
8.4 分阶段实施路线图
以下阶段按依赖关系排列,可根据资源与优先级调整。每个阶段给出目标、周期、具体任务、交付物与验收标准。
8.4.1 Phase 0:基础架构与门户(2 周)
目标:让 10 个子域名都有独立落地页和基础 API,建立可扩展、可观测、可部署的工程骨架。
| 序号 | 具体任务 | 交付物 |
|---|---|---|
| 1 | 统一配置管理:环境变量 .env + app/config.py 区分 dev/staging/prod | .env.example, app/config.py 完善 |
| 2 | Caddy 增强:添加 gzip 缓存头、基础限流、静态文件缓存策略 | Caddyfile 更新 |
| 3 | FastAPI 子域名中间件与路由表落地(已完成骨架) | app/main.py |
| 4 | 为每个子产品创建 app/routers/{product}.py 与 app/services/{product}.py 目录 | 10 套路由 + 服务骨架 |
| 5 | 沉淀统一设计系统 CSS,落地门户首页与 9 个产品落地页 | web/static/style.css, web/*/index.html |
| 6 | 编写 systemd 服务文件与生产启动脚本,配置日志轮转 | scripts/peyep.service, scripts/start.prod.sh |
| 7 | 接入结构化日志(structlog)与 /api/v1/status 健康聚合 | 日志配置、状态接口 |
| 8 | 建立 CI/CD 骨架:GitHub Actions 跑 lint、unit test、build | .github/workflows/ci.yml |
验收标准:curl https://*.peyep.com 全部返回 200 且风格统一;/api/v1/status 返回所有服务状态;CI 流水线通过。
8.4.2 Phase 1:cgajs 解析与 Golden 测试(6–8 周)
目标:自研 CGA 解析器可解析 780 个官方文件的核心子集,并用 PyPRT 建立 golden 几何对比基准。
| 序号 | 具体任务 | 交付物 |
|---|---|---|
| 1 | 用 Lark 编写 CGA grammar,覆盖 version / attr / const / import / rule / operation / case / probability | cgajs/grammar/cga.lark |
| 2 | 实现 AST 节点与解析器,跑 L0 解析测试并输出 780 文件通过率报告 | cgajs/parser.py, tests/test_l0_parse.py |
| 3 | 实现语义分析器:符号表、import 解析、规则引用检查 | cgajs/semantic.py, tests/test_l1_semantic.py |
| 4 | 实现 Shape / Scope / Pivot 与核心 OperationHandler:extrude / split / comp / t / s / r / NIL / color / texture | cga_runtime/shape.py, operations.py |
| 5 | 基于 trimesh / manifold3d 构建最小几何运行时,输出 GLB | cga_runtime/exporters/glb.py |
| 6 | 在持有 CityEngine 许可的环境安装 PyPRT,打包 5–10 个核心建筑 CGA 为 .rpk | tests/fixtures/rules/*.rpk |
| 7 | 编写 golden 对比脚本:顶点数 / 面数 / 面积 / 体积 / AABB / Hausdorff / Chamfer | tests/test_l3_reference.py |
| 8 | cgajs.peyep.com 在线 playground:编辑器、解析、AST 可视化、函数库索引 | web/cgajs/index.html + API |
验收标准:70% Tutorial 文件 L0 通过;simpleBuilding 系列 L2 通过;与 PyPRT 的 Hausdorff 距离 < 0.05 m。
8.4.3 Phase 2:NL2CGA 自然语言生成(4–6 周)
目标:通过自然语言描述生成可执行的 CGA 规则,并以建筑为起点验证闭环。
| 序号 | 具体任务 | 交付物 |
|---|---|---|
| 1 | 定义 Semantic IR JSON Schema:Building / Facade / Floor / Roof / Window / Material | nl2cga/schemas/semantic_ir.json |
| 2 | 建立建筑模板库:现代办公楼、板式住宅、联排别墅、古典建筑、高层建筑 | nl2cga/templates/*.cga.j2 |
| 3 | 实现 LLM Prompt + Few-shot,把中文/英文描述转为 Semantic IR | nl2cga/llm.py |
| 4 | 实现 Semantic IR → CGA 代码生成器(Jinja2) | nl2cga/codegen.py |
| 5 | 引入 Critic:自动解析 + 执行生成结果,失败时反馈给 LLM 迭代 | nl2cga/critic.py |
| 6 | nl2cga.peyep.com UI:输入区、参数面板、CGA 输出、一键运行到 Runtime | web/nl2cga/index.html + API |
| 7 | 收集 100+ 条真实描述,评估生成成功率并迭代 | nl2cga/benchmarks/ |
验收标准:5 类建筑描述成功率 > 70%;生成 CGA 可通过 cgajs 解析并执行出有效 GLB。
8.4.4 Phase 3:Runtime 几何引擎与 Viewer(4–6 周)
目标:让几何生成结果稳定、高效,并在 Web 端可交互预览。
| 序号 | 具体任务 | 交付物 |
|---|---|---|
| 1 | 评估是否引入自研半边结构:MVP 阶段推荐先用 trimesh/manifold,复杂阶段再替换 | 技术决策文档 |
| 2 | 实现高级几何操作:offset / roof / setupProjection / projectUV / bool / mirror | cga_runtime/operations/advanced.py |
| 3 | 多格式导出器:GLB / OBJ / FBX / CityJSON / USD | cga_runtime/exporters/ |
| 4 | runtime.peyep.com 执行页面:上传 CGA / footprint / 参数 / 实时日志 / 下载 | web/runtime/index.html + API |
| 5 | Three.js WebGL/WebGPU viewer 组件:加载 GLB、PBR、相机控制、参数面板 | viewer/three-viewer.js |
| 6 | viewer.peyep.com 示例库:建筑、街道、植物、城市场景 | web/viewer/index.html |
| 7 | 材质与 UV 系统:纹理图集、PBR 参数、法线贴图 | cga_runtime/materials.py |
验收标准:任意 Tutorial 建筑 CGA → GLB → viewer 预览,视角切换流畅,材质正确。
8.4.5 Phase 4:数据底座与全局工作台(4–6 周)
目标:接入真实地理数据,实现项目/资产/场景管理,完成「地块 → 模型 → 地形」闭环。
| 序号 | 具体任务 | 交付物 |
|---|---|---|
| 1 | 数据库设计:User / Organization / Project / Asset / Scene / ModelVersion | app/models.py, Alembic migrations |
| 2 | 对象存储接入:S3 或 MinIO,存储 CGA / 纹理 / GLB / 瓦片缓存 | app/storage.py |
| 3 | app.peyep.com 工作台:项目列表、资源树、编辑器/预览标签页、属性检查器 | web/app/index.html + API |
| 4 | data.peyep.com:OSM 矢量、SRTM DEM、卫星影像瓦片代理与搜索定位 | web/data/index.html + API |
| 5 | 坐标转换服务:WGS84 / Web Mercator / ECEF / ENU | app/geo.py |
| 6 | CesiumJS 集成:将 Runtime 输出的建筑模型放置到真实地形 | viewer/cesium-viewer.js |
| 7 | 权限与协作:项目共享、角色、版本历史 | app/auth.py, app/permissions.py |
验收标准:用户在地图上选择真实地块 → NL2CGA → Runtime → Viewer 看到建筑立于真实地形。
8.4.6 Phase 5:API / Docs / Test 与商业化(3–4 周)
目标:对外开放稳定 API,完善文档与测试环境,引入多租户与基础计费。
| 序号 | 具体任务 | 交付物 |
|---|---|---|
| 1 | REST API 规范:OpenAPI/Swagger、版本控制、错误码统一 | api.peyep.com 文档 |
| 2 | WebSocket 实时通道:执行进度、viewer 协同 | app/routers/ws.py |
| 3 | api.peyep.com 开发者门户:注册、API Key、用量统计 | web/api/index.html + API |
| 4 | docs.peyep.com:使用 MkDocs 或 Docusaurus 构建文档站 | docs/ 目录 + 部署 |
| 5 | test.peyep.com:沙盒环境、A/B 测试、回归测试报告 | web/test/index.html + 测试流水线 |
| 6 | 用量统计与限流:按 API Key 计费、速率限制 | app/billing.py, app/rate_limit.py |
| 7 | 多租户与基础付费:组织隔离、套餐、账单 | app/tenant.py, 支付对接 |
验收标准:外部开发者可通过 API Key 完成一次 NL2CGA → Runtime 调用;docs 站上线;test 环境可重置。
8.4.7 Phase 6:微服务拆分与规模化(持续)
目标:根据实际负载与团队规模,将模块化单体拆分为独立服务,支撑商用负载。
| 序号 | 具体任务 | 交付物 |
|---|---|---|
| 1 | 按子产品拆分为独立容器/服务:nl2cga、cgajs、runtime、viewer、data | Dockerfile / K8s manifests |
| 2 | 引入消息队列与异步 Worker:Celery/RQ 处理长时几何生成 | workers/ 目录 |
| 3 | CDN + 对象存储优化:静态资源、模型文件、瓦片缓存 | CDN 配置 |
| 4 | GPU 推理节点:LLM 推理、实时渲染、路径追踪 | GPU 节点方案 |
| 5 | 多区域部署:降低延迟,满足数据合规 | 多 K8s 集群 |
| 6 | 企业级 SSO、审计日志、合规认证 | SSO 集成、审计系统 |
验收标准:平台 SLA 达到 99.5%,并发生成稳定,支持企业级 SSO 与审计。
8.5 子域名功能定位优化与冲突消解
在第八章前半部分确定技术路线后,需要回过头来审视 10 个子域名的功能定位,检查是否存在重叠、冲突或可合并的空间,并明确 peyep.com 与 www.peyep.com 的关系。
8.5.1 当前 10 个子域名定位回顾
| 子域名 | 定位 | 目标用户 | 核心形态 |
|---|---|---|---|
www.peyep.com | 品牌官网与技术报告 | 访客、客户、投资者 | 营销门户 + 报告 |
app.peyep.com | 统一工作台 | 建模师、开发者、项目经理 | Web 应用 |
api.peyep.com | 开发者门户与控制台 | 后端开发者、SaaS 集成商 | API 控制台 + SDK |
nl2cga.peyep.com | 自然语言转 CGA | 建筑师、规划师、设计师 | 生成工具 / 嵌入式组件 |
cgajs.peyep.com | CGA 解析器游乐场 | 技术美术、引擎工程师 | 在线编辑器 / 调试器 |
runtime.peyep.com | 几何生成引擎 | 自动化流水线用户 | 执行服务 / 队列 |
viewer.peyep.com | 三维渲染组件与示例 | 前端开发者、3D 设计师 | 组件展示 + 场景预览 |
data.peyep.com | 全球数据底座 | GIS 工程师、城市规划师 | 数据目录 + 瓦片服务 |
docs.peyep.com | 开发文档与教程 | 开发者、技术美术 | 文档站 |
test.peyep.com | 测试与演示沙盒 | 测试工程师、售前、客户 PoC | Staging 环境 |
8.5.2 潜在冲突与重叠分析
| 潜在重叠点 | 分析 | 结论 |
|---|---|---|
api.peyep.com vs docs.peyep.com |
两者都会涉及 API 参考文档。api 侧重点是交互式控制台、SDK、API Key;docs 侧重点是静态教程、错误码、完整参考。 | 不合并。API reference 静态内容由 docs 承载;api 仅保留控制台与 SDK 下载。双向导航。 |
viewer.peyep.com vs app.peyep.com |
app 的项目预览会嵌入 viewer;viewer 也提供独立示例库。 | 不合并。viewer 作为可复用组件与示例站存在;app 是集成场景。 |
nl2cga.peyep.com vs app.peyep.com |
nl2cga 既可独立访问,也应作为 app 中「新建项目 → 自然语言生成」的一个模块。 | 不合并。nl2cga 是能力子站,app 是集成工作台;通过 iframe/组件/widget 方式嵌入。 |
data.peyep.com vs app.peyep.com |
app 中需要选择地块、加载底图;data 提供独立的数据浏览与瓦片服务。 | 不合并。data 是公共服务,app 是消费方之一。 |
cgajs.peyep.com vs runtime.peyep.com |
cgajs 负责解析与 AST;runtime 负责执行与几何。逻辑紧密耦合。 | 不合并。解析器与执行器职责不同,且未来用户群体不同(技术美术 vs 自动化流水线)。内部通过 API 协作。 |
test.peyep.com vs 其他子站 |
test 会部署各子站的 staging 版本,看起来像是复制。 | 不合并。test 是环境概念,不是产品概念;它使用与其他子站相同的代码但独立数据。 |
总体结论:当前 10 个子域名不存在必须合并的重大冲突。各子站定位清晰、目标用户不同,少量功能重叠通过「公共服务 + 集成嵌入」方式解决。
8.5.3 优化后的子域名架构
优化后保留 10 个子域名,但按「门户 / 工作台 / 能力服务 / 开发者 / 支撑环境」重新分组:
| 分组 | 子域名 | 说明 |
|---|---|---|
| 门户层 | www.peyep.com | 唯一官方入口,品牌、报告、产品矩阵。 |
| 应用层 | app.peyep.com | 统一工作台,集成 NL2CGA、viewer、data 选择。 |
| 能力服务层 | nl2cga.peyep.com | 自然语言生成 CGA(独立站 + 可被 app 嵌入)。 |
cgajs.peyep.com | CGA 解析器游乐场。 | |
runtime.peyep.com | 几何生成引擎。 | |
viewer.peyep.com | 三维渲染组件与示例。 | |
| 数据层 | data.peyep.com | 全球数据底座服务。 |
docs.peyep.com | 开发文档与教程(归类为支撑,但面向用户)。 | |
| 开发者/支撑层 | api.peyep.com | 开发者门户、API Key、用量、SDK。 |
test.peyep.com | 测试、演示、客户 PoC 沙盒。 |
8.5.4 peyep.com 与 www.peyep.com 的关系
为避免 SEO 分散、品牌入口不统一,以及用户混淆:
www.peyep.com是唯一官方主站,承载品牌门户、技术报告、产品矩阵。peyep.com裸域仅作为跳转入口,所有请求 301 永久重定向到https://www.peyep.com{uri}。- 搜索引擎只索引
www.peyep.com,避免重复内容。 - 所有对外宣传、链接、二维码统一使用
www.peyep.com。
实现方式:
# Caddyfile
peyep.com {
redir https://www.peyep.com{uri} permanent
}
同时在 FastAPI 层做兜底:当检测到 Host 为 peyep.com 时,也返回 301 跳转。
8.5.5 子产品间集成关系
flowchart LR
W[www.peyep.com
官网/报告]
A[app.peyep.com
工作台]
N[nl2cga.peyep.com
生成 CGA]
C[cgajs.peyep.com
解析/调试]
R[runtime.peyep.com
生成几何]
V[viewer.peyep.com
预览]
D[data.peyep.com
底图/数据]
AP[api.peyep.com
控制台]
DO[docs.peyep.com
文档]
T[test.peyep.com
沙盒]
W --> A
A --> N & D & V
N --> C --> R --> V
AP --> DO
T -.-> N & C & R & V & D
说明:
www向访客介绍产品并引流到app。app是核心集成入口,通过 iframe/组件调用nl2cga、viewer、data。nl2cga生成的 CGA 提交给cgajs解析,再交给runtime生成几何,最终在viewer预览。api提供程序化访问,docs提供详细文档,两者互相链接。test部署各子站的 staging 版本,用于演示与回归测试。
8.6 决策清单
在进入大规模开发前,建议先明确以下决策:
| 决策项 | 选项 | 推荐 |
|---|---|---|
| CityEngine 许可 | 暂不购买 / 购买商业许可 | 尽快购买,否则无法使用 PyPRT 做 golden 测试 |
| Parser 技术 | Lark / ANTLR4 / 手写 | Lark 做 MVP,稳定后迁移 ANTLR4 |
| 几何内核 | trimesh+manifold / 自研半边结构 / CGAL | trimesh+manifold 跑通 MVP,再逐步替换关键算法 |
| 前端框架 | 纯 HTML+CSS+JS / Vue / React | 先纯 HTML + htmx/Alpine,降低复杂度;复杂 SPA 再引入 Vue |
| 数据库 | PostgreSQL / MongoDB / SQLite | PostgreSQL + SQLAlchemy,关系型更适合项目/资产模型 |
| LLM 后端 | Kimi API / OpenAI / 本地模型 | Kimi API,中文能力强且已具备访问条件 |
| 对象存储 | MinIO / 云 S3 / 本地磁盘 | 开发用本地/MinIO,生产用云 S3 |
| 部署方式 | systemd / Docker / K8s | systemd + Docker Compose 先跑起来,再上 K8s |
九、服务器与基础设施配置清单
本章给出 peyep 项目从 MVP 到商业化不同阶段所需的服务器硬件、软件栈、网络、存储、安全与成本配置清单,用于采购、预算与部署决策。
9.1 总体原则
- 渐进投入:Phase 0–1 用单台高性能云服务器即可跑完全部 MVP;后续按实际负载水平扩展。
- 计算密集在 Runtime:CGA 解析与几何生成是 CPU/内存密集型,需优先为 runtime/cgajs 预留资源。
- GPU 非必需但推荐:MVP 阶段 LLM 走 API,无需 GPU;进入 Phase 3 后若要做本地化推理、实时渲染或路径追踪,再引入 GPU 节点。
- 数据与状态分离:应用无状态化,文件走对象存储,会话/缓存走 Redis,结构化数据走 PostgreSQL。
- 先云后裸金属:早期用云服务器灵活试错;规模化后可考虑裸金属或 GPU 专用服务器降低成本。
9.2 按开发阶段的服务器配置
9.2.1 Phase 0–1:MVP 单体阶段(约 2–10 周)
所有服务跑在单台 Linux 服务器上,Caddy + FastAPI + PostgreSQL + Redis 同机部署。
| 维度 | 推荐配置 | 说明 |
|---|---|---|
| CPU | 8–16 核(x86_64) | PyPRT golden 测试、Lark 解析、trimesh 运算均吃 CPU |
| 内存 | 32–64 GB | 780 个 CGA 批量解析、大模型加载需要内存 |
| GPU | 无 | LLM 调用 Kimi API,几何计算 CPU 完成 |
| 系统盘 | 200 GB NVMe SSD | 操作系统 + CityEngine 数据 11 GB + 日志 + 中间产物 |
| 数据盘 | 500 GB SSD(可扩容) | CGA 语料、 golden 模型、生成缓存 |
| 网络 | 100 Mbps+,独立公网 IP | 自动 HTTPS 证书、模型下载 |
| 操作系统 | Ubuntu 22.04 LTS / RHEL 9 兼容系 | PyPRT 官方支持 RHEL 8/9 兼容系 |
预估成本:云服务器约 ¥500–1,500/月(按国内主流云厂商 8 核 32G 计算型估算)。
9.2.2 Phase 2–3:NL2CGA + Runtime 强化(约 4–12 周)
开始拆分数据库、缓存、对象存储;runtime 可能跑独立 worker。
| 维度 | 推荐配置 | 说明 |
|---|---|---|
| CPU | 16–32 核 | 支撑并发几何生成与批量 golden 测试 |
| 内存 | 64–128 GB | 大场景三角网格、多线程 worker |
| GPU | 可选 RTX 4090 / A10 | 仅当需要本地 LLM 推理或实时渲染时引入 |
| 系统盘 | 200 GB NVMe SSD | 系统 + 容器镜像 |
| 数据盘 | 1 TB SSD | 模型、纹理、瓦片缓存 |
| 数据库 | Managed PostgreSQL 4 核 8G | 用户、项目、资产、模型版本 |
| 缓存 | Redis 2 核 4G | 会话、限流、任务状态 |
| 对象存储 | MinIO 或云 OSS | CGA / 纹理 / GLB / 瓦片 |
预估成本:约 ¥2,000–5,000/月(含计算、数据库、存储、带宽)。
9.2.3 Phase 4–5:多服务生产阶段(约 4–10 周)
子产品拆分为多个服务,需要多节点、负载均衡、独立数据服务。
| 节点类型 | 数量 | 配置 | 用途 |
|---|---|---|---|
| Gateway / Web | 1–2 | 4 核 8G | Caddy / Nginx + FastAPI 入口 |
| App / API | 2 | 4 核 16G | 业务 API、用户权限、计费 |
| cgajs Worker | 2 | 8 核 32G | CGA 解析、AST、语义分析 |
| Runtime Worker | 2–4 | 16 核 64G | 几何生成、导出、golden 对比 |
| NL2CGA Inference | 1 | 8 核 32G + A10/L4 | 本地 LLM 推理(可选) |
| Data / Tile | 1–2 | 4 核 16G | 瓦片代理、数据底座 |
| PostgreSQL | 1(主) | 8 核 16G + 500G SSD | 结构化数据 |
| Redis | 1–2 | 2 核 8G | 缓存、消息队列后端 |
预估成本:约 ¥8,000–30,000/月(含云服务器、数据库、对象存储、CDN、GPU)。
9.2.4 Phase 6:规模化与企业级(持续)
多区域、多可用区、Kubernetes、GPU 集群、企业合规。
| 维度 | 推荐配置 |
|---|---|
| 编排 | Kubernetes(云托管或自建) |
| 区域 | 至少 2 个区域(国内 + 海外,或华北 + 华南) |
| GPU 集群 | A10/A100/L40 节点,按需自动扩缩容 |
| 数据库 | PostgreSQL 主从 + 读写分离 + 定期备份 |
| 对象存储 | 多区域冗余,生命周期管理 |
| CDN | 全球加速,静态资源 + 模型下载 |
| 监控 | Prometheus + Grafana + Loki + 告警 |
预估成本:¥30,000+/月,视用户量与并发度而定。
9.3 节点类型与详细配置
| 节点 | CPU | 内存 | 存储 | 网络 | 特殊要求 |
|---|---|---|---|---|---|
| Web / Gateway | 4 核 | 8G | 50G SSD | 100 Mbps+ | 公网 IP、HTTPS 证书 |
| FastAPI App | 4 核 | 16G | 100G SSD | 内网 / 公网 | 无状态、可水平扩展 |
| cgajs Parser | 8 核 | 32G | 200G SSD | 内网 | 高主频 CPU 利于解析 |
| Runtime Worker | 16 核 | 64G | 500G SSD | 内网 | 大内存、高主频 |
| LLM Inference | 8 核 | 32G | 200G SSD | 内网 | GPU(A10/L4/RTX 4090) |
| Data / Tile | 4 核 | 16G | 1T SSD | 100 Mbps+ | 高出口带宽 |
| PostgreSQL | 8 核 | 16G | 500G SSD | 内网 | 主从备份、SSD |
| Redis | 2 核 | 8G | 50G SSD | 内网 | 持久化策略 AOF/RDB |
9.4 软件栈清单
| 层次 | 组件 | 推荐选型 |
|---|---|---|
| 操作系统 | Linux 发行版 | Ubuntu 22.04 LTS / RHEL 9 兼容系 |
| 容器化 | Docker / containerd | Docker 27+ |
| 编排(后期) | Kubernetes | 云托管 K8s 或 k3s |
| Web 服务器 / 网关 | Caddy / Nginx | Caddy(已配置,自动 HTTPS) |
| 应用框架 | FastAPI + Uvicorn | Python 3.10+ |
| 数据库 | PostgreSQL | 15+ |
| 缓存 / 队列后端 | Redis | 7+ |
| 对象存储 | MinIO / 云 OSS | MinIO 开发,生产切云 OSS |
| 任务队列 | Celery / RQ | Celery + Redis |
| 日志 | structlog / Loki | 结构化 JSON 日志 |
| 监控 | Prometheus + Grafana | 指标、告警、可视化 |
| CI/CD | GitHub Actions / GitLab CI | 自动化测试、构建、部署 |
| 反向代理 / 限流 | Caddy / Nginx + Redis | rate limit、WAF |
9.5 网络与域名要求
| 项目 | 要求 |
|---|---|
| 公网 IP | 至少 1 个独立 IPv4 |
| 域名 | peyep.com 已注册,泛解析 *.peyep.com |
| 端口 | 80/443 对外开放;内部 5432(PG)、6379(Redis)、8000(FastAPI)按需开放 |
| 带宽 | 初期 100 Mbps;规模化后 1 Gbps+ 或按流量计费 |
| CDN | Phase 4 起引入,用于静态资源、模型文件、瓦片 |
| DNS | 支持泛解析与按需添加子域名 |
| DDoS / WAF | 云厂商基础防护或 Cloudflare 等 |
9.6 存储与备份
| 类型 | 用途 | 容量/策略 |
|---|---|---|
| 本地 SSD | 系统、应用、临时计算 | 按节点 200G–1T |
| 对象存储 | CGA 源文件、纹理、GLB/OBJ 输出、瓦片缓存 | 起步 500G,生命周期管理 |
| 数据库存储 | 用户、项目、资产、模型版本元数据 | 500G 起,主从备份 |
| 备份策略 | 数据库每日全量 + binlog;对象存储跨区复制 | RPO < 24h,保留 30 天 |
9.7 安全基线
| 项目 | 要求 |
|---|---|
| TLS | 全站 HTTPS,自动证书(Let's Encrypt / 云证书) |
| 防火墙 | 仅开放 80/443,内部服务放内网安全组 |
| API 安全 | API Key + 签名/ JWT、速率限制、CORS 白名单 |
| Secrets | 数据库密码、API Key、TLS 私钥走环境变量或 Vault |
| 代码安全 | 依赖扫描、 secrets 扫描、容器镜像扫描 |
| 日志审计 | 关键操作留痕,保留 180 天 |
| 数据合规 | 用户数据加密存储,符合目标市场法规 |
9.8 开发环境与本地机器
| 角色 | 推荐配置 | 说明 |
|---|---|---|
| 后端开发 | 16 核 32G,500G SSD | 可本地跑 PyPRT、trimesh、PostgreSQL、Redis |
| 前端 / 3D 开发 | 8 核 16G,独立显卡 | Three.js / CesiumJS 调试、Blender 辅助 |
| AI / LLM 开发 | 16 核 32G,RTX 4090 或云端 GPU | 本地模型微调、Prompt 工程 |
| 测试环境 | 与生产同构但规模减半 | 使用 test.peyep.com |
9.9 成本估算
| 阶段 | 周期 | 月成本(人民币) | 主要构成 |
|---|---|---|---|
| Phase 0–1 | 2–10 周 | ¥500–1,500 | 1 台云服务器 |
| Phase 2–3 | 4–12 周 | ¥2,000–5,000 | 增强型服务器 + DB + Redis + 对象存储 |
| Phase 4–5 | 4–10 周 | ¥8,000–30,000 | 多节点 + GPU + 托管数据库 + CDN |
| Phase 6 | 持续 | ¥30,000+ | K8s 集群、多区域、GPU 集群、企业支持 |
注:以上为国内主流云厂商(阿里云 / 腾讯云 / 华为云)按量/包月估算,不含 CityEngine 商业许可、Esri 资产授权、第三方 SaaS(如 Cesium ion、Google 3D Tiles)费用。
十、结论与下一步
通过对 CityEngine 官方工程文件和文档的系统性学习,以及对 NL2CGA、cgajs、CGARuntime、viewer、全球数据底座五大子产品的深入技术调研,可以确认:
- CGA 是一套成熟、表达力强的程序化建模 DSL,核心思想是 Shape + Scope + Rule Replacement。
- 商业化 NL2CGA 必须采用 Semantic IR + 模板 + Agent/Critic 的混合架构,而非端到端 LLM。
- cgajs 应走 Lark 快速解析 → Python 执行器 → ANTLR4 规范化 → C++ 几何内核加速 的路线。
- CGARuntime 应以 自研半边结构为主核,嫁接 CGAL / Manifold / OpenCASCADE 作为算法后端。
- viewer 不要自研底层渲染器,采用 Three.js 做单体建筑 + CesiumJS 做城市级 GIS。
- 全球数据底座采用 开放数据 + 商业补充 + CesiumJS 的混合方案,注意各平台商用授权。
- 基础设施已就绪:
peyep.com与任意子域名均已支持 HTTPS,FastAPI + Caddy 反向代理运行稳定。 - PyPRT 可作为内部 golden 参考,但需严格与产品运行时隔离,避免 Esri 授权风险。
- 780 个官方 CGA 足以支撑 cgajs 的 MVP 种子语料,配合 LLM 自我迭代可显著加速解析器与运行时完善。
- 10 个子域名功能定位经冲突审查后确认无需合并,已按门户 / 工作台 / 能力服务 / 数据 / 开发者 / 支撑环境重新分组;
peyep.com裸域统一 301 跳转至www.peyep.com。
建议立即开始的下一步
- 在
/root/peyep下创建cgajs、nl2cga、cga_runtime、viewer模块目录,并补充app/routers。 - 安装
lark、trimesh、manifold3d,编写可解析 780 个官方 CGA 的 MVP 语法并跑 L0 通过率报告。 - 实现 Shape/Scope/Pivot 与 extrude/comp/split,跑通第一个简单建筑 → GLB。
- 在本地或持有 CityEngine 许可的 runner 上安装 PyPRT,对 5–10 个核心建筑 CGA 生成 golden OBJ,建立 Hausdorff 对比基准。
- 编写
cgajs/profiler.py生成 780 文件的能力画像,建立失败分类器与 A/B 对比脚本。 - 定义 Semantic IR JSON Schema,用 LLM 把“5 层现代办公楼”转为 JSON,再生成 CGA。
- 用 Three.js WebGPU 搭建 GLB 预览页面,验证 CGA → 几何 → 渲染闭环。
- 实现
app.peyep.com工作台首页与统一导航组件,作为其他子产品的基础。