2018-01-18 14:07:47 +01:00
|
|
|
"""
|
|
|
|
This module contains functions binded from the Assimp C++ API.
|
|
|
|
"""
|
|
|
|
|
|
|
|
from ._assimp import lib, ffi
|
|
|
|
|
|
|
|
|
2018-05-04 09:51:07 +02:00
|
|
|
def assimp_import_from_bytes(
|
2021-04-14 16:27:11 +02:00
|
|
|
bytes_in, optimize_graph, optimize_meshes, fix_infacing_normals, verbose
|
2021-03-29 13:46:56 +02:00
|
|
|
):
|
2018-01-22 17:18:10 +01:00
|
|
|
"""Generates an abstract 3D scene from a model file's bytes.
|
|
|
|
:param bytes_in: the input model's bytes
|
|
|
|
:param optimize_graph: whether the graph scene should be optimized
|
|
|
|
:param optimize_meshes: whether the meshes geometries should be optimized
|
2021-04-15 10:46:31 +02:00
|
|
|
:param fix_infacing_normals: disable the assimp's "fix-infancing-normals"
|
|
|
|
postprocess
|
2018-05-04 09:51:07 +02:00
|
|
|
:param verbose: whether verbose is active
|
2018-01-26 15:40:50 +01:00
|
|
|
:returns: An abstract scene dict
|
2018-01-22 17:18:10 +01:00
|
|
|
:raises ValueError: Assimp was not able to import the model
|
2018-01-18 14:07:47 +01:00
|
|
|
"""
|
|
|
|
|
2021-04-15 11:38:14 +02:00
|
|
|
flags = 0
|
2018-01-22 14:59:45 +01:00
|
|
|
if optimize_graph:
|
2021-04-15 11:38:14 +02:00
|
|
|
flags |= lib.FLAG_OPTIMIZE_GRAPH
|
2018-01-22 14:59:45 +01:00
|
|
|
if optimize_meshes:
|
2021-04-15 11:38:14 +02:00
|
|
|
flags |= lib.FLAG_OPTIMIZE_MESHES
|
2021-04-14 16:27:11 +02:00
|
|
|
if fix_infacing_normals:
|
2021-04-15 11:38:14 +02:00
|
|
|
flags |= lib.FLAG_FIX_INFACING_NORMALS
|
2018-01-22 14:54:38 +01:00
|
|
|
|
2018-01-26 15:40:50 +01:00
|
|
|
scene = {
|
|
|
|
"cffi_pointer": None,
|
2021-03-29 13:46:56 +02:00
|
|
|
"cffi_gc": None,
|
2018-01-26 15:40:50 +01:00
|
|
|
}
|
|
|
|
scene["cffi_pointer"] = ffi.new("Scene*")
|
|
|
|
scene["cffi_gc"] = ffi.gc(scene["cffi_pointer"], lib.assimp_free_scene)
|
|
|
|
|
|
|
|
lib.assimp_import_from_bytes(
|
2018-01-22 14:54:38 +01:00
|
|
|
bytes_in,
|
|
|
|
len(bytes_in),
|
2021-04-15 11:38:14 +02:00
|
|
|
flags,
|
2018-05-04 09:51:07 +02:00
|
|
|
scene["cffi_pointer"],
|
2021-03-29 13:46:56 +02:00
|
|
|
verbose,
|
|
|
|
)
|
2018-01-18 14:07:47 +01:00
|
|
|
|
2018-01-26 15:40:50 +01:00
|
|
|
if scene["cffi_pointer"].assimp_scene == ffi.NULL:
|
2021-03-29 13:46:56 +02:00
|
|
|
raise ValueError(
|
|
|
|
"Invalid model: Assimp was not able to import the model"
|
|
|
|
)
|
2018-01-18 14:07:47 +01:00
|
|
|
|
2018-01-19 09:56:47 +01:00
|
|
|
return scene
|
2018-01-18 17:44:43 +01:00
|
|
|
|
|
|
|
|
2018-01-26 15:40:50 +01:00
|
|
|
def assimp_export_to_bytes(scene_p, output_format):
|
2018-01-22 17:18:10 +01:00
|
|
|
"""Generates a glTF or a GLB file bytes from an abstract scene.
|
2018-01-26 15:40:50 +01:00
|
|
|
:param scene_p: the abstract scene (a CFFI pointer)
|
2018-01-22 17:18:10 +01:00
|
|
|
:param output_format: either "glb" or "gltf"
|
|
|
|
:returns: the generated bytes making a glb or gltf file
|
|
|
|
:rtype: bytes
|
|
|
|
:raises ValueError: Assimp was not able to export the model
|
2018-01-22 14:54:38 +01:00
|
|
|
"""
|
|
|
|
|
2018-01-19 09:56:47 +01:00
|
|
|
if output_format not in ("glb", "gltf"):
|
2021-03-29 13:46:56 +02:00
|
|
|
raise ValueError(
|
|
|
|
"Invalid output format: should be glb or gltf but is %s"
|
|
|
|
% output_format
|
|
|
|
)
|
2018-01-18 17:44:43 +01:00
|
|
|
|
2021-03-29 13:46:56 +02:00
|
|
|
output_format_dict = dict(
|
|
|
|
{
|
2018-01-18 17:44:43 +01:00
|
|
|
"glb": lib.OUTPUT_FORMAT_GLB,
|
2021-03-29 13:46:56 +02:00
|
|
|
"gltf": lib.OUTPUT_FORMAT_GLTF,
|
|
|
|
}
|
|
|
|
)
|
2018-01-19 09:56:47 +01:00
|
|
|
|
|
|
|
bytes_out_p = ffi.new("char**")
|
|
|
|
bytes_out_p_gc = ffi.gc(bytes_out_p, lib.assimp_free_bytes)
|
|
|
|
|
|
|
|
length = lib.assimp_export_to_bytes(
|
2021-03-29 13:46:56 +02:00
|
|
|
scene_p, output_format_dict[output_format], bytes_out_p
|
|
|
|
)
|
2018-01-19 09:56:47 +01:00
|
|
|
|
|
|
|
if length == 0:
|
|
|
|
raise ValueError("Invalid model: Assimp was not able to export")
|
|
|
|
|
|
|
|
bytes_out = ffi.cast("char*", bytes_out_p_gc[0])
|
2018-01-26 15:40:50 +01:00
|
|
|
|
2018-01-19 09:56:47 +01:00
|
|
|
return ffi.unpack(bytes_out, length)
|