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.

This is the search page.

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`‚    

Here is its image:
GLB file image

Asked By: George

||

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]]

Answered By: George
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.