mirror of
https://github.com/yeicor-3d/yet-another-cad-viewer.git
synced 2025-12-19 14:14:13 +01:00
134 lines
5.4 KiB
Python
134 lines
5.4 KiB
Python
import numpy as np
|
|
from pygltflib import *
|
|
|
|
_checkerboard_image = Image(uri='data:image/png;base64,'
|
|
'iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAF0lEQVQI12N49OjR////Gf'
|
|
'/////48WMATwULS8tcyj8AAAAASUVORK5CYII=')
|
|
|
|
|
|
def create_gltf(vertices: np.ndarray, indices: np.ndarray, tex_coord: np.ndarray, mode: int = TRIANGLES,
|
|
material: Optional[Material] = None, images: Optional[List[Image]] = None) -> GLTF2:
|
|
"""Create a glTF object from vertices and optionally indices.
|
|
|
|
If indices are not set, vertices are interpreted as line_strip."""
|
|
|
|
assert vertices.ndim == 2
|
|
assert vertices.shape[1] == 3
|
|
vertices = vertices.astype(np.float32)
|
|
vertices_blob = vertices.tobytes()
|
|
# print(vertices)
|
|
|
|
indices = indices.astype(np.uint8)
|
|
indices_blob = indices.flatten().tobytes()
|
|
# print(indices)
|
|
|
|
tex_coord = tex_coord.astype(np.float32)
|
|
tex_coord_blob = tex_coord.tobytes()
|
|
# print(tex_coord)
|
|
|
|
if images is None:
|
|
images = []
|
|
image_blob = b''
|
|
image_blob_pointers = []
|
|
for i, img in enumerate(images):
|
|
img = copy.deepcopy(img) # Avoid modifying the original image
|
|
assert img.bufferView is None
|
|
assert img.uri is not None
|
|
assert img.uri.startswith('data:')
|
|
image_blob_pointers.append(len(image_blob))
|
|
image_blob += base64.decodebytes(img.uri.split('base64,', maxsplit=1)[1].encode('ascii'))
|
|
img.mimeType = img.uri.split(';', maxsplit=1)[0].split(':', maxsplit=1)[1]
|
|
img.uri = None
|
|
img.bufferView = 3 + len(image_blob_pointers) - 1
|
|
images[i] = img # Replace the original image with the new copied and modified one
|
|
|
|
gltf = GLTF2(
|
|
scene=0,
|
|
scenes=[Scene(nodes=[0])],
|
|
nodes=[Node(mesh=0)],
|
|
meshes=[
|
|
Mesh(
|
|
primitives=[
|
|
Primitive(
|
|
attributes=Attributes(POSITION=1, TEXCOORD_0=2) if len(tex_coord) > 0 else Attributes(
|
|
POSITION=1),
|
|
indices=0,
|
|
mode=mode,
|
|
material=0 if material is not None else None,
|
|
)
|
|
]
|
|
)
|
|
],
|
|
materials=[material] if material is not None else [],
|
|
accessors=[
|
|
Accessor(
|
|
bufferView=0,
|
|
componentType=UNSIGNED_BYTE,
|
|
count=indices.size,
|
|
type=SCALAR,
|
|
max=[int(indices.max())],
|
|
min=[int(indices.min())],
|
|
),
|
|
Accessor(
|
|
bufferView=1,
|
|
componentType=FLOAT,
|
|
count=len(vertices),
|
|
type=VEC3,
|
|
max=vertices.max(axis=0).tolist(),
|
|
min=vertices.min(axis=0).tolist(),
|
|
),
|
|
] + ([
|
|
Accessor(
|
|
bufferView=2,
|
|
componentType=FLOAT,
|
|
count=len(tex_coord),
|
|
type=VEC2,
|
|
max=tex_coord.max(axis=0).tolist(),
|
|
min=tex_coord.min(axis=0).tolist(),
|
|
)] if len(tex_coord) > 0 else [])
|
|
,
|
|
bufferViews=[
|
|
BufferView(
|
|
buffer=0,
|
|
byteLength=len(indices_blob),
|
|
target=ELEMENT_ARRAY_BUFFER,
|
|
),
|
|
BufferView(
|
|
buffer=0,
|
|
byteOffset=len(indices_blob),
|
|
byteLength=len(vertices_blob),
|
|
target=ARRAY_BUFFER,
|
|
),
|
|
] + (
|
|
[
|
|
BufferView(
|
|
buffer=0,
|
|
byteOffset=len(indices_blob) + len(vertices_blob),
|
|
byteLength=len(tex_coord_blob),
|
|
target=ARRAY_BUFFER,
|
|
),
|
|
] if len(tex_coord) > 0 else []) + (
|
|
[
|
|
BufferView(
|
|
buffer=0,
|
|
byteOffset=len(indices_blob) + len(
|
|
vertices_blob) + len(tex_coord_blob) + image_blob_pointers[i],
|
|
byteLength=image_blob_pointers[i + 1] - image_blob_pointers[i] if i + 1 < len(
|
|
image_blob_pointers) else len(image_blob) - image_blob_pointers[i],
|
|
)
|
|
for i, img in enumerate(images)
|
|
] if len(images) > 0 else []),
|
|
buffers=[
|
|
Buffer(
|
|
byteLength=len(indices_blob) + len(vertices_blob) + len(tex_coord_blob) + len(image_blob),
|
|
)
|
|
],
|
|
samplers=[Sampler(magFilter=NEAREST, minFilter=NEAREST_MIPMAP_NEAREST)] if len(images) > 0 else [],
|
|
textures=[Texture(source=i, sampler=0) for i, _ in enumerate(images)],
|
|
images=images,
|
|
)
|
|
|
|
gltf.set_binary_blob(indices_blob + vertices_blob + tex_coord_blob + image_blob)
|
|
|
|
return gltf
|