Reverb commited on
Commit
444ea3a
·
1 Parent(s): 854c275

Patch trellis2/representations/mesh/base.py: guard cumesh and flex_gemm imports

Browse files

cumesh and flex_gemm C++ extensions are compiled against torch 2.6.0 and fail
to load under torch 2.8.0 (ABI symbol mismatch). Both imports now have
try/except guards:
- cumesh: fill_holes/remove_faces/simplify become no-ops when unavailable.
o_voxel handles its own decimation; mesh may have minor holes but exports fine.
- flex_gemm grid_sample_3d: query_attrs raises RuntimeError if called, but
it is not invoked in the generation → GLB export pipeline path.

TRELLIS.2/trellis2/representations/mesh/base.py CHANGED
@@ -1,8 +1,24 @@
1
  from typing import *
2
  import torch
3
  from ..voxel import Voxel
4
- import cumesh
5
- from flex_gemm.ops.grid_sample import grid_sample_3d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
 
8
  class Mesh:
@@ -33,10 +49,12 @@ class Mesh:
33
  return self.to('cpu')
34
 
35
  def fill_holes(self, max_hole_perimeter=3e-2):
 
 
36
  vertices = self.vertices.cuda()
37
  faces = self.faces.cuda()
38
-
39
- mesh = cumesh.CuMesh()
40
  mesh.init(vertices, faces)
41
  mesh.get_edges()
42
  mesh.get_boundary_info()
@@ -52,31 +70,37 @@ class Mesh:
52
  return
53
  mesh.fill_holes(max_hole_perimeter=max_hole_perimeter)
54
  new_vertices, new_faces = mesh.read()
55
-
56
  self.vertices = new_vertices.to(self.device)
57
  self.faces = new_faces.to(self.device)
58
 
59
  def remove_faces(self, face_mask: torch.Tensor):
 
 
 
 
60
  vertices = self.vertices.cuda()
61
  faces = self.faces.cuda()
62
-
63
- mesh = cumesh.CuMesh()
64
  mesh.init(vertices, faces)
65
  mesh.remove_faces(face_mask)
66
  new_vertices, new_faces = mesh.read()
67
-
68
  self.vertices = new_vertices.to(self.device)
69
  self.faces = new_faces.to(self.device)
70
 
71
  def simplify(self, target=1000000, verbose: bool=False, options: dict={}):
 
 
72
  vertices = self.vertices.cuda()
73
  faces = self.faces.cuda()
74
-
75
- mesh = cumesh.CuMesh()
76
  mesh.init(vertices, faces)
77
  mesh.simplify(target, verbose=verbose, options=options)
78
  new_vertices, new_faces = mesh.read()
79
-
80
  self.vertices = new_vertices.to(self.device)
81
  self.faces = new_faces.to(self.device)
82
 
@@ -221,7 +245,7 @@ class MeshWithVoxel(Mesh, Voxel):
221
 
222
  def query_attrs(self, xyz):
223
  grid = ((xyz - self.origin) / self.voxel_size).reshape(1, -1, 3)
224
- vertex_attrs = grid_sample_3d(
225
  self.attrs,
226
  torch.cat([torch.zeros_like(self.coords[..., :1]), self.coords], dim=-1),
227
  self.voxel_shape,
 
1
  from typing import *
2
  import torch
3
  from ..voxel import Voxel
4
+
5
+ # cumesh and flex_gemm are compiled against torch 2.6.0; they fail to load
6
+ # under torch 2.8.0+ due to C++ ABI changes. Guard both and provide minimal
7
+ # stubs so the rest of the module (and the generation pipeline) still works.
8
+ try:
9
+ import cumesh as _cumesh
10
+ _HAS_CUMESH = True
11
+ except Exception:
12
+ _cumesh = None
13
+ _HAS_CUMESH = False
14
+
15
+ try:
16
+ from flex_gemm.ops.grid_sample import grid_sample_3d as _grid_sample_3d
17
+ _HAS_FLEX_GRID = True
18
+ except Exception:
19
+ _HAS_FLEX_GRID = False
20
+ def _grid_sample_3d(*_a, **_kw):
21
+ raise RuntimeError("flex_gemm grid_sample_3d unavailable (ABI mismatch)")
22
 
23
 
24
  class Mesh:
 
49
  return self.to('cpu')
50
 
51
  def fill_holes(self, max_hole_perimeter=3e-2):
52
+ if not _HAS_CUMESH:
53
+ return # skip; mesh may have small holes but GLB export still works
54
  vertices = self.vertices.cuda()
55
  faces = self.faces.cuda()
56
+
57
+ mesh = _cumesh.CuMesh()
58
  mesh.init(vertices, faces)
59
  mesh.get_edges()
60
  mesh.get_boundary_info()
 
70
  return
71
  mesh.fill_holes(max_hole_perimeter=max_hole_perimeter)
72
  new_vertices, new_faces = mesh.read()
73
+
74
  self.vertices = new_vertices.to(self.device)
75
  self.faces = new_faces.to(self.device)
76
 
77
  def remove_faces(self, face_mask: torch.Tensor):
78
+ if not _HAS_CUMESH:
79
+ keep = ~face_mask.bool().to(self.faces.device)
80
+ self.faces = self.faces[keep]
81
+ return
82
  vertices = self.vertices.cuda()
83
  faces = self.faces.cuda()
84
+
85
+ mesh = _cumesh.CuMesh()
86
  mesh.init(vertices, faces)
87
  mesh.remove_faces(face_mask)
88
  new_vertices, new_faces = mesh.read()
89
+
90
  self.vertices = new_vertices.to(self.device)
91
  self.faces = new_faces.to(self.device)
92
 
93
  def simplify(self, target=1000000, verbose: bool=False, options: dict={}):
94
+ if not _HAS_CUMESH:
95
+ return # skip; o_voxel.postprocess handles its own decimation
96
  vertices = self.vertices.cuda()
97
  faces = self.faces.cuda()
98
+
99
+ mesh = _cumesh.CuMesh()
100
  mesh.init(vertices, faces)
101
  mesh.simplify(target, verbose=verbose, options=options)
102
  new_vertices, new_faces = mesh.read()
103
+
104
  self.vertices = new_vertices.to(self.device)
105
  self.faces = new_faces.to(self.device)
106
 
 
245
 
246
  def query_attrs(self, xyz):
247
  grid = ((xyz - self.origin) / self.voxel_size).reshape(1, -1, 3)
248
+ vertex_attrs = _grid_sample_3d(
249
  self.attrs,
250
  torch.cat([torch.zeros_like(self.coords[..., :1]), self.coords], dim=-1),
251
  self.voxel_shape,