some fixes

This commit is contained in:
Yousef Rafat 2025-07-10 21:32:35 +03:00
parent f49e4b5411
commit b184a61046
2 changed files with 16 additions and 28 deletions

View File

@ -5,7 +5,6 @@
import torch import torch
from torch import Tensor from torch import Tensor
import math import math
import trimesh
import numpy as np import numpy as np
from skimage import measure from skimage import measure
from dataclasses import dataclass from dataclasses import dataclass
@ -607,8 +606,8 @@ class PointCrossAttention(nn.Module):
@dataclass @dataclass
class Latent2MeshOutput(): class Latent2MeshOutput():
# mesh for vertices and faces # mesh for vertices and faces
mesh_v: None vertices: None
mesh_f: None faces: None
class SufraceExtractor(): class SufraceExtractor():
def compute_box_stat(self, bounds, octree_resolution: int): def compute_box_stat(self, bounds, octree_resolution: int):
@ -644,7 +643,7 @@ class SufraceExtractor():
vertices, faces = self.run(grid_logits[i], **kwds) vertices, faces = self.run(grid_logits[i], **kwds)
vertices = vertices.astype(np.float32) vertices = vertices.astype(np.float32)
faces = np.ascontiguousarray(faces) faces = np.ascontiguousarray(faces)
outputs.append(Latent2MeshOutput(mesh_v = vertices, mesh_f = faces)) outputs.append(Latent2MeshOutput(vertices = vertices, faces = faces))
except Exception: except Exception:
import traceback import traceback
@ -687,24 +686,6 @@ class VanillaVolumeDecoder():
return grid_logits return grid_logits
def export_to_trimesh(mesh_output):
import trimesh
if isinstance(mesh_output, list):
outputs = []
for mesh in mesh_output:
if mesh is None:
outputs.append(None)
else:
mesh.mesh_f = mesh.mesh_f[:, ::-1]
mesh_output = trimesh.Trimesh(mesh.mesh_v, mesh.mesh_f)
outputs.append(mesh_output)
return outputs
else:
mesh_output.mesh_f = mesh_output.mesh_f[:, ::-1]
mesh_output = trimesh.Trimesh(mesh_output.mesh_v, mesh_output.mesh_f)
return mesh_output
def normalize_mesh(mesh, scale = 0.9999): def normalize_mesh(mesh, scale = 0.9999):
"""Normalize mesh to fit in [-scale, scale]. Translate mesh so its center is [0,0,0]""" """Normalize mesh to fit in [-scale, scale]. Translate mesh so its center is [0,0,0]"""
@ -767,6 +748,8 @@ def sharp_sample_pointcloud(mesh, num = 16384):
def load_surface_sharpedge(mesh, num_points=4096, num_sharp_points=4096, sharpedge_flag = True, device = "cuda"): def load_surface_sharpedge(mesh, num_points=4096, num_sharp_points=4096, sharpedge_flag = True, device = "cuda"):
"""Load a surface with optional sharp-edge annotations from a trimesh mesh.""" """Load a surface with optional sharp-edge annotations from a trimesh mesh."""
import trimesh
try: try:
mesh_full = trimesh.util.concatenate(mesh.dump()) mesh_full = trimesh.util.concatenate(mesh.dump())
except Exception: except Exception:
@ -837,6 +820,7 @@ class SharpEdgeSurfaceLoader:
@staticmethod @staticmethod
def _load_mesh(mesh_input): def _load_mesh(mesh_input):
import trimesh
if isinstance(mesh_input, str): if isinstance(mesh_input, str):
mesh = trimesh.load(mesh_input, force="mesh", merge_primitives = True) mesh = trimesh.load(mesh_input, force="mesh", merge_primitives = True)

View File

@ -110,17 +110,15 @@ class VAEDecodeHunyuan3D:
}), }),
"num_chunks": ("INT", { "num_chunks": ("INT", {
"default": 8000, "min": 1000, "max": 500000, "default": 8000, "min": 1000, "max": 500000,
"visible_if": {"version": "2.0"}
}), }),
"octree_resolution": ("INT", { "octree_resolution": ("INT", {
"default": 256, "min": 16, "max": 512, "default": 256, "min": 16, "max": 512,
"visible_if": {"version": "2.0"}
}), }),
} }
} }
RETURN_TYPES = ("VOXEL", "SDF_FUNCTION") RETURN_TYPES = ("VOXEL", "MESH")
RETURN_NAMES = ("voxel", "sdf") RETURN_NAMES = ("voxel", "mesh")
FUNCTION = "decode" FUNCTION = "decode"
CATEGORY = "latent/3d" CATEGORY = "latent/3d"
@ -137,6 +135,12 @@ class VAEDecodeHunyuan3D:
mesh = vae.decode(samples["samples"], to_mesh = True, mesh = vae.decode(samples["samples"], to_mesh = True,
num_chunks = num_chunks, num_chunks = num_chunks,
octree_resolution = octree_resolution) octree_resolution = octree_resolution)
# ensure batch dim
if mesh.verticies.ndim == 2:
mesh.verticies = mesh.verticies[np.newaxis, ...]
mesh.faces = mesh.faces[np.newaxis, ...]
return (None, mesh) return (None, mesh)
def voxel_to_mesh(voxels, threshold=0.5, device=None): def voxel_to_mesh(voxels, threshold=0.5, device=None):
@ -495,7 +499,7 @@ class VoxelToMesh:
return (MESH(torch.stack(vertices), torch.stack(faces)), ) return (MESH(torch.stack(vertices), torch.stack(faces)), )
def save_glb(vertices, faces, filepath, metadata=None, numpy_ready = False): def save_glb(vertices, faces, filepath, metadata=None):
""" """
Save PyTorch tensor vertices and faces as a GLB file without external dependencies. Save PyTorch tensor vertices and faces as a GLB file without external dependencies.
@ -506,7 +510,7 @@ def save_glb(vertices, faces, filepath, metadata=None, numpy_ready = False):
""" """
# Convert tensors to numpy arrays # Convert tensors to numpy arrays
if not numpy_ready: if isinstance(vertices, torch.tensor) and isinstance(faces, torch.tensor):
vertices_np = vertices.cpu().numpy().astype(np.float32) vertices_np = vertices.cpu().numpy().astype(np.float32)
faces_np = faces.cpu().numpy().astype(np.uint32) faces_np = faces.cpu().numpy().astype(np.uint32)
else: else: