conquer3d 0.2.1__tar.gz → 0.2.5__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.
Files changed (71) hide show
  1. {conquer3d-0.2.1/conquer3d.egg-info → conquer3d-0.2.5}/PKG-INFO +54 -15
  2. conquer3d-0.2.5/README.md +109 -0
  3. conquer3d-0.2.5/conquer3d/_C.pyi +191 -0
  4. conquer3d-0.2.5/conquer3d/_C.so +0 -0
  5. conquer3d-0.2.5/conquer3d/__init__.py +8 -0
  6. conquer3d-0.2.5/conquer3d/creation/__init__.py +5 -0
  7. conquer3d-0.2.5/conquer3d/creation/triangle_creation.py +23 -0
  8. conquer3d-0.2.5/conquer3d/csrc/binds/creation/triangle_creation.cpp +13 -0
  9. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/binds/data_structure/bvh.cpp +89 -2
  10. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/binds/data_structure/gs_bvh.cpp +1 -1
  11. conquer3d-0.2.5/conquer3d/csrc/binds/data_structure/mesh_bvh.cpp +36 -0
  12. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/binds/data_structure/pgs_bvh.cpp +1 -1
  13. conquer3d-0.2.5/conquer3d/csrc/binds/data_structure/triangle_mesh.cpp +361 -0
  14. conquer3d-0.2.5/conquer3d/csrc/creation/triangle_creation.h +97 -0
  15. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/bvh.cu +173 -0
  16. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/bvh.h +36 -4
  17. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/kdtree.h +40 -33
  18. conquer3d-0.2.5/conquer3d/csrc/data_structure/mesh_bvh.cu +205 -0
  19. conquer3d-0.2.5/conquer3d/csrc/data_structure/mesh_bvh.h +33 -0
  20. conquer3d-0.2.5/conquer3d/csrc/data_structure/triangle_mesh.cu +398 -0
  21. conquer3d-0.2.5/conquer3d/csrc/data_structure/triangle_mesh.h +139 -0
  22. conquer3d-0.2.5/conquer3d/csrc/primitive/edge.h +31 -0
  23. conquer3d-0.2.5/conquer3d/csrc/primitive/ray.h +62 -0
  24. conquer3d-0.2.5/conquer3d/csrc/primitive/triangles.h +156 -0
  25. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/pybind.cpp +7 -0
  26. conquer3d-0.2.5/conquer3d/data_structure/__init__.py +13 -0
  27. {conquer3d-0.2.1 → conquer3d-0.2.5/conquer3d.egg-info}/PKG-INFO +54 -15
  28. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d.egg-info/SOURCES.txt +13 -0
  29. {conquer3d-0.2.1 → conquer3d-0.2.5}/pyproject.toml +2 -2
  30. {conquer3d-0.2.1 → conquer3d-0.2.5}/setup.py +1 -11
  31. conquer3d-0.2.1/README.md +0 -70
  32. conquer3d-0.2.1/conquer3d/_C.pyi +0 -69
  33. conquer3d-0.2.1/conquer3d/_C.so +0 -0
  34. conquer3d-0.2.1/conquer3d/__init__.py +0 -5
  35. conquer3d-0.2.1/conquer3d/data_structure/__init__.py +0 -8
  36. {conquer3d-0.2.1 → conquer3d-0.2.5}/LICENSE +0 -0
  37. {conquer3d-0.2.1 → conquer3d-0.2.5}/MANIFEST.in +0 -0
  38. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/binds/data_structure/kdtree.cpp +0 -0
  39. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/binds/primitive/gs.cpp +0 -0
  40. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/binds/primitive/pgs.cpp +0 -0
  41. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/check.h +0 -0
  42. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/constants.h +0 -0
  43. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/gs_bvh.h +0 -0
  44. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/kdtree.cu +0 -0
  45. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/pgs_bvh.h +0 -0
  46. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/zcurve.h +0 -0
  47. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/maths/f2x2.h +0 -0
  48. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/maths/f3x1.h +0 -0
  49. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/maths/f3x3.h +0 -0
  50. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/maths/f3x4.h +0 -0
  51. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/maths/f4x1.h +0 -0
  52. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/maths/f4x4.h +0 -0
  53. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/maths/maths.h +0 -0
  54. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/maths/ops.h +0 -0
  55. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/primitive/aabb.h +0 -0
  56. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/primitive/gs.cu +0 -0
  57. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/primitive/gs.h +0 -0
  58. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/primitive/gs_aabb.cu +0 -0
  59. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/primitive/gs_math.cuh +0 -0
  60. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/primitive/pgs.cu +0 -0
  61. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/primitive/pgs.h +0 -0
  62. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/primitive/pgs_aabb.cu +0 -0
  63. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/csrc/primitive/pgs_math.cuh +0 -0
  64. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/primitive/__init__.py +0 -0
  65. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/primitive/gs.py +0 -0
  66. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d/primitive/pgs.py +0 -0
  67. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d.egg-info/dependency_links.txt +0 -0
  68. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d.egg-info/not-zip-safe +0 -0
  69. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d.egg-info/requires.txt +0 -0
  70. {conquer3d-0.2.1 → conquer3d-0.2.5}/conquer3d.egg-info/top_level.txt +0 -0
  71. {conquer3d-0.2.1 → conquer3d-0.2.5}/setup.cfg +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conquer3d
