From 5d9db22b91bc2cb460c74a23d264c2529f3d32ea Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 26 Sep 2010 17:00:01 +0200 Subject: [PATCH] Changed: #1092 Reliability improvements for batched anim export from max --- .../3d/plugin_max/nel_export/nel_export.cpp | 12 +- .../3d/plugin_max/nel_export/nel_export.h | 7 +- .../nel_export/nel_export_export.cpp | 162 +++++++++++++----- .../nel_export/nel_export_script.cpp | 12 +- 4 files changed, 136 insertions(+), 57 deletions(-) diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export.cpp index 7b8d2862e..5526793d7 100644 --- a/code/nel/tools/3d/plugin_max/nel_export/nel_export.cpp +++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export.cpp @@ -766,7 +766,7 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP //--- CNelExport ------------------------------------------------------- -CNelExport::CNelExport() +CNelExport::CNelExport() : _ErrorInDialog(true), _TerminateOnFileOpenIssues(false) { _Ip = NULL; theHPanel = NULL; @@ -868,4 +868,12 @@ void CNelExport::init (bool view, bool errorInDialog, Interface *ip, bool loadSt // Create the CExportNel class _ExportNel = new CExportNel (errorInDialog, view, view, ip, "NeL Export", &theExportSceneStruct); -} \ No newline at end of file +} + +void nelExportTerminateProcess() +{ + DWORD ec = 0; + HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId()); + GetExitCodeProcess(h, &ec); + TerminateProcess(h, ec); +} diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export.h b/code/nel/tools/3d/plugin_max/nel_export/nel_export.h index e5d2e1f17..03dd0d7e7 100644 --- a/code/nel/tools/3d/plugin_max/nel_export/nel_export.h +++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export.h @@ -99,10 +99,13 @@ public: Interface *_Ip; // View - bool _View; + // bool _View; // View bool _ErrorInDialog; + + // Handle problematic file handles with max. + bool _TerminateOnFileOpenIssues; }; class CNelExportClassDesc:public ClassDesc2 @@ -122,5 +125,7 @@ extern CNelExportClassDesc CNelExportDesc; extern CNelExport theCNelExport; +void nelExportTerminateProcess(); + #endif // __NEL_EXPORT__H diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export_export.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export_export.cpp index a9aa9e3d1..63f89222c 100644 --- a/code/nel/tools/3d/plugin_max/nel_export/nel_export_export.cpp +++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export_export.cpp @@ -132,6 +132,8 @@ bool CNelExport::exportMesh (const char *sPath, INode& node, TimeValue time) else { nlwarning("Failed to create file %s", tempFileName); + if (_TerminateOnFileOpenIssues) + nelExportTerminateProcess(); } // Delete the pointer @@ -172,6 +174,8 @@ bool CNelExport::exportMesh (const char *sPath, INode& node, TimeValue time) else { nlwarning("Failed to open file: %s", tempFileName); + if (_TerminateOnFileOpenIssues) + nelExportTerminateProcess(); } } catch (...) @@ -246,67 +250,133 @@ bool CNelExport::exportAnim (const char *sPath, std::vector& vectNode, T { // Result to return bool bRet=false; - - // Create an animation file - CAnimation animFile; - - // For each node to export - for (uint n=0; n MAX_PATH || (dwRetVal == 0)) + nlerror("GetTempPath failed"); + UINT uRetVal = GetTempFileNameA(tempPathBuffer, TEXT("_nel_export_mesh_"), 0, tempFileName); + if (uRetVal == 0) + nlerror("GetTempFileName failed"); - // Set the name only if it is a scene animation - if (scene || prefixe) - { - // try to get the prefix from the appData if present. If not, takes it from the node name - nodeName = CExportNel::getScriptAppData (vectNode[n], NEL3D_APPDATA_INSTANCE_NAME, ""); - if (nodeName == "") // not found ? + // Create an animation file + CAnimation animFile; + + // For each node to export + for (uint n=0; nGetParentNode () == _Ip->GetRootNode(); + + // Add animation + _ExportNel->addAnimation (animFile, *vectNode[n], nodeName.c_str(), root); } - // Is a root ? - bool root = vectNode[n]->GetParentNode () == _Ip->GetRootNode(); - - // Add animation - _ExportNel->addAnimation (animFile, *vectNode[n], nodeName.c_str(), root); - } - - if (vectNode.size()) - { - // Open a file - COFile file; - if (file.open (sPath)) + if (vectNode.size()) { - try + // Open a file + COFile file; + if (file.open (tempFileName)) { - // Serial the animation - animFile.serial (file); - - // All is good - bRet=true; + try + { + nldebug("Serialize the animation"); + // Serial the animation + animFile.serial (file); + // Close the file + file.close(); + // All is good + bRet=true; + // Verify the file + nldebug("Verify exported anim file"); + try + { + bool tempBRet = bRet; + bRet = false; + CIFile vf; + if (vf.open(tempFileName)) + { + nldebug("File opened, size: %u", vf.getFileSize()); + CAnimation a; + a.serial(vf); + nldebug("Anim serialized"); + vf.close(); + nldebug("File closed"); + bRet = tempBRet; + } + else + { + nlwarning("Failed to open file: %s", tempFileName); + bRet = false; + if (_TerminateOnFileOpenIssues) + nelExportTerminateProcess(); + } + } + catch (...) + { + nlwarning("Failed to verify shape. Must crash now."); + remove(tempFileName); + bRet = false; + } + } + catch (Exception& e) + { + if (_ErrorInDialog) + MessageBox (NULL, e.what(), "NeL export", MB_OK|MB_ICONEXCLAMATION); + else + nlwarning ("ERROR : %s", e.what ()); + } } - catch (Exception& e) + else { if (_ErrorInDialog) - MessageBox (NULL, e.what(), "NeL export", MB_OK|MB_ICONEXCLAMATION); + MessageBox (NULL, "Can't open the file for writing.", "NeL export", MB_OK|MB_ICONEXCLAMATION); else - nlwarning ("ERROR : %s", e.what ()); + nlwarning ("ERROR : Can't open the file (%s) for writing", tempFileName); + if (_TerminateOnFileOpenIssues) + nelExportTerminateProcess(); } } - else + } + catch (...) + { + nlwarning("Fatal exception at CNelExport::exportAnim."); + bRet = false; + } + + if (bRet) + { + try { - if (_ErrorInDialog) - MessageBox (NULL, "Can't open the file for writing.", "NeL export", MB_OK|MB_ICONEXCLAMATION); - else - nlwarning ("ERROR : Can't open the file (%s) for writing", sPath); + remove(sPath); } + catch (...) + { + + } + CFile::moveFile(sPath, tempFileName); + nlinfo("MOVE %s -> %s", tempFileName, sPath); } return bRet; } diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export_script.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export_script.cpp index 8767ff7a9..9218e73ce 100644 --- a/code/nel/tools/3d/plugin_max/nel_export/nel_export_script.cpp +++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export_script.cpp @@ -945,10 +945,7 @@ protected: /// Put the string into the file. virtual void doDisplay( const CLog::TDisplayInfo& args, const char *message ) { - DWORD ec = 0; - HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId()); - GetExitCodeProcess(h, &ec); - TerminateProcess(h, ec); + nelExportTerminateProcess(); } }; @@ -958,6 +955,8 @@ Value* force_quit_on_msg_displayer_cf(Value** arg_list, int count) // disable the Windows popup telling that the application aborted and disable the dr watson report. _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); putenv("NEL_IGNORE_ASSERT=1"); + theCNelExport._ErrorInDialog = false; + theCNelExport._TerminateOnFileOpenIssues = true; if (NLMISC::DefaultMsgBoxDisplayer || INelContext::getInstance().getDefaultMsgBoxDisplayer()) { if (!NLMISC::DefaultMsgBoxDisplayer) @@ -978,10 +977,7 @@ Value* force_quit_right_now_cf(Value** arg_list, int count) { // because quitMAX can fail nlwarning("Force quit"); - DWORD ec = 0; - HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId()); - GetExitCodeProcess(h, &ec); - TerminateProcess(h, ec); + nelExportTerminateProcess(); return &true_value; }