Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

FileRenderList.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: FileRenderList.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.111 $      $Date: 2021/12/13 07:54:00 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *
00019  * The FileRenderList class maintains a list of available FileRenderer
00020  * objects
00021  *
00022  ***************************************************************************/
00023 
00024 #include "config.h"  // create dependency so new compile options cause rebuild
00025 #include "FileRenderList.h"
00026 #include "VMDApp.h"
00027 #include "CmdRender.h"
00028 #include "CommandQueue.h"
00029 #include "Scene.h"
00030 #include "DisplayDevice.h"
00031 #include "TextEvent.h"
00032 #include "Inform.h"
00033 #include "WKFThreads.h" // CPU capability flags
00034 #include <stdlib.h>  // for system()
00035 
00036 //
00037 // Supported external rendering programs
00038 //
00039 #if defined(VMDLIBANARI)
00040 #include "ANARIDisplayDevice.h"       // ANARI sci-vis rendering API
00041 #endif
00042 #include "ArtDisplayDevice.h"         // Art ray tracer
00043 #include "GelatoDisplayDevice.h"      // nVidia Gelato
00044 #if defined(VMDLIBOPTIX)
00045 // We include the OptiX related headers first to prevent collisions between
00046 // enums in OptiXRenderer, and preprocessor macros in Tachyon...
00047 #include "OptiXDisplayDevice.h"       // Compiled-in OptiX ray tracer
00048 #endif
00049 #if defined(VMDLIBOSPRAY)
00050 #include "OSPRayDisplayDevice.h"      // Compiled-in OSPRay 1.x ray tracer
00051 #endif
00052 #if defined(VMDLIBOSPRAY2)
00053 #include "OSPRay2DisplayDevice.h"     // Compiled-in OSPRay 2.x ray tracer
00054 #endif
00055 #if defined(VMDLIBTACHYON) 
00056 #include "LibTachyonDisplayDevice.h"  // Compiled-in Tachyon ray tracer
00057 #endif
00058 #if defined(VMDLIBGELATO)
00059 #include "LibGelatoDisplayDevice.h"   // Compiled-in Gelato renderer
00060 #endif
00061 #include "MayaDisplayDevice.h"        // Autodesk Maya
00062 #include "POV3DisplayDevice.h"        // POVRay 3.x 
00063 #include "PSDisplayDevice.h"          // Postscript
00064 #include "R3dDisplayDevice.h"         // Raster3D
00065 #include "RadianceDisplayDevice.h"    // Radiance, unknown version 
00066 #include "RayShadeDisplayDevice.h"    // Rayshade 4.0 
00067 #include "RenderManDisplayDevice.h"   // RenderMan interface
00068 #include "SnapshotDisplayDevice.h"    // Built-in snapshot capability
00069 #include "STLDisplayDevice.h"         // Stereolithography files
00070 #include "TachyonDisplayDevice.h"     // Tachyon ray tracer
00071 #include "VrmlDisplayDevice.h"        // VRML 1.0 
00072 #include "Vrml2DisplayDevice.h"       // VRML 2.0 / VRML97
00073 #include "WavefrontDisplayDevice.h"   // Wavefront "OBJ" files
00074 #include "X3DDisplayDevice.h"         // X3D (XML encoding)
00075 
00076 
00077 // constructor, start off with the default means of rendering
00078 FileRenderList::FileRenderList(VMDApp *vmdapp) : app(vmdapp) {
00079 
00080 #if defined(VMDLIBOSPRAY) || defined(VMDLIBOSPRAY2)
00081   // check CPU instruction set capabilities for SSE 4.1 required by OSPRay
00082   wkf_cpu_caps_t cpucaps;
00083   int havecpucaps=0;
00084   if (!wkf_cpu_capability_flags(&cpucaps)) {
00085     havecpucaps=1;
00086   } 
00087 #endif
00088 
00089   add(new ArtDisplayDevice());
00090   add(new GelatoDisplayDevice());
00091 #if defined(VMDLIBGELATO)
00092   // Only add the internally linked gelato display device to the
00093   // menu if the user has correctly set the GELATOHOME environment
00094   // variable.  If we allow them to use it otherwise, it may lead
00095   // to crashing, or failed renders.  This way they won't even see it
00096   // as an option unless they've got Gelato installed and the environment
00097   // at least minimally configured.
00098   if (getenv("GELATOHOME") != NULL) {
00099     add(new LibGelatoDisplayDevice());
00100   }
00101 #endif
00102   // XXX until the native Maya ASCII export code is finished,
00103   // only show it when a magic environment variable is set.
00104   if (getenv("VMDENABLEMAYA") != NULL) {
00105     add(new MayaDisplayDevice());
00106   }
00107   add(new PSDisplayDevice());
00108   add(new R3dDisplayDevice());
00109   add(new RadianceDisplayDevice());
00110   add(new RayShadeDisplayDevice());
00111   add(new RenderManDisplayDevice());
00112   add(new SnapshotDisplayDevice(app->display));
00113   add(new STLDisplayDevice());
00114   add(new TachyonDisplayDevice());
00115 #if defined(VMDLIBTACHYON)
00116   add(new LibTachyonDisplayDevice(vmdapp));
00117 #endif
00118 
00119 
00120 #if defined(VMDLIBANARI)
00121   // XXX ANARI initialization must precede OptiX 6.x to prevent
00122   //     conflicts with OpenGL/EGL context creation in GL-based
00123   //     renderer back-ends performed within the main VMD thread.
00124   //     This issue will be resolved by OptiX 7.x
00125   if (!getenv("VMDNOANARI")) {
00126     ANARIDisplayDevice::ANARI_Global_Init(); // call only ONCE
00127     if (!getenv("VMDNOANARIBATCH")) {
00128       add(new ANARIDisplayDevice(vmdapp, 0));
00129     }
00130 
00131 #if !defined(__APPLE__)
00132     // XXX Since the glwin code hasn't yet been adapted to wrap FLTK, SDL,
00133     // or Apple-native Aqua/Cocoa, we can't enable the interactive RT window yet
00134 #if defined(VMDOPENGL) && defined(VMDANARI_INTERACTIVE_OPENGL)
00135     if (!getenv("VMDNOANARIINTERACTIVE") && !getenv("VMDANARIUSD")) {
00136       add(new ANARIDisplayDevice(vmdapp, 1));
00137     }
00138 #endif
00139 #endif
00140   }
00141 #endif
00142 
00143 
00144 #if defined(VMDLIBOPTIX)
00145   if (!getenv("VMDNOOPTIX")) {
00146     int optixdevcount=OptiXDisplayDevice::device_count();
00147 
00148     // Only emit detailed OptiX GPU data if we're running on a single node.
00149     // Put the console informational text immediately prior to the creation of
00150     // FileRenderList objects where the renderers are actually instantiated, 
00151     // so that all of the OptiX GPU and compilation status info is together
00152     if (vmdapp->nodecount == 1) {
00153       if (optixdevcount > 0) {
00154         msgInfo << "Detected " << optixdevcount << " available TachyonL/OptiX ray tracing "
00155                 << ((optixdevcount > 1) ? "accelerators" : "accelerator")
00156                 << sendmsg;
00157       }
00158     }
00159 
00160     // Perform runtime check for OptiX availability before we add it to the
00161     // list of available renderers.
00162     if (optixdevcount > 0) { 
00163       // Emit a console message during OptiX renderer instantiation
00164       // since the JIT compilation and linkage of the 256+ shaders may
00165       // take several seconds on machines with several GPUs...
00166       if (vmdapp->nodecount == 1) {
00167         msgInfo << "  Compiling " 
00168 //                << OptiXRenderer::material_shader_table_size() 
00169                 << " OptiX shaders on " << optixdevcount << " target GPU" 
00170                 << ((optixdevcount > 1) ? "s" : "") << "..." << sendmsg;
00171       }
00172 
00173       add(new OptiXDisplayDevice(vmdapp, 0));
00174 
00175       // Even if we have no GUI, then we now add interactive renderer
00176       // to be able to support remote rendering via video streaming
00177       // from clusters, supercomputers, etc.  The renderer launch code
00178       // will determine whether or not to launch a GUI-based interactive
00179       // renderer or a renderer intended solely for video streaming.
00180       add(new OptiXDisplayDevice(vmdapp, 1));
00181     }
00182   }
00183 #endif
00184 
00185 #if defined(VMDLIBOSPRAY) || defined(VMDLIBOSPRAY2)
00186   if (!getenv("VMDNOOSPRAY")) {
00187     if (!havecpucaps || (havecpucaps && (cpucaps.flags & CPU_SSE4_1))) {
00188 #if defined(VMDLIBOSPRAY)
00189       int osprc = OSPRayDisplayDevice::OSPRay_Global_Init(); // call only ONCE
00190       if (osprc) {
00191         msgWarn << "Intel OSPRay renderer failed to initialize and is unavailable" << sendmsg;
00192       } else {
00193         add(new OSPRayDisplayDevice(vmdapp, 0));
00194 #if !defined(__APPLE__)
00195           // XXX Since glwin hasn't yet been adapted to wrap FLTK, SDL, or 
00196           // Apple-native Aqua/Cocoa, we can't enable the interactive RT window yet
00197 #if defined(VMDOPENGL) && defined(VMDOSPRAY_INTERACTIVE_OPENGL)
00198           if (!getenv("VMDNOOSPRAYINTERACTIVE")) {
00199             add(new OSPRayDisplayDevice(vmdapp, 1));
00200           }
00201 #endif
00202 #endif
00203       }
00204 #endif
00205 
00206 #if defined(VMDLIBOSPRAY2)
00207       OSPRay2DisplayDevice::OSPRay_Global_Init(); // call only ONCE
00208       int osprc = OSPRay2DisplayDevice::OSPRay_Global_Init(); // call only ONCE
00209       if (osprc) {
00210         msgWarn << "Intel OSPRay renderer failed to initialize and is unavailable" << sendmsg;
00211       } else {
00212         add(new OSPRay2DisplayDevice(vmdapp, 0));
00213 #if !defined(__APPLE__)
00214         // XXX Since glwin hasn't yet been adapted to wrap FLTK, SDL, or 
00215         // Apple-native Aqua/Cocoa, we can't enable the interactive RT window yet
00216 #if defined(VMDOPENGL) && defined(VMDOSPRAY_INTERACTIVE_OPENGL)
00217         add(new OSPRay2DisplayDevice(vmdapp, 1));
00218 #endif
00219 #endif
00220       }
00221 #endif
00222     } else {
00223       msgWarn << "OSPRay renderer disabled, requires SSE 4.1 or greater" << sendmsg;
00224     }
00225   }
00226 #endif
00227 
00228   add(new POV3DisplayDevice());
00229   add(new VrmlDisplayDevice());
00230   add(new Vrml2DisplayDevice());
00231   add(new WavefrontDisplayDevice());
00232   add(new X3DDisplayDevice());
00233   add(new X3DOMDisplayDevice());
00234 }
00235 
00236 
00237 // destructor, deallocate all the info
00238 FileRenderList::~FileRenderList(void) {
00239   for (int i=0;i<renderList.num();i++)
00240     delete renderList.data(i);
00241 
00242 #if defined(VMDLIBOSPRAY)
00243   if (!getenv("VMDNOOSPRAY")) {
00244     OSPRayDisplayDevice::OSPRay_Global_Shutdown(); // call only ONCE
00245   }
00246 #endif
00247 
00248 #if defined(VMDLIBOSPRAY2)
00249   if (!getenv("VMDNOOSPRAY")) {
00250     OSPRay2DisplayDevice::OSPRay_Global_Shutdown(); // call only ONCE
00251   }
00252 #endif
00253 
00254 #if defined(VMDLIBANARI)
00255   if (!getenv("VMDNOANARI")) {
00256     ANARIDisplayDevice::ANARI_Global_Shutdown(); // call only ONCE
00257   }
00258 #endif
00259 
00260 }
00261 
00262 
00263 // add a new render class with its corresponding name
00264 void FileRenderList::add(FileRenderer *newRenderer) {
00265   if (newRenderer)
00266     renderList.add_name(newRenderer->name, newRenderer);
00267 }
00268 
00269 // figure out how many render classes are installed
00270 int FileRenderList::num(void) {
00271   return renderList.num();
00272 }
00273 
00274 // return the name for the ith class, returns NULL if out of range
00275 const char *FileRenderList::name(int i) {
00276   if (i>=0 && i < renderList.num()) {
00277     return renderList.name(i);
00278   }
00279   return NULL;
00280 }
00281 
00282 // return the "pretty" name (used in GUIs) for the ith class.
00283 // returns NULL if out of range
00284 const char *FileRenderList::pretty_name(int i) {
00285   if (i>=0 && i < renderList.num()) {
00286     const FileRenderer * fr = renderList.data(i);
00287     return fr->pretty_name();
00288   }
00289   return NULL;
00290 }
00291 
00292 // find class (case-insensitive) for a renderer name, else return NULL  
00293 FileRenderer *FileRenderList::find(const char *rname) {
00294   int indx = renderList.typecode(rname);
00295   
00296   if (indx >= 0)
00297     return renderList.data(indx);
00298   else
00299     return NULL;
00300 }
00301 
00302 // given a "pretty" render name, return the corresponding class
00303 FileRenderer *FileRenderList::find_pretty_name(const char *pretty) {
00304   int i;
00305   for (i=0; i<renderList.num(); i++) {
00306     if (!strcmp(pretty_name(i), pretty)) {
00307       return renderList.data(i); 
00308     }
00309   }
00310   return NULL;
00311 }
00312 
00313 // given a "pretty" renderer name, return the short name
00314 const char *FileRenderList::find_short_name_from_pretty_name(const char *pretty) {
00315   const FileRenderer *fr = find_pretty_name(pretty);
00316   if (fr)
00317     return fr->visible_name();
00318   return NULL;
00319 }
00320 
00321 int FileRenderList::render(const char *filename, const char *method,
00322                            const char *extcmd) {
00323   msgInfo << "Rendering current scene to '" << filename << "' ..." << sendmsg;
00324 
00325   FileRenderer *render = find(method);
00326   if (!render) {
00327     msgErr << "Invalid render method '" << method << sendmsg;
00328     return FALSE;
00329   }
00330 
00331   // XXX Snapshot grabs the wrong buffer, so if we're doing snapshot, swap
00332   // the buffers, render, then swap back.
00333   if (!strcmp(method, "snapshot")) app->display->update(TRUE);
00334   int retval = app->scene->filedraw(render, filename, app->display);
00335   if (!strcmp(method, "snapshot")) app->display->update(TRUE);
00336 
00337   // if successful, execute external command
00338   if (retval && extcmd && *extcmd != '\0') {
00339     JString strbuf(extcmd);
00340     strbuf.gsub("%s", filename);
00341     // substitute display %w and %h for display width and height
00342     int w=100, h=100;
00343     char buf[32];
00344     app->display_get_size(&w, &h);
00345     sprintf(buf, "%d", w);
00346     strbuf.gsub("%w", buf);
00347     sprintf(buf, "%d", h);
00348     strbuf.gsub("%h", buf);
00349     msgInfo << "Executing post-render cmd '" << (const char *)strbuf << "' ..." << sendmsg;
00350     vmd_system(strbuf);
00351   }
00352 
00353   // return result
00354   msgInfo << "Rendering complete." << sendmsg;
00355   return retval;
00356 }
00357 
00358 int FileRenderList::set_render_option(const char *method, const char *option) {
00359   FileRenderer *ren;
00360   ren = find(method);
00361   if (!ren) {
00362     msgErr << "No rendering method '" << method << "' available." << sendmsg;
00363     return FALSE;
00364   }
00365   ren->set_exec_string(option);
00366   return TRUE;
00367 } 
00368 
00369 int FileRenderList::has_antialiasing(const char *method) {
00370   FileRenderer *ren = find(method);
00371   if (ren) return ren->has_antialiasing();
00372   return 0;
00373 }
00374 
00375 int FileRenderList::aasamples(const char *method, int aasamples) {
00376   FileRenderer *ren = find(method);
00377   if (ren) return ren->set_aasamples(aasamples);
00378   return -1;
00379 }
00380 
00381 int FileRenderList::aosamples(const char *method, int aosamples) {
00382   FileRenderer *ren = find(method);
00383   if (ren) return ren->set_aosamples(aosamples);
00384   return -1;
00385 }
00386 
00387 int FileRenderList::imagesize(const char *method, int *w, int *h) {
00388   FileRenderer *ren = find(method);
00389   if (!ren) return FALSE;
00390   return ren->set_imagesize(w, h);
00391 }
00392 
00393 int FileRenderList::has_imagesize(const char *method) {
00394   FileRenderer *ren = find(method);
00395   if (!ren) return FALSE;
00396   return ren->has_imagesize();
00397 }
00398 
00399 int FileRenderList::aspectratio(const char *method, float *aspect) {
00400   FileRenderer *ren = find(method);
00401   if (!ren) return FALSE;
00402   *aspect = ren->set_aspectratio(*aspect);
00403   return TRUE;
00404 }
00405 
00406 int FileRenderList::numformats(const char *method) {
00407   FileRenderer *ren = find(method);
00408   if (!ren) return 0;
00409   return ren->numformats();
00410 }
00411 
00412 const char *FileRenderList::format(const char *method, int i) {
00413   FileRenderer *ren = find(method);
00414   if (!ren) return NULL;
00415   if (i < 0) return ren->format();
00416   return ren->format(i);
00417 }
00418 
00419 int FileRenderList::set_format(const char *method, const char *format) {
00420   FileRenderer *ren = find(method);
00421   if (!ren) return FALSE;
00422   return ren->set_format(format);
00423 }
00424 

Generated on Fri Mar 29 02:45:15 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002