00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "lux.h"
00024 #include "api.h"
00025 #include "error.h"
00026 #include "paramset.h"
00027 #include "renderfarm.h"
00028 #include "scene.h"
00029 #include "camera.h"
00030
00031 #include "../renderer/include/asio.hpp"
00032
00033 #include <fstream>
00034 #include <boost/iostreams/filtering_stream.hpp>
00035 #include <boost/bind.hpp>
00036
00037 using namespace boost::iostreams;
00038 using namespace lux;
00039 using asio::ip::tcp;
00040
00041 void FilmUpdaterThread::updateFilm(FilmUpdaterThread *filmUpdaterThread) {
00042
00043
00044 boost::xtime reft;
00045 boost::xtime_get(&reft, boost::TIME_UTC);
00046
00047 while (filmUpdaterThread->signal == SIG_NONE) {
00048
00049
00050 for(;;) {
00051
00052 boost::xtime xt;
00053 boost::xtime_get(&xt, boost::TIME_UTC);
00054 xt.sec += 1;
00055 boost::thread::sleep(xt);
00056
00057 if (filmUpdaterThread->signal == SIG_EXIT)
00058 break;
00059
00060 if (xt.sec - reft.sec > filmUpdaterThread->renderFarm->serverUpdateInterval) {
00061 reft = xt;
00062 break;
00063 }
00064 }
00065
00066 if (filmUpdaterThread->signal == SIG_EXIT)
00067 break;
00068
00069 filmUpdaterThread->renderFarm->updateFilm(filmUpdaterThread->scene);
00070 }
00071 }
00072
00073
00074 void RenderFarm::startFilmUpdater(Scene *scene) {
00075 filmUpdateThread = new FilmUpdaterThread(this, scene);
00076 filmUpdateThread->thread = new boost::thread(boost::bind(
00077 FilmUpdaterThread::updateFilm, filmUpdateThread));
00078 }
00079
00080 void RenderFarm::stopFilmUpdater() {
00081 if (filmUpdateThread != NULL) {
00082 filmUpdateThread->interrupt();
00083 delete filmUpdateThread;
00084 filmUpdateThread = NULL;
00085 }
00086 }
00087
00088 bool RenderFarm::connect(const string &serverName) {
00089
00090
00091 std::stringstream ss;
00092 try {
00093 ss.str("");
00094 ss << "Connecting server: " << serverName;
00095 luxError(LUX_NOERROR, LUX_INFO, ss.str().c_str());
00096
00097 tcp::iostream stream(serverName, "18018");
00098 stream << "ServerConnect" << std::endl;
00099
00100
00101
00102 string result;
00103 if(!getline(stream, result)) {
00104 ss.str("");
00105 ss << "Unable to connect server: " << serverName;
00106 luxError(LUX_SYSTEM, LUX_ERROR, ss.str().c_str());
00107
00108 return false;
00109 }
00110
00111 ss.str("");
00112 ss << "Server connect result: " << result;
00113 luxError(LUX_NOERROR, LUX_INFO, ss.str().c_str());
00114
00115 if ("OK" != result) {
00116 ss.str("");
00117 ss << "Unable to connect server: " << serverName;
00118 luxError(LUX_SYSTEM, LUX_ERROR, ss.str().c_str());
00119
00120 return false;
00121 }
00122 } catch (std::exception& e) {
00123 ss.str("");
00124 ss << "Unable to connect server: " << serverName;
00125 luxError(LUX_SYSTEM, LUX_ERROR, ss.str().c_str());
00126
00127 luxError(LUX_SYSTEM, LUX_ERROR, e.what());
00128 return false;
00129 }
00130
00131 serverList.push_back(std::string(serverName));
00132
00133 return true;
00134 }
00135
00136 void RenderFarm::disconnectAll() {
00137 std::stringstream ss;
00138 for (vector<string>::iterator server = serverList.begin(); server
00139 != serverList.end(); ++server) {
00140 try {
00141 ss.str("");
00142 ss << "Disconnect from server: " << (*server);
00143 luxError(LUX_NOERROR, LUX_INFO, ss.str().c_str());
00144
00145 tcp::iostream stream((*server).c_str(), "18018");
00146 stream << "ServerDisconnect" << std::endl;
00147 } catch (std::exception& e) {
00148 luxError(LUX_SYSTEM, LUX_ERROR, e.what());
00149 }
00150 }
00151 }
00152
00153 void RenderFarm::flush() {
00154 std::stringstream ss;
00155
00156 string commands = netBuffer.str();
00157
00158
00159 for (vector<string>::iterator server = serverList.begin(); server
00160 != serverList.end(); ++server) {
00161 try {
00162 ss.str("");
00163 ss << "Sending commands to server: " << (*server);
00164 luxError(LUX_NOERROR, LUX_INFO, ss.str().c_str());
00165
00166 tcp::iostream stream((*server).c_str(), "18018");
00167 stream << commands << std::endl;
00168 } catch (std::exception& e) {
00169 luxError(LUX_SYSTEM, LUX_ERROR, e.what());
00170 }
00171 }
00172
00173
00174 if (serverList.size() > 0) {
00175 ss.str("");
00176 ss << "All servers are aligned";
00177 luxError(LUX_NOERROR, LUX_INFO, ss.str().c_str());
00178 }
00179 }
00180
00181 void RenderFarm::updateFilm(Scene *scene) {
00182
00183 FlexImageFilm *film = (FlexImageFilm *)(scene->camera->film);
00184
00185 std::stringstream ss;
00186 for (vector<string>::iterator server = serverList.begin(); server
00187 != serverList.end(); ++server) {
00188 try {
00189 ss.str("");
00190 ss << "Getting samples from: " << (*server);
00191 luxError(LUX_NOERROR, LUX_INFO, ss.str().c_str());
00192
00193 tcp::iostream stream((*server).c_str(), "18018");
00194 stream << "luxGetFilm" << std::endl;
00195
00196 if (stream.good()) {
00197 film->UpdateFilm(scene, stream);
00198
00199 ss.str("");
00200 ss << "Samples received from '" << (*server) << "'";
00201 luxError(LUX_NOERROR, LUX_INFO, ss.str().c_str());
00202 } else {
00203 ss.str("");
00204 ss << "Error while contacting server: " << (*server);
00205 luxError(LUX_SYSTEM, LUX_ERROR, ss.str().c_str());
00206 }
00207 } catch (std::exception& e) {
00208 luxError(LUX_SYSTEM, LUX_ERROR, e.what());
00209 }
00210 }
00211 }
00212
00213 void RenderFarm::send(const std::string &command) {
00214
00215
00216
00217
00218
00219
00220
00221
00222 netBuffer << command << std::endl;
00223
00224
00225
00226
00227
00228
00229 }
00230
00231 void RenderFarm::send(const std::string &command, const std::string &name,
00232 const ParamSet ¶ms) {
00233
00234
00235
00236 try {
00237
00238 netBuffer << command << std::endl << name << ' ';
00239 boost::archive::text_oarchive oa(netBuffer);
00240 oa << params;
00241 } catch (std::exception& e) {
00242 luxError(LUX_SYSTEM, LUX_ERROR, e.what());
00243 }
00244
00245 }
00246
00247 void RenderFarm::send(const std::string &command, const std::string &name) {
00248
00249
00250
00251 try {
00252
00253 netBuffer << command << std::endl << name << std::endl;
00254 } catch (std::exception& e) {
00255 luxError(LUX_SYSTEM, LUX_ERROR, e.what());
00256 }
00257
00258 }
00259
00260 void RenderFarm::send(const std::string &command, float x, float y, float z) {
00261
00262
00263
00264 try {
00265
00266 netBuffer << command << std::endl << x << ' ' << y << ' ' << z << std::endl;
00267 } catch (std::exception& e) {
00268 luxError(LUX_SYSTEM, LUX_ERROR, e.what());
00269 }
00270
00271 }
00272
00273 void RenderFarm::send(const std::string &command, float a, float x, float y,
00274 float z) {
00275
00276
00277
00278 try {
00279
00280 netBuffer << command << std::endl << a << ' ' << x << ' ' << y << ' ' << z << std::endl;
00281 } catch (std::exception& e) {
00282 luxError(LUX_SYSTEM, LUX_ERROR, e.what());
00283 }
00284
00285 }
00286
00287 void RenderFarm::send(const std::string &command, float ex, float ey, float ez,
00288 float lx, float ly, float lz, float ux, float uy, float uz) {
00289
00290
00291
00292 try {
00293
00294 netBuffer << command << std::endl << ex << ' ' << ey << ' ' << ez << ' ' << lx << ' ' << ly << ' ' << lz << ' ' << ux << ' ' << uy << ' ' << uz << std::endl;
00295 } catch (std::exception& e) {
00296 luxError(LUX_SYSTEM, LUX_ERROR, e.what());
00297 }
00298
00299 }
00300
00301 void RenderFarm::send(const std::string &command, float tr[16]) {
00302
00303
00304
00305 try {
00306
00307 netBuffer << command << std::endl;
00308 for (int i = 0; i < 16; i++)
00309 netBuffer << tr[i] << ' ';
00310 netBuffer << std::endl;
00311 } catch (std::exception& e) {
00312 luxError(LUX_SYSTEM, LUX_ERROR, e.what());
00313 }
00314
00315 }
00316
00317 void RenderFarm::send(const std::string &command, const string &name,
00318 const string &type, const string &texname, const ParamSet ¶ms) {
00319
00320
00321
00322 try {
00323
00324 netBuffer << command << std::endl << name << ' ' << type << ' ' << texname << ' ';
00325 boost::archive::text_oarchive oa(netBuffer);
00326 oa << params;
00327
00328
00329 std::string file = "";
00330 file = params.FindOneString(std::string("filename"), file);
00331 if (file.size()) {
00332 std::string s;
00333 std::ifstream in(file.c_str(), std::ios::out | std::ios::binary);
00334 while (getline(in, s))
00335 netBuffer << s << "\n";
00336 netBuffer << "LUX_END_FILE\n";
00337 }
00338
00339 } catch (std::exception& e) {
00340 luxError(LUX_SYSTEM, LUX_ERROR, e.what());
00341 }
00342
00343 }