3
- Version: 0.2.1
3
+ Version: 0.2.5
4
4
  Summary: Geometric Cuda Tool Box
5
5
  Author-email: Do Hoang Khoi <khoido8899@gmail.com>
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/KhoiDOO/conquer3d
8
8
  Project-URL: Repository, https://github.com/KhoiDOO/conquer3d.git
9
9
  Project-URL: Documentation, https://github.com/KhoiDOO/conquer3d#readme
@@ -68,17 +68,54 @@ twine upload dist/* --verbose
68
68
  ## Research Paper
69
69
  ```bibtex
70
70
  @inproceedings{2383795.2383801,
71
- author = {Karras, Tero},
72
- title = {Maximizing parallelism in the construction of BVHs, octrees, and k-d trees},
73
- year = {2012},
74
- isbn = {9783905674415},
75
- publisher = {Eurographics Association},
76
- address = {Goslar, DEU},
77
- booktitle = {Proceedings of the Fourth ACM SIGGRAPH / Eurographics Conference on High-Performance Graphics},
78
- pages = {33–37},
79
- numpages = {5},
80
- location = {Paris, France},
81
- series = {EGGH-HPG'12}
71
+ author = {Karras, Tero},
72
+ title = {Maximizing parallelism in the construction of BVHs, octrees, and k-d trees},
73
+ year = {2012},
74
+ isbn = {9783905674415},
75
+ publisher = {Eurographics Association},
76
+ address = {Goslar, DEU},
77
+ booktitle = {Proceedings of the Fourth ACM SIGGRAPH / Eurographics Conference on High-Performance Graphics},
78
+ pages = {33–37},
79
+ numpages = {5},
80
+ location = {Paris, France},
81
+ series = {EGGH-HPG'12}
82
+ }
83
+ ```
84
+
85
+ ```bibtex
86
+ @article{10.1080/10867651.1997.10487472,
87
+ author = {M\"{o}ller, Tomas},
88
+ title = {A fast triangle-triangle intersection test},
89
+ year = {1997},
90
+ issue_date = {1997},
91
+ publisher = {A. K. Peters, Ltd.},
92
+ address = {USA},
93
+ volume = {2},
94
+ number = {2},
95
+ issn = {1086-7651},
96
+ url = {https://doi.org/10.1080/10867651.1997.10487472},
97
+ doi = {10.1080/10867651.1997.10487472},
98
+ journal = {J. Graph. Tools},
99
+ month = nov,
100
+ pages = {25–30},
101
+ numpages = {6}
102
+ }
103
+ ```
104
+
105
+ ```bibtex
106
+ @inproceedings{10.1145/1198555.1198746,
107
+ author = {M\"{o}ller, Tomas and Trumbore, Ben},
108
+ title = {Fast, minimum storage ray/triangle intersection},
109
+ year = {2005},
110
+ isbn = {9781450378338},
111
+ publisher = {Association for Computing Machinery},
112
+ address = {New York, NY, USA},
113
+ url = {https://doi.org/10.1145/1198555.1198746},
114
+ doi = {10.1145/1198555.1198746},
115
+ pages = {7–es},
116
+ keywords = {base transformation, intersection, ray tracing, ray/triangle-intersection},
117
+ location = {Los Angeles, California},
118
+ series = {SIGGRAPH '05}
82
119
  }
83
120
  ```
84
121
 
@@ -90,5 +127,7 @@ series = {EGGH-HPG'12}
90
127
  ## Repository
91
128
  - [cuBQL](https://github.com/NVIDIA/cuBQL)
92
129
  - [cudaKDTree](https://github.com/ingowald/cudaKDTree)
93
- - [Kaolin] (https://github.com/NVIDIAGameWorks/kaolin)
94
- - [Pytorch3D] (https://github.com/facebookresearch/pytorch3d)
130
+ - [Kaolin](https://github.com/NVIDIAGameWorks/kaolin)
131
+ - [Pytorch3D](https://github.com/facebookresearch/pytorch3d)
132
+ - [Open3D](https://www.open3d.org/)
133
+ - [trimesh](https://github.com/mikedh/trimesh)
@@ -0,0 +1,109 @@
1
+ # Conquer3D
2
+
3
+ # Setup
4
+
5
+ ## Build from source
6
+ ```bash
7
+ git clone https://github.com/KhoiDOO/geocutool.git
8
+ pip install pybind11-stubgen
9
+
10
+ # then
11
+ cd geocutool
12
+ pip install -e . --no-build-isolation
13
+
14
+ # or
15
+ pip install pybind11-stubgen
16
+ pip install git+https://github.com/KhoiDOO/geocutool.git --no-build-isolation
17
+ ```
18
+
19
+ ## To run notebooks in examples
20
+ ```bash
21
+ conda create -c conda-forge -n geocutool python=3.10 gxx_linux-64=13 gcc_linux-64=13 -y
22
+ conda activate geocutool
23
+
24
+ conda install nvidia::cuda-toolkit==12.8.2 -y
25
+
26
+ pip install torch==2.8.0 torchvision==0.23.0 torchaudio==2.8.0 --index-url https://download.pytorch.org/whl/cu128
27
+
28
+ pip install pybind11-stubgen
29
+ pip install git+https://github.com/KhoiDOO/geocutool.git --no-build-isolation
30
+
31
+ pip install plotly open3d jupyter trimesh
32
+ ```
33
+
34
+ # Development
35
+ ```bash
36
+ pip install build twine
37
+ rm -rf dist
38
+ python -m build --sdist
39
+ twine upload dist/* --verbose
40
+ ```
41
+
42
+ # Reference
43
+
44
+ ## Research Paper
45
+ ```bibtex
46
+ @inproceedings{2383795.2383801,
47
+ author = {Karras, Tero},
48
+ title = {Maximizing parallelism in the construction of BVHs, octrees, and k-d trees},
49
+ year = {2012},
50
+ isbn = {9783905674415},
51
+ publisher = {Eurographics Association},
52
+ address = {Goslar, DEU},
53
+ booktitle = {Proceedings of the Fourth ACM SIGGRAPH / Eurographics Conference on High-Performance Graphics},
54
+ pages = {33–37},
55
+ numpages = {5},
56
+ location = {Paris, France},
57
+ series = {EGGH-HPG'12}
58
+ }
59
+ ```
60
+
61
+ ```bibtex
62
+ @article{10.1080/10867651.1997.10487472,
63
+ author = {M\"{o}ller, Tomas},
64
+ title = {A fast triangle-triangle intersection test},
65
+ year = {1997},
66
+ issue_date = {1997},
67
+ publisher = {A. K. Peters, Ltd.},
68
+ address = {USA},
69
+ volume = {2},
70
+ number = {2},
71
+ issn = {1086-7651},
72
+ url = {https://doi.org/10.1080/10867651.1997.10487472},
73
+ doi = {10.1080/10867651.1997.10487472},
74
+ journal = {J. Graph. Tools},
75
+ month = nov,
76
+ pages = {25–30},
77
+ numpages = {6}
78
+ }
79
+ ```
80
+
81
+ ```bibtex
82
+ @inproceedings{10.1145/1198555.1198746,
83
+ author = {M\"{o}ller, Tomas and Trumbore, Ben},
84
+ title = {Fast, minimum storage ray/triangle intersection},
85
+ year = {2005},
86
+ isbn = {9781450378338},
87
+ publisher = {Association for Computing Machinery},
88
+ address = {New York, NY, USA},
89
+ url = {https://doi.org/10.1145/1198555.1198746},
90
+ doi = {10.1145/1198555.1198746},
91
+ pages = {7–es},
92
+ keywords = {base transformation, intersection, ray tracing, ray/triangle-intersection},
93
+ location = {Los Angeles, California},
94
+ series = {SIGGRAPH '05}
95
+ }
96
+ ```
97
+
98
+ ## Blog Post
99
+ - [Thinking Parallel, Part I: Collision Detection on the GPU](https://developer.nvidia.com/blog/thinking-parallel-part-i-collision-detection-gpu/)
100
+ - [Thinking Parallel, Part II: Tree Traversal on the GPU](https://developer.nvidia.com/blog/thinking-parallel-part-ii-tree-traversal-gpu/)
101
+ - [Thinking Parallel, Part III: Tree Construction on the GPU](https://developer.nvidia.com/blog/thinking-parallel-part-iii-tree-construction-gpu/)
102
+
103
+ ## Repository
104
+ - [cuBQL](https://github.com/NVIDIA/cuBQL)
105
+ - [cudaKDTree](https://github.com/ingowald/cudaKDTree)
106
+ - [Kaolin](https://github.com/NVIDIAGameWorks/kaolin)
107
+ - [Pytorch3D](https://github.com/facebookresearch/pytorch3d)
108
+ - [Open3D](https://www.open3d.org/)
109
+ - [trimesh](https://github.com/mikedh/trimesh)
@@ -0,0 +1,191 @@
1
+ """
2
+ Geocutool Python bindings
3
+ """
4
+ from __future__ import annotations
5
+ import torch
6
+ import typing
7
+ __all__: list[str] = ['BVH', 'GSBVH', 'KDTree', 'MeshBVH', 'PGSBVH', 'TriangleMesh', 'compute_gs_aabb_func', 'compute_gs_covi_func', 'create_sphere', 'solve_gs_neighbor_mahalanobis_radius_func', 'solve_pgs_cluster_tangency_radius_func']
8
+ class BVH:
9
+ def __init__(self, in_aabb_mins: torch.Tensor, in_aabb_maxs: torch.Tensor) -> None:
10
+ """
11
+ Construct and build the Karras LBVH from Gaussian AABBs.
12
+ """
13
+ def query(self, query_aabb_mins: torch.Tensor, query_aabb_maxs: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
14
+ """
15
+ Query the BVH with bounding boxes or segments. Returns (query_ids, object_ids).
16
+ """
17
+ def query_ray(self, ray_origins: torch.Tensor, ray_dirs: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
18
+ """
19
+ Query the BVH with rays. Returns (query_ids, object_ids).
20
+ """
21
+ def query_self(self) -> tuple[torch.Tensor, torch.Tensor]:
22
+ """
23
+ Query the BVH against itself. Returns unique overlapping (query_ids, object_ids).
24
+ """
25
+ class GSBVH(BVH):
26
+ def __init__(self, in_aabb_mins: torch.Tensor, in_aabb_maxs: torch.Tensor) -> None:
27
+ """
28
+ Construct and build the Karras LBVH for Gaussians.
29
+ """
30
+ def query_edge(self, edge_starts: torch.Tensor, edge_ends: torch.Tensor, means: torch.Tensor, opacities: torch.Tensor, covis: torch.Tensor, isos: float | torch.Tensor = 11.345) -> tuple[torch.Tensor, torch.Tensor]:
31
+ """
32
+ Find the single highest-density Gaussian intersected by each line segment.
33
+ """
34
+ def query_edge_pair(self, edge_starts: torch.Tensor, edge_ends: torch.Tensor, means: torch.Tensor, covis: torch.Tensor, isos: float | torch.Tensor = 11.345, max_capacity: int = 10000000) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
35
+ """
36
+ Find all Gaussians intersected by each line segment.
37
+ """
38
+ def query_voxel_pair(self, vx_aabb_mins: torch.Tensor, vx_aabb_maxs: torch.Tensor, means: torch.Tensor, covis: torch.Tensor, opacities: torch.Tensor, gs_aabb_mins: torch.Tensor, gs_aabb_maxs: torch.Tensor, contact_points: torch.Tensor, isos: float | torch.Tensor = 11.345, ar_threshold: float = 0.0, p_threshold: float = 0.0, return_centroids: bool = False, max_capacity: int = 10000000) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor | None, torch.Tensor | None]:
39
+ """
40
+ Perform exact Broad-to-Narrow phase intersection between Voxels and Gaussians.
41
+ """
42
+ class KDTree:
43
+ def __init__(self, points: torch.Tensor) -> None:
44
+ """
45
+ Initializes and builds the KDTree on the GPU.
46
+ """
47
+ def query(self, query_points: torch.Tensor, k: int = 1, exclude_self: bool = False) -> tuple[torch.Tensor, torch.Tensor]:
48
+ """
49
+ Queries the KDTree for the K nearest neighbors.
50
+ """
51
+ class MeshBVH(BVH):
52
+ def __init__(self, in_aabb_mins: torch.Tensor, in_aabb_maxs: torch.Tensor) -> None:
53
+ """
54
+ Construct MeshBVH from Triangle AABBs.
55
+ """
56
+ def get_ray_intersection(self, ray_origins: torch.Tensor, ray_dirs: torch.Tensor, vertices: torch.Tensor, triangles: torch.Tensor, return_distance: bool = False) -> typing.Any:
57
+ """
58
+ Find all ray-triangle intersections. Returns (ray_ids, triangle_ids, intersect_points, [distances])
59
+ """
60
+ def get_self_intersection(self, vertices: torch.Tensor, triangles: torch.Tensor) -> torch.Tensor:
61
+ """
62
+ Find all self-intersecting triangle pairs
63
+ """
64
+ def is_self_intersection(self, vertices: torch.Tensor, triangles: torch.Tensor) -> bool:
65
+ """
66
+ Check if there are any self-intersecting triangle pairs
67
+ """
68
+ class PGSBVH(BVH):
69
+ def __init__(self, in_aabb_mins: torch.Tensor, in_aabb_maxs: torch.Tensor) -> None:
70
+ """
71
+ Construct and build the Karras LBVH for Planar Gaussians.
72
+ """
73
+ def query_edge(self, edge_starts: torch.Tensor, edge_ends: torch.Tensor, means: torch.Tensor, normals: torch.Tensor, opacities: torch.Tensor, covis: torch.Tensor, isos: float | torch.Tensor = 11.345) -> tuple[torch.Tensor, torch.Tensor]:
74
+ """
75
+ Find the single highest-density PGS intersected by each line segment.
76
+ """
77
+ def query_voxel_pair(self, vx_aabb_mins: torch.Tensor, vx_aabb_maxs: torch.Tensor, means: torch.Tensor, normals: torch.Tensor, covis: torch.Tensor, gs_aabb_mins: torch.Tensor, gs_aabb_maxs: torch.Tensor, isos: float | torch.Tensor = 11.345, return_centroids: bool = False, return_centroid_densities: bool = False, max_capacity: int = 10000000) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor | None, torch.Tensor | None]:
78
+ """
79
+ Perform exact Broad-to-Narrow phase intersection between Voxels and PGS.
80
+ """
81
+ class TriangleMesh:
82
+ def __init__(self, in_vertices: torch.Tensor, in_triangles: torch.Tensor, in_vertex_normals: torch.Tensor | None = None, in_vertex_colors: torch.Tensor | None = None) -> None:
83
+ ...
84
+ def build_bvh(self) -> MeshBVH:
85
+ ...
86
+ def compute_edges_to_triangle_map(self) -> None:
87
+ ...
88
+ def compute_triangle_areas(self) -> None:
89
+ ...
90
+ def compute_triangle_normals(self) -> None:
91
+ ...
92
+ def compute_vertices_to_triangle_map(self) -> None:
93
+ ...
94
+ def get_edges_to_triangle_map(self) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
95
+ ...
96
+ def get_non_manifold_vertices(self) -> torch.Tensor:
97
+ ...
98
+ def get_ray_intersection(self, ray_origins: torch.Tensor, ray_dirs: torch.Tensor, return_distance: bool = False) -> typing.Any:
99
+ """
100
+ Find all ray-triangle intersections. Returns (ray_ids, triangle_ids, intersect_points, [distances])
101
+ """
102
+ def get_self_intersection(self) -> torch.Tensor:
103
+ """
104
+ Find all self-intersecting triangle pairs
105
+ """
106
+ def get_vertices_to_triangle_map(self) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
107
+ ...
108
+ def is_edge_manifold(self, allow_boundary_edge: bool = True) -> bool:
109
+ ...
110
+ def is_manifold(self, allow_boundary_edge: bool = True) -> bool:
111
+ ...
112
+ def is_self_intersection(self) -> bool:
113
+ """
114
+ Check if there are any self-intersecting triangle pairs
115
+ """
116
+ def is_vertex_manifold(self) -> bool:
117
+ ...
118
+ def remove_triangles_by_mask(self, keep_mask: torch.Tensor) -> None:
119
+ ...
120
+ @property
121
+ def bvh(self) -> MeshBVH:
122
+ ...
123
+ @property
124
+ def edge_to_triangle_counts(self) -> torch.Tensor:
125
+ ...
126
+ @property
127
+ def edge_to_triangle_indices(self) -> torch.Tensor:
128
+ ...
129
+ @property
130
+ def edge_to_triangle_offsets(self) -> torch.Tensor:
131
+ ...
132
+ @property
133
+ def edges(self) -> torch.Tensor:
134
+ ...
135
+ @property
136
+ def euler_characteristic(self) -> int:
137
+ ...
138
+ @property
139
+ def genus(self) -> int:
140
+ ...
141
+ @property
142
+ def num_triangles(self) -> int:
143
+ ...
144
+ @property
145
+ def surface_area(self) -> torch.Tensor:
146
+ ...
147
+ @property
148
+ def triangle_areas(self) -> torch.Tensor:
149
+ ...
150
+ @property
151
+ def triangle_normals(self) -> torch.Tensor:
152
+ ...
153
+ @property
154
+ def triangles(self) -> torch.Tensor:
155
+ ...
156
+ @property
157
+ def vertex_colors(self) -> torch.Tensor:
158
+ ...
159
+ @property
160
+ def vertex_normals(self) -> torch.Tensor:
161
+ ...
162
+ @property
163
+ def vertex_to_triangle_counts(self) -> torch.Tensor:
164
+ ...
165
+ @property
166
+ def vertex_to_triangle_indices(self) -> torch.Tensor:
167
+ ...
168
+ @property
169
+ def vertex_to_triangle_offsets(self) -> torch.Tensor:
170
+ ...
171
+ @property
172
+ def vertices(self) -> torch.Tensor:
173
+ ...
174
+ def compute_gs_aabb_func(means: torch.Tensor, scales: torch.Tensor, covis: torch.Tensor, isos: torch.Tensor | None, iso: float, tol: float, level: int) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
175
+ """
176
+ Compute AABB for 3D Gaussians
177
+ """
178
+ def compute_gs_covi_func(means: torch.Tensor, rotations: torch.Tensor, scales: torch.Tensor, rotnorm: bool, tol: float, level: int) -> torch.Tensor:
179
+ """
180
+ Compute covariance matrices for 3D Gaussians
181
+ """
182
+ def create_sphere(sectors: int = 32, stacks: int = 16, radius: float = 1.0) -> tuple[torch.Tensor, torch.Tensor]:
183
+ """
184
+ Creates a UV sphere returning (vertices, triangles) tensors on the CPU.
185
+ """
186
+ def solve_gs_neighbor_mahalanobis_radius_func(means: torch.Tensor, covis: torch.Tensor, k: int) -> torch.Tensor:
187
+ """
188
+ Solve Gaussian Neighbor Mahalanobis Radius
189
+ """
190
+ def solve_pgs_cluster_tangency_radius_func(means: torch.Tensor, normals: torch.Tensor, covis: torch.Tensor, k: int = 16) -> tuple[torch.Tensor, torch.Tensor]:
191
+ ...
Binary file
@@ -0,0 +1,8 @@
1
+ import torch
2
+
3
+ from . import _C
4
+ from . import creation
5
+ from . import data_structure
6
+ from . import primitive
7
+
8
+ __all__ = ['_C', 'creation', 'data_structure', 'primitive']
@@ -0,0 +1,5 @@
1
+ from .triangle_creation import create_sphere
2
+
3
+ __all__ = [
4
+ "create_sphere",
5
+ ]
@@ -0,0 +1,23 @@
1
+ import torch
2
+ from typing import Tuple
3
+
4
+ from .._C import create_sphere as create_sphere_c
5
+
6
+ def create_sphere(
7
+ sectors: int = 32,
8
+ stacks: int = 16,
9
+ radius: float = 1.0
10
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
11
+ """
12
+ Creates a UV sphere returning (vertices, triangles) tensors on the CPU.
13
+
14
+ Args:
15
+ sectors (int, optional): Number of longitudinal sectors. Defaults to 32.
16
+ stacks (int, optional): Number of latitudinal stacks. Defaults to 16.
17
+ radius (float, optional): Radius of the sphere. Defaults to 1.0.
18
+
19
+ Returns:
20
+ vertices: (N, 3) float32 tensor of vertex positions.
21
+ triangles: (M, 3) int32 tensor of triangle indices.
22
+ """
23
+ return create_sphere_c(sectors, stacks, radius)
@@ -0,0 +1,13 @@
1
+ #include <torch/extension.h>
2
+ #include <pybind11/pybind11.h>
3
+ #include "../../creation/triangle_creation.h"
4
+
5
+ namespace py = pybind11;
6
+
7
+ void bind_creation_triangle_creation(py::module_& m) {
8
+ m.def("create_sphere", &triangle_creation::create_sphere,
9
+ py::arg("sectors") = 32,
10
+ py::arg("stacks") = 16,
11
+ py::arg("radius") = 1.0f,
12
+ "Creates a UV sphere returning (vertices, triangles) tensors on the CPU.");
13
+ }
@@ -120,7 +120,86 @@ std::tuple<torch::Tensor, torch::Tensor> BVH::query(
120
120
  );
121
121
  }
122
122
 
123
- void bind_ds_bvh(py::module &m)
123
+ std::tuple<torch::Tensor, torch::Tensor> BVH::query_self()
124
+ {
125
+ auto options_int64 = this->aabb_mins.options().dtype(torch::kInt64);
126
+
127
+ if (this->num_objects == 0) {
128
+ throw std::runtime_error("Cannot query BVH with 0 objects.");
129
+ }
130
+
131
+ torch::Tensor out_query_ids = torch::empty({BVH_MAX_CAPACITY}, options_int64);
132
+ torch::Tensor out_object_ids = torch::empty({BVH_MAX_CAPACITY}, options_int64);
133
+ torch::Tensor hit_counter = torch::zeros({1}, options_int64);
134
+
135
+ bvh::query_self(
136
+ this->num_objects,
137
+ reinterpret_cast<const float3 *>(this->aabb_mins.data_ptr<float>()),
138
+ reinterpret_cast<const float3 *>(this->aabb_maxs.data_ptr<float>()),
139
+ reinterpret_cast<const int2 *>(this->bvh_children.data_ptr<int>()),
140
+ reinterpret_cast<const int *>(this->object_ids.data_ptr<int>()),
141
+ reinterpret_cast<int64_t *>(out_query_ids.data_ptr<int64_t>()),
142
+ reinterpret_cast<int64_t *>(out_object_ids.data_ptr<int64_t>()),
143
+ reinterpret_cast<int64_t *>(hit_counter.data_ptr<int64_t>()),
144
+ static_cast<int64_t>(BVH_MAX_CAPACITY)
145
+ );
146
+
147
+ int64_t num_hits = hit_counter.item<int64_t>();
148
+ num_hits = std::min(num_hits, static_cast<int64_t>(BVH_MAX_CAPACITY));
149
+
150
+ return std::make_tuple(
151
+ out_query_ids.slice(0, 0, num_hits),
152
+ out_object_ids.slice(0, 0, num_hits)
153
+ );
154
+ }
155
+
156
+ std::tuple<torch::Tensor, torch::Tensor> BVH::query_ray(
157
+ const torch::Tensor &ray_origins,
158
+ const torch::Tensor &ray_dirs)
159
+ {
160
+ CHECK_INPUT(ray_origins);
161
+ CHECK_INPUT(ray_dirs);
162
+ TORCH_CHECK(ray_origins.scalar_type() == torch::kFloat32, "ray_origins must be float32");
163
+ TORCH_CHECK(ray_dirs.scalar_type() == torch::kFloat32, "ray_dirs must be float32");
164
+ TORCH_CHECK(ray_origins.size(1) == 3, "ray_origins must have shape (M, 3)");
165
+ TORCH_CHECK(ray_dirs.size(1) == 3, "ray_dirs must have shape (M, 3)");
166
+
167
+ const uint32_t num_queries = static_cast<uint32_t>(ray_origins.size(0));
168
+ auto options_int64 = ray_origins.options().dtype(torch::kInt64);
169
+
170
+ if (num_queries == 0) {
171
+ throw std::runtime_error("Cannot query BVH with 0 queries.");
172
+ }
173
+
174
+ torch::Tensor out_query_ids = torch::empty({BVH_MAX_CAPACITY}, options_int64);
175
+ torch::Tensor out_object_ids = torch::empty({BVH_MAX_CAPACITY}, options_int64);
176
+ torch::Tensor hit_counter = torch::zeros({1}, options_int64);
177
+
178
+ bvh::query_ray(
179
+ num_queries,
180
+ this->num_objects,
181
+ reinterpret_cast<const float3 *>(ray_origins.data_ptr<float>()),
182
+ reinterpret_cast<const float3 *>(ray_dirs.data_ptr<float>()),
183
+ reinterpret_cast<const float3 *>(this->aabb_mins.data_ptr<float>()),
184
+ reinterpret_cast<const float3 *>(this->aabb_maxs.data_ptr<float>()),
185
+ reinterpret_cast<const int2 *>(this->bvh_children.data_ptr<int>()),
186
+ reinterpret_cast<const int *>(this->object_ids.data_ptr<int>()),
187
+ reinterpret_cast<int64_t *>(out_query_ids.data_ptr<int64_t>()),
188
+ reinterpret_cast<int64_t *>(out_object_ids.data_ptr<int64_t>()),
189
+ reinterpret_cast<int64_t *>(hit_counter.data_ptr<int64_t>()),
190
+ static_cast<int64_t>(BVH_MAX_CAPACITY)
191
+ );
192
+
193
+ int64_t num_hits = hit_counter.item<int64_t>();
194
+ num_hits = std::min(num_hits, static_cast<int64_t>(BVH_MAX_CAPACITY));
195
+
196
+ return std::make_tuple(
197
+ out_query_ids.slice(0, 0, num_hits),
198
+ out_object_ids.slice(0, 0, num_hits)
199
+ );
200
+ }
201
+
202
+ void bind_ds_bvh(py::module_& m)
124
203
  {
125
204
  py::class_<BVH>(m, "BVH")
126
205
  .def(py::init<const torch::Tensor &, const torch::Tensor &>(),
@@ -131,5 +210,13 @@ void bind_ds_bvh(py::module &m)
131
210
  .def("query", &BVH::query,
132
211
  py::arg("query_aabb_mins"),
133
212
  py::arg("query_aabb_maxs"),
134
- "Query the BVH with bounding boxes or segments. Returns (query_ids, object_ids).");
213
+ "Query the BVH with bounding boxes or segments. Returns (query_ids, object_ids).")
214
+
215
+ .def("query_self", &BVH::query_self,
216
+ "Query the BVH against itself. Returns unique overlapping (query_ids, object_ids).")
217
+
218
+ .def("query_ray", &BVH::query_ray,
219
+ py::arg("ray_origins"),
220
+ py::arg("ray_dirs"),
221
+ "Query the BVH with rays. Returns (query_ids, object_ids).");
135
222
  }
@@ -312,7 +312,7 @@ std::tuple<torch::Tensor, torch::Tensor> GSBVH::query_edge(
312
312
  return std::make_tuple(hit_mask, out_gaus_ids);
313
313
  }
314
314
 
315
- void bind_ds_gs_bvh(py::module &m)
315
+ void bind_ds_gs_bvh(py::module_& m)
316
316
  {
317
317
  py::class_<GSBVH, BVH>(m, "GSBVH")
318
318
  .def(py::init<const torch::Tensor &, const torch::Tensor &>(),
@@ -0,0 +1,36 @@
1
+ #include <torch/extension.h>
2
+ #include "../../data_structure/mesh_bvh.h"
3
+ #include <pybind11/pybind11.h>
4
+
5
+ namespace py = pybind11;
6
+
7
+ void bind_ds_mesh_bvh(py::module_& m)
8
+ {
9
+ py::class_<MeshBVH, BVH>(m, "MeshBVH")
10
+ .def(py::init<const torch::Tensor &, const torch::Tensor &>(),
11
+ py::arg("in_aabb_mins"),
12
+ py::arg("in_aabb_maxs"),
13
+ "Construct MeshBVH from Triangle AABBs.")
14
+ .def("get_self_intersection", &MeshBVH::get_self_intersection,
15
+ py::arg("vertices"),
16
+ py::arg("triangles"),
17
+ "Find all self-intersecting triangle pairs")
18
+ .def("is_self_intersection", &MeshBVH::is_self_intersection,
19
+ py::arg("vertices"),
20
+ py::arg("triangles"),
21
+ "Check if there are any self-intersecting triangle pairs")
22
+ .def("get_ray_intersection", [](MeshBVH& self, const torch::Tensor& ray_origins, const torch::Tensor& ray_dirs, const torch::Tensor& vertices, const torch::Tensor& triangles, bool return_distance) -> py::object {
23
+ auto result = self.get_ray_intersection(ray_origins, ray_dirs, vertices, triangles, return_distance);
24
+ if (return_distance) {
25
+ return py::cast(result);
26
+ } else {
27
+ return py::cast(std::make_tuple(std::get<0>(result), std::get<1>(result), std::get<2>(result)));
28
+ }
29
+ },
30
+ py::arg("ray_origins"),
31
+ py::arg("ray_dirs"),
32
+ py::arg("vertices"),
33
+ py::arg("triangles"),
34
+ py::arg("return_distance") = false,
35
+ "Find all ray-triangle intersections. Returns (ray_ids, triangle_ids, intersect_points, [distances])");
36
+ }
@@ -222,7 +222,7 @@ std::tuple<torch::Tensor, torch::Tensor> PGSBVH::query_edge(
222
222
  return std::make_tuple(hit_mask, out_gaus_ids);
223
223
  }
224
224
 
225
- void bind_ds_pgs_bvh(py::module &m)
225
+ void bind_ds_pgs_bvh(py::module_& m)
226
226
  {
227
227
  py::class_<PGSBVH, BVH>(m, "PGSBVH")
228
228
  .def(py::init<const torch::Tensor &, const torch::Tensor &>(),