如何将‘pygltflib’Python库中的颜色定义添加到3D三角网格?

问题描述 投票:0回答:2

以下示例使用任意三角形定义(顶点和连接矩阵)生成 3D 对象。 https://gitlab.com/dodgyville/pygltflib#create-a-mesh-convert-to-bytes-convert-back-to-mesh

如何为顶点设置自定义颜色?

就像在这个 matlab 库中一样:https://www.mathworks.com/matlabcentral/fileexchange/109264-matlab2glb

带有顶点颜色定义的 Matlab 示例代码:

example.POSITION = [0 0 0; 1 0 0; 1 1 0; 0 1 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1]; 
example.indices = [1 4 2; 4 3 2; 3 7 2; 7 6 2; 3 4 7; 4 8 7; 8 5 7; 5 6 7; 5 2 6; 5 1 2; 1 5 4; 5 8 4];
example.COLOR_0 = [1 0 0; 0.5 0.5 0.5; 0.5 0.5 0.5; 0.5 0.5 0.5; 0.5 0.5 0.5; 0.5 0.5 0.5; 0 1 0; 0.5 0.5 0.5];
example.prop.material.pbrMetallicRoughness.baseColorFactor = [0.7 0.7 1 0.5];
example.prop.material.pbrMetallicRoughness.metallicFactor = 1;
example.prop.material.pbrMetallicRoughness.roughnessFactor = 0.1;
example.prop.material.alphaMode = 'BLEND';
example.prop.material.doubleSided = true;
write_glb('example.glb', example);
python colors 3d mesh gltf
2个回答
0
投票

对于顶点上的颜色,您需要将其定义为每个顶点的 RGB 向量,类似于

pygltflib

中每个顶点的 x,y,z

对于您的数据,我创建了一个示例代码来使用

gltf
创建
pygltflib
文件,如下所示。

我从

here
获取了
wavefront
obj到gltf的转换代码 并根据您的用例和数据进行调整

import sys
import os
import traceback
import numpy as np
from pygltflib import *

