2
0
Эх сурвалжийг харах

Merge branch 'master' into kimmi_dev

Kim Kulling 7 жил өмнө
parent
commit
5d091c4591

+ 2 - 2
code/glTF2Asset.h

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

+ 10 - 10
code/glTF2Asset.inl

@@ -688,7 +688,6 @@ T Accessor::Indexer::GetValue(int i)
 inline Image::Image()
     : width(0)
     , height(0)
-    , mData(0)
     , mDataLength(0)
 {
 
@@ -704,7 +703,9 @@ inline void Image::Read(Value& obj, Asset& r)
             if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
                 mimeType = dataURI.mediaType;
                 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 {
@@ -717,8 +718,9 @@ inline void Image::Read(Value& obj, Asset& r)
 
             this->mDataLength = this->bufferView->byteLength;
             // 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")) {
                 this->mimeType = mtype->GetString();
@@ -729,10 +731,8 @@ inline void Image::Read(Value& obj, Asset& r)
 
 inline uint8_t* Image::StealData()
 {
-    uint8_t* data = mData;
-    mDataLength = 0;
-    mData = 0;
-    return data;
+	mDataLength = 0;
+	return mData.release();
 }
 
 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);
     }
     else { // text file: will be stored as a data uri
-        this->mData = data;
-        this->mDataLength = length;
+		this->mData.reset(data);
+		this->mDataLength = length;
     }
 }
 

+ 1 - 1
code/glTF2Importer.cpp

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

+ 28 - 1
port/PyAssimp/pyassimp/core.py

@@ -35,7 +35,7 @@ class AssimpLib(object):
     """
     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()
 
 def make_tuple(ai_obj, type = None):
@@ -352,6 +352,33 @@ def export(scene,
     if exportStatus != 0:
         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):
     from ctypes import pointer
     _assimp_lib.release(pointer(scene))

+ 6 - 2
port/PyAssimp/pyassimp/helper.py

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

+ 33 - 0
port/PyAssimp/pyassimp/structs.py

@@ -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):
     """
     See 'aiScene.h' for details.

+ 18 - 0
test/unit/utglTF2ImportExport.cpp

@@ -101,6 +101,24 @@ TEST_F( utglTF2ImportExport, importBinaryglTF2FromFileTest ) {
     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) {
     Assimp::Importer importer;
     //Points without indices

+ 3 - 0
tools/assimp_cmd/Main.cpp

@@ -466,6 +466,9 @@ int ProcessStandardArguments(
 		else if (! strcmp( param, "-sbc") || ! strcmp( param, "--split-by-bone-count")) {
 			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)) {
 			const unsigned int ofs = (params[i][1] == '-' ? 9 : 2);