diff --git a/code/nel/include/nel/misc/tool_logger.h b/code/nel/include/nel/misc/tool_logger.h
new file mode 100644
index 000000000..85171095c
--- /dev/null
+++ b/code/nel/include/nel/misc/tool_logger.h
@@ -0,0 +1,210 @@
+/**
+ * \file tool_logger.h
+ * \brief CToolLogger
+ * \date 2012-02-19 10:33GMT
+ * \author Jan Boon (Kaetemi)
+ * Tool logger is fully implemented in header so small tools do not
+ * need to link to this library unnecessarily.
+ * NOTE: Needs to be changed not to use time_nl and string_common.
+ */
+
+/*
+ * Copyright (C) 2012 by authors
+ *
+ * This file is part of RYZOM CORE PIPELINE.
+ * RYZOM CORE PIPELINE is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * RYZOM CORE PIPELINE is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RYZOM CORE PIPELINE; see the file COPYING. If not, see
+ * .
+ */
+
+#ifndef NLMISC_TOOL_LOGGER_H
+#define NLMISC_TOOL_LOGGER_H
+#include
+
+// STL includes
+#include
+#include
+#include
+
+// NeL includes
+#include
+#include
+
+// Project includes
+
+#ifdef ERROR
+#undef ERROR
+#endif
+
+#ifdef NL_DEBUG_H
+#define tlerror(toolLogger, path, error, ...) nlwarning(error, __VA_ARGS__), toolLogger.writeError(NLMISC::ERROR, path, error, __VA_ARGS__)
+#define tlwarning(toolLogger, path, error, ...) nlwarning(error, __VA_ARGS__), toolLogger.writeError(NLMISC::WARNING, path, error, __VA_ARGS__)
+#define tlmessage(toolLogger, path, error, ...) nlinfo(error, __VA_ARGS__), toolLogger.writeError(NLMISC::MESSAGE, path, error, __VA_ARGS__)
+#else
+#define tlerror(toolLogger, path, error, ...) toolLogger.writeError(NLMISC::ERROR, path, error, __VA_ARGS__)
+#define tlwarning(toolLogger, path, error, ...) toolLogger.writeError(NLMISC::WARNING, path, error, __VA_ARGS__)
+#define tlmessage(toolLogger, path, error, ...) toolLogger.writeError(NLMISC::MESSAGE, path, error, __VA_ARGS__)
+#endif
+
+namespace NLMISC {
+
+enum TError
+{
+ ERROR,
+ WARNING,
+ MESSAGE,
+};
+
+enum TDepend
+{
+ BUILD,
+ DIRECTORY,
+ RUNTIME,
+};
+
+const std::string s_ErrorHeader = "type\tpath\ttime\terror";
+const std::string s_DependHeader = "type\toutput_file\tinput_file";
+
+/**
+ * \brief CToolLogger
+ * \date 2012-02-19 10:33GMT
+ * \author Jan Boon (Kaetemi)
+ * CToolLogger
+ */
+class CToolLogger
+{
+private:
+ FILE *m_ErrorLog;
+ FILE *m_DependLog;
+
+public:
+ inline CToolLogger()
+ {
+
+ }
+
+ inline ~CToolLogger()
+ {
+ release();
+ }
+
+ inline void initError(const std::string &errorLog)
+ {
+ releaseError();
+
+ m_ErrorLog = fopen(errorLog.c_str(), "wt");
+ fwrite(s_ErrorHeader.c_str(), 1, s_ErrorHeader.length(), m_ErrorLog);
+ fwrite("\n", 1, 1, m_ErrorLog);
+ fflush(m_ErrorLog);
+
+ }
+
+ inline void initDepend(const std::string &dependLog)
+ {
+ releaseDepend();
+
+ m_DependLog = fopen(dependLog.c_str(), "wt");
+ fwrite(s_DependHeader.c_str(), 1, s_DependHeader.length(), m_DependLog);
+ fwrite("\n", 1, 1, m_DependLog);
+ // fflush(m_DependLog);
+ }
+
+ inline void writeError(TError type, const char *path, const char *error, ...)
+ {
+ if (m_ErrorLog)
+ {
+ switch (type)
+ {
+ case ERROR:
+ fwrite("ERROR", 1, 5, m_ErrorLog);
+ break;
+ case WARNING:
+ fwrite("WARNING", 1, 7, m_ErrorLog);
+ break;
+ case MESSAGE:
+ fwrite("MESSAGE", 1, 7, m_ErrorLog);
+ break;
+ }
+ fwrite("\t", 1, 1, m_ErrorLog);
+ fprintf(m_ErrorLog, "%s", path);
+ fwrite("\t", 1, 1, m_ErrorLog);
+ std::string time = NLMISC::toString(NLMISC::CTime::getSecondsSince1970());
+ fwrite(time.c_str(), 1, time.length(), m_ErrorLog);
+ fwrite("\t", 1, 1, m_ErrorLog);
+ va_list args;
+ va_start(args, error);
+ vfprintf(m_ErrorLog, error, args);
+ va_end(args);
+ fwrite("\n", 1, 1, m_ErrorLog);
+ fflush(m_ErrorLog);
+ }
+ }
+
+ /// inputFile can only be file. [? May be not-yet-existing file for expected input for future build runs. ?] Directories are handled on process level. [? You should call this before calling writeError on inputFile, so the error is also linked from the outputFile. ?]
+ inline void writeDepend(TDepend type, const char *outputFile, const char *inputFile)
+ {
+ if (m_DependLog)
+ {
+ switch (type)
+ {
+ case BUILD:
+ fwrite("BUILD", 1, 5, m_DependLog);
+ break;
+ case DIRECTORY:
+ fwrite("DIRECTORY", 1, 9, m_DependLog);
+ break;
+ case RUNTIME:
+ fwrite("RUNTIME", 1, 7, m_DependLog);
+ break;
+ }
+ fwrite("\t", 1, 1, m_DependLog);
+ fprintf(m_DependLog, "%s", outputFile);
+ fwrite("\t", 1, 1, m_DependLog);
+ fprintf(m_DependLog, "%s", inputFile);
+ fwrite("\n", 1, 1, m_DependLog);
+ // fflush(m_DependLog);
+ }
+ }
+
+ inline void releaseError()
+ {
+ if (m_ErrorLog)
+ {
+ fflush(m_ErrorLog);
+ fclose(m_ErrorLog);
+ m_ErrorLog = NULL;
+ }
+ }
+
+ inline void releaseDepend()
+ {
+ if (m_DependLog)
+ {
+ fflush(m_DependLog);
+ fclose(m_DependLog);
+ m_DependLog = NULL;
+ }
+ }
+
+ inline void release()
+ {
+ releaseError();
+ releaseDepend();
+ }
+}; /* class CToolLogger */
+
+} /* namespace NLMISC */
+
+#endif /* #ifndef NLMISC_TOOL_LOGGER_H */
+
+/* end of file */
diff --git a/code/nel/src/misc/tool_logger.cpp b/code/nel/src/misc/tool_logger.cpp
new file mode 100644
index 000000000..e6a9fbf36
--- /dev/null
+++ b/code/nel/src/misc/tool_logger.cpp
@@ -0,0 +1,45 @@
+/**
+ * \file tool_logger.cpp
+ * \brief CToolLogger
+ * \date 2012-02-19 10:33GMT
+ * \author Jan Boon (Kaetemi)
+ * CToolLogger
+ */
+
+/*
+ * Copyright (C) 2012 by authors
+ *
+ * This file is part of RYZOM CORE PIPELINE.
+ * RYZOM CORE PIPELINE is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * RYZOM CORE PIPELINE is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RYZOM CORE PIPELINE; see the file COPYING. If not, see
+ * .
+ */
+
+#include "stdmisc.h"
+#include "nel/misc/tool_logger.h"
+
+// STL includes
+
+// NeL includes
+// #include
+
+// Project includes
+
+namespace NLMISC {
+
+// Tool logger is fully implemented in header so small tools do not need to link to this library unnecessarily.
+void dummy_tool_logger_cpp() { }
+
+} /* namespace NLMISC */
+
+/* end of file */
diff --git a/code/nel/tools/3d/mesh_export/main.cpp b/code/nel/tools/3d/mesh_export/main.cpp
index 2e97be830..1503a4b16 100644
--- a/code/nel/tools/3d/mesh_export/main.cpp
+++ b/code/nel/tools/3d/mesh_export/main.cpp
@@ -61,6 +61,13 @@ int main(int argc, char *argv[])
settings.DestinationDirectoryPath = filePath + "_export";
settings.DestinationDirectoryPath += "/";
+ settings.ToolDependLog = args.getLongArg("dependlog");
+ if (settings.ToolDependLog.empty())
+ settings.ToolDependLog = settings.DestinationDirectoryPath + "depend.log";
+ settings.ToolErrorLog = args.getLongArg("errorlog");
+ if (settings.ToolErrorLog.empty())
+ settings.ToolErrorLog = settings.DestinationDirectoryPath + "error.log";
+
NL3D::CScene::registerBasics();
NL3D::registerSerial3d();
diff --git a/code/nel/tools/3d/mesh_utils/mesh_utils.cpp b/code/nel/tools/3d/mesh_utils/mesh_utils.cpp
index 60e5c7201..c8a0eb12d 100644
--- a/code/nel/tools/3d/mesh_utils/mesh_utils.cpp
+++ b/code/nel/tools/3d/mesh_utils/mesh_utils.cpp
@@ -19,6 +19,8 @@
#include "mesh_utils.h"
#include
+#include
+#include
#include
#include
@@ -52,9 +54,12 @@ struct CMeshUtilsContext
}
const CMeshUtilsSettings &Settings;
+
+ NLMISC::CToolLogger ToolLogger;
const aiScene *AssimpScene;
- std::map Nodes;
+ std::map Nodes;
+ std::map MeshNames; // Maps meshes to a node name ********************* todo ***************
};
struct CNodeMeta
@@ -82,7 +87,8 @@ void validateAssimpNodeNames(CMeshUtilsContext &context, const aiNode *node)
}
else if (node->mName.length == 0)
{
- nlwarning("CRITICAL: Node has no name");
+ tlwarning(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
+ "Node has no name");
}
else
{
@@ -90,7 +96,8 @@ void validateAssimpNodeNames(CMeshUtilsContext &context, const aiNode *node)
if (nodeContext.AssimpNode && nodeContext.AssimpNode != node)
{
- nlwarning("CRITICAL: Node name '%s' appears multiple times", node->mName.C_Str());
+ tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
+ "Node name '%s' appears multiple times", node->mName.C_Str());
}
else
{
@@ -115,7 +122,8 @@ void flagAssimpBones(CMeshUtilsContext &context)
CNodeContext &nodeContext = context.Nodes[mesh->mBones[i]->mName.C_Str()];
if (!nodeContext.AssimpNode)
{
- nlwarning("CRITICAL: Bone '%s' has no associated node", mesh->mBones[i]->mName.C_Str());
+ tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(),
+ "Bone '%s' has no associated node", mesh->mBones[i]->mName.C_Str());
}
else
{
@@ -123,11 +131,11 @@ void flagAssimpBones(CMeshUtilsContext &context)
nodeContext.IsBone = true;
// Flag all parents as bones
- const aiNode *parent = nodeContext.AssimpNode;
+ /*const aiNode *parent = nodeContext.AssimpNode;
while (parent = parent->mParent) if (parent->mName.length)
{
context.Nodes[parent->mName.C_Str()].IsBone = true;
- }
+ }*/
}
}
}
@@ -136,14 +144,31 @@ void flagAssimpBones(CMeshUtilsContext &context)
// TODO: Separate load scene and save scene functions
int exportScene(const CMeshUtilsSettings &settings)
{
+ CMeshUtilsContext context(settings);
+
+ if (!settings.ToolDependLog.empty())
+ context.ToolLogger.initDepend(settings.ToolDependLog);
+ if (!settings.ToolErrorLog.empty())
+ context.ToolLogger.initDepend(settings.ToolErrorLog);
+ context.ToolLogger.writeDepend(NLMISC::BUILD, "*", context.Settings.SourceFilePath.c_str()); // Base input file
+
+ // Find database configuration
+
+
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(settings.SourceFilePath, aiProcess_Triangulate | aiProcess_ValidateDataStructure); // aiProcess_SplitLargeMeshes | aiProcess_LimitBoneWeights
+ if (!scene)
+ {
+ const char *errs = importer.GetErrorString();
+ if (errs) tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(), errs);
+ else tlerror(context.ToolLogger, context.Settings.SourceFilePath.c_str(), "Unable to load scene");
+ return EXIT_FAILURE;
+ }
// aiProcess_ValidateDataStructure: TODO: Catch Assimp error output stream
// aiProcess_RemoveRedundantMaterials: Not used because we may override materials with NeL Material from meta
// aiProcess_ImproveCacheLocality: TODO: Verify this does not modify vertex indices
//scene->mRootNode->mMetaData
- CMeshUtilsContext context(settings);
context.AssimpScene = scene;
flagAssimpBones(context);
diff --git a/code/nel/tools/3d/mesh_utils/mesh_utils.h b/code/nel/tools/3d/mesh_utils/mesh_utils.h
index b7c549689..1af319dec 100644
--- a/code/nel/tools/3d/mesh_utils/mesh_utils.h
+++ b/code/nel/tools/3d/mesh_utils/mesh_utils.h
@@ -26,6 +26,8 @@ struct CMeshUtilsSettings
// Absolute Paths
std::string SourceFilePath;
std::string DestinationDirectoryPath;
+ std::string ToolDependLog;
+ std::string ToolErrorLog;
// Relative Directories
std::string ShapeDirectory;