Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
cubvh
Commits
9bb0634a
"fair_dev/testing/testing.py" did not exist on "c9fdf50602c6e46413770ff0575f52cff27c6d7d"
Commit
9bb0634a
authored
Jan 24, 2025
by
ashawkey
Browse files
update mesh occ example
parent
7f935a0f
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
116 additions
and
0 deletions
+116
-0
readme.md
readme.md
+32
-0
test/extract_mesh_occupancy.py
test/extract_mesh_occupancy.py
+84
-0
No files found.
readme.md
View file @
9bb0634a
...
...
@@ -32,6 +32,8 @@ We have included it as a submodule in this repository, but you can also install
### Usage
**Basics:**
```
python
import
numpy
as
np
import
trimesh
...
...
@@ -60,6 +62,36 @@ distances, face_id, uvw = BVH.signed_distance(points, return_uvw=True, mode='wat
distances
,
face_id
,
uvw
=
BVH
.
signed_distance
(
points
,
return_uvw
=
True
,
mode
=
'raystab'
)
# [N], [N], [N, 3]
```
**Robust Mesh Occupancy:**
UDF + flood-fill for possibly non-watertight/single-layer meshes:
```
python
resolution
=
512
device
=
torch
.
device
(
'cuda'
)
BVH
=
cubvh
.
cuBVH
(
vertices
,
faces
)
grid_points
=
torch
.
stack
(
torch
.
meshgrid
(
torch
.
linspace
(
-
1
,
1
,
resolution
,
device
=
device
),
torch
.
linspace
(
-
1
,
1
,
resolution
,
device
=
device
),
torch
.
linspace
(
-
1
,
1
,
resolution
,
device
=
device
),
indexing
=
"ij"
,
),
dim
=-
1
,
)
# [N, N, N, 3]
udf
,
_
,
_
=
BVH
.
unsigned_distance
(
grid_points
.
view
(
-
1
,
3
),
return_uvw
=
False
)
udf
=
udf
.
cpu
().
numpy
().
reshape
(
resolution
,
resolution
,
resolution
)
occ
=
udf
<
2
/
resolution
# tolerance 2 voxels
empty_mask
=
morphology
.
flood
(
occ
,
(
0
,
0
,
0
),
connectivity
=
1
)
# flood from the corner, which is for sure empty
occ
=
~
empty_mask
```
Check
[
`test/robust_occupancy.py`
](
test/robust_occupancy.py
)
for more details.
**Renderer:**
Example for a mesh normal renderer by
`ray_trace`
:
...
...
test/extract_mesh_occupancy.py
0 → 100644
View file @
9bb0634a
import
os
import
zlib
import
time
import
numpy
as
np
import
torch
import
cubvh
import
mcubes
import
trimesh
import
argparse
import
kiui
from
kiui.mesh
import
Mesh
from
skimage
import
morphology
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
'mesh'
,
type
=
str
)
parser
.
add_argument
(
'--res'
,
type
=
int
,
default
=
512
)
opt
=
parser
.
parse_args
()
device
=
torch
.
device
(
'cuda'
)
points
=
torch
.
stack
(
torch
.
meshgrid
(
torch
.
linspace
(
-
1
,
1
,
opt
.
res
,
device
=
device
),
torch
.
linspace
(
-
1
,
1
,
opt
.
res
,
device
=
device
),
torch
.
linspace
(
-
1
,
1
,
opt
.
res
,
device
=
device
),
indexing
=
"ij"
,
),
dim
=-
1
,
)
# [N, N, N, 3]
def
run
(
path
):
mesh
=
Mesh
.
load
(
path
,
wotex
=
True
,
bound
=
0.95
,
device
=
device
)
t0
=
time
.
time
()
BVH
=
cubvh
.
cuBVH
(
mesh
.
v
,
mesh
.
f
)
print
(
'BVH build time:'
,
time
.
time
()
-
t0
)
# naive sdf
# sdf, _, _ = BVH.signed_distance(points.view(-1, 3), return_uvw=False, mode='raystab') # some mesh may not be watertight...
# sdf = sdf.cpu().numpy()
# occ = (sdf < 0)
# udf floodfill
t0
=
time
.
time
()
udf
,
_
,
_
=
BVH
.
unsigned_distance
(
points
.
view
(
-
1
,
3
),
return_uvw
=
False
)
print
(
'UDF time:'
,
time
.
time
()
-
t0
)
udf
=
udf
.
cpu
().
numpy
().
reshape
(
opt
.
res
,
opt
.
res
,
opt
.
res
)
occ
=
udf
<
2
/
opt
.
res
# tolerance 2 voxels
t0
=
time
.
time
()
empty_mask
=
morphology
.
flood
(
occ
,
(
0
,
0
,
0
),
connectivity
=
1
)
# flood from the corner, which is for sure empty
print
(
'Floodfill time:'
,
time
.
time
()
-
t0
)
occ
=
~
empty_mask
# # packbits and compress
# occ = occ.astype(np.uint8).reshape(-1)
# occ = np.packbits(occ)
# occ = zlib.compress(occ.tobytes())
# # save to disk
# with open(os.path.basename(path).split('.')[0] + '.bin', 'wb') as f:
# f.write(occ)
# # uncompress and unpack
# occ = zlib.decompress(occ)
# occ = np.frombuffer(occ, dtype=np.uint8)
# occ = np.unpackbits(occ, count=opt.res**3).reshape(opt.res, opt.res, opt.res)
# marching cubes
occ
=
occ
.
reshape
(
opt
.
res
,
opt
.
res
,
opt
.
res
)
t0
=
time
.
time
()
verts
,
faces
=
mcubes
.
marching_cubes
(
occ
,
0.5
)
# smoothed_occ = mcubes.smooth(occ, method='constrained') # very slow
# verts, faces = mcubes.marching_cubes(smoothed_occ, 0)
print
(
'MC time:'
,
time
.
time
()
-
t0
)
verts
=
verts
/
(
opt
.
res
-
1
)
*
2
-
1
mesh
=
trimesh
.
Trimesh
(
vertices
=
verts
,
faces
=
faces
)
mesh
.
export
(
os
.
path
.
basename
(
path
).
split
(
'.'
)[
0
]
+
'.ply'
)
run
(
opt
.
mesh
)
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment