witwin 0.0.2__tar.gz → 0.4.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.
- witwin-0.4.0/.github/workflows/publish-witwin.yml +210 -0
- {witwin-0.0.2 → witwin-0.4.0}/.gitignore +6 -6
- witwin-0.4.0/PKG-INFO +122 -0
- witwin-0.4.0/README.md +102 -0
- witwin-0.4.0/pyproject.toml +29 -0
- witwin-0.4.0/tests/test_channel_contract_gaps.py +233 -0
- witwin-0.4.0/tests/test_contracts.py +56 -0
- witwin-0.4.0/tests/test_dependency_contract.py +26 -0
- witwin-0.4.0/tests/test_distribution_contract.py +33 -0
- witwin-0.4.0/tests/test_dynamics_contracts.py +164 -0
- {witwin-0.0.2 → witwin-0.4.0}/tests/test_geometry_sdf.py +14 -255
- {witwin-0.0.2 → witwin-0.4.0}/tests/test_geometry_smoke.py +47 -60
- witwin-0.4.0/tests/test_identity_allocation.py +111 -0
- witwin-0.4.0/tests/test_physical_material.py +135 -0
- witwin-0.4.0/tests/test_public_api.py +86 -0
- witwin-0.4.0/tests/test_scene_version_traversal.py +132 -0
- witwin-0.4.0/tests/test_world_contracts.py +424 -0
- witwin-0.4.0/tests/test_world_import_boundary.py +35 -0
- witwin-0.4.0/witwin/core/__init__.py +143 -0
- witwin-0.4.0/witwin/core/antenna.py +407 -0
- witwin-0.4.0/witwin/core/dynamics.py +402 -0
- {witwin-0.0.2 → witwin-0.4.0}/witwin/core/geometry/__init__.py +4 -7
- {witwin-0.0.2 → witwin-0.4.0}/witwin/core/geometry/base.py +79 -12
- {witwin-0.0.2 → witwin-0.4.0}/witwin/core/geometry/mesh.py +314 -64
- witwin-0.4.0/witwin/core/geometry/mesh_sdf.py +481 -0
- witwin-0.4.0/witwin/core/geometry/polygon.py +91 -0
- {witwin-0.0.2 → witwin-0.4.0}/witwin/core/geometry/primitives.py +38 -324
- witwin-0.4.0/witwin/core/identity.py +148 -0
- witwin-0.4.0/witwin/core/material.py +484 -0
- {witwin-0.0.2 → witwin-0.4.0}/witwin/core/math.py +36 -2
- witwin-0.4.0/witwin/core/scene.py +887 -0
- witwin-0.4.0/witwin/core/structure.py +215 -0
- witwin-0.0.2/.github/workflows/publish-witwin.yml +0 -287
- witwin-0.0.2/PKG-INFO +0 -53
- witwin-0.0.2/README.md +0 -30
- witwin-0.0.2/benchmark/benchmark_mesh_sdf.py +0 -193
- witwin-0.0.2/hatch_build.py +0 -17
- witwin-0.0.2/pyproject.toml +0 -42
- witwin-0.0.2/scripts/build_mesh_sdf_cuda_prebuilt.py +0 -68
- witwin-0.0.2/tests/test_scene_base.py +0 -18
- witwin-0.0.2/witwin/core/__init__.py +0 -70
- witwin-0.0.2/witwin/core/geometry/cuda/__init__.py +0 -9
- witwin-0.0.2/witwin/core/geometry/cuda/backend.py +0 -177
- witwin-0.0.2/witwin/core/geometry/cuda/build.py +0 -247
- witwin-0.0.2/witwin/core/geometry/cuda/extension.cpp +0 -43
- witwin-0.0.2/witwin/core/geometry/cuda/mesh_sdf_kernels.cu +0 -688
- witwin-0.0.2/witwin/core/geometry/mesh_sdf.py +0 -761
- witwin-0.0.2/witwin/core/geometry/smpl.py +0 -229
- witwin-0.0.2/witwin/core/material.py +0 -239
- witwin-0.0.2/witwin/core/scene.py +0 -38
- witwin-0.0.2/witwin/core/scene_to_mitsuba.py +0 -138
- {witwin-0.0.2 → witwin-0.4.0}/tests/conftest.py +0 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
name: Build and publish witwin
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
- "codex/**"
|
|
8
|
+
pull_request:
|
|
9
|
+
release:
|
|
10
|
+
types: [published]
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
validate_release:
|
|
15
|
+
if: github.event_name != 'release' || (startsWith(github.event.release.tag_name, 'witwin-v') && !github.event.release.prerelease)
|
|
16
|
+
name: Validate release
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
outputs:
|
|
19
|
+
package_dir: ${{ steps.package_dir.outputs.path }}
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- name: Check out repository
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Set up Python
|
|
26
|
+
uses: actions/setup-python@v5
|
|
27
|
+
with:
|
|
28
|
+
python-version: "3.11"
|
|
29
|
+
|
|
30
|
+
- name: Resolve package directory
|
|
31
|
+
id: package_dir
|
|
32
|
+
shell: bash
|
|
33
|
+
run: |
|
|
34
|
+
if [ -f pyproject.toml ]; then
|
|
35
|
+
echo "path=." >> "$GITHUB_OUTPUT"
|
|
36
|
+
elif [ -f core/pyproject.toml ]; then
|
|
37
|
+
echo "path=core" >> "$GITHUB_OUTPUT"
|
|
38
|
+
else
|
|
39
|
+
echo "Unable to find pyproject.toml for the witwin package." >&2
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
- name: Validate release tag and package version
|
|
44
|
+
if: github.event_name == 'release'
|
|
45
|
+
shell: bash
|
|
46
|
+
env:
|
|
47
|
+
PACKAGE_DIR: ${{ steps.package_dir.outputs.path }}
|
|
48
|
+
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
|
49
|
+
run: |
|
|
50
|
+
python - <<'PY'
|
|
51
|
+
import os
|
|
52
|
+
import re
|
|
53
|
+
import sys
|
|
54
|
+
import tomllib
|
|
55
|
+
from pathlib import Path
|
|
56
|
+
|
|
57
|
+
tag = os.environ["RELEASE_TAG"]
|
|
58
|
+
match = re.fullmatch(r"witwin-v(?P<version>[0-9A-Za-z.+_-]+)", tag)
|
|
59
|
+
if match is None:
|
|
60
|
+
print(f"Release tag '{tag}' must match 'witwin-v<version>'.", file=sys.stderr)
|
|
61
|
+
raise SystemExit(1)
|
|
62
|
+
|
|
63
|
+
expected_version = match.group("version")
|
|
64
|
+
pyproject_path = Path(os.environ["PACKAGE_DIR"]) / "pyproject.toml"
|
|
65
|
+
project = tomllib.loads(pyproject_path.read_text(encoding="utf-8"))["project"]
|
|
66
|
+
if project["name"] != "witwin":
|
|
67
|
+
print(f"Expected package name 'witwin', found '{project['name']}'.", file=sys.stderr)
|
|
68
|
+
raise SystemExit(1)
|
|
69
|
+
if project["version"] != expected_version:
|
|
70
|
+
print(
|
|
71
|
+
f"Release tag version '{expected_version}' does not match "
|
|
72
|
+
f"pyproject version '{project['version']}'.",
|
|
73
|
+
file=sys.stderr,
|
|
74
|
+
)
|
|
75
|
+
raise SystemExit(1)
|
|
76
|
+
PY
|
|
77
|
+
|
|
78
|
+
build_wheel:
|
|
79
|
+
name: Build pure Python wheel
|
|
80
|
+
needs: validate_release
|
|
81
|
+
runs-on: ubuntu-latest
|
|
82
|
+
|
|
83
|
+
steps:
|
|
84
|
+
- name: Check out repository
|
|
85
|
+
uses: actions/checkout@v4
|
|
86
|
+
|
|
87
|
+
- name: Set up Python
|
|
88
|
+
uses: actions/setup-python@v5
|
|
89
|
+
with:
|
|
90
|
+
python-version: "3.11"
|
|
91
|
+
|
|
92
|
+
- name: Build wheel
|
|
93
|
+
shell: bash
|
|
94
|
+
env:
|
|
95
|
+
PACKAGE_DIR: ${{ needs.validate_release.outputs.package_dir }}
|
|
96
|
+
run: |
|
|
97
|
+
python -m pip install --upgrade pip build
|
|
98
|
+
python -m build --wheel "$PACKAGE_DIR"
|
|
99
|
+
|
|
100
|
+
- name: Verify pure Python wheel
|
|
101
|
+
shell: bash
|
|
102
|
+
env:
|
|
103
|
+
PACKAGE_DIR: ${{ needs.validate_release.outputs.package_dir }}
|
|
104
|
+
run: |
|
|
105
|
+
python - <<'PY'
|
|
106
|
+
import os
|
|
107
|
+
import zipfile
|
|
108
|
+
from pathlib import Path
|
|
109
|
+
|
|
110
|
+
wheels = list((Path(os.environ["PACKAGE_DIR"]) / "dist").glob("*.whl"))
|
|
111
|
+
assert len(wheels) == 1, wheels
|
|
112
|
+
wheel = wheels[0]
|
|
113
|
+
assert wheel.name.endswith("-py3-none-any.whl"), wheel.name
|
|
114
|
+
native_suffixes = (".c", ".cc", ".cpp", ".cxx", ".cu", ".cuh", ".h", ".hpp", ".so", ".pyd", ".dll")
|
|
115
|
+
native = [
|
|
116
|
+
name for name in zipfile.ZipFile(wheel).namelist()
|
|
117
|
+
if name.lower().endswith(native_suffixes)
|
|
118
|
+
]
|
|
119
|
+
assert not native, native
|
|
120
|
+
PY
|
|
121
|
+
|
|
122
|
+
- name: Upload wheel artifact
|
|
123
|
+
uses: actions/upload-artifact@v4
|
|
124
|
+
with:
|
|
125
|
+
name: wheel
|
|
126
|
+
path: ${{ needs.validate_release.outputs.package_dir }}/dist/*.whl
|
|
127
|
+
if-no-files-found: error
|
|
128
|
+
|
|
129
|
+
build_sdist:
|
|
130
|
+
name: Build source distribution
|
|
131
|
+
needs: validate_release
|
|
132
|
+
runs-on: ubuntu-latest
|
|
133
|
+
|
|
134
|
+
steps:
|
|
135
|
+
- name: Check out repository
|
|
136
|
+
uses: actions/checkout@v4
|
|
137
|
+
|
|
138
|
+
- name: Set up Python
|
|
139
|
+
uses: actions/setup-python@v5
|
|
140
|
+
with:
|
|
141
|
+
python-version: "3.11"
|
|
142
|
+
|
|
143
|
+
- name: Build source distribution
|
|
144
|
+
shell: bash
|
|
145
|
+
env:
|
|
146
|
+
PACKAGE_DIR: ${{ needs.validate_release.outputs.package_dir }}
|
|
147
|
+
run: |
|
|
148
|
+
python -m pip install --upgrade pip build
|
|
149
|
+
python -m build --sdist "$PACKAGE_DIR"
|
|
150
|
+
|
|
151
|
+
- name: Verify pure Python source distribution
|
|
152
|
+
shell: bash
|
|
153
|
+
env:
|
|
154
|
+
PACKAGE_DIR: ${{ needs.validate_release.outputs.package_dir }}
|
|
155
|
+
run: |
|
|
156
|
+
python - <<'PY'
|
|
157
|
+
import os
|
|
158
|
+
import tarfile
|
|
159
|
+
from pathlib import Path
|
|
160
|
+
|
|
161
|
+
archives = list((Path(os.environ["PACKAGE_DIR"]) / "dist").glob("*.tar.gz"))
|
|
162
|
+
assert len(archives) == 1, archives
|
|
163
|
+
native_suffixes = (".c", ".cc", ".cpp", ".cxx", ".cu", ".cuh", ".h", ".hpp")
|
|
164
|
+
with tarfile.open(archives[0]) as archive:
|
|
165
|
+
native = [
|
|
166
|
+
member.name for member in archive.getmembers()
|
|
167
|
+
if member.isfile() and member.name.lower().endswith(native_suffixes)
|
|
168
|
+
]
|
|
169
|
+
assert not native, native
|
|
170
|
+
PY
|
|
171
|
+
|
|
172
|
+
- name: Upload source distribution artifact
|
|
173
|
+
uses: actions/upload-artifact@v4
|
|
174
|
+
with:
|
|
175
|
+
name: sdist
|
|
176
|
+
path: ${{ needs.validate_release.outputs.package_dir }}/dist/*.tar.gz
|
|
177
|
+
if-no-files-found: error
|
|
178
|
+
|
|
179
|
+
publish:
|
|
180
|
+
name: Publish to PyPI
|
|
181
|
+
if: github.event_name == 'release'
|
|
182
|
+
needs:
|
|
183
|
+
- build_wheel
|
|
184
|
+
- build_sdist
|
|
185
|
+
runs-on: ubuntu-latest
|
|
186
|
+
permissions:
|
|
187
|
+
contents: read
|
|
188
|
+
id-token: write
|
|
189
|
+
environment:
|
|
190
|
+
name: pypi
|
|
191
|
+
url: https://pypi.org/project/witwin/
|
|
192
|
+
|
|
193
|
+
steps:
|
|
194
|
+
- name: Download wheel artifact
|
|
195
|
+
uses: actions/download-artifact@v4
|
|
196
|
+
with:
|
|
197
|
+
name: wheel
|
|
198
|
+
path: dist
|
|
199
|
+
|
|
200
|
+
- name: Download source distribution artifact
|
|
201
|
+
uses: actions/download-artifact@v4
|
|
202
|
+
with:
|
|
203
|
+
name: sdist
|
|
204
|
+
path: dist
|
|
205
|
+
|
|
206
|
+
- name: Publish distributions to PyPI
|
|
207
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
208
|
+
with:
|
|
209
|
+
packages-dir: dist
|
|
210
|
+
skip-existing: true
|
|
@@ -171,9 +171,6 @@ venv.bak/
|
|
|
171
171
|
|
|
172
172
|
# mkdocs documentation
|
|
173
173
|
/site
|
|
174
|
-
.slangtorch_cache/
|
|
175
|
-
.fdtd_runtime_*.slang
|
|
176
|
-
.adjoint_kernels_runtime_*.slang
|
|
177
174
|
*.png
|
|
178
175
|
*.npy
|
|
179
176
|
*.npz
|
|
@@ -229,6 +226,9 @@ __marimo__/
|
|
|
229
226
|
# Streamlit
|
|
230
227
|
.streamlit/secrets.toml
|
|
231
228
|
|
|
232
|
-
#
|
|
233
|
-
|
|
234
|
-
|
|
229
|
+
# Repository-local agent and test scratch directories
|
|
230
|
+
.pytest_tmp/
|
|
231
|
+
.codex_tmp/
|
|
232
|
+
.codex-tmp/
|
|
233
|
+
.test-tmp/
|
|
234
|
+
.tmp/
|
witwin-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: witwin
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Witwin shared logical-world, geometry, material, and dynamics contracts
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Requires-Python: <3.15,>=3.10
|
|
7
|
+
Requires-Dist: numpy>=1.24
|
|
8
|
+
Requires-Dist: torch>=2.10
|
|
9
|
+
Provides-Extra: all
|
|
10
|
+
Requires-Dist: witwin-genesis<0.2,>=0.1; extra == 'all'
|
|
11
|
+
Requires-Dist: witwin-maxwell<0.3,>=0.2; extra == 'all'
|
|
12
|
+
Requires-Dist: witwin-radar<0.4,>=0.3; extra == 'all'
|
|
13
|
+
Provides-Extra: genesis
|
|
14
|
+
Requires-Dist: witwin-genesis<0.2,>=0.1; extra == 'genesis'
|
|
15
|
+
Provides-Extra: maxwell
|
|
16
|
+
Requires-Dist: witwin-maxwell<0.3,>=0.2; extra == 'maxwell'
|
|
17
|
+
Provides-Extra: radar
|
|
18
|
+
Requires-Dist: witwin-radar<0.4,>=0.3; extra == 'radar'
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# WiTwin Core
|
|
22
|
+
|
|
23
|
+
WiTwin Core is the shared logical-world and geometry package of the WiTwin stack. It defines solver-neutral scene, material, antenna, dynamics, snapshot, and geometry contracts. Solver packages compile those contracts into their own runtime resources and results.
|
|
24
|
+
|
|
25
|
+
## Get Started
|
|
26
|
+
|
|
27
|
+
Core supports CPython 3.10-3.14 and PyTorch 2.10 or newer.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install witwin
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Pure Python Distribution
|
|
34
|
+
|
|
35
|
+
Core ships as a platform-independent `py3-none-any` wheel and contains no C++ or
|
|
36
|
+
CUDA sources. Mesh SDF evaluation always has a PyTorch implementation. Solver
|
|
37
|
+
packages may register their own optional accelerators; Maxwell owns and packages
|
|
38
|
+
the CUDA mesh-SDF implementation used by Maxwell workflows.
|
|
39
|
+
|
|
40
|
+
## What It Provides
|
|
41
|
+
|
|
42
|
+
- Canonical `Scene`, `SceneSnapshot`, `Structure`, and stable logical IDs
|
|
43
|
+
- Solver-neutral `PhysicalMaterial`, layers, roughness, dispersion, and phase-screen assignments
|
|
44
|
+
- Logical TX/RX antenna state, planar receiver grids, rigid motion, trajectories, and deformation state
|
|
45
|
+
- Stable structure, surface, material, assignment, primitive, and antenna identities
|
|
46
|
+
- Typed mesh UV topology and explicit finite/perfect conductor material identity
|
|
47
|
+
- Runtime-checkable `GeometrySpec` and `MaterialSpec` contracts
|
|
48
|
+
- Shared analytic geometry primitives and differentiable mesh/SDF utilities
|
|
49
|
+
- Granular topology, geometry, material, and assignment versions
|
|
50
|
+
|
|
51
|
+
Core owns the logical `Scene`; each solver owns its compiled scene lifecycle, native resources, caches, and results. Radar-specific SMPL geometry lives in `witwin.radar.geometry`; Maxwell-specific `PolySlab` geometry lives in `witwin.maxwell.geometry`.
|
|
52
|
+
|
|
53
|
+
## Stable API
|
|
54
|
+
|
|
55
|
+
The supported public API is the set of names exported by `witwin.core.__all__`.
|
|
56
|
+
Applications should import contracts, geometry types, identity allocators, and
|
|
57
|
+
math utilities directly from `witwin.core`. CI locks this symbol set so adding,
|
|
58
|
+
removing, or renaming a public symbol requires an intentional API change.
|
|
59
|
+
Modules and names outside that export set are implementation details and may be
|
|
60
|
+
reorganized between releases.
|
|
61
|
+
|
|
62
|
+
## Coordinate and Motion Semantics
|
|
63
|
+
|
|
64
|
+
Antenna orientation maps endpoint-local coordinates into world coordinates.
|
|
65
|
+
Euler orientation is `(yaw, pitch, roll)` in radians with intrinsic Z-Y-X
|
|
66
|
+
rotations; quaternion orientation is scalar-first `(w, x, y, z)`.
|
|
67
|
+
Polarization and antenna element positions are endpoint-local, while
|
|
68
|
+
`ReceiverGrid.x_axis` and `y_axis` are world-frame grid directions. Core's
|
|
69
|
+
Torch rotation and projection helpers preserve autograd.
|
|
70
|
+
|
|
71
|
+
Snapshot deformation is composed before motion: absolute deformation vertices
|
|
72
|
+
replace authored local mesh vertices, or offsets are added to them; authored
|
|
73
|
+
geometry transforms are applied next. `RigidMotion.rotation` then left-composes
|
|
74
|
+
the authored rotation and its world-frame translation is added last. Endpoint
|
|
75
|
+
motion follows the same rule after antenna-local orientation.
|
|
76
|
+
|
|
77
|
+
`PhysicalMaterial(conductor_model="perfect")`, or the equivalent
|
|
78
|
+
`PhysicalMaterial.perfect_conductor()`, carries explicit PEC identity while
|
|
79
|
+
keeping finite logical material parameters. Solver-owned compilers map that
|
|
80
|
+
identity to their native material ABI; Core does not encode native model IDs or
|
|
81
|
+
effective conductivity constants.
|
|
82
|
+
|
|
83
|
+
## 0.4 Migration
|
|
84
|
+
|
|
85
|
+
- `Mesh.vertices`, `Mesh.faces`, `Mesh.world_vertices`, and
|
|
86
|
+
`Mesh.bounds_world` are tensor-valued contracts. `bounds_world` has shape
|
|
87
|
+
`(2, 3)`, with minimum coordinates in row 0 and maximum coordinates in row 1.
|
|
88
|
+
- Tensor-authored geometry is never implicitly moved to the requested device.
|
|
89
|
+
Place authored tensors explicitly before construction; conflicting devices
|
|
90
|
+
fail loudly.
|
|
91
|
+
- CUDA-authored meshes do not run host topology diagnostics or build a host BVH.
|
|
92
|
+
`fill_mode="auto"` therefore requires an explicit topology decision before
|
|
93
|
+
an SDF query.
|
|
94
|
+
- `Material` is removed. `PhysicalMaterial` is the only public name for the
|
|
95
|
+
material contract; the two were aliases of one class. Replace
|
|
96
|
+
`from witwin.core import Material` with
|
|
97
|
+
`from witwin.core import PhysicalMaterial`.
|
|
98
|
+
- `Structure` and `MaterialAssignment` now live in `witwin.core.structure`
|
|
99
|
+
rather than `witwin.core.material`, which keeps only material specifications.
|
|
100
|
+
Both remain exported from `witwin.core`, so package-level imports are
|
|
101
|
+
unaffected.
|
|
102
|
+
- Continuous physical quantities are annotated `ScalarLike`
|
|
103
|
+
(`float | torch.Tensor`) instead of `Any`. `ScalarLike` and `ComplexLike` are
|
|
104
|
+
exported from `witwin.core`. This is a typing change only; the accepted
|
|
105
|
+
runtime values are unchanged.
|
|
106
|
+
- `witwin.core.identity` documents its two allocation modes. Use
|
|
107
|
+
`reserve_*_id(value)` whenever identities must be reproducible across
|
|
108
|
+
processes; `new_*_id()` draws from a process-global counter and is
|
|
109
|
+
order-dependent.
|
|
110
|
+
|
|
111
|
+
## Related Solvers
|
|
112
|
+
|
|
113
|
+
- [WiTwin Maxwell](https://github.com/witwin-ai/witwin-maxwell)
|
|
114
|
+
- [WiTwin Radar](https://github.com/witwin-ai/witwin-radar)
|
|
115
|
+
|
|
116
|
+
## Developer
|
|
117
|
+
|
|
118
|
+
<a href="http://xingyuchen.me/">
|
|
119
|
+
<img src="https://github.com/Asixa.png" alt="Xingyu Chen" width="48" height="48" style="border-radius:50%;">
|
|
120
|
+
</a>
|
|
121
|
+
|
|
122
|
+
[Xingyu Chen](http://xingyuchen.me/)
|
witwin-0.4.0/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# WiTwin Core
|
|
2
|
+
|
|
3
|
+
WiTwin Core is the shared logical-world and geometry package of the WiTwin stack. It defines solver-neutral scene, material, antenna, dynamics, snapshot, and geometry contracts. Solver packages compile those contracts into their own runtime resources and results.
|
|
4
|
+
|
|
5
|
+
## Get Started
|
|
6
|
+
|
|
7
|
+
Core supports CPython 3.10-3.14 and PyTorch 2.10 or newer.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install witwin
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Pure Python Distribution
|
|
14
|
+
|
|
15
|
+
Core ships as a platform-independent `py3-none-any` wheel and contains no C++ or
|
|
16
|
+
CUDA sources. Mesh SDF evaluation always has a PyTorch implementation. Solver
|
|
17
|
+
packages may register their own optional accelerators; Maxwell owns and packages
|
|
18
|
+
the CUDA mesh-SDF implementation used by Maxwell workflows.
|
|
19
|
+
|
|
20
|
+
## What It Provides
|
|
21
|
+
|
|
22
|
+
- Canonical `Scene`, `SceneSnapshot`, `Structure`, and stable logical IDs
|
|
23
|
+
- Solver-neutral `PhysicalMaterial`, layers, roughness, dispersion, and phase-screen assignments
|
|
24
|
+
- Logical TX/RX antenna state, planar receiver grids, rigid motion, trajectories, and deformation state
|
|
25
|
+
- Stable structure, surface, material, assignment, primitive, and antenna identities
|
|
26
|
+
- Typed mesh UV topology and explicit finite/perfect conductor material identity
|
|
27
|
+
- Runtime-checkable `GeometrySpec` and `MaterialSpec` contracts
|
|
28
|
+
- Shared analytic geometry primitives and differentiable mesh/SDF utilities
|
|
29
|
+
- Granular topology, geometry, material, and assignment versions
|
|
30
|
+
|
|
31
|
+
Core owns the logical `Scene`; each solver owns its compiled scene lifecycle, native resources, caches, and results. Radar-specific SMPL geometry lives in `witwin.radar.geometry`; Maxwell-specific `PolySlab` geometry lives in `witwin.maxwell.geometry`.
|
|
32
|
+
|
|
33
|
+
## Stable API
|
|
34
|
+
|
|
35
|
+
The supported public API is the set of names exported by `witwin.core.__all__`.
|
|
36
|
+
Applications should import contracts, geometry types, identity allocators, and
|
|
37
|
+
math utilities directly from `witwin.core`. CI locks this symbol set so adding,
|
|
38
|
+
removing, or renaming a public symbol requires an intentional API change.
|
|
39
|
+
Modules and names outside that export set are implementation details and may be
|
|
40
|
+
reorganized between releases.
|
|
41
|
+
|
|
42
|
+
## Coordinate and Motion Semantics
|
|
43
|
+
|
|
44
|
+
Antenna orientation maps endpoint-local coordinates into world coordinates.
|
|
45
|
+
Euler orientation is `(yaw, pitch, roll)` in radians with intrinsic Z-Y-X
|
|
46
|
+
rotations; quaternion orientation is scalar-first `(w, x, y, z)`.
|
|
47
|
+
Polarization and antenna element positions are endpoint-local, while
|
|
48
|
+
`ReceiverGrid.x_axis` and `y_axis` are world-frame grid directions. Core's
|
|
49
|
+
Torch rotation and projection helpers preserve autograd.
|
|
50
|
+
|
|
51
|
+
Snapshot deformation is composed before motion: absolute deformation vertices
|
|
52
|
+
replace authored local mesh vertices, or offsets are added to them; authored
|
|
53
|
+
geometry transforms are applied next. `RigidMotion.rotation` then left-composes
|
|
54
|
+
the authored rotation and its world-frame translation is added last. Endpoint
|
|
55
|
+
motion follows the same rule after antenna-local orientation.
|
|
56
|
+
|
|
57
|
+
`PhysicalMaterial(conductor_model="perfect")`, or the equivalent
|
|
58
|
+
`PhysicalMaterial.perfect_conductor()`, carries explicit PEC identity while
|
|
59
|
+
keeping finite logical material parameters. Solver-owned compilers map that
|
|
60
|
+
identity to their native material ABI; Core does not encode native model IDs or
|
|
61
|
+
effective conductivity constants.
|
|
62
|
+
|
|
63
|
+
## 0.4 Migration
|
|
64
|
+
|
|
65
|
+
- `Mesh.vertices`, `Mesh.faces`, `Mesh.world_vertices`, and
|
|
66
|
+
`Mesh.bounds_world` are tensor-valued contracts. `bounds_world` has shape
|
|
67
|
+
`(2, 3)`, with minimum coordinates in row 0 and maximum coordinates in row 1.
|
|
68
|
+
- Tensor-authored geometry is never implicitly moved to the requested device.
|
|
69
|
+
Place authored tensors explicitly before construction; conflicting devices
|
|
70
|
+
fail loudly.
|
|
71
|
+
- CUDA-authored meshes do not run host topology diagnostics or build a host BVH.
|
|
72
|
+
`fill_mode="auto"` therefore requires an explicit topology decision before
|
|
73
|
+
an SDF query.
|
|
74
|
+
- `Material` is removed. `PhysicalMaterial` is the only public name for the
|
|
75
|
+
material contract; the two were aliases of one class. Replace
|
|
76
|
+
`from witwin.core import Material` with
|
|
77
|
+
`from witwin.core import PhysicalMaterial`.
|
|
78
|
+
- `Structure` and `MaterialAssignment` now live in `witwin.core.structure`
|
|
79
|
+
rather than `witwin.core.material`, which keeps only material specifications.
|
|
80
|
+
Both remain exported from `witwin.core`, so package-level imports are
|
|
81
|
+
unaffected.
|
|
82
|
+
- Continuous physical quantities are annotated `ScalarLike`
|
|
83
|
+
(`float | torch.Tensor`) instead of `Any`. `ScalarLike` and `ComplexLike` are
|
|
84
|
+
exported from `witwin.core`. This is a typing change only; the accepted
|
|
85
|
+
runtime values are unchanged.
|
|
86
|
+
- `witwin.core.identity` documents its two allocation modes. Use
|
|
87
|
+
`reserve_*_id(value)` whenever identities must be reproducible across
|
|
88
|
+
processes; `new_*_id()` draws from a process-global counter and is
|
|
89
|
+
order-dependent.
|
|
90
|
+
|
|
91
|
+
## Related Solvers
|
|
92
|
+
|
|
93
|
+
- [WiTwin Maxwell](https://github.com/witwin-ai/witwin-maxwell)
|
|
94
|
+
- [WiTwin Radar](https://github.com/witwin-ai/witwin-radar)
|
|
95
|
+
|
|
96
|
+
## Developer
|
|
97
|
+
|
|
98
|
+
<a href="http://xingyuchen.me/">
|
|
99
|
+
<img src="https://github.com/Asixa.png" alt="Xingyu Chen" width="48" height="48" style="border-radius:50%;">
|
|
100
|
+
</a>
|
|
101
|
+
|
|
102
|
+
[Xingyu Chen](http://xingyuchen.me/)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "witwin"
|
|
7
|
+
version = "0.4.0"
|
|
8
|
+
description = "Witwin shared logical-world, geometry, material, and dynamics contracts"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10,<3.15"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
|
|
13
|
+
dependencies = [
|
|
14
|
+
"numpy>=1.24",
|
|
15
|
+
"torch>=2.10",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.optional-dependencies]
|
|
19
|
+
maxwell = ["witwin-maxwell>=0.2,<0.3"]
|
|
20
|
+
radar = ["witwin-radar>=0.3,<0.4"]
|
|
21
|
+
genesis = ["witwin-genesis>=0.1,<0.2"]
|
|
22
|
+
all = [
|
|
23
|
+
"witwin-maxwell>=0.2,<0.3",
|
|
24
|
+
"witwin-radar>=0.3,<0.4",
|
|
25
|
+
"witwin-genesis>=0.1,<0.2",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[tool.hatch.build.targets.wheel]
|
|
29
|
+
packages = ["witwin"]
|