if __name__ == "__main__":

    output_path = "/content/sample_data/square.glb"
    
    # instantiate GLTF2
    gltf = GLTF2()
    gltf.asset = Asset()
    gltf.scenes = [Scene()]
    gltf.nodes = [Node()]       # Mesh node
    gltf.meshes = [Mesh()]
    gltf.accessors = [Accessor() for _ in range(3)]     # faces, vertices, v_colors
    gltf.materials = [Material()]
    gltf.bufferViews = [BufferView() for _ in range(3)]
    gltf.buffers = [Buffer()]

    # asset
    gltf.asset = Asset()

    # scene
    gltf.scene = 0

    # vertices
    vertices_lst = [[0.0 ,0.0 ,0.0],[1.0 ,0.0, 0.0],[1.0, 1.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 1.0],[1.0, 1.0, 1.0],[0.0, 1.0, 1.0]]
    # faces indices
    faceindices_lst = [[1,4,2], [4,3,2], [3,7,2], [7,6,2], [3,4,7], [4,8,7], [8,5,7], [5,6,7], [5,2,6], [5,1,2], [1,5,4], [5,8,4]]
    # colors
    vertices_colors_lst = [[1,0,0],[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5],[0,1,0],[0.5,0.5,0.5]] 
    # convert colorlist to np.array
    vertices_colors_nparray = np.array([np.array(xi) for xi in vertices_colors_lst])
    
    
    # store faces
    indices_chunk = b""
    for f in faceindices_lst:
        indices_chunk += struct.pack("<III", *f)    
    gltf.bufferViews[0].buffer = 0
    gltf.bufferViews[0].byteOffset = 0
    gltf.bufferViews[0].byteLength = len(indices_chunk)
    gltf.bufferViews[0].target = ELEMENT_ARRAY_BUFFER
    gltf.accessors[0].bufferView = 0
    gltf.accessors[0].byteOffset = 0
    gltf.accessors[0].componentType = UNSIGNED_INT
    gltf.accessors[0].normalized = False
    gltf.accessors[0].count = len(faceindices_lst) * 3
    gltf.accessors[0].type = "SCALAR"

    # store vertices
    vertices_chunk = b""
    for v in vertices_lst:
        vertices_chunk += struct.pack("<fff", *v)
    gltf.bufferViews[1].buffer = 0
    gltf.bufferViews[1].byteOffset = gltf.bufferViews[0].byteLength
    gltf.bufferViews[1].byteLength = len(vertices_chunk)
    gltf.bufferViews[1].target = ARRAY_BUFFER
    gltf.accessors[1].bufferView = 1
    gltf.accessors[1].byteOffset = 0
    gltf.accessors[1].componentType = FLOAT
    gltf.accessors[1].normalized = False
    gltf.accessors[1].count = len(vertices_lst)
    gltf.accessors[1].type = "VEC3"
    gltf.accessors[1].max = list(np.max(np.array(vertices_lst).T, axis=1))       # get the max value for each xyz
    gltf.accessors[1].min = list(np.min(np.array(vertices_lst).T, axis=1))

    # store vertex colors
    vcolor_chunk = b""
    for vc in vertices_colors_nparray:
        vc_rgb = vc[:3]
        vcolor_chunk += struct.pack("<fff", *vc_rgb)
    gltf.bufferViews[2].buffer = 0
    gltf.bufferViews[2].byteOffset = gltf.bufferViews[1].byteOffset + gltf.bufferViews[1].byteLength
    gltf.bufferViews[2].byteLength = len(vcolor_chunk)
    gltf.bufferViews[2].target = ARRAY_BUFFER
    gltf.accessors[2].bufferView = 2
    gltf.accessors[2].byteOffset = 0
    gltf.accessors[2].componentType = FLOAT
    gltf.accessors[2].normalized = False
    gltf.accessors[2].count = len(vertices_colors_nparray)
    gltf.accessors[2].type = "VEC3"

    
    # store buffer data

    gltf.identify_uri = BufferFormat.BINARYBLOB
    gltf._glb_data = indices_chunk + vertices_chunk + vcolor_chunk
    gltf.buffers[0].byteLength = gltf.bufferViews[2].byteOffset + gltf.bufferViews[2].byteLength
    
    # mesh
    gltf.meshes[0].primitives = [
        Primitive(
            attributes=Attributes(
                POSITION=1,
                #NORMAL=3,
                COLOR_0=2,
            ),
            indices=0,
            material=0
        )
    ]
    gltf.meshes[0].name = "Mesh"

    # assemble nodes
    gltf.nodes[0].mesh = 0
    gltf.nodes[0].name = "Mesh"

    gltf.scenes[0].nodes = [0]

    # export
    gltf.save_binary(output_path)

0
投票

感谢您提供的示例。我通过在颜色列表中添加 alpha 值进行了一些修改,但是 alpha 值无法识别并且透明度不起作用。有人可以帮助告诉我如何使用 pygltflib 实现透明度吗?预先感谢。

import sys
import os
import traceback
import numpy as np
from pygltflib import *

