Merge branch 'master' into kimmi_dev

pull/2153/head
Kim Kulling 2018-09-26 19:15:58 +02:00 committed by GitHub
commit 5d091c4591
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 101 additions and 16 deletions

View File

@ -659,7 +659,7 @@ namespace glTF2
int width, height; int width, height;
private: private:
uint8_t* mData; std::unique_ptr<uint8_t[]> mData;
size_t mDataLength; size_t mDataLength;
public: public:
@ -674,7 +674,7 @@ namespace glTF2
{ return mDataLength; } { return mDataLength; }
inline const uint8_t* GetData() const inline const uint8_t* GetData() const
{ return mData; } { return mData.get(); }
inline uint8_t* StealData(); inline uint8_t* StealData();

View File

@ -688,7 +688,6 @@ T Accessor::Indexer::GetValue(int i)
inline Image::Image() inline Image::Image()
: width(0) : width(0)
, height(0) , height(0)
, mData(0)
, mDataLength(0) , mDataLength(0)
{ {
@ -704,7 +703,9 @@ inline void Image::Read(Value& obj, Asset& r)
if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) { if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
mimeType = dataURI.mediaType; mimeType = dataURI.mediaType;
if (dataURI.base64) { if (dataURI.base64) {
mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, mData); uint8_t *ptr = nullptr;
mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
mData.reset(ptr);
} }
} }
else { else {
@ -717,8 +718,9 @@ inline void Image::Read(Value& obj, Asset& r)
this->mDataLength = this->bufferView->byteLength; this->mDataLength = this->bufferView->byteLength;
// maybe this memcpy could be avoided if aiTexture does not delete[] pcData at destruction. // maybe this memcpy could be avoided if aiTexture does not delete[] pcData at destruction.
this->mData = new uint8_t [this->mDataLength];
memcpy(this->mData, buffer->GetPointer() + this->bufferView->byteOffset, this->mDataLength); this->mData.reset(new uint8_t[this->mDataLength]);
memcpy(this->mData.get(), buffer->GetPointer() + this->bufferView->byteOffset, this->mDataLength);
if (Value* mtype = FindString(obj, "mimeType")) { if (Value* mtype = FindString(obj, "mimeType")) {
this->mimeType = mtype->GetString(); this->mimeType = mtype->GetString();
@ -729,10 +731,8 @@ inline void Image::Read(Value& obj, Asset& r)
inline uint8_t* Image::StealData() inline uint8_t* Image::StealData()
{ {
uint8_t* data = mData; mDataLength = 0;
mDataLength = 0; return mData.release();
mData = 0;
return data;
} }
inline void Image::SetData(uint8_t* data, size_t length, Asset& r) inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
@ -747,8 +747,8 @@ inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
bufferView->byteOffset = b->AppendData(data, length); bufferView->byteOffset = b->AppendData(data, length);
} }
else { // text file: will be stored as a data uri else { // text file: will be stored as a data uri
this->mData = data; this->mData.reset(data);
this->mDataLength = length; this->mDataLength = length;
} }
} }

View File

