Explorar o código

Add common metadata to Collada

Also add AI_METADATA_SOURCE_COPYRIGHT common metadata
RichardTea %!s(int64=5) %!d(string=hai) anos
pai
achega
f498a395e4

+ 2 - 0
code/CMakeLists.txt

@@ -66,6 +66,7 @@ SET( PUBLIC_HEADERS
   ${HEADER_PATH}/color4.h
   ${HEADER_PATH}/color4.h
   ${HEADER_PATH}/color4.inl
   ${HEADER_PATH}/color4.inl
   ${CMAKE_CURRENT_BINARY_DIR}/../include/assimp/config.h
   ${CMAKE_CURRENT_BINARY_DIR}/../include/assimp/config.h
+  ${HEADER_PATH}/commonMetaData.h
   ${HEADER_PATH}/defs.h
   ${HEADER_PATH}/defs.h
   ${HEADER_PATH}/Defines.h
   ${HEADER_PATH}/Defines.h
   ${HEADER_PATH}/cfileio.h
   ${HEADER_PATH}/cfileio.h
@@ -348,6 +349,7 @@ ADD_ASSIMP_IMPORTER( BVH
 )
 )
 
 
 ADD_ASSIMP_IMPORTER( COLLADA
 ADD_ASSIMP_IMPORTER( COLLADA
+  Collada/ColladaHelper.cpp
   Collada/ColladaHelper.h
   Collada/ColladaHelper.h
   Collada/ColladaLoader.cpp
   Collada/ColladaLoader.cpp
   Collada/ColladaLoader.h
   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 "ColladaExporter.h"
 #include <assimp/Bitmap.h>
 #include <assimp/Bitmap.h>
+#include <assimp/commonMetaData.h>
 #include <assimp/MathFunctions.h>
 #include <assimp/MathFunctions.h>
 #include <assimp/fast_atof.h>
 #include <assimp/fast_atof.h>
 #include <assimp/SceneCombiner.h>
 #include <assimp/SceneCombiner.h>
@@ -277,7 +278,7 @@ void ColladaExporter::WriteHeader() {
         mOutput << startstr << "<author>" << XMLEscape(value.C_Str()) << "</author>" << endstr;
         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;
         mOutput << startstr << "<authoring_tool>" << "Assimp Exporter" << "</authoring_tool>" << endstr;
     } else {
     } else {
         mOutput << startstr << "<authoring_tool>" << XMLEscape(value.C_Str()) << "</authoring_tool>" << endstr;
         mOutput << startstr << "<authoring_tool>" << XMLEscape(value.C_Str()) << "</authoring_tool>" << endstr;
@@ -287,7 +288,7 @@ void ColladaExporter::WriteHeader() {
         if (meta->Get("Comments", value)) {
         if (meta->Get("Comments", value)) {
             mOutput << startstr << "<comments>" << XMLEscape(value.C_Str()) << "</comments>" << endstr;
             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;
             mOutput << startstr << "<copyright>" << XMLEscape(value.C_Str()) << "</copyright>" << endstr;
         }
         }
         if (meta->Get("SourceData", value)) {
         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
     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 */
 /** Contains all data for one of the different transformation types */
 struct Transform
 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 <sstream>
 #include <stdarg.h>
 #include <stdarg.h>
 #include "ColladaParser.h"
 #include "ColladaParser.h"
+#include <assimp/commonMetaData.h>
 #include <assimp/fast_atof.h>
 #include <assimp/fast_atof.h>
 #include <assimp/ParsingUtils.h>
 #include <assimp/ParsingUtils.h>
 #include <assimp/StringUtils.h>
 #include <assimp/StringUtils.h>
@@ -276,6 +277,9 @@ void ColladaParser::ReadContents()
                 if (attrib != -1) {
                 if (attrib != -1) {
                     const char* version = mReader->getAttributeValue(attrib);
                     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)) {
                     if (!::strncmp(version, "1.5", 3)) {
                         mFormat = FV_1_5_n;
                         mFormat = FV_1_5_n;
                         ASSIMP_LOG_DEBUG("Collada schema version is 1.5.n");
                         ASSIMP_LOG_DEBUG("Collada schema version is 1.5.n");
@@ -399,7 +403,7 @@ void ColladaParser::ReadAssetInfo()
             }
             }
             else
             else
             {
             {
-                ReadMetaDataItem(mAssetMetaData);
+                ReadMetaDataItem(mAssetMetaData, GetColladaAssimpMetaKeys());
             }
             }
         }
         }
         else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
         else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
@@ -423,7 +427,7 @@ void ColladaParser::ReadContributorInfo()
     {
     {
         if (mReader->getNodeType() == irr::io::EXN_ELEMENT)
         if (mReader->getNodeType() == irr::io::EXN_ELEMENT)
         {
         {
-            ReadMetaDataItem(mAssetMetaData);
+            ReadMetaDataItem(mAssetMetaData, GetColladaAssimpMetaKeys());
         }
         }
         else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
         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
 // 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 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;
             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());
         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 */
         /** Reads contributor information such as author and legal blah */
         void ReadContributorInfo();
         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" */
         /** Convert underscore_seperated to CamelCase "authoring_tool" becomes "AuthoringTool" */
         static void ToCamelCase(std::string &text);
         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.
 /// Not all formats add this metadata.
 #define AI_METADATA_SOURCE_GENERATOR "SourceAsset_Generator"
 #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
 #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.
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 */
 */
-#include "UnitTestPCH.h"
 #include "AbstractImportExportBase.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/postprocess.h>
+#include <assimp/scene.h>
+#include <assimp/Importer.hpp>
 
 
 using namespace Assimp;
 using namespace Assimp;
 
 
 class utColladaImportExport : public AbstractImportExportBase {
 class utColladaImportExport : public AbstractImportExportBase {
 public:
 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) {
 TEST_F(utColladaImportExport, importBlenFromFileTest) {
-    EXPECT_TRUE(importerTest());
+	EXPECT_TRUE(importerTest());
 }
 }
 
 
 class utColladaZaeImportExport : public AbstractImportExportBase {
 class utColladaZaeImportExport : public AbstractImportExportBase {
 public:
 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) {
 TEST_F(utColladaZaeImportExport, importBlenFromFileTest) {
-    EXPECT_TRUE(importerTest());
+	EXPECT_TRUE(importerTest());
 }
 }