if __name__ == "__main__":

    output_path = "square.glb"
    
    # instantiate GLTF2
    gltf = GLTF2()
    gltf.asset = Asset()
    gltf.scenes = [Scene()]
    gltf.nodes = [Node()]       # Mesh node
    gltf.meshes = [Mesh()]
    gltf.accessors = [Accessor() for _ in range(3)]     # faces, vertices, v_colors
    #gltf.materials = [Material()]
    gltf.bufferViews = [BufferView() for _ in range(3)]
    gltf.buffers = [Buffer()]

    # asset
    gltf.asset = Asset()

    # scene
    gltf.scene = 0

    # vertices
    vertices_lst = [[0.0 ,0.0 ,0.0],[1.0 ,0.0, 0.0],[1.0, 1.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 1.0],[1.0, 1.0, 1.0],[0.0, 1.0, 1.0]]
    faceindices_lst = [[1,4,2], [4,3,2], [3,7,2], [7,6,2], [3,4,7], [4,6,7], [6,5,7], [5,6,7], [5,2,6], [5,1,2], [1,5,4], [5,6,4]]
    
    # colors
    #vertices_colors_lst = [[1,0,0],[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5],[0,1,0],[0.5,0.5,0.5]] 
    #vertices_colors_lst = [[1,0,0, 0.1],[0.5,0.5,0.5,0.1],[0.5,0.5,0.5, 0.1],[0.5,0.5,0.5, 0.1],[0.5,0.5,0.5,0.1],[0.5,0.5,0.5,0.1],[0,1,0, 0.1],[0.5,0.5,0.5,0.1]] 
    vertices_colors_lst = [[1,0,0, 0.9],[0.5,0.5,0.5,0.9],[0.5,0.5,0.5, 0.9],[0.5,0.5,0.5, 0.9],[0.5,0.5,0.5,0.9],[0.5,0.5,0.5,0.9],[0,1,0, 0.9],[0.5,0.5,0.5,0.9]] 
    # convert colorlist to np.array
    vertices_colors_nparray = np.array([np.array(xi) for xi in vertices_colors_lst])
    
    
    # store faces
    indices_chunk = b""
    for f in faceindices_lst:
        indices_chunk += struct.pack("<III", *f)    
    gltf.bufferViews[0].buffer = 0
    gltf.bufferViews[0].byteOffset = 0
    gltf.bufferViews[0].byteLength = len(indices_chunk)
    gltf.bufferViews[0].target = ELEMENT_ARRAY_BUFFER
    gltf.accessors[0].bufferView = 0
    gltf.accessors[0].byteOffset = 0
    gltf.accessors[0].componentType = UNSIGNED_INT
    gltf.accessors[0].normalized = False
    gltf.accessors[0].count = len(faceindices_lst) * 3
    gltf.accessors[0].type = "SCALAR"

    # store vertices
    vertices_chunk = b""
    for v in vertices_lst:
        vertices_chunk += struct.pack("<fff", *v)
    gltf.bufferViews[1].buffer = 0
    gltf.bufferViews[1].byteOffset = gltf.bufferViews[0].byteLength
    gltf.bufferViews[1].byteLength = len(vertices_chunk)
    gltf.bufferViews[1].target = ARRAY_BUFFER
    gltf.accessors[1].bufferView = 1
    gltf.accessors[1].byteOffset = 0
    gltf.accessors[1].componentType = FLOAT
    gltf.accessors[1].normalized = False
    gltf.accessors[1].count = len(vertices_lst)
    gltf.accessors[1].type = "VEC3"
    gltf.accessors[1].max = list(np.max(np.array(vertices_lst).T, axis=1))       # get the max value for each xyz
    gltf.accessors[1].min = list(np.min(np.array(vertices_lst).T, axis=1))

    # store vertex colors
    vcolor_chunk = b""
    for vc in vertices_colors_nparray:
        #print("vc", vc)
        vc_rgb = vc[:4]
        vcolor_chunk += struct.pack("<ffff", *vc_rgb)
    gltf.bufferViews[2].buffer = 0
    gltf.bufferViews[2].byteOffset = gltf.bufferViews[1].byteOffset + gltf.bufferViews[1].byteLength
    gltf.bufferViews[2].byteLength = len(vcolor_chunk)
    gltf.bufferViews[2].target = ARRAY_BUFFER
    gltf.accessors[2].bufferView = 2
    gltf.accessors[2].byteOffset = 0
    gltf.accessors[2].componentType = FLOAT
    gltf.accessors[2].normalized = False
    gltf.accessors[2].count = len(vertices_colors_nparray)
    gltf.accessors[2].type = "VEC4"


    #materials
    material = Material()
    pbr = PbrMetallicRoughness() # Use PbrMetallicRoughness
    #pbr.baseColorFactor = [1.0, 0.0, 0.0, 1.0] # solid red
    material.pbrMetallicRoughness = pbr
    material.doubleSided = True # make material double sided
    material.alphaMode = MASK   # to get around 'MATERIAL_ALPHA_CUTOFF_INVALID_MODE' warning
    material.alphaCutoff=None


    
    # store buffer data

    gltf.identify_uri = BufferFormat.BINARYBLOB
    gltf._glb_data = indices_chunk + vertices_chunk + vcolor_chunk
    gltf.buffers[0].byteLength = gltf.bufferViews[2].byteOffset + gltf.bufferViews[2].byteLength
    
    # mesh
    gltf.meshes[0].primitives = [
        Primitive(
            attributes=Attributes(
                POSITION=1,
                #NORMAL=3,
                COLOR_0=2,
            ),
            indices=0,
            material=0
        )
    ]
    gltf.meshes[0].name = "Mesh"

    gltf.materials.append(material)
    
    # assemble nodes
    gltf.nodes[0].mesh = 0
    gltf.nodes[0].name = "Mesh"

    gltf.scenes[0].nodes = [0]

    # export
    gltf.save_binary(output_path)
© www.soinside.com 2019 - 2024. All rights reserved.