conquer3d 0.3.4__tar.gz → 0.3.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.
- {conquer3d-0.3.4/conquer3d.egg-info → conquer3d-0.3.5}/PKG-INFO +3 -1
- {conquer3d-0.3.4 → conquer3d-0.3.5}/README.md +1 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data_structure/grid.py +18 -1
- conquer3d-0.3.5/conquer3d/io/__init__.py +2 -0
- conquer3d-0.3.5/conquer3d/io/obj.py +42 -0
- conquer3d-0.3.5/conquer3d/io/off.py +23 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5/conquer3d.egg-info}/PKG-INFO +3 -1
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d.egg-info/requires.txt +1 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/pyproject.toml +2 -1
- conquer3d-0.3.4/conquer3d/io/__init__.py +0 -0
- conquer3d-0.3.4/conquer3d/io/obj.py +0 -46
- conquer3d-0.3.4/conquer3d/io/off.py +0 -84
- {conquer3d-0.3.4 → conquer3d-0.3.5}/LICENSE +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/MANIFEST.in +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/_C.pyi +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/_C.so +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/__init__.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/conversion/__init__.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/conversion/grid.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/conversion/mesh.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/creation/__init__.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/creation/triangle_creation.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/creation/triangle_creation.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/data_structure/bvh.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/data_structure/grid.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/data_structure/gs_bvh.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/data_structure/kdtree.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/data_structure/mesh_bvh.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/data_structure/pgs_bvh.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/data_structure/triangle_mesh.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/ops/chamfer.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/ops/mc.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/primitive/gs.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/primitive/pgs.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/primitive/ray.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/binds/primitive/triangle.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/check.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/constants.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/creation/triangle_creation.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/data_structure/bvh.cu +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/data_structure/bvh.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/data_structure/gs_bvh.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/data_structure/kdtree.cu +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/data_structure/kdtree.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/data_structure/mesh_bvh.cu +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/data_structure/mesh_bvh.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/data_structure/pgs_bvh.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/data_structure/triangle_mesh.cu +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/data_structure/triangle_mesh.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/data_structure/zcurve.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/maths/f2x2.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/maths/f3x1.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/maths/f3x3.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/maths/f3x4.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/maths/f4x1.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/maths/f4x4.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/maths/maths.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/maths/ops.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/ops/chamfer.cu +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/ops/chamfer.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/ops/mc.cu +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/ops/mc.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/ops/mc_data.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/primitive/aabb.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/primitive/edge.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/primitive/gs.cu +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/primitive/gs.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/primitive/gs_aabb.cu +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/primitive/gs_math.cuh +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/primitive/pgs.cu +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/primitive/pgs.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/primitive/pgs_aabb.cu +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/primitive/pgs_math.cuh +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/primitive/ray.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/primitive/triangle.h +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/csrc/pybind.cpp +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/__init__.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/assets/__init__.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/assets/common.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/assets/iphigenia.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/collate/__init__.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/collate/mesh.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/collate/sparse_tensor.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/dataset/__init__.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/dataset/base_mesh.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/dataset/digit3d.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/transform/__init__.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/transform/base.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/transform/ops.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data/transform/vertex.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data_structure/__init__.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/data_structure/bmesh.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/ops/__init__.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/ops/delaunay_triangulation.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/ops/diff_marching_cubes.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/ops/distance.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/ops/marching_cubes.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/ops/marching_tetrahedra.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/primitive/__init__.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/primitive/gs.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d/primitive/pgs.py +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d.egg-info/SOURCES.txt +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d.egg-info/dependency_links.txt +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d.egg-info/not-zip-safe +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/conquer3d.egg-info/top_level.txt +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/setup.cfg +0 -0
- {conquer3d-0.3.4 → conquer3d-0.3.5}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: conquer3d
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.5
|
|
4
4
|
Summary: Geometric Cuda Tool Box
|
|
5
5
|
Author-email: Do Hoang Khoi <khoido8899@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -13,6 +13,7 @@ Requires-Python: >=3.9
|
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Requires-Dist: torch>=2.0.0
|
|
16
|
+
Requires-Dist: meshio>=5.3.5
|
|
16
17
|
Requires-Dist: gdown
|
|
17
18
|
Provides-Extra: cuda
|
|
18
19
|
Requires-Dist: cuda-toolkit==12.8.2; extra == "cuda"
|
|
@@ -49,6 +50,7 @@ pip install git+https://github.com/KhoiDOO/geocutool.git --no-build-isolation
|
|
|
49
50
|
```bash
|
|
50
51
|
conda create -c conda-forge -n geocutool python=3.10 gxx_linux-64=13 gcc_linux-64=13 -y
|
|
51
52
|
conda activate geocutool
|
|
53
|
+
conda install -c conda-forge sparsehash -y
|
|
52
54
|
|
|
53
55
|
conda install nvidia::cuda-toolkit==12.8.2 -y
|
|
54
56
|
|
|
@@ -20,6 +20,7 @@ pip install git+https://github.com/KhoiDOO/geocutool.git --no-build-isolation
|
|
|
20
20
|
```bash
|
|
21
21
|
conda create -c conda-forge -n geocutool python=3.10 gxx_linux-64=13 gcc_linux-64=13 -y
|
|
22
22
|
conda activate geocutool
|
|
23
|
+
conda install -c conda-forge sparsehash -y
|
|
23
24
|
|
|
24
25
|
conda install nvidia::cuda-toolkit==12.8.2 -y
|
|
25
26
|
|
|
@@ -62,4 +62,21 @@ def compute_active_voxels(
|
|
|
62
62
|
Returns:
|
|
63
63
|
torch.Tensor: An int64 tensor containing the indices of the active voxels.
|
|
64
64
|
"""
|
|
65
|
-
return _C.compute_active_voxels(voxels.contiguous(), sdf.contiguous(), iso)
|
|
65
|
+
return _C.compute_active_voxels(voxels.contiguous(), sdf.contiguous(), iso)
|
|
66
|
+
|
|
67
|
+
def create_random_points_ball(n_points: int, radius: float = 1.0, device: str = 'cuda') -> torch.Tensor:
|
|
68
|
+
"""
|
|
69
|
+
Creates a set of random points uniformly distributed inside a sphere.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
n_points (int): Number of points to sample.
|
|
73
|
+
radius (float): Radius of the sphere. Defaults to 1.0.
|
|
74
|
+
device (str): Device to place the tensor on. Defaults to 'cuda'.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
torch.Tensor: Random points of shape (n_points, 3).
|
|
78
|
+
"""
|
|
79
|
+
points = torch.randn(n_points, 3, device=device)
|
|
80
|
+
radii = torch.rand(n_points, 1, device=device) ** (1/3) * radius
|
|
81
|
+
points = (points / points.norm(dim=-1, keepdim=True)) * radii
|
|
82
|
+
return points
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import meshio
|
|
3
|
+
|
|
4
|
+
def read_obj(file_obj):
|
|
5
|
+
"""
|
|
6
|
+
Reads an OBJ file and returns vertices, faces, and optional vertex colors using meshio.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
file_obj: A file-like object or a string path.
|
|
10
|
+
"""
|
|
11
|
+
mesh = meshio.read(file_obj, file_format="obj")
|
|
12
|
+
vertices = torch.tensor(mesh.points, dtype=torch.float32)
|
|
13
|
+
|
|
14
|
+
faces = None
|
|
15
|
+
if "triangle" in mesh.cells_dict:
|
|
16
|
+
faces = torch.tensor(mesh.cells_dict["triangle"], dtype=torch.long)
|
|
17
|
+
else:
|
|
18
|
+
faces = torch.empty((0, 3), dtype=torch.long)
|
|
19
|
+
|
|
20
|
+
# Meshio sometimes places vertex colors in point_data under 'obj:vc'
|
|
21
|
+
colors = None
|
|
22
|
+
if mesh.point_data is not None and "obj:vc" in mesh.point_data:
|
|
23
|
+
colors = torch.tensor(mesh.point_data["obj:vc"], dtype=torch.float32)
|
|
24
|
+
|
|
25
|
+
return vertices, faces, colors
|
|
26
|
+
|
|
27
|
+
def write_obj(filepath, vertices, faces, colors=None):
|
|
28
|
+
"""
|
|
29
|
+
Writes vertices, faces, and optional vertex colors to an OBJ file using meshio.
|
|
30
|
+
"""
|
|
31
|
+
point_data = {}
|
|
32
|
+
if colors is not None:
|
|
33
|
+
point_data["obj:vc"] = colors.detach().cpu().numpy()
|
|
34
|
+
|
|
35
|
+
mesh = meshio.Mesh(
|
|
36
|
+
points=vertices.detach().cpu().numpy(),
|
|
37
|
+
cells=[("triangle", faces.detach().cpu().numpy())],
|
|
38
|
+
point_data=point_data if len(point_data) > 0 else None
|
|
39
|
+
)
|
|
40
|
+
meshio.write(filepath, mesh, file_format="obj")
|
|
41
|
+
|
|
42
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import meshio
|
|
3
|
+
|
|
4
|
+
def read_off(filepath_or_filelike):
|
|
5
|
+
"""
|
|
6
|
+
Read an OFF (Object File Format) file and return vertices and faces as PyTorch tensors using meshio.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
filepath_or_filelike: A string path or a file-like object.
|
|
10
|
+
|
|
11
|
+
Returns:
|
|
12
|
+
tuple: (vertices, faces) as torch.Tensor
|
|
13
|
+
"""
|
|
14
|
+
mesh = meshio.read(filepath_or_filelike, file_format="off")
|
|
15
|
+
vertices = torch.tensor(mesh.points, dtype=torch.float32)
|
|
16
|
+
|
|
17
|
+
faces = None
|
|
18
|
+
if "triangle" in mesh.cells_dict:
|
|
19
|
+
faces = torch.tensor(mesh.cells_dict["triangle"], dtype=torch.long)
|
|
20
|
+
else:
|
|
21
|
+
faces = torch.empty((0, 3), dtype=torch.long)
|
|
22
|
+
|
|
23
|
+
return vertices, faces
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: conquer3d
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.5
|
|
4
4
|
Summary: Geometric Cuda Tool Box
|
|
5
5
|
Author-email: Do Hoang Khoi <khoido8899@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -13,6 +13,7 @@ Requires-Python: >=3.9
|
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Requires-Dist: torch>=2.0.0
|
|
16
|
+
Requires-Dist: meshio>=5.3.5
|
|
16
17
|
Requires-Dist: gdown
|
|
17
18
|
Provides-Extra: cuda
|
|
18
19
|
Requires-Dist: cuda-toolkit==12.8.2; extra == "cuda"
|
|
@@ -49,6 +50,7 @@ pip install git+https://github.com/KhoiDOO/geocutool.git --no-build-isolation
|
|
|
49
50
|
```bash
|
|
50
51
|
conda create -c conda-forge -n geocutool python=3.10 gxx_linux-64=13 gcc_linux-64=13 -y
|
|
51
52
|
conda activate geocutool
|
|
53
|
+
conda install -c conda-forge sparsehash -y
|
|
52
54
|
|
|
53
55
|
conda install nvidia::cuda-toolkit==12.8.2 -y
|
|
54
56
|
|
|
@@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta"
|
|
|
9
9
|
|
|
10
10
|
[project]
|
|
11
11
|
name = "conquer3d"
|
|
12
|
-
version = "0.3.
|
|
12
|
+
version = "0.3.5"
|
|
13
13
|
description = "Geometric Cuda Tool Box"
|
|
14
14
|
readme = "README.md"
|
|
15
15
|
license = "MIT"
|
|
@@ -20,6 +20,7 @@ requires-python = ">=3.9"
|
|
|
20
20
|
keywords = ["geometry"]
|
|
21
21
|
dependencies = [
|
|
22
22
|
"torch>=2.0.0",
|
|
23
|
+
"meshio>=5.3.5",
|
|
23
24
|
"gdown",
|
|
24
25
|
]
|
|
25
26
|
|
|
File without changes
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import torch
|
|
2
|
-
|
|
3
|
-
def read_obj(file_obj):
|
|
4
|
-
"""
|
|
5
|
-
Reads an OBJ file and returns vertices, faces, and optional vertex colors.
|
|
6
|
-
|
|
7
|
-
Args:
|
|
8
|
-
file_obj: A file-like object or a string path.
|
|
9
|
-
"""
|
|
10
|
-
vertices = []
|
|
11
|
-
faces = []
|
|
12
|
-
colors = []
|
|
13
|
-
|
|
14
|
-
close_file = False
|
|
15
|
-
if isinstance(file_obj, str):
|
|
16
|
-
file_obj = open(file_obj, 'r', encoding='utf-8')
|
|
17
|
-
close_file = True
|
|
18
|
-
|
|
19
|
-
try:
|
|
20
|
-
for line in file_obj:
|
|
21
|
-
if isinstance(line, bytes):
|
|
22
|
-
line = line.decode('utf-8', errors='ignore')
|
|
23
|
-
line = line.strip()
|
|
24
|
-
if line.startswith('v '):
|
|
25
|
-
parts = line.split()
|
|
26
|
-
vertices.append([float(parts[1]), float(parts[2]), float(parts[3])])
|
|
27
|
-
if len(parts) >= 7:
|
|
28
|
-
colors.append([float(parts[4]), float(parts[5]), float(parts[6])])
|
|
29
|
-
elif line.startswith('f '):
|
|
30
|
-
parts = line.split()
|
|
31
|
-
# Face elements can be v, v/vt, or v/vt/vn. We just want the first index (v).
|
|
32
|
-
face = [int(p.split('/')[0]) - 1 for p in parts[1:4]]
|
|
33
|
-
faces.append(face)
|
|
34
|
-
finally:
|
|
35
|
-
if close_file:
|
|
36
|
-
file_obj.close()
|
|
37
|
-
|
|
38
|
-
vertices = torch.tensor(vertices, dtype=torch.float32)
|
|
39
|
-
faces = torch.tensor(faces, dtype=torch.long)
|
|
40
|
-
|
|
41
|
-
if len(colors) == len(vertices):
|
|
42
|
-
colors = torch.tensor(colors, dtype=torch.float32)
|
|
43
|
-
else:
|
|
44
|
-
colors = None
|
|
45
|
-
|
|
46
|
-
return vertices, faces, colors
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import torch
|
|
2
|
-
import numpy as np
|
|
3
|
-
import io
|
|
4
|
-
|
|
5
|
-
def read_off(filepath_or_filelike):
|
|
6
|
-
"""
|
|
7
|
-
Read an OFF (Object File Format) file and return vertices and faces as PyTorch tensors.
|
|
8
|
-
Supports reading from a file path or a file-like object.
|
|
9
|
-
|
|
10
|
-
Args:
|
|
11
|
-
filepath_or_filelike: A string path or a file-like object.
|
|
12
|
-
|
|
13
|
-
Returns:
|
|
14
|
-
tuple: (vertices, faces) as torch.Tensor
|
|
15
|
-
"""
|
|
16
|
-
if isinstance(filepath_or_filelike, str):
|
|
17
|
-
with open(filepath_or_filelike, "r") as f:
|
|
18
|
-
lines = f.readlines()
|
|
19
|
-
else:
|
|
20
|
-
# Assuming text-based or bytes file-like object
|
|
21
|
-
lines = filepath_or_filelike.readlines()
|
|
22
|
-
if len(lines) > 0 and isinstance(lines[0], bytes):
|
|
23
|
-
lines = [line.decode('utf-8') for line in lines]
|
|
24
|
-
|
|
25
|
-
# Clean up empty lines and comments
|
|
26
|
-
lines = [line.strip() for line in lines if line.strip() and not line.startswith('#')]
|
|
27
|
-
|
|
28
|
-
if not lines:
|
|
29
|
-
raise ValueError("Empty OFF file.")
|
|
30
|
-
|
|
31
|
-
first_line = lines[0].strip()
|
|
32
|
-
if first_line.upper().startswith("OFF"):
|
|
33
|
-
if len(first_line) > 3:
|
|
34
|
-
# Format: 'OFF 123 456 0'
|
|
35
|
-
parts = first_line[3:].strip().split()
|
|
36
|
-
# If the rest of the line doesn't contain counts, maybe they are on the next line
|
|
37
|
-
if parts:
|
|
38
|
-
lines = [parts] + lines[1:]
|
|
39
|
-
else:
|
|
40
|
-
lines = lines[1:]
|
|
41
|
-
else:
|
|
42
|
-
lines = lines[1:]
|
|
43
|
-
|
|
44
|
-
# If the format parsing above resulted in a list of parts at index 0, handle it
|
|
45
|
-
if isinstance(lines[0], list):
|
|
46
|
-
counts = lines[0]
|
|
47
|
-
else:
|
|
48
|
-
counts = lines[0].split()
|
|
49
|
-
|
|
50
|
-
num_verts, num_faces, num_edges = map(int, counts[:3])
|
|
51
|
-
|
|
52
|
-
# Fast parsing with numpy
|
|
53
|
-
verts_lines = lines[1:num_verts + 1]
|
|
54
|
-
verts_str = '\n'.join(verts_lines)
|
|
55
|
-
verts = np.fromstring(verts_str, sep=' ').reshape(num_verts, -1)[:, :3]
|
|
56
|
-
|
|
57
|
-
faces_lines = lines[num_verts + 1 : num_verts + 1 + num_faces]
|
|
58
|
-
faces_str = '\n'.join(faces_lines)
|
|
59
|
-
|
|
60
|
-
# In an OFF file, face lines look like: `3 v1 v2 v3` for triangles.
|
|
61
|
-
# We parse the flat array and reshape based on the number of elements per line
|
|
62
|
-
faces_raw = np.fromstring(faces_str, sep=' ', dtype=int)
|
|
63
|
-
|
|
64
|
-
# We assume all faces are triangles!
|
|
65
|
-
# The first element of each chunk will be 3, followed by 3 indices.
|
|
66
|
-
# Total length should be num_faces * 4
|
|
67
|
-
if len(faces_raw) == num_faces * 4:
|
|
68
|
-
faces = faces_raw.reshape(num_faces, 4)[:, 1:4]
|
|
69
|
-
else:
|
|
70
|
-
# If faces are mixed (e.g. some quads), we fall back to a slower parsing
|
|
71
|
-
faces_list = []
|
|
72
|
-
idx = 0
|
|
73
|
-
for _ in range(num_faces):
|
|
74
|
-
n_v = faces_raw[idx]
|
|
75
|
-
if n_v == 3:
|
|
76
|
-
faces_list.append([faces_raw[idx+1], faces_raw[idx+2], faces_raw[idx+3]])
|
|
77
|
-
else:
|
|
78
|
-
# Naive triangulation for ngons (fan triangulation)
|
|
79
|
-
for i in range(1, n_v - 1):
|
|
80
|
-
faces_list.append([faces_raw[idx+1], faces_raw[idx+i+1], faces_raw[idx+i+2]])
|
|
81
|
-
idx += n_v + 1
|
|
82
|
-
faces = np.array(faces_list, dtype=int)
|
|
83
|
-
|
|
84
|
-
return torch.from_numpy(verts).float(), torch.from_numpy(faces).long()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|