00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "dynload.h"
00026 #include "paramset.h"
00027 #include "shape.h"
00028 #include "material.h"
00029 #ifndef WIN32
00030 #ifndef __APPLE__
00031 #include <dlfcn.h>
00032 #else
00033 #include <mach-o/dyld.h>
00034 #endif
00035 #endif
00036 #include <map>
00037 using std::map;
00038
00039 static string SearchPath(const string &searchpath,
00040 const string &filename);
00041 template <class D> D *GetPlugin(const string &name,
00042 map<string, D *> &loadedPlugins,
00043 const string &searchPath) {
00044 if (loadedPlugins.find(name) != loadedPlugins.end())
00045 return loadedPlugins[name];
00046 string filename = name;
00047
00048 #ifdef WIN32
00049 filename += ".dll";
00050 #else
00051 filename += ".so";
00052 #endif
00053 string path = SearchPath(searchPath, filename);
00054 D *plugin = NULL;
00055 if (path != "")
00056 loadedPlugins[name] = plugin = new D(path.c_str());
00057 else
00058 Error("Unable to find Plugin/DLL for \"%s\"",
00059 name.c_str());
00060 return plugin;
00061 }
00062 class ShapePlugin;
00063 class FilterPlugin;
00064 class MaterialPlugin;
00065 class TexturePlugin;
00066 class FilmPlugin;
00067 class LightPlugin;
00068 class AreaLightPlugin;
00069 class VolumeRegionPlugin;
00070 class SurfaceIntegratorPlugin;
00071 class VolumeIntegratorPlugin;
00072 class ToneMapPlugin;
00073 class AcceleratorPlugin;
00074 class CameraPlugin;
00075 class SamplerPlugin;
00076 static string SearchPath(const string &searchpath,
00077 const string &filename);
00078
00079 static string PluginSearchPath;
00080 static map<string, ShapePlugin *> shapePlugins;
00081 static map<string, FilterPlugin *> filterPlugins;
00082 static map<string, MaterialPlugin *> materialPlugins;
00083 static map<string, TexturePlugin *> texturePlugins;
00084 static map<string, FilmPlugin *> filmPlugins;
00085 static map<string, LightPlugin *> lightPlugins;
00086 static map<string, AreaLightPlugin *> arealightPlugins;
00087 static map<string, VolumeRegionPlugin *> volumePlugins;
00088 static map<string, SurfaceIntegratorPlugin *> surf_integratorPlugins;
00089 static map<string, VolumeIntegratorPlugin *> vol_integratorPlugins;
00090 static map<string, ToneMapPlugin *> tonemapPlugins;
00091 static map<string, AcceleratorPlugin *> acceleratorPlugins;
00092 static map<string, CameraPlugin *> cameraPlugins;
00093 static map<string, SamplerPlugin *> samplerPlugins;
00094
00095 class Plugin {
00096 public:
00097
00098 Plugin(const string &fname);
00099 ~Plugin();
00100 void *GetSymbol(const string &symname);
00101 private:
00102
00103 #if defined(WIN32)
00104 HMODULE hinstLib;
00105 #elif defined(__APPLE__)
00106 NSModule hinstLib;
00107 #else
00108 void *hinstLib;
00109 #endif
00110 string pluginName;
00111 };
00112 class ShapePlugin : public Plugin {
00113 public:
00114
00115 ShapePlugin(const string &name)
00116 : Plugin(name) {
00117 CreateShape =
00118 (CreateShapeFunc)(GetSymbol("CreateShape"));
00119 }
00120 typedef Shape * (*CreateShapeFunc)(const Transform &o2w,
00121 bool reverseOrientation, const ParamSet ¶ms);
00122 CreateShapeFunc CreateShape;
00123 };
00124 class MaterialPlugin : public Plugin {
00125 typedef Material * (*CreateMaterialFunc)(const Transform &shader2world, const TextureParams &);
00126 public:
00127 MaterialPlugin( const string &name ): Plugin( name )
00128 {
00129 CreateMaterial =
00130 (CreateMaterialFunc)(GetSymbol("CreateMaterial"));
00131 }
00132 CreateMaterialFunc CreateMaterial;
00133 };
00134 class TexturePlugin : public Plugin {
00135 typedef Texture<float> *
00136 (*CreateFloatFunc)(const Transform &shader2world, const TextureParams &);
00137 typedef Texture<Spectrum> *
00138 (*CreateSpectrumFunc)(const Transform &shader2world, const TextureParams &);
00139 public:
00140 TexturePlugin( const string &name ): Plugin( name )
00141 {
00142 CreateFloatTex =
00143 (CreateFloatFunc)(GetSymbol("CreateFloatTexture"));
00144 CreateSpectrumTex =
00145 (CreateSpectrumFunc)(GetSymbol("CreateSpectrumTexture"));
00146 }
00147 CreateFloatFunc CreateFloatTex;
00148 CreateSpectrumFunc CreateSpectrumTex;
00149 };
00150 class LightPlugin : public Plugin {
00151 typedef Light *(*CreateLightFunc)(
00152 const Transform &light2world, const ParamSet ¶ms);
00153 public:
00154 LightPlugin( const string &name ): Plugin( name )
00155 {
00156 CreateLight =
00157 (CreateLightFunc)(GetSymbol("CreateLight"));
00158 }
00159 CreateLightFunc CreateLight;
00160 };
00161 class VolumeRegionPlugin : public Plugin {
00162 typedef VolumeRegion *(*CreateVolumeFunc)(const Transform &volume2world,
00163 const ParamSet ¶ms);
00164 public:
00165 VolumeRegionPlugin( const string &name ): Plugin( name )
00166 {
00167 CreateVolumeRegion =
00168 (CreateVolumeFunc)(GetSymbol("CreateVolumeRegion"));
00169 }
00170 CreateVolumeFunc CreateVolumeRegion;
00171 };
00172 class AreaLightPlugin : public Plugin {
00173 typedef AreaLight *(*CreateAreaLightFunc)(
00174 const Transform &light2world, const ParamSet ¶ms,
00175 const Reference<Shape> &shape);
00176 public:
00177 AreaLightPlugin( const string &name ): Plugin( name )
00178 {
00179 CreateAreaLight =
00180 (CreateAreaLightFunc)(GetSymbol("CreateAreaLight"));
00181 }
00182 CreateAreaLightFunc CreateAreaLight;
00183 };
00184 class SurfaceIntegratorPlugin : public Plugin {
00185 typedef SurfaceIntegrator *(*CreateSurfaceIntegratorFunc)(const ParamSet ¶ms);
00186 public:
00187 SurfaceIntegratorPlugin( const string &name ): Plugin( name )
00188 {
00189 CreateSurfaceIntegrator =
00190 (CreateSurfaceIntegratorFunc)(GetSymbol("CreateSurfaceIntegrator"));
00191 }
00192 CreateSurfaceIntegratorFunc CreateSurfaceIntegrator;
00193 };
00194 class VolumeIntegratorPlugin : public Plugin {
00195 typedef VolumeIntegrator *(*CreateVolumeIntegratorFunc)(const ParamSet ¶ms);
00196 public:
00197 VolumeIntegratorPlugin( const string &name ): Plugin( name )
00198 {
00199 CreateVolumeIntegrator =
00200 (CreateVolumeIntegratorFunc)(GetSymbol("CreateVolumeIntegrator"));
00201 }
00202 CreateVolumeIntegratorFunc CreateVolumeIntegrator;
00203 };
00204 class AcceleratorPlugin : public Plugin {
00205 typedef Primitive *(*CreateAcceleratorFunc)(const vector<Reference<Primitive> > &prims, const ParamSet ¶ms);
00206 public:
00207 AcceleratorPlugin( const string &name ): Plugin( name )
00208 {
00209 CreateAccelerator =
00210 (CreateAcceleratorFunc)(GetSymbol("CreateAccelerator"));
00211 }
00212 CreateAcceleratorFunc CreateAccelerator;
00213 };
00214 class SamplerPlugin : public Plugin {
00215 typedef Sampler *(*CreateSamplerFunc)(const ParamSet ¶ms, const Film *film);
00216 public:
00217 SamplerPlugin( const string &name ): Plugin( name )
00218 {
00219 CreateSampler =
00220 (CreateSamplerFunc)(GetSymbol("CreateSampler"));
00221 }
00222 CreateSamplerFunc CreateSampler;
00223 };
00224 class CameraPlugin : public Plugin {
00225 typedef Camera *(*CreateCameraFunc)(const ParamSet ¶ms, const Transform &world2cam, Film *film);
00226 public:
00227 CameraPlugin( const string &name ): Plugin( name )
00228 {
00229 CreateCamera =
00230 (CreateCameraFunc)(GetSymbol("CreateCamera"));
00231 }
00232 CreateCameraFunc CreateCamera;
00233 };
00234 class FilterPlugin : public Plugin {
00235 typedef Filter *(*CreateFilterFunc)(const ParamSet ¶ms);
00236 public:
00237 FilterPlugin( const string &name ): Plugin( name ) {
00238 CreateFilter =
00239 (CreateFilterFunc)(GetSymbol("CreateFilter"));
00240 }
00241 CreateFilterFunc CreateFilter;
00242 };
00243 class ToneMapPlugin : public Plugin {
00244 typedef ToneMap *(*CreateToneMapFunc)(const ParamSet ¶ms);
00245 public:
00246 ToneMapPlugin( const string &name ): Plugin( name ) {
00247 CreateToneMap =
00248 (CreateToneMapFunc)(GetSymbol("CreateToneMap"));
00249 }
00250 CreateToneMapFunc CreateToneMap;
00251 };
00252 class FilmPlugin : public Plugin {
00253 typedef Film *(*CreateFilmFunc)(const ParamSet ¶ms, Filter *filter);
00254 public:
00255 FilmPlugin( const string &name ): Plugin( name ) {
00256 CreateFilm =
00257 (CreateFilmFunc)(GetSymbol("CreateFilm"));
00258 }
00259 CreateFilmFunc CreateFilm;
00260 };
00261
00262 COREDLL void UpdatePluginPath(const string &newpath) {
00263 string ret;
00264 for (u_int i = 0; i < newpath.size(); ++i) {
00265 if (newpath[i] != '&')
00266 ret += newpath[i];
00267 else
00268 ret += PluginSearchPath;
00269 }
00270 PluginSearchPath = ret;
00271 }
00272 COREDLL Reference<Shape> MakeShape(const string &name,
00273 const Transform &object2world,
00274 bool reverseOrientation,
00275 const ParamSet ¶mSet) {
00276 ShapePlugin *plugin =
00277 GetPlugin<ShapePlugin>(name,
00278 shapePlugins,
00279 PluginSearchPath);
00280 if (plugin)
00281 return plugin->CreateShape(object2world,
00282 reverseOrientation,
00283 paramSet);
00284 return NULL;
00285 }
00286 static string SearchPath(const string &searchpath,
00287 const string &filename) {
00288 const char *start = searchpath.c_str();
00289 const char *end = start;
00290 while (*start) {
00291 while (*end && *end != PBRT_PATH_SEP[0])
00292 ++end;
00293 string component(start, end);
00294
00295 string fn = component + "/" + filename;
00296 FILE *f = fopen(fn.c_str(), "r");
00297 if (f) {
00298 fclose(f);
00299 return fn;
00300 }
00301 if (*end == PBRT_PATH_SEP[0]) ++end;
00302 start = end;
00303 }
00304 return "";
00305 }
00306 COREDLL Reference<Material> MakeMaterial(const string &name,
00307 const Transform &mtl2world,
00308 const TextureParams &mp) {
00309 MaterialPlugin *plugin = GetPlugin<MaterialPlugin>(name, materialPlugins,
00310 PluginSearchPath);
00311 if (plugin) {
00312 Reference<Material> ret =
00313 plugin->CreateMaterial(mtl2world, mp);
00314 mp.ReportUnused();
00315 return ret;
00316 }
00317 return NULL;
00318 }
00319 COREDLL Reference<Texture<float> > MakeFloatTexture(const string &name,
00320 const Transform &tex2world, const TextureParams &tp) {
00321 TexturePlugin *plugin = GetPlugin<TexturePlugin>(name, texturePlugins,
00322 PluginSearchPath);
00323 if (plugin) {
00324 Reference<Texture<float> > ret =
00325 plugin->CreateFloatTex(tex2world, tp);
00326 tp.ReportUnused();
00327 return ret;
00328 }
00329 return NULL;
00330 }
00331 COREDLL Reference<Texture<Spectrum> > MakeSpectrumTexture(const string &name,
00332 const Transform &tex2world, const TextureParams &tp) {
00333 TexturePlugin *plugin = GetPlugin<TexturePlugin>(name, texturePlugins,
00334 PluginSearchPath);
00335 if (plugin) {
00336 Reference<Texture<Spectrum> > ret =
00337 plugin->CreateSpectrumTex(tex2world, tp);
00338 tp.ReportUnused();
00339 return ret;
00340 }
00341 return NULL;
00342 }
00343 COREDLL Light *MakeLight(const string &name,
00344 const Transform &light2world, const ParamSet ¶mSet) {
00345 LightPlugin *plugin = GetPlugin<LightPlugin>(name, lightPlugins, PluginSearchPath);
00346 if (plugin) {
00347 Light *ret = plugin->CreateLight(light2world, paramSet);
00348 paramSet.ReportUnused();
00349 return ret;
00350 }
00351 return NULL;
00352 }
00353 COREDLL AreaLight *MakeAreaLight(const string &name,
00354 const Transform &light2world, const ParamSet ¶mSet,
00355 const Reference<Shape> &shape) {
00356 AreaLightPlugin *plugin = GetPlugin<AreaLightPlugin>(name, arealightPlugins,
00357 PluginSearchPath);
00358 if (plugin) {
00359 AreaLight *ret = plugin->CreateAreaLight(light2world, paramSet, shape);
00360 paramSet.ReportUnused();
00361 return ret;
00362 }
00363 return NULL;
00364 }
00365 COREDLL VolumeRegion *MakeVolumeRegion(const string &name,
00366 const Transform &volume2world, const ParamSet ¶mSet) {
00367 VolumeRegionPlugin *plugin = GetPlugin<VolumeRegionPlugin>(name, volumePlugins,
00368 PluginSearchPath);
00369 if (plugin) {
00370 VolumeRegion *ret = plugin->CreateVolumeRegion(volume2world, paramSet);
00371 paramSet.ReportUnused();
00372 return ret;
00373 }
00374 return NULL;
00375 }
00376 COREDLL SurfaceIntegrator *MakeSurfaceIntegrator(const string &name,
00377 const ParamSet ¶mSet) {
00378 SurfaceIntegratorPlugin *plugin = GetPlugin<SurfaceIntegratorPlugin>(name,
00379 surf_integratorPlugins, PluginSearchPath);
00380 if (plugin) {
00381 SurfaceIntegrator *ret = plugin->CreateSurfaceIntegrator(paramSet);
00382 paramSet.ReportUnused();
00383 return ret;
00384 }
00385 return NULL;
00386 }
00387 COREDLL VolumeIntegrator *MakeVolumeIntegrator(const string &name,
00388 const ParamSet ¶mSet) {
00389 VolumeIntegratorPlugin *plugin = GetPlugin<VolumeIntegratorPlugin>(name, vol_integratorPlugins,
00390 PluginSearchPath);
00391 if (plugin) {
00392 VolumeIntegrator *ret = plugin->CreateVolumeIntegrator(paramSet);
00393 paramSet.ReportUnused();
00394 return ret;
00395 }
00396 return NULL;
00397 }
00398 COREDLL Primitive *MakeAccelerator(const string &name,
00399 const vector<Reference<Primitive> > &prims,
00400 const ParamSet ¶mSet) {
00401 AcceleratorPlugin *plugin = GetPlugin<AcceleratorPlugin>(name, acceleratorPlugins,
00402 PluginSearchPath);
00403 if (plugin) {
00404 Primitive *ret = plugin->CreateAccelerator(prims, paramSet);
00405 paramSet.ReportUnused();
00406 return ret;
00407 }
00408 return NULL;
00409 }
00410 COREDLL Camera *MakeCamera(const string &name,
00411 const ParamSet ¶mSet,
00412 const Transform &world2cam, Film *film) {
00413 CameraPlugin *plugin = GetPlugin<CameraPlugin>(name, cameraPlugins, PluginSearchPath);
00414 if (plugin) {
00415 Camera *ret = plugin->CreateCamera(paramSet, world2cam, film);
00416 paramSet.ReportUnused();
00417 return ret;
00418 }
00419 return NULL;
00420 }
00421 COREDLL Sampler *MakeSampler(const string &name,
00422 const ParamSet ¶mSet, const Film *film) {
00423 SamplerPlugin *plugin = GetPlugin<SamplerPlugin>(name, samplerPlugins, PluginSearchPath);
00424 if (plugin) {
00425 Sampler *ret = plugin->CreateSampler(paramSet, film);
00426 paramSet.ReportUnused();
00427 return ret;
00428 }
00429 return NULL;
00430 }
00431 COREDLL Filter *MakeFilter(const string &name,
00432 const ParamSet ¶mSet) {
00433 FilterPlugin *plugin = GetPlugin<FilterPlugin>(name, filterPlugins, PluginSearchPath);
00434 if (plugin) {
00435 Filter *ret = plugin->CreateFilter(paramSet);
00436 paramSet.ReportUnused();
00437 return ret;
00438 }
00439 return NULL;
00440 }
00441 COREDLL ToneMap *MakeToneMap(const string &name,
00442 const ParamSet ¶mSet) {
00443 ToneMapPlugin *plugin = GetPlugin<ToneMapPlugin>(name, tonemapPlugins, PluginSearchPath);
00444 if (plugin) {
00445 ToneMap *ret = plugin->CreateToneMap(paramSet);
00446 paramSet.ReportUnused();
00447 return ret;
00448 }
00449 return NULL;
00450 }
00451 COREDLL Film *MakeFilm(const string &name,
00452 const ParamSet ¶mSet, Filter *filter) {
00453 FilmPlugin *plugin = GetPlugin<FilmPlugin>(name, filmPlugins, PluginSearchPath);
00454 if (plugin) {
00455 Film *ret = plugin->CreateFilm(paramSet, filter);
00456 paramSet.ReportUnused();
00457 return ret;
00458 }
00459 return NULL;
00460 }
00461
00462 Plugin::Plugin(const string &fname) {
00463 pluginName = fname;
00464 #if defined(WIN32)
00465 hinstLib = LoadLibrary(fname.c_str());
00466 if (!hinstLib)
00467 Error("Can't open plug-in \"%s\"", fname.c_str());
00468 #elif defined(__APPLE__)
00469 NSObjectFileImage fileImage;
00470 NSObjectFileImageReturnCode returnCode =
00471 NSCreateObjectFileImageFromFile(fname.c_str(), &fileImage);
00472 if(returnCode == NSObjectFileImageSuccess) {
00473 hinstLib = NSLinkModule(fileImage,fname.c_str(),
00474 NSLINKMODULE_OPTION_RETURN_ON_ERROR
00475 | NSLINKMODULE_OPTION_PRIVATE);
00476 NSDestroyObjectFileImage(fileImage);
00477 if (!hinstLib) {
00478 Error("Can't open plug-in \"%s\"", fname.c_str());
00479 }
00480 }
00481 else {
00482 Error("Can't open plug-in \"%s\"", fname.c_str());
00483 }
00484 #else
00485 hinstLib = dlopen(fname.c_str(), RTLD_LAZY);
00486 if (!hinstLib)
00487 Error("Can't open plug-in \"%s\" (%s)", fname.c_str(),
00488 dlerror());
00489 #endif
00490 }
00491 Plugin::~Plugin() {
00492 #if defined(WIN32)
00493 FreeLibrary(hinstLib);
00494 #elif defined(__APPLE__)
00495 NSUnLinkModule(hinstLib,0);
00496 #else
00497 dlclose(hinstLib);
00498 #endif
00499 }
00500 void *Plugin::GetSymbol(const string &symname) {
00501 void *data;
00502 #if defined(WIN32)
00503 data = GetProcAddress(hinstLib, symname.c_str());
00504 #elif defined(__APPLE__)
00505 string apple_lossage = string("_") + symname;
00506 NSSymbol nssym = NSLookupSymbolInModule(hinstLib,apple_lossage.c_str());
00507 data = NSAddressOfSymbol(nssym);
00508 #else
00509 data = dlsym(hinstLib, symname.c_str());
00510 #endif
00511 if (!data)
00512 Severe("Couldn't get symbol \"%s\" in Plugin %s.", symname.c_str(), pluginName.c_str());
00513 return data;
00514 }