【3D-AICG 系列-15】Trellis 2 的 O-voxel Shape: Flexible Dual Grid 代码与论文对应

系列文章目录


文章目录

  • 系列文章目录
  • [Mesh -> O-voxel](#Mesh -> O-voxel)
    • 总目标
    • [关键输入(只有 4 个需要关心的)](#关键输入(只有 4 个需要关心的))
    • [关键输出(只有 3 个)](#关键输出(只有 3 个))
    • [关键算法:只有 **2 步**](#关键算法:只有 2 步)
      • [第 1 步:收集约束("哪些体素被穿过、穿过时的几何信息是什么")](#第 1 步:收集约束("哪些体素被穿过、穿过时的几何信息是什么"))
      • [第 2 步:求解("在每个体素内找最佳代表点")](#第 2 步:求解("在每个体素内找最佳代表点"))
    • 一张图串起来

  • 前文有介绍 Trellis 2 的 Flexible Dual Grid 整体流程,本文则聚焦于将这部分的 C++ 代码细节和论文对应起来。

  • 代码来自 /repo/TRELLIS.2/o-voxel/src/convert/flexible_dual_grid.cpp

    /repo/TRELLIS.2/data_toolkit/dual_grid.py 中的 o_voxel.convert.mesh_to_flexible_dual_grid 函数调用

Mesh -> O-voxel

跳出细节,看大局。整个 flexible_dual_grid.cpp 文件只干一件事


总目标

输入一个三角网格(mesh),输出一组稀疏体素,每个体素内有一个"最佳代表点"(dual vertex)。


关键输入(只有 4 个需要关心的)

输入 含义
vertices (N,3) 网格顶点坐标
faces (M,3) 三角面的顶点索引
voxel_size (3,) 每个体素在 x/y/z 方向的尺寸
grid_range (2,3) 体素索引的范围 [min, max)

关键输出(只有 3 个)

输出 含义
voxel_indices (K,3) int K 个活跃体素的整数坐标
dual_vertices (K,3) float 每个体素内的最佳代表点坐标
intersected (K,3) bool 每个体素在 x/y/z 三个方向上是否被表面穿过
  • 活跃体素 = Mesh 表面与体素网格有交的体素
  • voxel_indices (i, j, k):表示"第几格",只能是整数。
  • dual_vertices (x, y, z):表示"这一格里的点在世界/局部坐标下的具体位置",可以是格子内的任意一点。并且 QEF 求出来的解是连续坐标,例如 (2.3, 1.7, 0.8),表示在局部坐标系下 x=2.3、y=1.7、z=0.8 的点,所以必须用 float 才能存这些小数。

关键算法:只有 2 步

第 1 步:收集约束("哪些体素被穿过、穿过时的几何信息是什么")

由 3 个函数完成,每个函数只做一件事------往 QEF (quadratic error function) 矩阵里加一项约束

函数 做什么 一句话
intersect_qef 扫描线找"三角面穿过了哪些体素边",记录交点和法平面 发现活跃体素 + 加"交点平面"约束
face_qef 遍历三角面的包围盒,找与三角面重叠的体素 加"面片平面"约束(让代表点靠近面)
boundry_qef 找只被一个三角形引用的边(开边界),DDA 遍历经过的体素 加"边界线"约束(让代表点靠近边界)

三个函数的共同点:都在往同一个 qefs[i](4×4 矩阵)里 累加,本质是在说"这个体素的代表点应该尽量满足这些几何约束"。

第 2 步:求解("在每个体素内找最佳代表点")

就是 562--765 行的循环:

复制代码
对每个活跃体素:
    Q = 累加好的 QEF 矩阵(+ 可选正则项)
    先无约束解 Ax=b
    如果解在体素内 → 用它
    如果解跑到体素外 → 依次试"固定1个面/2个面/3个面(角点)",取误差最小的
    → 得到 dual_vertex

一句话 :在体素的小盒子里,找一个点,使它离所有穿过该体素的三角面尽量近


一张图串起来

复制代码
mesh (vertices + faces)
        │
        ▼
  ┌─────────────────┐
  │  intersect_qef  │  扫描线 → 发现活跃体素 + 累加 QEF
  └────────┬────────┘
           ▼
  ┌─────────────────┐
  │    face_qef     │  面片重叠检测 → 累加 QEF(可选)
  └────────┬────────┘
           ▼
  ┌─────────────────┐
  │  boundry_qef    │  边界 DDA → 累加 QEF(可选)
  └────────┬────────┘
           ▼
  ┌─────────────────┐
  │   QEF 求解循环   │  每体素解 min ||Ax-b||² → dual_vertex
  └────────┬────────┘
           ▼
  (voxel_indices, dual_vertices, intersected)

所以你只需要记住 :前面 3 个函数是"收集约束、往 QEF 矩阵里加东西",最后一个循环是"解方程、得代表点"。其它所有代码(扫描线怎么扫、投影怎么测、DDA 怎么走、约束求解的分支枚举)都是这两步的实现细节

相关推荐
DeepVisionary4 小时前
谷歌 Gemini Omni 1.1 Flash 正式发布:4K 视频、40 秒场景延伸,视频生成进入按 token 计费时代
python·自动化
ZGIAI4 小时前
ZGI Workflow:条件分支走错时先查哪一层
人工智能·架构
X54先生(人文科技)4 小时前
《元创力》纪实录 · 桥段 《窑变纪元:一份来自星历2227年的深空考古笔记》
人工智能·开源·ai写作·零知识证明
ZGIAI4 小时前
ZGI 文件产物:生成报告后怎样交付
人工智能·架构
东方-教育技术博主4 小时前
自动编码在教育场景中的重要性:一项基于多源证据的深度综述
大数据·人工智能
骥龙4 小时前
模块二:Ollama本地模型部署与OpenCode代理配置
人工智能
阡之尘埃4 小时前
Python数据分析案例85——大模型微调全流程(SFT的LoRA微调)
人工智能·python·深度学习·语言模型·llm·微调·千问
Regentsoft丽晶软件4 小时前
品牌方新品上市促销政策无法实时同步经销商,有没有支持总部-经销商-终端一站式的分销解决方案?
人工智能·经验分享·数据库架构
liuqs3324 小时前
机器人产业加速发展,制造业正在迎来新的自动化探索
大数据·人工智能
腾讯云大数据4 小时前
DataBuddy数据语义驱动的企业Agent Runtime实践
大数据·人工智能·腾讯云·agent