Reputation: 1
The following example generates a 3D object using arbitrary triangle definitions (vertices and connectivity matrix). https://gitlab.com/dodgyville/pygltflib#create-a-mesh-convert-to-bytes-convert-back-to-mesh
How can I set custom colors to the vertices?
Just like the same way as in this matlab library: https://www.mathworks.com/matlabcentral/fileexchange/109264-matlab2glb
Matlab example code with color definition for vertices:
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);
Upvotes: 0
Views: 861
Reputation: 1
For color on vertex, you need to define it as a RGB vector for each vertex, similar to x,y,z for each vertex in pygltflib
For your data, I created a sample code to create a gltf
file using pygltflib
as shown below.
I took the wavefront
obj to gltf
conversion code from here
and tweaked it to your use case and data
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)
Upvotes: 0