Full chain of import/export with assimp working

This commit is contained in:
Alexis Breust 2018-01-19 09:56:47 +01:00
parent 7faee5804a
commit 5c6712e0cb
5 changed files with 59 additions and 35 deletions

View File

@ -2,8 +2,6 @@ import io
import os
import json
import pytest
import yoga.model
@ -34,7 +32,6 @@ class Test_optimize(object):
output.seek(0)
assert output.read().startswith(_MAGIC_GLB)
def test_input_file_format(self):
# FBX
output = io.BytesIO()
@ -84,6 +81,6 @@ class Test_optimize(object):
"output_format": "gltf"
})
output.seek(0)
assert json.load(output)["asset"]["version"] == 2
assert json.load(output)["asset"]["version"] == "2.0"
# TODO Tests for no_graph_optimization and such

View File

@ -29,39 +29,39 @@ class Test_normalize_options(object):
def test_no_graph_optimization(self):
opt = options.normalize_options({"no_graph_optimization": True})
assert opt["no_graph_optimization"] == True
assert opt["no_graph_optimization"] is True
opt = options.normalize_options({"no_graph_optimization": False})
assert opt["no_graph_optimization"] == False
assert opt["no_graph_optimization"] is False
opt = options.normalize_options({"no_graph_optimization": ""})
assert opt["no_graph_optimization"] == False
assert opt["no_graph_optimization"] is False
opt = options.normalize_options({"no_graph_optimization": "foobar"})
assert opt["no_graph_optimization"] == True
assert opt["no_graph_optimization"] is True
def test_no_meshes_optimization(self):
opt = options.normalize_options({"no_meshes_optimization": True})
assert opt["no_meshes_optimization"] == True
assert opt["no_meshes_optimization"] is True
opt = options.normalize_options({"no_meshes_optimization": False})
assert opt["no_meshes_optimization"] == False
assert opt["no_meshes_optimization"] is False
opt = options.normalize_options({"no_meshes_optimization": ""})
assert opt["no_meshes_optimization"] == False
assert opt["no_meshes_optimization"] is False
opt = options.normalize_options({"no_meshes_optimization": "foobar"})
assert opt["no_meshes_optimization"] == True
assert opt["no_meshes_optimization"] is True
def test_no_textures_optimization(self):
opt = options.normalize_options({"no_textures_optimization": True})
assert opt["no_textures_optimization"] == True
assert opt["no_textures_optimization"] is True
opt = options.normalize_options({"no_textures_optimization": False})
assert opt["no_textures_optimization"] == False
assert opt["no_textures_optimization"] is False
opt = options.normalize_options({"no_textures_optimization": ""})
assert opt["no_textures_optimization"] == False
assert opt["no_textures_optimization"] is False
opt = options.normalize_options({"no_textures_optimization": "foobar"})
assert opt["no_textures_optimization"] == True
assert opt["no_textures_optimization"] is True

View File

@ -1,25 +1,24 @@
import io
from .assimp import (assimp_import_from_bytes)
from .options import (normalize_options, extract_image_options)
from .assimp import (assimp_import_from_bytes, assimp_export_to_bytes)
from .options import (normalize_options)
def optimize(input_file, output_file, options={}):
model_options = normalize_options(options)
image_options = extract_image_options(options)
# TODO image_options = extract_image_options(options)
# input_file -> string (path), bytes, file-like
if not hasattr(input_file, "read"):
input_file = open(input_file, "rb")
if hasattr(input_file, "read"):
input_file = input_file.read()
# output_file -> string (path), file-like
if not hasattr(output_file, "write"):
output_file = open(output_file, "wb")
assimp_import_from_bytes("glb", input_file) # @fixme
# Import the bytes
scene = assimp_import_from_bytes(input_file)
bytes_out = assimp_export_to_bytes(scene, model_options["output_format"])
output_file.write(bytes_out)
# TODO input_file -> string (path), bytes, file-like
# TODO output_file -> string (path), file-like
# raise NotImplementedError() # TODO
output_file.write(b"glTF")
# TODO Don't forget to free memory in C++!

View File

@ -3,6 +3,7 @@ extern "C" {
}
#include <assimp/Importer.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/DefaultLogger.hpp>
using namespace Assimp;
@ -14,16 +15,27 @@ Scene assimp_import_from_bytes(int optimization_flags_in, char* bytes_in, int le
DefaultLogger::get()->attachStream(LogStream::createDefaultStream(aiDefaultLogStream_STDERR), Assimp::Logger::Err);
Importer importer;
scene.assimp_scene = const_cast<aiScene*>(importer.ReadFileFromMemory(bytes_in, length_in, 0u));
importer.ReadFileFromMemory(bytes_in, length_in, 0u);
// GetOrphanedScene () to free the ownership?
// Free the ownership of the scene from the importer
scene.assimp_scene = importer.GetOrphanedScene();
return scene;
}
int assimp_export_to_bytes(Scene scene_in, OutputFormat output_format_in, char** bytes_out) {
// @fixme Not implemented yet
return 0;
Exporter exporter;
auto outputFormat = output_format_in == OUTPUT_FORMAT_GLB ? "glb2" : "gltf2";
// @todo Apply images bytes back
auto scene = reinterpret_cast<aiScene*>(scene_in.assimp_scene);
auto blob = exporter.ExportToBlob(scene, outputFormat, 0, nullptr); // @fixme
if (blob == nullptr) return 0;
*bytes_out = reinterpret_cast<char*>(blob->data);
return blob->size;
}
void assimp_free_scene(Scene scene) {

View File

@ -6,7 +6,7 @@ This module contains functions binded from the Assimp C++ API.
from ._assimp import lib, ffi
def assimp_import_from_bytes(output_format, bytes_in):
def assimp_import_from_bytes(bytes_in):
"""
@fixme doc
"""
@ -20,13 +20,29 @@ def assimp_import_from_bytes(output_format, bytes_in):
if scene.assimp_scene == ffi.NULL:
raise ValueError("Invalid model: Assimp was not able to import the model") # noqa
print("Model was imported")
return scene
# OUTPUTTING...
def assimp_export_to_bytes(scene, output_format):
if output_format not in ("glb", "gltf"):
raise ValueError("Invalid output format: should be glb or gltf but is %s" % output_format) # noqa
output_format_dict = dict({
"glb": lib.OUTPUT_FORMAT_GLB,
"gltf": lib.OUTPUT_FORMAT_GLTF
})
print(output_format_dict[output_format])
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(
scene,
output_format_dict[output_format],
bytes_out_p
)
if length == 0:
raise ValueError("Invalid model: Assimp was not able to export")
bytes_out = ffi.cast("char*", bytes_out_p_gc[0])
return ffi.unpack(bytes_out, length)