How to efficiently read a GLB file in Python 3.11.1 and extract formatted triangle data?
Question:
What I need
How to efficiently extract formatted triangle data from the GLB file in this data type:
triangles = [triangle1,triangle2,...]
triangle = [x1,y1,z1,x2,y2,z2,x3,y3,z3] (1,2,3 - points, values - their coords, x,y,z - dimensions)
Here is example of the extracted and rightly formatted data:
triangles = [[0,0,0,0,0,1,1,1,1],[1,1,1,2,2,2,3,3,4]]
Also, I need code on the python 3.11.1.
My results
Here are my search results:
This is the first search result. It can read triangles.
GLB file
Here is the raw GLB file:
glTF
а JSON{"asset":{"version":"2.0","generator":"Microsoft GLTF Exporter 2.4.2.17"},"accessors":[{"bufferView":0,"componentType":5123,"count":36,"type":"SCALAR"},{"bufferView":1,"componentType":5126,"count":24,"type":"VEC3","max":[22.08578109741211,22.55755615234375,22.08578109741211],"min":[-22.08578109741211,-22.55755615234375,-22.08578109741211]},{"bufferView":2,"componentType":5126,"count":24,"type":"VEC3"}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":72,"byteLength":288,"target":34962},{"buffer":0,"byteOffset":360,"byteLength":288,"target":34962},{"buffer":0,"byteOffset":648,"byteLength":163},{"buffer":0,"byteOffset":811,"byteLength":163},{"buffer":0,"byteOffset":974,"byteLength":163},{"buffer":0,"byteOffset":1137,"byteLength":163}],"buffers":[{"byteLength":1304}],"images":[{"bufferView":3,"mimeType":"image/png"},{"bufferView":4,"mimeType":"image/png"},{"bufferView":5,"mimeType":"image/png"},{"bufferView":6,"mimeType":"image/png"}],"materials":[{"pbrMetallicRoughness":{"baseColorTexture":{"index":2},"metallicRoughnessTexture":{"index":3}},"name":"50","doubleSided":true,"extensions":{"KHR_materials_pbrSpecularGlossiness":{"diffuseTexture":{"index":0},"specularGlossinessTexture":{"index":1}}},"extras":{"MSFT_sRGBFactors":false}}],"meshes":[{"name":"mesh_id27","primitives":[{"attributes":{"POSITION":1,"NORMAL":2},"indices":0,"material":0}]}],"nodes":[{"translation":[-0.09220179170370102,-0.02062331698834896,0.2000107318162918],"rotation":[0.4009096622467041,0.4017220437526703,-0.201762393116951,0.7982372641563416],"scale":[0.0009999999310821295,0.0009999999310821295,0.0009999999310821295],"mesh":0},{"children":[0],"name":"root"}],"samplers":[{"minFilter":9985}],"scenes":[{"nodes":[1]}],"textures":[{"name":"texture184","sampler":0,"source":0},{"name":"texture185","sampler":0,"source":1},{"name":"50_bc","sampler":0,"source":2},{"name":"50_mr","sampler":0,"source":3}],"scene":0,"extensionsUsed":["KHR_materials_pbrSpecularGlossiness"]} BIN
®Ї°AаuґA®Ї°Б®Ї°БаuґБ®Ї°Б®Ї°БаuґA®Ї°Б®Ї°AаuґБ®Ї°Б®Ї°БаuґA®Ї°A®Ї°AаuґБ®Ї°A®Ї°AаuґA®Ї°A®Ї°БаuґБ®Ї°A®Ї°AаuґA®Ї°A®Ї°AаuґБ®Ї°Б®Ї°AаuґA®Ї°Б®Ї°AаuґБ®Ї°A®Ї°БаuґA®Ї°Б®Ї°БаuґБ®Ї°A®Ї°БаuґA®Ї°A®Ї°БаuґБ®Ї°Б®Ї°БаuґA®Ї°Б®Ї°AаuґA®Ї°A®Ї°AаuґA®Ї°Б®Ї°БаuґA®Ї°A®Ї°БаuґБ®Ї°A®Ї°AаuґБ®Ї°Б®Ї°AаuґБ®Ї°A®Ї°БаuґБ®Ї°Б Ђї Ђї Ђї Ђї Ђ? Ђ? Ђ? Ђ? Ђ? Ђ? Ђ? Ђ? Ђї Ђї Ђї Ђї Ђ? Ђ? Ђ? Ђ? Ђї Ђї Ђї Ђї ‰PNG
IHDR Дѕ‹ sRGB ®Ой gAMA ±Џьa pHYs ТЭ~ь tEXtSoftware DirectXTexКFц— IDAT(Scґч8уџ`‚Т8БpPАА fЗbЧґ IEND®B`‚‰PNG
IHDR Дѕ‹ sRGB ®Ой gAMA ±Џьa pHYs ТЭ~ь tEXtSoftware DirectXTexКFц— IDAT(Scґ°°HcА 4N000 ЯVиш[ IEND®B`‚‰PNG
IHDR Дѕ‹ sRGB ®Ой gAMA ±Џьa pHYs ТЭ~ь tEXtSoftware DirectXTexКFц— IDAT(Scґч8уџ`‚Т8БpPАА fЗbЧґ IEND®B`‚‰PNG
IHDR Дѕ‹ sRGB ®Ой gAMA ±Џьa pHYs ТЭ~ь tEXtSoftware DirectXTexКFц— IDAT(ScdЙрџ`‚Т8БpPАА ЁйЁЂ`W IEND®B`‚
Answers:
This is working code:
import pathlib
import struct
from pygltflib import GLTF2
from pygltflib.utils import glb2gltf, gltf2glb
# convert glb to gltf
glb2gltf("C:/Users/User/Desktop/cube.glb")
# load a gltf file
fname = pathlib.Path("C:/Users/User/Desktop/cube.gltf")
gltf = GLTF2().load(fname)
# get the first mesh in the current scene
mesh = gltf.meshes[gltf.scenes[gltf.scene].nodes[0]-1]
# get the vertices for each primitive in the mesh
for primitive in mesh.primitives:
# get the binary data for this mesh primitive from the buffer
accessor = gltf.accessors[primitive.attributes.POSITION]
bufferView = gltf.bufferViews[accessor.bufferView]
buffer = gltf.buffers[bufferView.buffer]
data = gltf.get_data_from_buffer_uri(buffer.uri)
# pull each vertex from the binary buffer and convert it into a tuple of python floats
vertices = []
for i in range(accessor.count):
index = bufferView.byteOffset + accessor.byteOffset + i*12 # the location in the buffer of this vertex
d = data[index:index+12] # the vertex data
v = struct.unpack("<fff", d) # convert from base64 to three floats
vertices.append(v)
# unpack floats
vertices2 = []
for a,b,c in vertices:
vertices2 += [a,b,c]
# create triangles
vertices = vertices2
triangles = []
for i in range(0,len(vertices),9):
triangles.append(vertices[i:i+9])
# print data
print(triangles)
It extracts triangle data from the first mesh.
It returns for the cube:
[[22.08578109741211, 22.55755615234375, -22.08578109741211, -22.08578109741211, -22.55755615234375, -22.08578109741211, -22.08578109741211, 22.55755615234375, -22.08578109741211], [22.08578109741211, -22.55755615234375, -22.08578109741211, -22.08578109741211, 22.55755615234375, 22.08578109741211, 22.08578109741211, -22.55755615234375, 22.08578109741211], [22.08578109741211, 22.55755615234375, 22.08578109741211, -22.08578109741211, -22.55755615234375, 22.08578109741211, 22.08578109741211, 22.55755615234375, 22.08578109741211], [22.08578109741211, -22.55755615234375, -22.08578109741211, 22.08578109741211, 22.55755615234375, -22.08578109741211, 22.08578109741211, -22.55755615234375, 22.08578109741211], [-22.08578109741211, 22.55755615234375, -22.08578109741211, -22.08578109741211, -22.55755615234375, 22.08578109741211, -22.08578109741211, 22.55755615234375, 22.08578109741211], [-22.08578109741211, -22.55755615234375, -22.08578109741211, -22.08578109741211, 22.55755615234375, -22.08578109741211, 22.08578109741211, 22.55755615234375, 22.08578109741211], [22.08578109741211, 22.55755615234375, -22.08578109741211, -22.08578109741211, 22.55755615234375, 22.08578109741211, -22.08578109741211, -22.55755615234375, 22.08578109741211], [22.08578109741211, -22.55755615234375, -22.08578109741211, 22.08578109741211, -22.55755615234375, 22.08578109741211, -22.08578109741211, -22.55755615234375, -22.08578109741211]]
What I need
How to efficiently extract formatted triangle data from the GLB file in this data type:
triangles = [triangle1,triangle2,...]
triangle = [x1,y1,z1,x2,y2,z2,x3,y3,z3] (1,2,3 - points, values - their coords, x,y,z - dimensions)
Here is example of the extracted and rightly formatted data:
triangles = [[0,0,0,0,0,1,1,1,1],[1,1,1,2,2,2,3,3,4]]
Also, I need code on the python 3.11.1.
My results
Here are my search results:
This is the first search result. It can read triangles.
GLB file
Here is the raw GLB file:
glTF
а JSON{"asset":{"version":"2.0","generator":"Microsoft GLTF Exporter 2.4.2.17"},"accessors":[{"bufferView":0,"componentType":5123,"count":36,"type":"SCALAR"},{"bufferView":1,"componentType":5126,"count":24,"type":"VEC3","max":[22.08578109741211,22.55755615234375,22.08578109741211],"min":[-22.08578109741211,-22.55755615234375,-22.08578109741211]},{"bufferView":2,"componentType":5126,"count":24,"type":"VEC3"}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":72,"byteLength":288,"target":34962},{"buffer":0,"byteOffset":360,"byteLength":288,"target":34962},{"buffer":0,"byteOffset":648,"byteLength":163},{"buffer":0,"byteOffset":811,"byteLength":163},{"buffer":0,"byteOffset":974,"byteLength":163},{"buffer":0,"byteOffset":1137,"byteLength":163}],"buffers":[{"byteLength":1304}],"images":[{"bufferView":3,"mimeType":"image/png"},{"bufferView":4,"mimeType":"image/png"},{"bufferView":5,"mimeType":"image/png"},{"bufferView":6,"mimeType":"image/png"}],"materials":[{"pbrMetallicRoughness":{"baseColorTexture":{"index":2},"metallicRoughnessTexture":{"index":3}},"name":"50","doubleSided":true,"extensions":{"KHR_materials_pbrSpecularGlossiness":{"diffuseTexture":{"index":0},"specularGlossinessTexture":{"index":1}}},"extras":{"MSFT_sRGBFactors":false}}],"meshes":[{"name":"mesh_id27","primitives":[{"attributes":{"POSITION":1,"NORMAL":2},"indices":0,"material":0}]}],"nodes":[{"translation":[-0.09220179170370102,-0.02062331698834896,0.2000107318162918],"rotation":[0.4009096622467041,0.4017220437526703,-0.201762393116951,0.7982372641563416],"scale":[0.0009999999310821295,0.0009999999310821295,0.0009999999310821295],"mesh":0},{"children":[0],"name":"root"}],"samplers":[{"minFilter":9985}],"scenes":[{"nodes":[1]}],"textures":[{"name":"texture184","sampler":0,"source":0},{"name":"texture185","sampler":0,"source":1},{"name":"50_bc","sampler":0,"source":2},{"name":"50_mr","sampler":0,"source":3}],"scene":0,"extensionsUsed":["KHR_materials_pbrSpecularGlossiness"]} BIN
®Ї°AаuґA®Ї°Б®Ї°БаuґБ®Ї°Б®Ї°БаuґA®Ї°Б®Ї°AаuґБ®Ї°Б®Ї°БаuґA®Ї°A®Ї°AаuґБ®Ї°A®Ї°AаuґA®Ї°A®Ї°БаuґБ®Ї°A®Ї°AаuґA®Ї°A®Ї°AаuґБ®Ї°Б®Ї°AаuґA®Ї°Б®Ї°AаuґБ®Ї°A®Ї°БаuґA®Ї°Б®Ї°БаuґБ®Ї°A®Ї°БаuґA®Ї°A®Ї°БаuґБ®Ї°Б®Ї°БаuґA®Ї°Б®Ї°AаuґA®Ї°A®Ї°AаuґA®Ї°Б®Ї°БаuґA®Ї°A®Ї°БаuґБ®Ї°A®Ї°AаuґБ®Ї°Б®Ї°AаuґБ®Ї°A®Ї°БаuґБ®Ї°Б Ђї Ђї Ђї Ђї Ђ? Ђ? Ђ? Ђ? Ђ? Ђ? Ђ? Ђ? Ђї Ђї Ђї Ђї Ђ? Ђ? Ђ? Ђ? Ђї Ђї Ђї Ђї ‰PNG
IHDR Дѕ‹ sRGB ®Ой gAMA ±Џьa pHYs ТЭ~ь tEXtSoftware DirectXTexКFц— IDAT(Scґч8уџ`‚Т8БpPАА fЗbЧґ IEND®B`‚‰PNG
IHDR Дѕ‹ sRGB ®Ой gAMA ±Џьa pHYs ТЭ~ь tEXtSoftware DirectXTexКFц— IDAT(Scґ°°HcА 4N000 ЯVиш[ IEND®B`‚‰PNG
IHDR Дѕ‹ sRGB ®Ой gAMA ±Џьa pHYs ТЭ~ь tEXtSoftware DirectXTexКFц— IDAT(Scґч8уџ`‚Т8БpPАА fЗbЧґ IEND®B`‚‰PNG
IHDR Дѕ‹ sRGB ®Ой gAMA ±Џьa pHYs ТЭ~ь tEXtSoftware DirectXTexКFц— IDAT(ScdЙрџ`‚Т8БpPАА ЁйЁЂ`W IEND®B`‚
This is working code:
import pathlib
import struct
from pygltflib import GLTF2
from pygltflib.utils import glb2gltf, gltf2glb
# convert glb to gltf
glb2gltf("C:/Users/User/Desktop/cube.glb")
# load a gltf file
fname = pathlib.Path("C:/Users/User/Desktop/cube.gltf")
gltf = GLTF2().load(fname)
# get the first mesh in the current scene
mesh = gltf.meshes[gltf.scenes[gltf.scene].nodes[0]-1]
# get the vertices for each primitive in the mesh
for primitive in mesh.primitives:
# get the binary data for this mesh primitive from the buffer
accessor = gltf.accessors[primitive.attributes.POSITION]
bufferView = gltf.bufferViews[accessor.bufferView]
buffer = gltf.buffers[bufferView.buffer]
data = gltf.get_data_from_buffer_uri(buffer.uri)
# pull each vertex from the binary buffer and convert it into a tuple of python floats
vertices = []
for i in range(accessor.count):
index = bufferView.byteOffset + accessor.byteOffset + i*12 # the location in the buffer of this vertex
d = data[index:index+12] # the vertex data
v = struct.unpack("<fff", d) # convert from base64 to three floats
vertices.append(v)
# unpack floats
vertices2 = []
for a,b,c in vertices:
vertices2 += [a,b,c]
# create triangles
vertices = vertices2
triangles = []
for i in range(0,len(vertices),9):
triangles.append(vertices[i:i+9])
# print data
print(triangles)
It extracts triangle data from the first mesh.
It returns for the cube:
[[22.08578109741211, 22.55755615234375, -22.08578109741211, -22.08578109741211, -22.55755615234375, -22.08578109741211, -22.08578109741211, 22.55755615234375, -22.08578109741211], [22.08578109741211, -22.55755615234375, -22.08578109741211, -22.08578109741211, 22.55755615234375, 22.08578109741211, 22.08578109741211, -22.55755615234375, 22.08578109741211], [22.08578109741211, 22.55755615234375, 22.08578109741211, -22.08578109741211, -22.55755615234375, 22.08578109741211, 22.08578109741211, 22.55755615234375, 22.08578109741211], [22.08578109741211, -22.55755615234375, -22.08578109741211, 22.08578109741211, 22.55755615234375, -22.08578109741211, 22.08578109741211, -22.55755615234375, 22.08578109741211], [-22.08578109741211, 22.55755615234375, -22.08578109741211, -22.08578109741211, -22.55755615234375, 22.08578109741211, -22.08578109741211, 22.55755615234375, 22.08578109741211], [-22.08578109741211, -22.55755615234375, -22.08578109741211, -22.08578109741211, 22.55755615234375, -22.08578109741211, 22.08578109741211, 22.55755615234375, 22.08578109741211], [22.08578109741211, 22.55755615234375, -22.08578109741211, -22.08578109741211, 22.55755615234375, 22.08578109741211, -22.08578109741211, -22.55755615234375, 22.08578109741211], [22.08578109741211, -22.55755615234375, -22.08578109741211, 22.08578109741211, -22.55755615234375, 22.08578109741211, -22.08578109741211, -22.55755615234375, -22.08578109741211]]