// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 #include "stdafx.h" #include <tbb/task_scheduler_init.h> // Get the class descs needed #include "LegacyXMeshLoader.hpp" #include "MaxMeshCacheModifier.h" #include "XMeshLoader.hpp" extern void InitializeMeshLoaderLogging(); BOOL gbControlsInit = FALSE; HINSTANCE ghInstance = 0; namespace { // Put all the classdesc's in a vector, to make adding & removing plugins easier std::vector<ClassDesc*> classDescList; } // anonymous namespace BOOL MeshLoaderInitialize() { classDescList.clear(); classDescList.push_back( GetXMeshLoaderClassDesc() ); classDescList.push_back( GetLegacyXMeshLoaderClassDesc() ); #ifdef ENABLE_MAX_MESH_CACHE_MODIFIER classDescList.push_back( GetMaxMeshCacheModifierDesc() ); #endif return true; } BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/ ) { if( !gbControlsInit ) { gbControlsInit = TRUE; // InitCustomControls() is deprecated in max 2009 #if MAX_VERSION_MAJOR < 11 // init 3DStudio Max controls InitCustomControls( ghInstance ); #endif // init Windows controls InitCommonControls(); } if( ul_reason_for_call == DLL_PROCESS_ATTACH ) { ghInstance = (HINSTANCE)hModule; return MeshLoaderInitialize(); } return true; } TCHAR* GetString( UINT id ) { static TCHAR buf[256]; if( ghInstance ) return LoadString( ghInstance, id, buf, sizeof( buf ) / sizeof( TCHAR ) ) ? buf : NULL; return NULL; } static tbb::task_scheduler_init g_tbbScheduler( tbb::task_scheduler_init::deferred ); extern "C" { //------------------------------------------------------ // This is the interface to 3DSMax //------------------------------------------------------ __declspec( dllexport ) const TCHAR* LibDescription() { return _T("XMesh Loader - Thinkbox Software - www.thinkboxsoftware.com"); } __declspec( dllexport ) int LibNumberClasses() { return (int)classDescList.size(); } __declspec( dllexport ) ClassDesc* LibClassDesc( int i ) { if( i >= 0 && i < (int)classDescList.size() ) return classDescList[i]; else return 0; } // Return version so can detect obsolete DLLs __declspec( dllexport ) ULONG LibVersion() { return VERSION_3DSMAX; } // Let the plug-in register itself for deferred loading __declspec( dllexport ) ULONG CanAutoDefer() { #if MAX_VERSION_MAJOR >= 14 return 1; #else return 0; #endif } __declspec( dllexport ) int LibInitialize() { try { g_tbbScheduler.initialize(); // BEWARE!! InitializeMeshLoaderLogging() schedules a callback from 3ds Max. // If LibInitialize returns FALSE after this callback is registered, // then 3ds Max will crash. InitializeMeshLoaderLogging(); return TRUE; } catch( std::exception& e ) { Interface* coreInterface = GetCOREInterface(); if( coreInterface ) { const std::string errmsg = std::string( "Unable to initialize XMesh Loader: " ) + e.what(); LogSys* log = GetCOREInterface()->Log(); if( log ) { log->LogEntry( SYSLOG_ERROR, DISPLAY_DIALOG, _T( "XMesh Loader" ), _T( "%s" ), errmsg.c_str() ); } } } return FALSE; } __declspec( dllexport ) int LibShutdown() { // IMPORTANT! This is in LibShutdown since the destructor on g_tbbScheduler was hanging // under certain conditions. g_tbbScheduler.terminate(); return TRUE; } } // extern "C"