Equalizer  1.8.0
Parallel Rendering Framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
application.cpp
1 
2 /* Copyright (c) 2011-2013, Stefan Eilemann <eile@eyescale.ch>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * - Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  * - Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation
11  * and/or other materials provided with the distribution.
12  * - Neither the name of Eyescale Software GmbH nor the names of its
13  * contributors may be used to endorse or promote products derived from this
14  * software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "application.h"
30 
31 #include "renderer.h"
32 
33 #pragma warning( disable: 4275 )
34 #include <boost/program_options.hpp>
35 #pragma warning( default: 4275 )
36 
37 #ifndef MIN
38 # define MIN LB_MIN
39 #endif
40 
41 namespace po = boost::program_options;
42 
43 namespace seqPly
44 {
45 bool Application::init( const int argc, char** argv )
46 {
47  const eq::Strings& models = _parseArguments( argc, argv );
48  if( !seq::Application::init( argc, argv, 0 ))
49  return false;
50 
51  _loadModel( models );
52  return true;
53 }
54 
55 bool Application::run()
56 {
57  return seq::Application::run( &_frameData );
58 }
59 
61 {
62  _unloadModel();
63  return seq::Application::exit();
64 }
65 
67 {
68  return new Renderer( *this );
69 }
70 
71 co::Object* Application::createObject( const uint32_t type )
72 {
73  switch( type )
74  {
76  return new eqPly::FrameData;
77 
78  default:
79  return seq::Application::createObject( type );
80  }
81 }
82 
83 namespace
84 {
85 static bool _isPlyfile( const std::string& filename )
86 {
87  const size_t size = filename.length();
88  if( size < 5 )
89  return false;
90 
91  if( filename[size-4] != '.' || filename[size-3] != 'p' ||
92  filename[size-2] != 'l' || filename[size-1] != 'y' )
93  {
94  return false;
95  }
96  return true;
97 }
98 }
99 
100 eq::Strings Application::_parseArguments( const int argc, char** argv )
101 {
102  std::string userDefinedModelPath("");
103 
104  try //parse command line arguments
105  {
106  po::options_description options(
107  std::string("seqPly - Sequel polygonal rendering example ")
109  bool showHelp(false);
110 
111  options.add_options()
112  ( "help,h", po::bool_switch(&showHelp)->default_value(false),
113  "produce help message" )
114  ( "model,m", po::value<std::string>(&userDefinedModelPath),
115  "ply model file name" );
116 
117  // parse program options, ignore all non related options
118  po::variables_map variableMap;
119  po::store( po::command_line_parser( argc, argv ).options(
120  options ).allow_unregistered().run(),
121  variableMap );
122  po::notify( variableMap );
123 
124  // Evaluate parsed command line options
125  if( showHelp )
126  {
127  LBWARN << options << std::endl;
128  ::exit( EXIT_SUCCESS );
129  }
130  }
131  catch( std::exception& exception )
132  {
133  LBERROR << "Error parsing command line: " << exception.what()
134  << std::endl;
135  }
136 
137 
138  eq::Strings filenames;
139  filenames.push_back( lunchbox::getExecutablePath() +
140  "/../share/Equalizer/data" );
141 
142  if( !userDefinedModelPath.empty( ))
143  {
144  filenames.clear();
145  filenames.push_back( userDefinedModelPath );
146  }
147  return filenames;
148 }
149 
150 void Application::_loadModel( const eq::Strings& models )
151 {
152  eq::Strings files = models;
153  while( !files.empty( ))
154  {
155  const std::string filename = files.back();
156  files.pop_back();
157 
158  if( _isPlyfile( filename ))
159  {
160  _model = new Model;
161  if( _model->readFromFile( filename.c_str( )))
162  {
163  _modelDist = new ModelDist( _model );
164  _modelDist->registerTree( this );
165  _frameData.setModelID( _modelDist->getID( ));
166  return;
167  }
168  delete _model;
169  _model = 0;
170  }
171  else
172  {
173  const std::string basename = lunchbox::getFilename( filename );
174  if( basename == "." || basename == ".." )
175  continue;
176 
177  // recursively search directories
178  const eq::Strings subFiles = lunchbox::searchDirectory( filename,
179  ".*" );
180  for(eq::StringsCIter i = subFiles.begin(); i != subFiles.end(); ++i)
181  files.push_back( filename + '/' + *i );
182  }
183  }
184 }
185 
186 void Application::_unloadModel()
187 {
188  if( !_modelDist )
189  return;
190 
191  _modelDist->deregisterTree();
192  delete _modelDist;
193  _modelDist = 0;
194 
195  delete _model;
196  _model = 0;
197 }
198 
199 const Model* Application::getModel( const eq::uint128_t& modelID )
200 {
201  if( modelID == 0 )
202  return 0;
203  if( _model )
204  return _model;
205  lunchbox::memoryBarrier();
206 
207  // Accessed concurrently from render threads
208  lunchbox::ScopedMutex<> mutex( _modelLock );
209  if( _model )
210  return _model;
211 
212  LBASSERT( !_modelDist );
213  _modelDist = new ModelDist;
214  Model* model = _modelDist->loadModel( getMasterNode(), this, modelID );
215  LBASSERT( model );
216  _model = model;
217 
218  return model;
219 }
220 
221 }
virtual SEQ_API bool exit()
Exit this application instance.
virtual SEQ_API bool run(co::Object *frameData)
Run the application main loop.
static std::string getString()
virtual seq::Renderer * createRenderer()
Create a new renderer instance.
Definition: application.cpp:66
A renderer instance.
The object passed to Application::run()
Definition: objectType.h:30
SEQ_API co::NodePtr getMasterNode()
virtual bool exit()
Exit this application instance.
Definition: application.cpp:60
virtual SEQ_API bool init(const int argc, char **argv, co::Object *initData)
Initialize the application instance.