Equalizer  1.6.1
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 #ifndef MIN
34 # define MIN LB_MIN
35 #endif
36 #include <tclap/CmdLine.h>
37 
38 namespace seqPly
39 {
40 
41 bool Application::init( const int argc, char** argv )
42 {
43  const eq::Strings& models = _parseArguments( argc, argv );
44  if( !seq::Application::init( argc, argv, 0 ))
45  return false;
46 
47  _loadModel( models );
48  return true;
49 }
50 
51 bool Application::run()
52 {
53  return seq::Application::run( &_frameData );
54 }
55 
57 {
58  _unloadModel();
59  return seq::Application::exit();
60 }
61 
63 {
64  return new Renderer( *this );
65 }
66 
67 co::Object* Application::createObject( const uint32_t type )
68 {
69  switch( type )
70  {
72  return new eqPly::FrameData;
73 
74  default:
75  return seq::Application::createObject( type );
76  }
77 }
78 
79 namespace
80 {
81 static bool _isPlyfile( const std::string& filename )
82 {
83  const size_t size = filename.length();
84  if( size < 5 )
85  return false;
86 
87  if( filename[size-4] != '.' || filename[size-3] != 'p' ||
88  filename[size-2] != 'l' || filename[size-1] != 'y' )
89  {
90  return false;
91  }
92  return true;
93 }
94 }
95 
96 eq::Strings Application::_parseArguments( const int argc, char** argv )
97 {
98  TCLAP::CmdLine command( "seqPly - Sequel polygonal rendering example", ' ',
100  TCLAP::ValueArg<std::string> modelArg( "m", "model", "ply model file name",
101  false, "", "string", command );
102  TCLAP::UnlabeledMultiArg< std::string >
103  ignoreArgs( "ignore", "Ignored unlabeled arguments", false, "any",
104  command );
105 
106 #ifdef TCPLAP_HAS_IGNOREUNMATCHED
107  command.ignoreUnmatched( true );
108 #endif
109  command.parse( argc, argv );
110 
111  eq::Strings filenames;
112 #ifdef EQ_RELEASE
113 # ifdef _WIN32 // final INSTALL_DIR is not known at compile time
114  filenames.push_back( "../share/Equalizer/data" );
115 # else
116  filenames.push_back( std::string( EQ_INSTALL_DIR ) +
117  std::string( "share/Equalizer/data" ));
118  filenames.push_back( std::string( "/usr/share/Equalizer/data" ));
119 # endif
120 #else
121  filenames.push_back( std::string( EQ_SOURCE_DIR ) +
122  std::string( "examples/eqPly" ));
123 #endif
124 
125  if( modelArg.isSet( ))
126  {
127  filenames.clear();
128  filenames.push_back( modelArg.getValue( ));
129  }
130  return filenames;
131 }
132 
133 void Application::_loadModel( const eq::Strings& models )
134 {
135  eq::Strings files = models;
136  while( !files.empty( ))
137  {
138  const std::string filename = files.back();
139  files.pop_back();
140 
141  if( _isPlyfile( filename ))
142  {
143  _model = new Model;
144  if( _model->readFromFile( filename.c_str( )))
145  {
146  _modelDist = new ModelDist( _model );
147  _modelDist->registerTree( this );
148  _frameData.setModelID( _modelDist->getID( ));
149  return;
150  }
151  delete _model;
152  _model = 0;
153  }
154  else
155  {
156  const std::string basename = lunchbox::getFilename( filename );
157  if( basename == "." || basename == ".." )
158  continue;
159 
160  // recursively search directories
161  const eq::Strings subFiles = lunchbox::searchDirectory( filename,
162  ".*" );
163  for(eq::StringsCIter i = subFiles.begin(); i != subFiles.end(); ++i)
164  files.push_back( filename + '/' + *i );
165  }
166  }
167 }
168 
169 void Application::_unloadModel()
170 {
171  if( !_modelDist )
172  return;
173 
174  _modelDist->deregisterTree();
175  delete _modelDist;
176  _modelDist = 0;
177 
178  delete _model;
179  _model = 0;
180 }
181 
182 const Model* Application::getModel( const eq::uint128_t& modelID )
183 {
184  if( modelID == 0 )
185  return 0;
186  if( _model )
187  return _model;
188  lunchbox::memoryBarrier();
189 
190  // Accessed concurrently from render threads
191  lunchbox::ScopedMutex<> mutex( _modelLock );
192  if( _model )
193  return _model;
194 
195  LBASSERT( !_modelDist );
196  _modelDist = new ModelDist;
197  Model* model = _modelDist->loadModel( getMasterNode(), this, modelID );
198  LBASSERT( model );
199  _model = model;
200 
201  return model;
202 }
203 
204 }
virtual bool exit()
Exit this application instance.
Definition: application.cpp:56
virtual bool init(const int argc, char **argv, co::Object *initData)
Initialize the application instance.
static std::string getString()
co::NodePtr getMasterNode()
virtual bool exit()
Exit this application instance.
virtual bool run(co::Object *frameData)
Run the application main loop.
virtual seq::Renderer * createRenderer()
Create a new renderer instance.
Definition: application.cpp:62
The object passed to Application::run()
Definition: objectType.h:30
A renderer instance.