Browse Source

Add common metadata to Collada

Also add AI_METADATA_SOURCE_COPYRIGHT common metadata
RichardTea 5 years ago
parent
commit
f498a395e4

+ 2 - 0
code/CMakeLists.txt

@@ -66,6 +66,7 @@ SET( PUBLIC_HEADERS
   ${HEADER_PATH}/color4.h
   ${HEADER_PATH}/color4.inl
   ${CMAKE_CURRENT_BINARY_DIR}/../include/assimp/config.h
+  ${HEADER_PATH}/commonMetaData.h
   ${HEADER_PATH}/defs.h
   ${HEADER_PATH}/Defines.h
   ${HEADER_PATH}/cfileio.h
@@ -348,6 +349,7 @@ ADD_ASSIMP_IMPORTER( BVH
 )
 
 ADD_ASSIMP_IMPORTER( COLLADA
+  Collada/ColladaHelper.cpp
   Collada/ColladaHelper.h
   Collada/ColladaLoader.cpp
   Collada/ColladaLoader.h

+ 3 - 2
code/Collada/ColladaExporter.cpp

@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "ColladaExporter.h"
 #include <assimp/Bitmap.h>
+#include <assimp/commonMetaData.h>
 #include <assimp/MathFunctions.h>
 #include <assimp/fast_atof.h>
 #include <assimp/SceneCombiner.h>
@@ -277,7 +278,7 @@ void ColladaExporter::WriteHeader() {
         mOutput << startstr << "<author>" << XMLEscape(value.C_Str()) << "</author>" << endstr;
     }
 
-    if (nullptr == meta || !meta->Get("AuthoringTool", value)) {
+    if (nullptr == meta || !meta->Get(AI_METADATA_SOURCE_GENERATOR, value)) {
         mOutput << startstr << "<authoring_tool>" << "Assimp Exporter" << "</authoring_tool>" << endstr;
     } else {
         mOutput << startstr << "<authoring_tool>" << XMLEscape(value.C_Str()) << "</authoring_tool>" << endstr;
@@ -287,7 +288,7 @@ void ColladaExporter::WriteHeader() {
         if (meta->Get("Comments", value)) {
             mOutput << startstr << "<comments>" << XMLEscape(value.C_Str()) << "</comments>" << endstr;
         }
-        if (meta->Get("Copyright", value)) {
+        if (meta->Get(AI_METADATA_SOURCE_COPYRIGHT, value)) {
             mOutput << startstr << "<copyright>" << XMLEscape(value.C_Str()) << "</copyright>" << endstr;
         }
         if (meta->Get("SourceData", value)) {

+ 65 - 0
code/Collada/ColladaHelper.cpp

@@ -0,0 +1,65 @@
+/** Helper structures for the Collada loader */
+
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+#include "ColladaHelper.h"
+
+#include <assimp/commonMetaData.h>
+
+namespace Assimp {
+namespace Collada {
+
+const MetaKeyPairVector MakeColladaAssimpMetaKeys() {
+	MetaKeyPairVector result;
+	result.emplace_back("authoring_tool", AI_METADATA_SOURCE_GENERATOR);
+    result.emplace_back("copyright", AI_METADATA_SOURCE_COPYRIGHT);
+	return result;
+};
+
+const MetaKeyPairVector &GetColladaAssimpMetaKeys() {
+	static const MetaKeyPairVector result = MakeColladaAssimpMetaKeys();
+	return result;
+}
+
+} // namespace Collada
+} // namespace Assimp

+ 5 - 0
code/Collada/ColladaHelper.h

@@ -104,6 +104,11 @@ enum MorphMethod
     Relative
 };
 
+/** Common metadata keys as <Collada, Assimp> */
+typedef std::pair<const char*, const char*> MetaKeyPair;
+typedef std::vector<MetaKeyPair> MetaKeyPairVector;
+
+const MetaKeyPairVector &GetColladaAssimpMetaKeys();
 
 /** Contains all data for one of the different transformation types */
 struct Transform

+ 32 - 15
code/Collada/ColladaParser.cpp

@@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <sstream>
 #include <stdarg.h>
 #include "ColladaParser.h"
+#include <assimp/commonMetaData.h>
 #include <assimp/fast_atof.h>
 #include <assimp/ParsingUtils.h>
 #include <assimp/StringUtils.h>
@@ -276,6 +277,9 @@ void ColladaParser::ReadContents()
                 if (attrib != -1) {
                     const char* version = mReader->getAttributeValue(attrib);
 
+                    // Store declared format version string
+                    mAssetMetaData.emplace(AI_METADATA_SOURCE_FORMAT_VERSION, version);
+
                     if (!::strncmp(version, "1.5", 3)) {
                         mFormat = FV_1_5_n;
                         ASSIMP_LOG_DEBUG("Collada schema version is 1.5.n");
@@ -399,7 +403,7 @@ void ColladaParser::ReadAssetInfo()
             }
             else
             {
-                ReadMetaDataItem(mAssetMetaData);
+                ReadMetaDataItem(mAssetMetaData, GetColladaAssimpMetaKeys());
             }
         }
         else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
@@ -423,7 +427,7 @@ void ColladaParser::ReadContributorInfo()
     {
         if (mReader->getNodeType() == irr::io::EXN_ELEMENT)
         {
-            ReadMetaDataItem(mAssetMetaData);
+            ReadMetaDataItem(mAssetMetaData, GetColladaAssimpMetaKeys());
         }
         else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
         {
@@ -434,23 +438,36 @@ void ColladaParser::ReadContributorInfo()
     }
 }
 
+bool FindCommonKey(const char *collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) {
+    for (size_t i = 0; i < key_renaming.size(); ++i) {
+		if (strcmp(key_renaming[i].first, collada_key) == 0) {
+            found_index = i;
+            return true;
+		}
+	}
+    return false;
+}
+
 // ------------------------------------------------------------------------------------------------
 // Reads a single string metadata item
-void ColladaParser::ReadMetaDataItem(StringMetaData &metadata)
-{
-    // Metadata such as created, keywords, subject etc
-    const char* key_char = mReader->getNodeName();
-    if (key_char != nullptr)
-    {
+void ColladaParser::ReadMetaDataItem(StringMetaData &metadata, const MetaKeyPairVector &key_renaming) {
+	// Metadata such as created, keywords, subject etc
+	const char *key_char = mReader->getNodeName();
+	if (key_char != nullptr) {
         const std::string key_str(key_char);
-        const char* value_char = TestTextContent();
-        if (value_char != nullptr)
-        {
-            std::string camel_key_str = key_str;
-            ToCamelCase(camel_key_str);
+		const char *value_char = TestTextContent();
+		if (value_char != nullptr) {
             aiString aistr;
-            aistr.Set(value_char);
-            metadata.emplace(camel_key_str, aistr);
+			aistr.Set(value_char);
+
+			size_t found_index;
+			if (FindCommonKey(key_str.c_str(), key_renaming, found_index)) {
+                metadata.emplace(key_renaming[found_index].second, aistr);
+            } else {
+				std::string camel_key_str(key_str);
+				ToCamelCase(camel_key_str);
+				metadata.emplace(camel_key_str, aistr);
+			}
         }
         TestClosing(key_str.c_str());
     }

+ 2 - 2
code/Collada/ColladaParser.h

@@ -94,8 +94,8 @@ namespace Assimp
         /** Reads contributor information such as author and legal blah */
         void ReadContributorInfo();
 
-        /** Reads generic metadata into provided map */
-        void ReadMetaDataItem(StringMetaData &metadata);
+        /** Reads generic metadata into provided map and renames keys for Assimp */
+        void ReadMetaDataItem(StringMetaData &metadata, const Collada::MetaKeyPairVector &key_renaming);
 
         /** Convert underscore_seperated to CamelCase "authoring_tool" becomes "AuthoringTool" */
         static void ToCamelCase(std::string &text);

+ 4 - 0
include/assimp/commonMetaData.h

@@ -60,4 +60,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /// Not all formats add this metadata.
 #define AI_METADATA_SOURCE_GENERATOR "SourceAsset_Generator"
 
+/// Scene metadata holding the source asset copyright statement, if available.
+/// Not all formats add this metadata.
+#define AI_METADATA_SOURCE_COPYRIGHT "SourceAsset_Copyright"
+
 #endif

+ 69 - 54
test/unit/utColladaImportExport.cpp

@@ -40,76 +40,91 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
-#include "UnitTestPCH.h"
 #include "AbstractImportExportBase.h"
+#include "UnitTestPCH.h"
 
-#include <assimp/Importer.hpp>
-#include <assimp/scene.h>
+#include <assimp/commonMetaData.h>
 #include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <assimp/Importer.hpp>
 
 using namespace Assimp;
 
 class utColladaImportExport : public AbstractImportExportBase {
 public:
-    virtual bool importerTest() {
-        Assimp::Importer importer;
-        const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck.dae", aiProcess_ValidateDataStructure);
-        if (scene == nullptr)
-            return false;
-
-        // Expected number of items
-        EXPECT_EQ(scene->mNumMeshes, 1u);
-        EXPECT_EQ(scene->mNumMaterials, 1u);
-        EXPECT_EQ(scene->mNumAnimations, 0u);
-        EXPECT_EQ(scene->mNumTextures, 0u);
-        EXPECT_EQ(scene->mNumLights, 1u);
-        EXPECT_EQ(scene->mNumCameras, 1u);
-
-        return true;
-    }
+	virtual bool importerTest() {
+		Assimp::Importer importer;
+		const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck.dae", aiProcess_ValidateDataStructure);
+		if (scene == nullptr)
+			return false;
+
+		// Expected number of items
+		EXPECT_EQ(scene->mNumMeshes, 1u);
+		EXPECT_EQ(scene->mNumMaterials, 1u);
+		EXPECT_EQ(scene->mNumAnimations, 0u);
+		EXPECT_EQ(scene->mNumTextures, 0u);
+		EXPECT_EQ(scene->mNumLights, 1u);
+		EXPECT_EQ(scene->mNumCameras, 1u);
+
+		// Expected common metadata
+		aiString value;
+		EXPECT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_FORMAT, value)) << "No importer format metadata";
+		EXPECT_STREQ("Collada Importer", value.C_Str());
+
+		EXPECT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_FORMAT_VERSION, value)) << "No format version metadata";
+		EXPECT_STREQ("1.4.1", value.C_Str());
+
+		EXPECT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_GENERATOR, value)) << "No generator metadata";
+		EXPECT_EQ(strncmp(value.C_Str(), "Maya 8.0", 8), 0) << "AI_METADATA_SOURCE_GENERATOR was: " << value.C_Str();
+
+		EXPECT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_COPYRIGHT, value));
+		EXPECT_EQ(strncmp(value.C_Str(), "Copyright 2006", 14), 0) << "AI_METADATA_SOURCE_COPYRIGHT was: " << value.C_Str();
+
+		return true;
+	}
 };
 
 TEST_F(utColladaImportExport, importBlenFromFileTest) {
-    EXPECT_TRUE(importerTest());
+	EXPECT_TRUE(importerTest());
 }
 
 class utColladaZaeImportExport : public AbstractImportExportBase {
 public:
-    virtual bool importerTest() {
-        {
-            Assimp::Importer importer;
-            const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck.zae", aiProcess_ValidateDataStructure);
-            if (scene == nullptr)
-                return false;
-
-            // Expected number of items
-            EXPECT_EQ(scene->mNumMeshes, 1u);
-            EXPECT_EQ(scene->mNumMaterials, 1u);
-            EXPECT_EQ(scene->mNumAnimations, 0u);
-            EXPECT_EQ(scene->mNumTextures, 1u);
-            EXPECT_EQ(scene->mNumLights, 1u);
-            EXPECT_EQ(scene->mNumCameras, 1u);
-        }
-
-        {
-            Assimp::Importer importer;
-            const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck_nomanifest.zae", aiProcess_ValidateDataStructure);
-            if (scene == nullptr)
-                return false;
-
-            // Expected number of items
-            EXPECT_EQ(scene->mNumMeshes, 1u);
-            EXPECT_EQ(scene->mNumMaterials, 1u);
-            EXPECT_EQ(scene->mNumAnimations, 0u);
-            EXPECT_EQ(scene->mNumTextures, 1u);
-            EXPECT_EQ(scene->mNumLights, 1u);
-            EXPECT_EQ(scene->mNumCameras, 1u);
-        }
-
-        return true;
-    }
+	virtual bool importerTest() {
+		{
+			Assimp::Importer importer;
+			const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck.zae", aiProcess_ValidateDataStructure);
+			if (scene == nullptr)
+				return false;
+
+			// Expected number of items
+			EXPECT_EQ(scene->mNumMeshes, 1u);
+			EXPECT_EQ(scene->mNumMaterials, 1u);
+			EXPECT_EQ(scene->mNumAnimations, 0u);
+			EXPECT_EQ(scene->mNumTextures, 1u);
+			EXPECT_EQ(scene->mNumLights, 1u);
+			EXPECT_EQ(scene->mNumCameras, 1u);
+		}
+
+		{
+			Assimp::Importer importer;
+			const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck_nomanifest.zae", aiProcess_ValidateDataStructure);
+			if (scene == nullptr)
+				return false;
+
+			// Expected number of items
+			EXPECT_EQ(scene->mNumMeshes, 1u);
+			EXPECT_EQ(scene->mNumMaterials, 1u);
+			EXPECT_EQ(scene->mNumAnimations, 0u);
+			EXPECT_EQ(scene->mNumTextures, 1u);
+			EXPECT_EQ(scene->mNumLights, 1u);
+			EXPECT_EQ(scene->mNumCameras, 1u);
+		}
+
+		return true;
+	}
 };
 
 TEST_F(utColladaZaeImportExport, importBlenFromFileTest) {
-    EXPECT_TRUE(importerTest());
+	EXPECT_TRUE(importerTest());
 }