3d拆件 SegviGen 部署踩坑笔记

目录

模型TRELLIS.2-4B:

glb2vxz

拆子部件:


模型TRELLIS.2-4B:

File "/data/lbg/project/chaijian/TRELLIS.2-main/SegviGen-main/inference_full.py", line 302, in inference

with open("microsoft/TRELLIS.2-4B/pipeline.json", "r") as f:

glb2vxz

python 复制代码
import torch
import trimesh

import os

os.environ['OPENCV_IO_ENABLE_OPENEXR'] = '1'
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True"

import sys

current_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(current_dir)
print('current_dir', current_dir)
paths = [current_dir, current_dir + '/../']
for path in paths:
    sys.path.insert(0, path)
    os.environ['PYTHONPATH'] = (os.environ.get('PYTHONPATH', '') + ':' + path).strip(':')
    
import o_voxel

from PIL import Image

def make_texture_square_pow2(img: Image.Image, target_size=None):
    w, h = img.size
    max_side = max(w, h)
    pow2 = 1
    while pow2 < max_side:
        pow2 *= 2
    if target_size is not None:
        pow2 = target_size
    pow2 = min(pow2, 2048)
    return img.resize((pow2, pow2), Image.BILINEAR)

def preprocess_scene_textures(asset):
    if not isinstance(asset, trimesh.Scene):
        return asset
    TEX_KEYS = ["baseColorTexture", "normalTexture", "metallicRoughnessTexture", "emissiveTexture", "occlusionTexture"]
    for geom in asset.geometry.values():
        visual = getattr(geom, "visual", None)
        mat = getattr(visual, "material", None)
        if mat is None:
            continue
        for key in TEX_KEYS:
            if not hasattr(mat, key):
                continue
            tex = getattr(mat, key)
            if tex is None:
                continue
            if isinstance(tex, Image.Image):
                setattr(mat, key, make_texture_square_pow2(tex))
            elif hasattr(tex, "image") and tex.image is not None:
                img = tex.image
                if not isinstance(img, Image.Image):
                    img = Image.fromarray(img)
                tex.image = make_texture_square_pow2(img)
        if hasattr(mat, "image") and mat.image is not None:
            img = mat.image
            if not isinstance(img, Image.Image):
                img = Image.fromarray(img)
            mat.image = make_texture_square_pow2(img)
    return asset

def glb_to_vxz(glb_path, vxz_path):
    asset = trimesh.load(glb_path, force='scene')
    asset = preprocess_scene_textures(asset)
    aabb = asset.bounding_box.bounds
    center = (aabb[0] + aabb[1]) / 2
    scale = 0.99999 / (aabb[1] - aabb[0]).max()
    asset.apply_translation(-center)
    asset.apply_scale(scale)
    mesh = asset.to_mesh()
    vertices = torch.from_numpy(mesh.vertices).float()
    faces = torch.from_numpy(mesh.faces).long()

    voxel_indices, dual_vertices, intersected = o_voxel.convert.mesh_to_flexible_dual_grid(
        vertices, faces, grid_size=512, aabb=[[-0.5, -0.5, -0.5], [0.5, 0.5, 0.5]],
        face_weight=1.0, boundary_weight=0.2, regularization_weight=1e-2, timing=False
    )
    vid = o_voxel.serialize.encode_seq(voxel_indices)
    mapping = torch.argsort(vid)
    voxel_indices = voxel_indices[mapping]
    dual_vertices = dual_vertices[mapping]
    intersected = intersected[mapping]

    voxel_indices_mat, attributes = o_voxel.convert.textured_mesh_to_volumetric_attr(
        asset, grid_size=512, aabb=[[-0.5, -0.5, -0.5], [0.5, 0.5, 0.5]], timing=False
    )
    vid_mat = o_voxel.serialize.encode_seq(voxel_indices_mat)
    mapping_mat = torch.argsort(vid_mat)
    attributes = {k: v[mapping_mat] for k, v in attributes.items()}

    dual_vertices = dual_vertices * 512 - voxel_indices
    dual_vertices = (torch.clamp(dual_vertices, 0, 1) * 255).type(torch.uint8)
    intersected = (intersected[:, 0:1] + 2 * intersected[:, 1:2] + 4 * intersected[:, 2:3]).type(torch.uint8)

    attributes['dual_vertices'] = dual_vertices
    attributes['intersected'] = intersected
    o_voxel.io.write(vxz_path, voxel_indices, attributes)

if __name__ == "__main__":
    glb_path = "./assets/example.glb"
    vxz_path = "./assets/input.vxz"
    glb_to_vxz(glb_path, vxz_path)

拆子部件:

子部件是一个整体,只是颜色不一样,需要自行后处理

感谢提供详细的调试输出!现在问题很明确了:颜色来自纹理贴图(PBR材质),而不是顶点或面颜色。因为:

  • 网格只有一个几何体(没有多个独立物体)。

  • UV坐标visual.uv 形状为 (65414, 2)),这是纹理映射的基础。

  • visual.materialPBRMaterial 类型,说明材质很可能包含基础颜色纹理(baseColorTexture)。

这意味着 :模型的不同区域呈现出不同颜色,是因为纹理图像 上绘制了不同的颜色区域,而网格的所有面共享这一个纹理。要按"颜色"拆分部件,本质上是要根据纹理颜色将面分组,但这相当于对纹理图像做分割并映射回网格,非常复杂且容易出错。

相关推荐
吴佳浩1 小时前
为什么现在越来越多的开源模型,都“毕业“于 Qwen?
人工智能·llm·ai编程
xxwl5851 小时前
高斯消元法异或版
人工智能·算法·机器学习
嘿嘿-661 小时前
gpt-6-astra测试,测试你的模型有没有降智
人工智能·gpt·chatgpt·web
思录Echo1 小时前
光学轮廓仪质检设备厂家怎么选?优可测国产替代方案深度解析
大数据·人工智能
麻瓜code1 小时前
【Agent】AI 应用开发环境搭建 & 大模型三种接入方式对比
人工智能
R²AIN SUITE1 小时前
2026企业级AI Agent开发平台怎么选?RAG知识库到工作流编排的四层架构拆解
人工智能·架构
延凡科技2 小时前
建筑节能新视角:智慧冷站的数字化实践
java·人工智能·能源·暖通
zzzll11112 小时前
RAG(检索增强生成)会不会消亡?
人工智能·深度学习·机器学习
鹿鸣天涯2 小时前
Hugging Face AI开源平台学习入门
人工智能