给 LLM 一些样例椅子/桌子 + 文字描述,LLM 发明一套 Python 函数库(每个函数 = 一类几何结构,如
sled_base()/ladder_back()),再训练 Transformer recognition network 把新形状的点云/voxel 编译成这套库的函数调用序列;novelty 在于:用户可以用自然语言指定函数的语义,geometric reconstruction validation 负责过滤 LLM 幻觉。
| 术语 | 在本文中的具体含义 |
|---|---|
| abstraction / function | 一个 Python 函数,如 def sled_base(width, length, height),代表椅子底座的一种几何结构 |
| library | 一组 abstraction 函数的集合,覆盖某个形状类别(如"椅子")的常见结构变体 |
| seed set | 用户手选的 5-20 个真实 3D 形状(如从 ShapeNet 里选的椅子 mesh),提供几何 ground truth;用户输入 = 文字描述 + 这批真实形状,缺一不可 |
| program | 一连串函数调用,如 sled_base(0.4,0.5,0.3); ladder_back(...),描述一个形状的完整结构 |
| recognition network | 把点云/voxel 映射到函数调用序列的 autoregressive Transformer decoder |
| validation | 用 LLM 生成的函数实现去重建 seed set 形状,geometric F-score 在阈值内才算通过 |
func_0、func_1 这类无意义 label,用户无法指定"我希望 func_0 代表梯形背板";Semantic F1 仅 27。
flowchart LR
U["User:\ntext desc\n+ seed set"]
S1["Stage 1\nInterface\nCreation"]
S2["Stage 2\nApplication\nProposal"]
S3["Stage 3\nImplementation\nProposal"]
S4["Stage 4\nValidation"]
LIB["Library\nof Functions"]
U --> S1
S1 -->|"typed interface\n+ docstring"| S2
S2 -->|"K_A=5 programs\nper seed shape"| S3
S3 -->|"K_I=4 implementations\nper function"| S4
S4 -->|"geometric threshold\nfilter"| LIB
Stage 1:Interface Creation——LLM 接受文字描述(如"chairs with ladderbacks, sled bases, and arm rests")和设计模板,输出带有 typed 参数和 docstring 的函数接口:
# LLM 生成的接口示例
def ladder_back(num_rungs: int, rung_width: float, rung_height: float,
post_width: float, post_height: float) -> list[Cuboid]:
"""A chair back consisting of horizontal rungs attached to two vertical posts."""
...
Stage 2:Application Proposal——对 seed set 里每个形状,LLM 提出 K_A=5 个程序(调用哪些函数、参数大致是什么),选择与 seed 形状 point cloud F-score 最高的一个作为 input-output example。
Stage 3:Implementation Proposal——LLM 根据 Stage 2 的 input-output examples 生成 K_I=4 个函数实现。每个实现都通过已有函数(如基础 cuboid/cylinder 原语)组合来构建。
Stage 4:Validation——用每个实现重建 seed set 中的样例形状,计算 point cloud F-score。超过阈值则该实现通过;若所有 K_I 个实现都不通过,该函数从 library 移除。最终只保留几何上可行的实现。
Stage 1 — Interface Creation
输入:5 个不同 storage cabinet 的点云(seed set)。LLM 看这些形状,设计函数签名:
def rectangular_body(width: float, depth: float, height: float) -> Part:
"""Axis-aligned box forming cabinet body"""
def shelf_array(num_shelves: int, spacing: float) -> Part:
"""Evenly spaced horizontal shelves inside body"""
def door_panel(side: str, hinge: str) -> Part:
"""Single rectangular door, side='left'/'right'"""只有接口,没有实现,没有具体调用。LLM 在这一步扮演 API 设计者。
Stage 2 — Application Proposal
输入:Stage 1 的接口 + 同一批 seed 形状。LLM 为每个 seed 形状写具体程序(此时程序是幻觉——接口还没实现,还不知道能否真正生成几何体):
# seed shape #3: tall bookshelf with no door body = rectangular_body(0.4, 0.3, 1.8) shelves = shelf_array(num_shelves=5, spacing=0.3) result = compose(body, shelves) # seed shape #5: low cabinet with two doors body = rectangular_body(0.9, 0.4, 0.6) door_l = door_panel(side='left', hinge='left') door_r = door_panel(side='right', hinge='right') result = compose(body, door_l, door_r)
Stage 3 — Implementation Proposal
输入:接口 + Stage 2 的示例程序。LLM 写函数体(真正的几何代码):
def rectangular_body(width, depth, height):
verts = box_vertices(width, depth, height)
return Part(mesh=verts, transform=identity())
def shelf_array(num_shelves, spacing):
parts = []
for i in range(num_shelves):
p = thin_box(width=1.0, depth=0.9, height=0.02)
p = translate(p, y=i*spacing)
parts.append(p)
return union(parts)此时有完整程序,但实现可能有 bug(比如 spacing 方向错、尺寸超界)。
Stage 4 — Validation(几何 oracle 作为 hallucination filter)
注意:用户输入不只是文字。用户提供两样东西:文字描述(语义意图,只用于 Stage 1)+ seed set 真实 3D 形状(从 ShapeNet 等数据集里选出的真实 mesh,5–20 个,贯穿全部 stage)。Stage 4 的"原始点云"就是这些真实形状采样出来的点云——几何约束完全来自这里,跟文字无关。
对每个 seed 形状:跑 Stage 2 的程序 → 渲染 3D mesh → 采样点云 → 与 seed set 真实形状的点云比 Chamfer Distance / IoU:
seed #3 bookshelf: 程序跑出 mesh → voxel IoU = 0.74 ✓ seed #5 cabinet: shelf_array spacing 方向错 → IoU = 0.21 ✗ → 打回 LLM 修 shelf_array 实现
这步是唯一真实 ground truth,用几何误差过滤 LLM 的 bug。
Recognition Network — inference 时
Library 固定(Stage 1–4 已完成)。输入新 cabinet 的点云,Transformer decoder autoregressive 输出函数调用序列:
输入: 新 cabinet 的点云 (2048 × 3 coords)
↓
Transformer decoder (autoregressive token prediction)
↓
输出 token 序列:
rectangular_body ( 0.6 , 0.35 , 1.1 )
shelf_array ( num_shelves=4 , spacing=0.25 )
compose ( body , shelves )输出只含函数名 + 参数值——函数实现在 library 里,网络不生成实现。类比 SQL query:写 SELECT ... FROM ... 但不包含数据库引擎源码。
| 层次 | 内容 | 谁生成 |
|---|---|---|
| Library 函数体 | def rectangular_body(...) 几何实现 | Stage 3 LLM |
| 训练集程序 | body = rectangular_body(0.6, 0.35, 1.1) | Stage 2 LLM |
| 识别网络输出 | 同上格式,对新形状 | Recognition network |
Recognition network 是 autoregressive Transformer decoder,把形状输入(点云、voxel 或 cuboid primitives)映射到函数调用序列。训练数据通过 LLM 生成的 sampling procedures(随机采样参数 → 合成新程序 → 渲染几何)自动生成,无需人工标注。
ShapeLib 把"函数库设计"从几何优化问题转化为 LLM 引导的程序合成问题,用 geometric reconstruction validation 作为唯一约束——让 LLM 的语义知识和几何样例的具体约束各司其职。
| 方法 | Functions/Shape ↓ | Functions/Library ↓ | Semantic F1 ↑ | Voxel IoU ↑ | PC F-Score ↑ |
|---|---|---|---|---|---|
| ShapeLib | 9.6 | 5.6 | 36 | 50.0 | 54.0 |
| ShapeCoder | 13.5 | 19.2 | 27 | 32.3 | 40.9 |
| LLM-Only | 14.9 | 5.6 | 18 | 34.9 | 37.4 |
Functions/Shape 越少 = 接口越简洁;ShapeLib 比 ShapeCoder 少 30%。ShapeLib Semantic F1 是 LLM-Only 的 2 倍、ShapeCoder 的 1.3 倍。
| 方法 | 输入模态 | Voxel IoU ↑ |
|---|---|---|
| ShapeLib | Voxels | 62.2 |
| ShapeLib | Primitives | 56.3 |
| GPT-4o | Primitives | 38.4 |
| GPT-4o | Images | 18.2 |
| 方法 | FPD ↓ | MMD ↓ |
|---|---|---|
| ShapeLib | 278 | 0.079 |
| ShapeCoder | 449 | 0.091 |
| LLM-Only | 2219 | 0.100 |
ShapeLib 属于"LLM 作为程序合成器 + 几何约束 oracle"这一方向的代表,与 ProgGEO、ShapeCoder 一脉相承,但把约束从纯几何优化推向了用户意图可控的范式。下一步关键问题:(1) 如何把 recognition network 扩展到噪声真实扫描;(2) 能否从用户的编辑历史自动 refine library;(3) 能否用类似机制建立跨类别的通用函数库(如"四腿底座"同时适用于椅子和桌子)。该工作对程序化 3D 内容生成(游戏、CAD)有直接应用价值。