xuvdb 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- xuvdb-0.1.0/LICENSE +201 -0
- xuvdb-0.1.0/PKG-INFO +208 -0
- xuvdb-0.1.0/README.md +190 -0
- xuvdb-0.1.0/pyproject.toml +32 -0
- xuvdb-0.1.0/setup.cfg +4 -0
- xuvdb-0.1.0/src/xuvdb/__init__.py +64 -0
- xuvdb-0.1.0/src/xuvdb/gpu.py +96 -0
- xuvdb-0.1.0/src/xuvdb/io.py +173 -0
- xuvdb-0.1.0/src/xuvdb/kernels.py +258 -0
- xuvdb-0.1.0/src/xuvdb/openvdb_bridge.py +101 -0
- xuvdb-0.1.0/src/xuvdb/openvdb_file.py +686 -0
- xuvdb-0.1.0/src/xuvdb/ray.py +132 -0
- xuvdb-0.1.0/src/xuvdb/runtime.py +17 -0
- xuvdb-0.1.0/src/xuvdb/tree.py +494 -0
- xuvdb-0.1.0/src/xuvdb.egg-info/PKG-INFO +208 -0
- xuvdb-0.1.0/src/xuvdb.egg-info/SOURCES.txt +18 -0
- xuvdb-0.1.0/src/xuvdb.egg-info/dependency_links.txt +1 -0
- xuvdb-0.1.0/src/xuvdb.egg-info/requires.txt +11 -0
- xuvdb-0.1.0/src/xuvdb.egg-info/top_level.txt +1 -0
- xuvdb-0.1.0/tests/test_smoke.py +76 -0
xuvdb-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright 2026 xuvdb contributors
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
xuvdb-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: xuvdb
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Editable sparse voxel volumes with OpenVDB interop, built on quadrants kernels
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
Requires-Python: <3.14,>=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: numpy
|
|
10
|
+
Requires-Dist: quadrants
|
|
11
|
+
Provides-Extra: genesis
|
|
12
|
+
Requires-Dist: genesis-world; extra == "genesis"
|
|
13
|
+
Provides-Extra: openvdb
|
|
14
|
+
Requires-Dist: pyopenvdb; extra == "openvdb"
|
|
15
|
+
Provides-Extra: test
|
|
16
|
+
Requires-Dist: pytest; extra == "test"
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
|
|
19
|
+
# XUVDB 太虚 — genesis 自研稀疏体素格式(可编辑 · 与 OpenVDB 互转)
|
|
20
|
+
|
|
21
|
+
> 「不游乎太虚。」——《庄子·知北游》
|
|
22
|
+
> 「太虚无形,气之本体。」——张载《正蒙·太和》
|
|
23
|
+
|
|
24
|
+
`xuvdb` 取「太虚」之音:这是中文里对 VDB「无界而稀疏的索引域」最准确的翻译——无界
|
|
25
|
+
(root 哈希域不设上限),无形(未分配的空间没有形态,采样即得背景值)。
|
|
26
|
+
|
|
27
|
+
`xuvdb` 基于 quadrants 内核:**自己的 `.xuvdb` 格式**(可修改、可在内核里写值),
|
|
28
|
+
以及**与 OpenVDB 的双向互转**(原生 `.vdb` 文件读写,无需安装 OpenVDB;有 `pyopenvdb`
|
|
29
|
+
绑定时还能内存级互转)。
|
|
30
|
+
|
|
31
|
+
## 命名规范(三层名字,各归其位)
|
|
32
|
+
|
|
33
|
+
| 层 | 名字 | 规则 |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| 项目名 | `xuvdb` | 拼音;不用 Open 前缀(ASWF 语境下暗示基金会血统) |
|
|
36
|
+
| 命名空间 / 扩展名 | `xuvdb` / `.xuvdb` | API 标识符一律英文:`xuvdb.prune()`、`xuvdb.VdbGrid`,绝不是 `xuvdb.sunyi()`。道家词只活在概念层(文档题词、日志、可视化标签) |
|
|
37
|
+
| 互转文件 | `.vdb` | **自有格式绝不写 `.vdb` 后缀**(Houdini/Blender/Cycles/Arnold 按扩展名当 OpenVDB 解析,格式不符时静默出错或崩溃,极难定位;`save()` 对 `.vdb` 路径直接拒绝)。要互通就单独导出:`write_vdb()` 产出真正的 OpenVDB 流 |
|
|
38
|
+
|
|
39
|
+
## 为什么是它
|
|
40
|
+
|
|
41
|
+
| | OpenVDB | NanoVDB | XUVDB |
|
|
42
|
+
|---|---|---|---|
|
|
43
|
+
| 结构 | 5 层 B+树,CPU C++ | 同构只读缓冲,GPU | 两级:dict 叶根 + 稠密叶块 |
|
|
44
|
+
| 可修改 | ✅(CPU) | ❌ GPU 只读 | ✅ Python 端任意结构编辑;**内核端可写值** |
|
|
45
|
+
| 可微分包差 | ❌ | ❌ | 值缓冲可被 quadrants 内核读写(拓扑固定) |
|
|
46
|
+
| Python 依赖 | pyopenvdb(需自行构建) | — | 仅 numpy + quadrants |
|
|
47
|
+
|
|
48
|
+
定位不是替换任何求解器,而是补齐 README 物理栈背后的**空间表示层**(落点见下文)。
|
|
49
|
+
|
|
50
|
+
## 安装
|
|
51
|
+
|
|
52
|
+
独立 Python 包(src 布局,`import xuvdb` 即用):
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uv pip install . # 或 pip install .
|
|
56
|
+
uv pip install -e ".[test]" # 开发模式 + pytest
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
可选 extras:`[openvdb]`(pyopenvdb 内存级互转)、`[genesis]`(运行引擎侧示例需要 genesis-world)、
|
|
60
|
+
`[test]`(pytest)。
|
|
61
|
+
|
|
62
|
+
## 快速上手
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
import numpy as np
|
|
66
|
+
import xuvdb
|
|
67
|
+
|
|
68
|
+
# 1) 编辑:窄带 level set 球(体素 0.05,带宽 3 体素)
|
|
69
|
+
grid = xuvdb.VdbGrid(background=3 * 0.05, voxel_size=0.05, leaf_log2=4,
|
|
70
|
+
name="shield", grid_class="level set")
|
|
71
|
+
grid.stamp_sphere((0.3, 0.2, 0.1), radius=0.25, band=3.0)
|
|
72
|
+
grid.stamp_sphere((0.5, 0.2, 0.1), radius=0.10) # CSG:并入第二个球
|
|
73
|
+
grid.fill_box((-2, -2, -2), (2, 2, 2), value=0.0) # 任意稠密填充(示例)
|
|
74
|
+
grid.prune()
|
|
75
|
+
|
|
76
|
+
# 2) 自有格式落盘 / 读回(多网格、f32/f64/vec3)
|
|
77
|
+
xuvdb.save("scene.xuvdb", [grid])
|
|
78
|
+
grids = xuvdb.load("scene.xuvdb")
|
|
79
|
+
|
|
80
|
+
# 3) 与 OpenVDB 互通(显式导出:真正的 OpenVDB 流,Houdini/Blender 直接打开)
|
|
81
|
+
xuvdb.write_vdb("scene.vdb", [grid])
|
|
82
|
+
back = xuvdb.read_vdb("scene.vdb", grid_name="shield")
|
|
83
|
+
|
|
84
|
+
# 4) 内核采样 / 写值(等同 Warp example_nvdb 的用法,但值可写)
|
|
85
|
+
vol = xuvdb.GpuVolume(grid)
|
|
86
|
+
pts = np.array([[0.3, 0.2, 0.36]], dtype=np.float32)
|
|
87
|
+
d = vol.sample(pts, linear=True) # SDF 距离
|
|
88
|
+
n = vol.sdf_normal(pts) # 有限差分表面法向
|
|
89
|
+
vol.write_voxels(pts, np.array([-0.01], np.float32)); vol.sync_to_host()
|
|
90
|
+
|
|
91
|
+
# 5) 粒子 ⇄ 体积(液体/油,见落点④)
|
|
92
|
+
drops = np.array([[0.1, 0.0, 0.0], [0.2, 0.0, 0.0]])
|
|
93
|
+
fog = xuvdb.VdbGrid(voxel_size=0.05, name="liquid", grid_class="fog volume")
|
|
94
|
+
fog.scatter_particles(drops, h=4 * 0.05, weights=1.0) # SPH cubic 核密度 splat
|
|
95
|
+
surf = xuvdb.VdbGrid(background=3 * 0.05, voxel_size=0.05, grid_class="level set")
|
|
96
|
+
surf.union_spheres(drops, radius=0.03) # particle level set 表面代理
|
|
97
|
+
|
|
98
|
+
# 6) DDA 射线(空叶块按块跳过,交叉点二分细化到亚体素)
|
|
99
|
+
t, point, value = xuvdb.ray_surface_hit(grid, (0.3, 0.2, 2.0), (0, 0, -1))
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
与引擎稠密场的桥:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
# 稠密 qd.field / numpy SDF(如 rigid geom 的 sdf_val)→ 稀疏
|
|
106
|
+
sparse = xuvdb.VdbGrid.from_dense(dense_sdf, origin=ijk_min, voxel_size=h,
|
|
107
|
+
background=band_h, grid_class="level set")
|
|
108
|
+
dense, ijk_min = sparse.to_dense() # 反向:渲染器 / 求解器输入
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 格式
|
|
112
|
+
|
|
113
|
+
### `.xuvdb`(自有格式,小端)
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
"XUVDB" | u8 version=1 | u8 flags | u16 n_grids
|
|
117
|
+
per grid:
|
|
118
|
+
str name | u8 type(0=f32,1=f64,2=vec3f) | u8 leaf_log2 | u8 class | u8 rsv
|
|
119
|
+
f64[3] voxel_size | f64[3] origin_world | background
|
|
120
|
+
u32 n_leaves
|
|
121
|
+
per leaf(按叶原点排序): i32[3] origin | u64[dim³/64] active mask | 值稠密数组
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
- 叶内线性序 `n = x·dim² + y·dim + z`(z 最快),**与 OpenVDB leaf 序一致**,互转零转置。
|
|
125
|
+
- 叶块与 OpenVDB LeafNode 同为稠密缓冲:level set 内部体素的 `-background` 值在
|
|
126
|
+
save/load 后保留。
|
|
127
|
+
- 变换约定与 OpenVDB 线性映射一致:`world = index · voxel_size + origin_world`,
|
|
128
|
+
体素中心在整数索引处。
|
|
129
|
+
|
|
130
|
+
### `.vdb`(OpenVDB 官方流格式,仅显式导出用)
|
|
131
|
+
|
|
132
|
+
字节布局逐一对照 OpenVDB 源码实现(`io/Archive.cc`、`GridDescriptor.cc`、`Compression.h`、
|
|
133
|
+
`tree/*.h`、`math/Maps.h`、`Metadata.h`):
|
|
134
|
+
|
|
135
|
+
- 头 57B:`int64 magic 0x56444220`、u32 文件版本、u32 库主/次版本、u8 offsets 标志、36 字符 UUID;
|
|
136
|
+
- 文件级元数据表 → i32 网格数 → **描述符与网格流交错**(描述符、i64×3 偏移、网格流、下一描述符…);
|
|
137
|
+
- 网格流:u32 压缩标志 → 元数据表(name/class/file_* 统计)→ 变换(ScaleTranslate 家族
|
|
138
|
+
= 类型字符串 + 6×Vec3d)→ 树(`i32 buffer_count`、root 背景 + tiles + 子节点);
|
|
139
|
+
- 树:root → InternalNode(5)(32³ 桌、512×u64 双掩码、值表)→ InternalNode(4)(64 项)→
|
|
140
|
+
LeafNode(8³)(拓扑段只有值掩码,origin 由树路径隐含;缓冲段掩码重写一遍 + 值块);
|
|
141
|
+
- 值块:`io::writeCompressedValues` 语义 —— 1 字节 metadata(0=惰性值全为 +bg、1=-bg、
|
|
142
|
+
2/4/5=带 1~2 个惰性值/选择掩码、6=全量数组)+ 值(按 ACTIVE_MASK 只存 active)。
|
|
143
|
+
|
|
144
|
+
写侧:文件版本 224、压缩 = `COMPRESS_ACTIVE_MASK`(无 zip/blosc),任何 OpenVDB ≥ 9 可读。
|
|
145
|
+
读侧:支持 `COMPRESS_NONE` / `COMPRESS_ZIP`(stdlib zlib)/ `COMPRESS_ACTIVE_MASK` /
|
|
146
|
+
`_HalfFloat` 网格;Blosc 抛出明确错误;root/internode 活动 tile 物化为稠密叶
|
|
147
|
+
(受 `max_tile_voxels` 上限保护)。
|
|
148
|
+
|
|
149
|
+
## 已知边界
|
|
150
|
+
|
|
151
|
+
- `GpuVolume` 只支持 f32 标量网格;写入只改值不改拓扑、不动 active 掩码(掩码是宿主侧
|
|
152
|
+
状态)。结构性编辑后需重新打包。
|
|
153
|
+
- `scatter_particles`/`union_spheres` 是 Python 循环 + 叶切片向量化:千级粒子适用,
|
|
154
|
+
大规模生产需按叶批处理(未做)。`union_spheres` 的 min-of-spheres 距离在重叠粒子间
|
|
155
|
+
的凹桥区是真实距离的上界(Lipschitz 精确),做碰撞/渲染代理足够,精确表面请离线
|
|
156
|
+
用正规表面重建精修。
|
|
157
|
+
- `.vdb` 读侧不支持:Blosc 压缩、实例化网格(instance parent)、点云网格(PointDataGrid)、
|
|
158
|
+
`5_4_3` 以外的树形。写侧不产生 root tile(全部以叶表达)。
|
|
159
|
+
- 与求解器自动微分的边界:XUVDB 提供的是**采样/写入原语**;把 VDB 值直接接入反传图需要
|
|
160
|
+
包一层自定义求导规则(这正是 FastSweeping 等算子不可微的同一边界)。
|
|
161
|
+
|
|
162
|
+
## 与引擎四个落点的对接
|
|
163
|
+
|
|
164
|
+
对应《Genesis × OpenVDB 重合度报告》(`genesis_openvdb_overlap.html`)的结论:
|
|
165
|
+
|
|
166
|
+
1. **刚性 SDF(`utils/sdf.py`,风险最低)**:`geom.sdf_val` 稠密体 → `VdbGrid.from_dense`
|
|
167
|
+
窄带化 → `GpuVolume.sample/sdf_normal` 做内核内碰撞采样;粗块最小值下界的带宽门控
|
|
168
|
+
对应这里"空叶块直接跳过"——稀疏性免费获得。维护/雕刻工装(`csg` + `stamp_sphere`)
|
|
169
|
+
可离线改碰撞体。
|
|
170
|
+
2. **MPM 背景网格(解除 1e9 上限)**:`use_sparse_grid` 被移除的原因在 GPU 端动态拓扑;
|
|
171
|
+
XUVDB 的分工是"拓扑宿主端冻结 + 值内核端可写"。粒子覆盖块用 `fill_box` 声明、每步
|
|
172
|
+
`write_voxels` 回写网格值,是向稀疏 MPM 过渡的最小代价路径(需自行验证与现有
|
|
173
|
+
dense reset 的性能对比)。
|
|
174
|
+
3. **烟尘 / 稳定流体(收益上限最高)**:压力投影每帧回写全网格,短期不建议动求解器;
|
|
175
|
+
现实路径是**出口侧**:每 N 步 `from_dense(density_field)` → `write_vdb` 交给
|
|
176
|
+
Houdini/Blender 体渲染;进口侧用 Houdini 烘的 `.vdb` 作初始条件(`read_vdb` →
|
|
177
|
+
`to_dense`)。
|
|
178
|
+
4. **液体与油(SPH,粒子 ⇄ 体积)**:Genesis 的液体是 Lagrangian SPH(hash grid 邻域,
|
|
179
|
+
VDB 不做邻居搜索),与稀疏体积的接口在两端——
|
|
180
|
+
- **出口(每步/每 N 步)**:`scatter_particles(pos, h, mass)` 把粒子 splat 成密度
|
|
181
|
+
fog 网格(SPH cubic 核、单位积分,质量守恒已测)→ `write_vdb` 给 Houdini/Blender
|
|
182
|
+
体渲染液体,比逐粒子渲染便宜得多;要表面就 `union_spheres(pos, r, band)` 出
|
|
183
|
+
particle level set 表面代理(喷雾/液滴场景),离线可用 OpenVDB 生态精修。
|
|
184
|
+
- **进口**:Houdini 烘的液面/容器 `.vdb` level set → `read_vdb` → `GpuVolume.sample`
|
|
185
|
+
做容器碰撞 SDF 或装液初始条件(与落点①同一套采样机制,SPH 边界碰撞即刚体 SDF
|
|
186
|
+
碰撞的复用)。
|
|
187
|
+
- **油(高黏/两相)**:黏性在 SPH 求解器侧,体积层只管表征——两相液体(油-水、
|
|
188
|
+
油-气)每相一个 fog 网格,即混合分数场 α:`scatter_particles` 按相内粒子各 splat
|
|
189
|
+
一份,导出双网格 `.vdb`,渲染端做 α 混合;界面 SDF 用两相 `union_spheres` 之差
|
|
190
|
+
(`csg 'diff'`)。
|
|
191
|
+
- **在线更新**:`GpuVolume.write_voxels` 可增量回写密度值做实时可视化;拓扑(叶
|
|
192
|
+
集合)按粒子包围盒周期性重打包(拓扑宿主端冻结的同一分工)。
|
|
193
|
+
|
|
194
|
+
## 许可证
|
|
195
|
+
|
|
196
|
+
Apache-2.0(与上游 quadrants、genesis-world 一致),见 [LICENSE](LICENSE)。
|
|
197
|
+
|
|
198
|
+
## 测试
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
pytest tests/ -q
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
覆盖:树编辑/CSG/稠密互转、粒子 splat(质量守恒、可加性、vec3 速度场、双核函数)、
|
|
205
|
+
`union_spheres`(表面/窄带/逐粒子半径/射线命中/与 stamp 复合)、`.xuvdb` 多网格多类型
|
|
206
|
+
往返、`.vdb` 头部字节与偏移校验、f32/f64/vec3/fog/level-set 往返、多叶尺寸重分块、
|
|
207
|
+
负坐标、惰性值压缩路径、`save()` 拒绝 `.vdb` 后缀、GPU 采样对齐宿主三线性、内核写值
|
|
208
|
+
往返、DDA 射线(含空块跳跃、内部出发、tmax 截断、变换偏移)。
|
xuvdb-0.1.0/README.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# XUVDB 太虚 — genesis 自研稀疏体素格式(可编辑 · 与 OpenVDB 互转)
|
|
2
|
+
|
|
3
|
+
> 「不游乎太虚。」——《庄子·知北游》
|
|
4
|
+
> 「太虚无形,气之本体。」——张载《正蒙·太和》
|
|
5
|
+
|
|
6
|
+
`xuvdb` 取「太虚」之音:这是中文里对 VDB「无界而稀疏的索引域」最准确的翻译——无界
|
|
7
|
+
(root 哈希域不设上限),无形(未分配的空间没有形态,采样即得背景值)。
|
|
8
|
+
|
|
9
|
+
`xuvdb` 基于 quadrants 内核:**自己的 `.xuvdb` 格式**(可修改、可在内核里写值),
|
|
10
|
+
以及**与 OpenVDB 的双向互转**(原生 `.vdb` 文件读写,无需安装 OpenVDB;有 `pyopenvdb`
|
|
11
|
+
绑定时还能内存级互转)。
|
|
12
|
+
|
|
13
|
+
## 命名规范(三层名字,各归其位)
|
|
14
|
+
|
|
15
|
+
| 层 | 名字 | 规则 |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| 项目名 | `xuvdb` | 拼音;不用 Open 前缀(ASWF 语境下暗示基金会血统) |
|
|
18
|
+
| 命名空间 / 扩展名 | `xuvdb` / `.xuvdb` | API 标识符一律英文:`xuvdb.prune()`、`xuvdb.VdbGrid`,绝不是 `xuvdb.sunyi()`。道家词只活在概念层(文档题词、日志、可视化标签) |
|
|
19
|
+
| 互转文件 | `.vdb` | **自有格式绝不写 `.vdb` 后缀**(Houdini/Blender/Cycles/Arnold 按扩展名当 OpenVDB 解析,格式不符时静默出错或崩溃,极难定位;`save()` 对 `.vdb` 路径直接拒绝)。要互通就单独导出:`write_vdb()` 产出真正的 OpenVDB 流 |
|
|
20
|
+
|
|
21
|
+
## 为什么是它
|
|
22
|
+
|
|
23
|
+
| | OpenVDB | NanoVDB | XUVDB |
|
|
24
|
+
|---|---|---|---|
|
|
25
|
+
| 结构 | 5 层 B+树,CPU C++ | 同构只读缓冲,GPU | 两级:dict 叶根 + 稠密叶块 |
|
|
26
|
+
| 可修改 | ✅(CPU) | ❌ GPU 只读 | ✅ Python 端任意结构编辑;**内核端可写值** |
|
|
27
|
+
| 可微分包差 | ❌ | ❌ | 值缓冲可被 quadrants 内核读写(拓扑固定) |
|
|
28
|
+
| Python 依赖 | pyopenvdb(需自行构建) | — | 仅 numpy + quadrants |
|
|
29
|
+
|
|
30
|
+
定位不是替换任何求解器,而是补齐 README 物理栈背后的**空间表示层**(落点见下文)。
|
|
31
|
+
|
|
32
|
+
## 安装
|
|
33
|
+
|
|
34
|
+
独立 Python 包(src 布局,`import xuvdb` 即用):
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
uv pip install . # 或 pip install .
|
|
38
|
+
uv pip install -e ".[test]" # 开发模式 + pytest
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
可选 extras:`[openvdb]`(pyopenvdb 内存级互转)、`[genesis]`(运行引擎侧示例需要 genesis-world)、
|
|
42
|
+
`[test]`(pytest)。
|
|
43
|
+
|
|
44
|
+
## 快速上手
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import numpy as np
|
|
48
|
+
import xuvdb
|
|
49
|
+
|
|
50
|
+
# 1) 编辑:窄带 level set 球(体素 0.05,带宽 3 体素)
|
|
51
|
+
grid = xuvdb.VdbGrid(background=3 * 0.05, voxel_size=0.05, leaf_log2=4,
|
|
52
|
+
name="shield", grid_class="level set")
|
|
53
|
+
grid.stamp_sphere((0.3, 0.2, 0.1), radius=0.25, band=3.0)
|
|
54
|
+
grid.stamp_sphere((0.5, 0.2, 0.1), radius=0.10) # CSG:并入第二个球
|
|
55
|
+
grid.fill_box((-2, -2, -2), (2, 2, 2), value=0.0) # 任意稠密填充(示例)
|
|
56
|
+
grid.prune()
|
|
57
|
+
|
|
58
|
+
# 2) 自有格式落盘 / 读回(多网格、f32/f64/vec3)
|
|
59
|
+
xuvdb.save("scene.xuvdb", [grid])
|
|
60
|
+
grids = xuvdb.load("scene.xuvdb")
|
|
61
|
+
|
|
62
|
+
# 3) 与 OpenVDB 互通(显式导出:真正的 OpenVDB 流,Houdini/Blender 直接打开)
|
|
63
|
+
xuvdb.write_vdb("scene.vdb", [grid])
|
|
64
|
+
back = xuvdb.read_vdb("scene.vdb", grid_name="shield")
|
|
65
|
+
|
|
66
|
+
# 4) 内核采样 / 写值(等同 Warp example_nvdb 的用法,但值可写)
|
|
67
|
+
vol = xuvdb.GpuVolume(grid)
|
|
68
|
+
pts = np.array([[0.3, 0.2, 0.36]], dtype=np.float32)
|
|
69
|
+
d = vol.sample(pts, linear=True) # SDF 距离
|
|
70
|
+
n = vol.sdf_normal(pts) # 有限差分表面法向
|
|
71
|
+
vol.write_voxels(pts, np.array([-0.01], np.float32)); vol.sync_to_host()
|
|
72
|
+
|
|
73
|
+
# 5) 粒子 ⇄ 体积(液体/油,见落点④)
|
|
74
|
+
drops = np.array([[0.1, 0.0, 0.0], [0.2, 0.0, 0.0]])
|
|
75
|
+
fog = xuvdb.VdbGrid(voxel_size=0.05, name="liquid", grid_class="fog volume")
|
|
76
|
+
fog.scatter_particles(drops, h=4 * 0.05, weights=1.0) # SPH cubic 核密度 splat
|
|
77
|
+
surf = xuvdb.VdbGrid(background=3 * 0.05, voxel_size=0.05, grid_class="level set")
|
|
78
|
+
surf.union_spheres(drops, radius=0.03) # particle level set 表面代理
|
|
79
|
+
|
|
80
|
+
# 6) DDA 射线(空叶块按块跳过,交叉点二分细化到亚体素)
|
|
81
|
+
t, point, value = xuvdb.ray_surface_hit(grid, (0.3, 0.2, 2.0), (0, 0, -1))
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
与引擎稠密场的桥:
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
# 稠密 qd.field / numpy SDF(如 rigid geom 的 sdf_val)→ 稀疏
|
|
88
|
+
sparse = xuvdb.VdbGrid.from_dense(dense_sdf, origin=ijk_min, voxel_size=h,
|
|
89
|
+
background=band_h, grid_class="level set")
|
|
90
|
+
dense, ijk_min = sparse.to_dense() # 反向:渲染器 / 求解器输入
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 格式
|
|
94
|
+
|
|
95
|
+
### `.xuvdb`(自有格式,小端)
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
"XUVDB" | u8 version=1 | u8 flags | u16 n_grids
|
|
99
|
+
per grid:
|
|
100
|
+
str name | u8 type(0=f32,1=f64,2=vec3f) | u8 leaf_log2 | u8 class | u8 rsv
|
|
101
|
+
f64[3] voxel_size | f64[3] origin_world | background
|
|
102
|
+
u32 n_leaves
|
|
103
|
+
per leaf(按叶原点排序): i32[3] origin | u64[dim³/64] active mask | 值稠密数组
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
- 叶内线性序 `n = x·dim² + y·dim + z`(z 最快),**与 OpenVDB leaf 序一致**,互转零转置。
|
|
107
|
+
- 叶块与 OpenVDB LeafNode 同为稠密缓冲:level set 内部体素的 `-background` 值在
|
|
108
|
+
save/load 后保留。
|
|
109
|
+
- 变换约定与 OpenVDB 线性映射一致:`world = index · voxel_size + origin_world`,
|
|
110
|
+
体素中心在整数索引处。
|
|
111
|
+
|
|
112
|
+
### `.vdb`(OpenVDB 官方流格式,仅显式导出用)
|
|
113
|
+
|
|
114
|
+
字节布局逐一对照 OpenVDB 源码实现(`io/Archive.cc`、`GridDescriptor.cc`、`Compression.h`、
|
|
115
|
+
`tree/*.h`、`math/Maps.h`、`Metadata.h`):
|
|
116
|
+
|
|
117
|
+
- 头 57B:`int64 magic 0x56444220`、u32 文件版本、u32 库主/次版本、u8 offsets 标志、36 字符 UUID;
|
|
118
|
+
- 文件级元数据表 → i32 网格数 → **描述符与网格流交错**(描述符、i64×3 偏移、网格流、下一描述符…);
|
|
119
|
+
- 网格流:u32 压缩标志 → 元数据表(name/class/file_* 统计)→ 变换(ScaleTranslate 家族
|
|
120
|
+
= 类型字符串 + 6×Vec3d)→ 树(`i32 buffer_count`、root 背景 + tiles + 子节点);
|
|
121
|
+
- 树:root → InternalNode(5)(32³ 桌、512×u64 双掩码、值表)→ InternalNode(4)(64 项)→
|
|
122
|
+
LeafNode(8³)(拓扑段只有值掩码,origin 由树路径隐含;缓冲段掩码重写一遍 + 值块);
|
|
123
|
+
- 值块:`io::writeCompressedValues` 语义 —— 1 字节 metadata(0=惰性值全为 +bg、1=-bg、
|
|
124
|
+
2/4/5=带 1~2 个惰性值/选择掩码、6=全量数组)+ 值(按 ACTIVE_MASK 只存 active)。
|
|
125
|
+
|
|
126
|
+
写侧:文件版本 224、压缩 = `COMPRESS_ACTIVE_MASK`(无 zip/blosc),任何 OpenVDB ≥ 9 可读。
|
|
127
|
+
读侧:支持 `COMPRESS_NONE` / `COMPRESS_ZIP`(stdlib zlib)/ `COMPRESS_ACTIVE_MASK` /
|
|
128
|
+
`_HalfFloat` 网格;Blosc 抛出明确错误;root/internode 活动 tile 物化为稠密叶
|
|
129
|
+
(受 `max_tile_voxels` 上限保护)。
|
|
130
|
+
|
|
131
|
+
## 已知边界
|
|
132
|
+
|
|
133
|
+
- `GpuVolume` 只支持 f32 标量网格;写入只改值不改拓扑、不动 active 掩码(掩码是宿主侧
|
|
134
|
+
状态)。结构性编辑后需重新打包。
|
|
135
|
+
- `scatter_particles`/`union_spheres` 是 Python 循环 + 叶切片向量化:千级粒子适用,
|
|
136
|
+
大规模生产需按叶批处理(未做)。`union_spheres` 的 min-of-spheres 距离在重叠粒子间
|
|
137
|
+
的凹桥区是真实距离的上界(Lipschitz 精确),做碰撞/渲染代理足够,精确表面请离线
|
|
138
|
+
用正规表面重建精修。
|
|
139
|
+
- `.vdb` 读侧不支持:Blosc 压缩、实例化网格(instance parent)、点云网格(PointDataGrid)、
|
|
140
|
+
`5_4_3` 以外的树形。写侧不产生 root tile(全部以叶表达)。
|
|
141
|
+
- 与求解器自动微分的边界:XUVDB 提供的是**采样/写入原语**;把 VDB 值直接接入反传图需要
|
|
142
|
+
包一层自定义求导规则(这正是 FastSweeping 等算子不可微的同一边界)。
|
|
143
|
+
|
|
144
|
+
## 与引擎四个落点的对接
|
|
145
|
+
|
|
146
|
+
对应《Genesis × OpenVDB 重合度报告》(`genesis_openvdb_overlap.html`)的结论:
|
|
147
|
+
|
|
148
|
+
1. **刚性 SDF(`utils/sdf.py`,风险最低)**:`geom.sdf_val` 稠密体 → `VdbGrid.from_dense`
|
|
149
|
+
窄带化 → `GpuVolume.sample/sdf_normal` 做内核内碰撞采样;粗块最小值下界的带宽门控
|
|
150
|
+
对应这里"空叶块直接跳过"——稀疏性免费获得。维护/雕刻工装(`csg` + `stamp_sphere`)
|
|
151
|
+
可离线改碰撞体。
|
|
152
|
+
2. **MPM 背景网格(解除 1e9 上限)**:`use_sparse_grid` 被移除的原因在 GPU 端动态拓扑;
|
|
153
|
+
XUVDB 的分工是"拓扑宿主端冻结 + 值内核端可写"。粒子覆盖块用 `fill_box` 声明、每步
|
|
154
|
+
`write_voxels` 回写网格值,是向稀疏 MPM 过渡的最小代价路径(需自行验证与现有
|
|
155
|
+
dense reset 的性能对比)。
|
|
156
|
+
3. **烟尘 / 稳定流体(收益上限最高)**:压力投影每帧回写全网格,短期不建议动求解器;
|
|
157
|
+
现实路径是**出口侧**:每 N 步 `from_dense(density_field)` → `write_vdb` 交给
|
|
158
|
+
Houdini/Blender 体渲染;进口侧用 Houdini 烘的 `.vdb` 作初始条件(`read_vdb` →
|
|
159
|
+
`to_dense`)。
|
|
160
|
+
4. **液体与油(SPH,粒子 ⇄ 体积)**:Genesis 的液体是 Lagrangian SPH(hash grid 邻域,
|
|
161
|
+
VDB 不做邻居搜索),与稀疏体积的接口在两端——
|
|
162
|
+
- **出口(每步/每 N 步)**:`scatter_particles(pos, h, mass)` 把粒子 splat 成密度
|
|
163
|
+
fog 网格(SPH cubic 核、单位积分,质量守恒已测)→ `write_vdb` 给 Houdini/Blender
|
|
164
|
+
体渲染液体,比逐粒子渲染便宜得多;要表面就 `union_spheres(pos, r, band)` 出
|
|
165
|
+
particle level set 表面代理(喷雾/液滴场景),离线可用 OpenVDB 生态精修。
|
|
166
|
+
- **进口**:Houdini 烘的液面/容器 `.vdb` level set → `read_vdb` → `GpuVolume.sample`
|
|
167
|
+
做容器碰撞 SDF 或装液初始条件(与落点①同一套采样机制,SPH 边界碰撞即刚体 SDF
|
|
168
|
+
碰撞的复用)。
|
|
169
|
+
- **油(高黏/两相)**:黏性在 SPH 求解器侧,体积层只管表征——两相液体(油-水、
|
|
170
|
+
油-气)每相一个 fog 网格,即混合分数场 α:`scatter_particles` 按相内粒子各 splat
|
|
171
|
+
一份,导出双网格 `.vdb`,渲染端做 α 混合;界面 SDF 用两相 `union_spheres` 之差
|
|
172
|
+
(`csg 'diff'`)。
|
|
173
|
+
- **在线更新**:`GpuVolume.write_voxels` 可增量回写密度值做实时可视化;拓扑(叶
|
|
174
|
+
集合)按粒子包围盒周期性重打包(拓扑宿主端冻结的同一分工)。
|
|
175
|
+
|
|
176
|
+
## 许可证
|
|
177
|
+
|
|
178
|
+
Apache-2.0(与上游 quadrants、genesis-world 一致),见 [LICENSE](LICENSE)。
|
|
179
|
+
|
|
180
|
+
## 测试
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
pytest tests/ -q
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
覆盖:树编辑/CSG/稠密互转、粒子 splat(质量守恒、可加性、vec3 速度场、双核函数)、
|
|
187
|
+
`union_spheres`(表面/窄带/逐粒子半径/射线命中/与 stamp 复合)、`.xuvdb` 多网格多类型
|
|
188
|
+
往返、`.vdb` 头部字节与偏移校验、f32/f64/vec3/fog/level-set 往返、多叶尺寸重分块、
|
|
189
|
+
负坐标、惰性值压缩路径、`save()` 拒绝 `.vdb` 后缀、GPU 采样对齐宿主三线性、内核写值
|
|
190
|
+
往返、DDA 射线(含空块跳跃、内部出发、tmax 截断、变换偏移)。
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "xuvdb"
|
|
7
|
+
description = "Editable sparse voxel volumes with OpenVDB interop, built on quadrants kernels"
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
dynamic = ["version"]
|
|
10
|
+
requires-python = ">=3.10,<3.14"
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"numpy",
|
|
15
|
+
"quadrants",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.optional-dependencies]
|
|
19
|
+
# engine-side example (examples/test_packages.py) drives a genesis-world simulation
|
|
20
|
+
genesis = ["genesis-world"]
|
|
21
|
+
# in-memory OpenVDB bridge (to_openvdb / from_openvdb) via the official bindings
|
|
22
|
+
openvdb = ["pyopenvdb"]
|
|
23
|
+
test = ["pytest"]
|
|
24
|
+
|
|
25
|
+
[tool.setuptools.dynamic]
|
|
26
|
+
version = { attr = "xuvdb.__version__" }
|
|
27
|
+
|
|
28
|
+
[tool.setuptools.packages.find]
|
|
29
|
+
where = ["src"]
|
|
30
|
+
|
|
31
|
+
[tool.pytest.ini_options]
|
|
32
|
+
testpaths = ["tests"]
|
xuvdb-0.1.0/setup.cfg
ADDED