// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 /********************************************************************** *< FILE: shaveVraySharedFunctions.cpp DESCRIPTION: Various shared functions CREATED BY: Vladimir Dubovoy HISTORY: created 21-08-2008 ( as part of 3ds Max + VRay hair shaders) merged 31-03-2010 *> **********************************************************************/ #include "shaveVraySharedFunctions.h" #include "shaveVrayPlugin.h" #include #include #include #include #include #ifdef LINUX #include #endif #ifdef WIN32 HINSTANCE hInstance = NULL; static HINSTANCE lib_handle = NULL; #else #include #include static void *lib_handle = NULL; #endif PFNCREATEBSDFPOOL CreateShaveBSDFPool = NULL; static char separator = #ifdef WIN32 ';' #else ':' #endif ; int GetNumPaths(const char* multi) { unsigned int len = (unsigned int)strlen(multi); if(len == 0) return 0; int n = 1; for(int i = 0; i < len; i++) if(multi[i] == separator) n++; return n; } bool GetPath(const char* multi, int idx, char* path) { unsigned int len = (unsigned int)strlen(multi); if(len == 0) return false; assert(idx >= 0); int start = 0; int end = 0; if(idx == 0) { bool found = false; for(int i = 1; i < len; i++) { if(multi[i] == separator) { end = i-1; found = true; break; } } if(!found) end = len-1; int j = 0; for(int i = start; i <= end; i++) { path[j] = multi[i]; j++; } return true; } else { bool found = false; int n = 0; for(int i = 0; i < len; i++) { if(multi[i] == separator) { n++; if(n == idx) { if(i+1 < len) { start = i+1; found = true; } break; } } } if(found) { for(int i = start; i < len; i++) { if(multi[i] == separator) { end = i-1; break; } } if(end == 0) end = len-1; if(end > start) { int j = 0; for(int i = start; i <= end; i++) { path[j] = multi[i]; j++; } return true; } } } return false; } bool LoadShaveBSDFPoolLib(const char* libPath) { LOGMSGS("SHADE","LoadShaveBSDFPoolLib from",libPath); #if defined(WIN32) # ifdef VRAY_DUAL # ifdef VRAY30 # if VRAY_DLL_VERSION < 0x31000 const char* dllName = "shaveSh30.dll"; # elif VRAY_DLL_VERSION < 0x36000 const char* dllName = "shaveSh31.dll"; # else const char* dllName = "shaveSh36.dll"; # endif # elif defined(VRAY40) const char* dllName = "shaveSh40.dll"; # else const char* dllName = "shaveSh.dll"; # endif # else char* dllName = "shaveSh.dll"; # endif if(!lib_handle) { //look up the paths passed from maya bool found = false; char libname[MAX_PATH]= {'\0'}; if(libPath != NULL && strlen(libPath) > 1) { //parse multiple paths int npaths = GetNumPaths(libPath); for(int i = 0; i < npaths; i++) { char libname1[MAX_PATH]= {'\0'}; char libPath1[MAX_PATH]= {'\0'}; if(GetPath(libPath,i,libPath1)) { LOGMSGI("SHADE","File 1 :",i); sprintf(libname1,"%s/%s",libPath1,dllName); //check file existance struct stat buf; int result = stat( libname1, &buf ); if( result != 0 ) { LOGMSGS("SHADE",libname1,"not found or can not be opened."); } else { LOGMSGS("SHADE","Found",libname1); strcpy(libname,libname1); found = true; break; } } } } //look into mayaroot/vray/plugins if(!found) { char libname1[MAX_PATH]= {'\0'}; char to[MAX_PATH] = {'\0'}; char path[MAX_PATH] = {'\0'}; if( GetModuleFileName(hInstance, path, MAX_PATH ) ) { char drive[6]; char dir[MAX_PATH]; char file[100]; char ext[6]; errno_t err = _splitpath_s(path,drive,6,dir,MAX_PATH,file,100,ext,6); if(err == 0) { sprintf(to,"%s%s",drive,dir); } } sprintf(libname1,"%s%s",to,dllName); #ifdef _DEBUG fprintf(stdout,"LoadShaveBSDFPoolLib: load %s\n",libname);fflush(stdout); #endif //check file existance struct stat buf; int result = stat( libname1, &buf ); LOGMSG("SHADE","File 2"); if( result != 0 ) { LOGMSGS("SHADE",libname1,"not found or can not be opened."); } else { LOGMSGS("SHADE","Found",libname1); strcpy(libname,libname1); found = true; } } if(!found) //standalone { char libname1[MAX_PATH]= {'\0'}; #ifdef _WIN64 char* libPath = getenv("VRAY_PLUGINS_x64"); #else char* libPath = getenv("VRAY_PLUGINS_x86"); #endif if(libPath && strlen(libPath) > 0) { //parse multiple paths int npaths = GetNumPaths(libPath); for(int i = 0; i < npaths; i++) { char libPath1[MAX_PATH]= {'\0'}; char libname1[MAX_PATH]= {'\0'}; if(GetPath(libPath,i,libPath1)) { sprintf(libname1,"%s/%s",libPath1,dllName); LOGMSGI("SHADE","File 3 :",i); //check file existance struct stat buf; int result = stat( libname1, &buf ); if( result != 0 ) { LOGMSGS("SHADE",libname1,"not found or can not be opened."); } else { LOGMSGS("SHADE","Found",libname1); strcpy(libname,libname1); found = true; break; } } } } } fflush(stdout); if(!found) { //do not specify path excplicitly let system find it in libdirs sprintf(libname,"%s",dllName); } lib_handle = LoadLibrary(libname); if (!lib_handle) { int err = GetLastError(); LOGMSGI("SHADE","LoadShaveBSDFPoolLib: can not load shaveSh**.dll, error ",err); return false; } CreateShaveBSDFPool = (PFNCREATEBSDFPOOL)GetProcAddress(lib_handle, "CreateShaveBSDFPool"); if(CreateShaveBSDFPool == NULL) { int err = GetLastError(); LOGMSGI("SHADE","LoadShaveBSDFPoolLib: can not load 'CreateShaveBSDFPool' function, error ",err); return false; } } #elif defined(LINUX) # ifdef VRAY_DUAL # ifdef VRAY30 # if VRAY_DLL_VERSION < 0x31000 const char* soName = "ShaveSh30.so"; # elif VRAY_DLL_VERSION < 0x36000 const char* soName = "ShaveSh31.so"; # else const char* soName = "ShaveSh36.so"; # endif # elif defined(VRAY40) const char* soName = "ShaveSh40.so"; # else const char* soName = "ShaveSh.so"; # endif # else const char* soName = "ShaveSh.so"; # endif if(!lib_handle) { bool found = false; char libname[MAX_PATH]= {'\0'}; if(libPath != NULL && strlen(libPath) > 1) { //parse multiple paths int npaths = GetNumPaths(libPath); for(int i = 0; i < npaths; i++) { char libname1[MAX_PATH]= {'\0'}; char libPath1[MAX_PATH]= {'\0'}; if(GetPath(libPath,i,libPath1)) { sprintf(libname1,"%s/%s",libPath1,soName); //check file existance struct stat buf; int result = stat( libname1, &buf ); if( result != 0 ) fprintf(stdout,"File %s (1:%i) \nnot found or can not be opened.\n", libname1,i); else { fprintf(stdout,"Found %s (1:%i).\n", libname1,i); strcpy(libname,libname1); found = true; break; } } } } if(!found) { char id[526] = {'\0'}; char path[526] = {'\0'}; pid_t pid = getpid(); sprintf(id, "/proc/%d/exe", getpid()); readlink(id, path, 526); #ifdef _DEBUG fprintf(stdout,"pid: %d bin path: %s \n",pid,path); #endif char* ptr = strstr(path,"bin"); if(ptr) { int pos = (ptr - path); int len = (int)strlen(path); for(int i = pos; i < len; i++) path[i] = '\0'; strcat(path,"vray/vrayplugins/"); strcat(path,soName); } else { fprintf(stdout,"LoadShaveBSDFPoolLib: can not find %s dir (%s).\n",soName,path);fflush(stdout); return false; } struct stat buf; int result = stat( path, &buf ); if( result != 0 ) fprintf(stdout,"File %s (2) not found in \n%s \nor can not be opened.\n",soName, path); else { fprintf(stdout,"File %s (2) is found in \n %s.\n",soName, path); strcpy(libname,path); found = true; } } if(!found) //standalone vray { char libname1[MAX_PATH]= {'\0'}; #ifdef Bits64_ char* libPath = getenv("VRAY_PLUGINS_x64"); #else char* libPath = getenv("VRAY_PLUGINS_x86"); #endif if(libPath) { //parse multiple paths int npaths = GetNumPaths(libPath); for(int i = 0; i < npaths; i++) { char libname1[MAX_PATH]= {'\0'}; char libPath1[MAX_PATH]= {'\0'}; if(GetPath(libPath,i,libPath1)) { sprintf(libname1,"%s/%s",libPath1,soName); //check file existance struct stat buf; int result = stat( libname1, &buf ); if( result != 0 ) fprintf(stdout,"File %s (3:%i) \nnot found or can not be opened.\n", libname1,i); else { fprintf(stdout,"Found %s (3:%i).\n", libname1,i); strcpy(libname,libname1); found = true; break; } } } } } if(!found) { //do not specify path excplicitly let system find it in libdirs sprintf(libname,"%s",soName); } lib_handle = dlopen(libname, RTLD_NOW | RTLD_GLOBAL); if (!lib_handle) { printf("LoadShaveBSDFPoolLib: can not load %s\n",soName); char* errstr = dlerror(); if (errstr != NULL) fprintf(stdout,"A dynamic linking error occurred: (%s).\n", errstr); fflush(stdout); return false; } CreateShaveBSDFPool = (PFNCREATEBSDFPOOL)dlsym(lib_handle, "CreateShaveBSDFPool"); const char* dlsym_error = dlerror(); if (dlsym_error || CreateShaveBSDFPool == NULL) { fprintf(stdout,"LoadShaveBSDFPoolLib: can not load 'CreateShaveBSDFPool' function (%s).\n",dlsym_error);fflush(stdout); return false; } } #else // osx // For MacOS/OS X CreateShaveBSDFPool() is built directly into libvray_Shave*.so. There's // no separate lib to load. #endif return true; } void UnLoadShaveBSDFPoolLib() { #if defined(WIN32) || defined(LINUX) if(lib_handle) { #ifdef WIN32 FreeLibrary(lib_handle); #else dlclose(lib_handle); #endif } CreateShaveBSDFPool = NULL; lib_handle = NULL; #else // osx // For MacOS/OS X CreateShaveBSDFPool() is built directly into libvray_Shave*.so. There's // no separate lib to unload. #endif }