@ -818,7 +818,7 @@ void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset& r)
// Add the embedded textures // Add the embedded textures
for (size_t i = 0; i < r.images.Size(); ++i) { for (size_t i = 0; i < r.images.Size(); ++i) {
Image img = r.images[i]; Image &img = r.images[i];
if (!img.HasData()) continue; if (!img.HasData()) continue;
int idx = mScene->mNumTextures++; int idx = mScene->mNumTextures++;

View File

@ -35,7 +35,7 @@ class AssimpLib(object):
""" """
Assimp-Singleton Assimp-Singleton
""" """
load, load_mem, export, release, dll = helper.search_library() load, load_mem, export, export_blob, release, dll = helper.search_library()
_assimp_lib = AssimpLib() _assimp_lib = AssimpLib()
def make_tuple(ai_obj, type = None): def make_tuple(ai_obj, type = None):
@ -352,6 +352,33 @@ def export(scene,
if exportStatus != 0: if exportStatus != 0:
raise AssimpError('Could not export scene!') raise AssimpError('Could not export scene!')
def export_blob(scene,
file_type = None,
processing = postprocess.aiProcess_Triangulate):
'''
Export a scene and return a blob in the correct format. On failure throws AssimpError.
Arguments
---------
scene: scene to export.
file_type: string of file exporter to use. For example "collada".
processing: assimp postprocessing parameters. Verbose keywords are imported
from postprocessing, and the parameters can be combined bitwise to
generate the final processing value. Note that the default value will
triangulate quad faces. Example of generating other possible values:
processing = (pyassimp.postprocess.aiProcess_Triangulate |
pyassimp.postprocess.aiProcess_OptimizeMeshes)
Returns
---------
Pointer to structs.ExportDataBlob
'''
from ctypes import pointer
exportBlobPtr = _assimp_lib.export_blob(pointer(scene), file_type.encode("ascii"), processing)
if exportBlobPtr == 0:
raise AssimpError('Could not export scene to blob!')
return exportBlobPtr
def release(scene): def release(scene):
from ctypes import pointer from ctypes import pointer
_assimp_lib.release(pointer(scene)) _assimp_lib.release(pointer(scene))

View File

@ -176,6 +176,7 @@ def try_load_functions(library_path, dll):
load from filename function, load from filename function,
load from memory function, load from memory function,
export to filename function, export to filename function,
export to blob function,
release function, release function,
ctypes handle to assimp library) ctypes handle to assimp library)
''' '''
@ -185,15 +186,17 @@ def try_load_functions(library_path, dll):
release = dll.aiReleaseImport release = dll.aiReleaseImport
load_mem = dll.aiImportFileFromMemory load_mem = dll.aiImportFileFromMemory
export = dll.aiExportScene export = dll.aiExportScene
export2blob = dll.aiExportSceneToBlob
except AttributeError: except AttributeError:
#OK, this is a library, but it doesn't have the functions we need #OK, this is a library, but it doesn't have the functions we need
return None return None
# library found! # library found!
from .structs import Scene from .structs import Scene, ExportDataBlob
load.restype = POINTER(Scene) load.restype = POINTER(Scene)
load_mem.restype = POINTER(Scene) load_mem.restype = POINTER(Scene)
return (library_path, load, load_mem, export, release, dll) export2blob.restype = POINTER(ExportDataBlob)
return (library_path, load, load_mem, export, export2blob, release, dll)
def search_library(): def search_library():
''' '''
@ -203,6 +206,7 @@ def search_library():
Returns: tuple, (load from filename function, Returns: tuple, (load from filename function,
load from memory function, load from memory function,
export to filename function, export to filename function,
export to blob function,
release function, release function,
dll) dll)
''' '''

View File

@ -996,6 +996,39 @@ class Animation(Structure):
] ]
class ExportDataBlob(Structure):
"""
See 'cexport.h' for details.
Note that the '_fields_' definition is outside the class to allow the 'next' field to be recursive
"""
pass
ExportDataBlob._fields_ = [
# Size of the data in bytes
("size", c_size_t),
# The data.
("data", c_void_p),
# Name of the blob. An empty string always
# indicates the first (and primary) blob,
# which contains the actual file data.
# Any other blobs are auxiliary files produced
# by exporters (i.e. material files). Existence
# of such files depends on the file format. Most
# formats don't split assets across multiple files.
#
# If used, blob names usually contain the file
# extension that should be used when writing
# the data to disc.
("name", String),
# Pointer to the next blob in the chain or NULL if there is none.
("next", POINTER(ExportDataBlob)),
]
class Scene(Structure): class Scene(Structure):
""" """
See 'aiScene.h' for details. See 'aiScene.h' for details.

View File

@ -101,6 +101,24 @@ TEST_F( utglTF2ImportExport, importBinaryglTF2FromFileTest ) {
EXPECT_TRUE( binaryImporterTest() ); EXPECT_TRUE( binaryImporterTest() );
} }
#ifndef ASSIMP_BUILD_NO_EXPORT
TEST_F(utglTF2ImportExport, importglTF2AndExportToOBJ) {
Assimp::Importer importer;
Assimp::Exporter exporter;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "obj", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured_out.obj"));
}
TEST_F(utglTF2ImportExport, importglTF2EmbeddedAndExportToOBJ) {
Assimp::Importer importer;
Assimp::Exporter exporter;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-Embedded/BoxTextured.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "obj", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-Embedded/BoxTextured_out.obj"));
}
#endif // ASSIMP_BUILD_NO_EXPORT
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModePointsWithoutIndices) { TEST_F(utglTF2ImportExport, importglTF2PrimitiveModePointsWithoutIndices) {
Assimp::Importer importer; Assimp::Importer importer;
//Points without indices //Points without indices

View File

@ -466,6 +466,9 @@ int ProcessStandardArguments(
else if (! strcmp( param, "-sbc") || ! strcmp( param, "--split-by-bone-count")) { else if (! strcmp( param, "-sbc") || ! strcmp( param, "--split-by-bone-count")) {
fill.ppFlags |= aiProcess_SplitByBoneCount; fill.ppFlags |= aiProcess_SplitByBoneCount;
} }
else if (!strcmp(param, "-embtex") || ! strcmp(param, "--embed-textures")) {
fill.ppFlags |= aiProcess_EmbedTextures;
}
else if (! strncmp( param, "-c",2) || ! strncmp( param, "--config=",9)) { else if (! strncmp( param, "-c",2) || ! strncmp( param, "--config=",9)) {
const unsigned int ofs = (params[i][1] == '-' ? 9 : 2); const unsigned int ofs = (params[i][1] == '-' ? 9 : 2);