mirror of https://github.com/wanadev/yoga.git
Full chain of import/export with assimp working
This commit is contained in:
parent
7faee5804a
commit
5c6712e0cb
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++!
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue