00001
00002
00003
00004
00005 #include "vtkImageData.h"
00006 #include "vtkPointData.h"
00007 #include "vtkDataArray.h"
00008 #include "vtkUnsignedShortArray.h"
00009 #include "vtkMath.h"
00010 #include "vtkPolyData.h"
00011 #include "vtkPolyDataMapper.h"
00012 #include "vtkRenderWindow.h"
00013 #include "vtkRenderWindowInteractor.h"
00014 #include "vtkRenderer.h"
00015 #include "vtkCamera.h"
00016 #include "vtkContourFilter.h"
00017 #include "vtkDataSet.h"
00018 #include "vtkMultiProcessController.h"
00019 #include "vtkMPIController.h"
00020 #include "vtkAppendPolyData.h"
00021 #include "vtkTimerLog.h"
00022 #include "vtkProperty.h"
00023 #include "vtkLookupTable.h"
00024
00025 #include "vtkCompositeRenderManager.h"
00026
00027 #include <mpi.h>
00028 #include <cassert>
00029 #include <unistd.h>
00030 #include <iostream>
00031 #include "RedCORBA.hh"
00032 #include "RedSYM.hh"
00033 #include "CorbaTools.hh"
00034 using namespace std;
00035
00036
00037
00038 RedCORBA::Proxy * proxy;;
00039 RedCORBA::Node * node;
00040 RedSYM::Grid * grid;
00041 RedSYM::DistributionInt * distribution;
00042 int prank, psize;
00043 string sourceID, dataID;
00044 RedSYM::TypeCode rs_typecode;
00045 int vtk_typecode, sizeoftype;
00046 CORBA::ORB_ptr orb;
00047 RedCORBA::ConnectionID connection;
00048 RedCORBA::ProxyChannel * channel;
00049 static const int NODE_TAG=999;
00050
00051 float ISO_VALUE = 900.0;
00052
00053
00054
00055
00056 void MyMain( vtkMultiProcessController *controller, void *arg )
00057 {
00058 vtkImageData * imagedata;
00059
00060 try {
00061
00062
00063 if(prank == 0)
00064 proxy = new RedCORBA::Proxy("viewer3D",psize,orb,RedCORBA::_non_blocking);
00065 node = new RedCORBA::Node("viewer3D",prank,psize,orb,RedCORBA::_blocking);
00066 if(prank == 0) proxy->waitActivation();
00067
00068
00069 if(prank == 0)
00070 connection = proxy->connect(sourceID);
00071 node->waitConnection(sourceID);
00072 controller->Barrier();
00073
00074
00075
00076 connection = node->getConnectionID(sourceID);
00077 RedSYM::ParallelGrid * remote_grid =
00078 (RedSYM::ParallelGrid *) node->getRemoteParallelObjectFromProxy(connection,dataID,RedSYM::_grid);
00079 RedSYM::BlockInt domain = remote_grid->getDomain();
00080 assert(domain.getNumberOfDimensions() == 3);
00081
00082
00083
00084
00085
00086
00087 RedSYM::AxisProc axisproc[3] = {0, 0, 0};
00088 RedSYM::AxisType axistype[3] = {RedSYM::_collapsed, RedSYM::_collapsed, RedSYM::_collapsed} ;
00089 RedSYM::AxisInfo axisinfo[3] = {0, 0, 0};
00090
00091 if ((psize%4 == 0)&&(psize > 4)){
00092 axisproc[0] = psize/4;
00093 axisproc[1] = 2;
00094 axisproc[2] = 2;
00095 axistype[0] = RedSYM::_block;
00096 axistype[1] = RedSYM::_block;
00097 axistype[2] = RedSYM::_block;
00098 }
00099 else if ((psize%3 == 0)&&(psize > 3)){
00100 axisproc[0] = psize/3;
00101 axisproc[1] = 3;
00102 axistype[0] = RedSYM::_block;
00103 axistype[1] = RedSYM::_block;
00104 }
00105 else if ((psize%2 == 0)&&(psize > 3)){
00106 axisproc[0] = psize/2;
00107 axisproc[1] = 2;
00108 axistype[0] = RedSYM::_block;
00109 axistype[1] = RedSYM::_block;
00110 }
00111 else {
00112 axisproc[0] = psize;
00113 axistype[0] = RedSYM::_block;
00114 }
00115
00116 float dx, dy, dz;
00117 dx = 200.0/(domain[0].upperbound() - domain[0].lowerbound() + 1);
00118 dy = 200.0/(domain[1].upperbound() - domain[1].lowerbound() + 1);
00119 dz = 200.0/(domain[2].upperbound() - domain[2].lowerbound() + 1);
00120 distribution = RedSYM::DistributionFactoryInt::createBlockCyclic(domain, prank, axisproc, axistype, axisinfo);
00121
00122
00123 assert(distribution->size() == 1);
00124 if ((*distribution)[0][0].lowerbound() != 0) (*distribution)[0][0].lowerbound()--;
00125 if ((*distribution)[0][1].lowerbound() != 0) (*distribution)[0][1].lowerbound()--;
00126 if ((*distribution)[0][2].lowerbound() != 0) (*distribution)[0][2].lowerbound()--;
00127 int x0, x1, y0, y1, z0, z1;
00128 x0 = (*distribution)[0][0].lowerbound();
00129 x1 = (*distribution)[0][0].upperbound();
00130 y0 = (*distribution)[0][1].lowerbound();
00131 y1 = (*distribution)[0][1].upperbound();
00132 z0 = (*distribution)[0][2].lowerbound();
00133 z1 = (*distribution)[0][2].upperbound();
00134
00135 rs_typecode = remote_grid->getTypeCode();
00136
00137
00138 sizeoftype = RedSYM::SizeOfType[rs_typecode];
00139 switch(rs_typecode) {
00140 case RedSYM::_octet :
00141 vtk_typecode = VTK_CHAR;
00142 break;
00143 case RedSYM::_short :
00144 vtk_typecode = VTK_SHORT;
00145 break;
00146 case RedSYM::_long :
00147 vtk_typecode = VTK_LONG;
00148 break;
00149 case RedSYM::_unsigned_short :
00150 vtk_typecode = VTK_UNSIGNED_SHORT;
00151 break;
00152 case RedSYM::_unsigned_long :
00153 vtk_typecode = VTK_UNSIGNED_LONG;
00154 break;
00155 case RedSYM::_float :
00156 vtk_typecode = VTK_FLOAT;
00157 break;
00158 case RedSYM::_double :
00159 vtk_typecode = VTK_DOUBLE;
00160 break;
00161 default:
00162 cerr << "unknown type code !!!" << endl;
00163 }
00164
00165
00166 imagedata = vtkImageData::New();
00167 imagedata->SetDimensions(x1-x0+1, y1-y0+1, z1-z0+1) ;
00168 imagedata->SetSpacing(dx, dy, dz);
00169 imagedata->SetOrigin(x0*dx,y0*dy,z0*dz);
00170 imagedata->SetScalarType(vtk_typecode) ;
00171 imagedata->AllocateScalars() ;
00172
00173
00174 grid = new RedSYM::Grid(dataID,prank,psize,3);
00175 int serie0 = grid->addSerie("serie0",rs_typecode);
00176 grid->setDistribution(*distribution);
00177 grid->wrap(serie0, 0, imagedata->GetScalarPointer());
00178 node->addData(grid);
00179
00180
00181 if(prank == 0)
00182 proxy->ready(RedCORBA::_non_blocking);
00183 node->ready(RedCORBA::_blocking);
00184 cout << "Node " << prank << " Ready" << endl;
00185 controller->Barrier();
00186
00187
00188 if(prank == 0) {
00189 cout << "create channel for " << dataID << "... " << flush;
00190 channel = proxy->createChannel(connection,dataID);
00191 cout << "done" << endl;
00192 }
00193 controller->Barrier();
00194
00195
00196 if(prank == 0) {
00197 cout << "get data from reader... " << flush;
00198 channel->get(0,RedCORBA::_blocking);
00199 cout << "done" << endl;
00200 }
00201 controller->Barrier();
00202
00203 }
00204 catch(RedCORBA::Exception & ex) {
00205 cout << "RedCORBA Exception: " << ex << endl;
00206 exit(EXIT_FAILURE);
00207 }
00208 catch(ColCOWS::ColCOWSException & ex) {
00209 cout << "ColCOWS Exception: " << ex << endl;
00210 exit(EXIT_FAILURE);
00211 }
00212 catch(...) {
00213 cout << "Unknown Exception!" << endl; exit(EXIT_FAILURE);
00214 }
00215
00216
00217 vtkContourFilter * iso = vtkContourFilter::New();
00218 iso->SetInput(imagedata);
00219 iso->SetValue(0, ISO_VALUE);
00220 iso->ComputeScalarsOff();
00221 iso->ComputeGradientsOff();
00222
00223 vtkActor * isoActor;
00224 vtkPolyDataMapper * isoMapper;
00225
00226 vtkCompositeRenderManager* renMan = vtkCompositeRenderManager::New();
00227 renMan->SetController(controller);
00228
00229
00230 vtkRenderer *ren = renMan->MakeRenderer();
00231 vtkRenderWindow *renWindow = renMan->MakeRenderWindow();
00232 vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
00233 vtkTimerLog *timer = vtkTimerLog::New();
00234 vtkCamera *cam = vtkCamera::New();
00235
00236 isoMapper = vtkPolyDataMapper::New();
00237 isoMapper->SetInput(iso->GetOutput());
00238 isoActor = vtkActor::New();
00239 isoActor->SetMapper(isoMapper);
00240 ren->AddActor(isoActor);
00241
00242
00243 vtkLookupTable *lookupTable = vtkLookupTable::New();
00244 lookupTable->SetTableRange (0, psize-1);
00245 lookupTable->SetHueRange (.70, 0);
00246 lookupTable->SetSaturationRange (1, 1);
00247 lookupTable->SetValueRange (1, 1);
00248 lookupTable->Build();
00249
00250
00251 double procColor[3];
00252 lookupTable->GetColor(prank,procColor);
00253 isoActor->GetProperty()->SetColor(procColor);
00254
00255
00256 int nb_triangles = isoMapper->GetInput()->GetNumberOfCells();
00257 cerr << nb_triangles << " triangles on process " << prank << endl;
00258
00259
00260 iren->SetRenderWindow(renWindow);
00261 renWindow->AddRenderer(ren);
00262 ren->SetBackground(0.9, 0.9, 0.9);
00263 renWindow->SetSize( 400, 400);
00264 cam->SetFocalPoint(100, 100, 100);
00265 cam->SetPosition(100, -450, -100);
00266 cam->SetViewUp(0, 0, 1);
00267 cam->SetViewAngle(30);
00268 cam->SetClippingRange(177.0, 536.0);
00269 ren->SetActiveCamera(cam);
00270
00271 renMan->SetRenderWindow(renWindow);
00272
00273 renMan->SetMaxImageReductionFactor(4);
00274 renMan->AutoImageReductionFactorOn();
00275
00276
00277 renMan->InitializeRMIs();
00278 cout << "start parallel iso-surface calculation and parallel rendering, wait few seconds..." << endl;
00279 renMan->StartInteractor();
00280
00281
00282 ren->Delete();
00283 renWindow->Delete();
00284 renMan->Delete();
00285 iren->Delete();
00286 cam->Delete();
00287 timer->Delete();
00288
00289
00290 try {
00291
00292
00293 if(prank == 0) {
00294 proxy->disconnect(connection);
00295 proxy->deactivate();
00296 }
00297
00298 controller->Barrier();
00299 if(prank == 0) delete proxy;
00300 delete node;
00301 delete grid;
00302 delete distribution;
00303 }
00304 catch(RedCORBA::Exception & ex) {
00305 cout << "RedCORBA Exception: " << ex << endl;
00306 exit(EXIT_FAILURE);
00307 }
00308 catch(ColCOWS::ColCOWSException & ex) {
00309 cout << "ColCOWS Exception: " << ex << endl;
00310 }
00311 catch(...) {
00312 cout << "Unknown Exception!" << endl;
00313 exit(EXIT_FAILURE);
00314 }
00315
00316 controller->Barrier();
00317 }
00318
00319
00320
00321 int main(int argc, char** argv)
00322 {
00323 sourceID = "reader3D";
00324 dataID = "mygrid";
00325
00326 if (argc >= 2) {
00327 ISO_VALUE = atof(argv[1]);
00328 }
00329 else {
00330 cout << "Usage: " << " [iso_value] [ORB options]" << endl;
00331 return 0;
00332 }
00333
00334 vtkMultiProcessController *controller;
00335 controller = vtkMPIController::New();
00336 controller->Initialize(&argc, &argv);
00337
00338 if (controller->IsA("vtkThreadedController"))
00339 controller->SetNumberOfProcesses(2);
00340
00341 prank = controller->GetLocalProcessId();
00342 psize = controller->GetNumberOfProcesses();
00343 cout << "prank = " << prank << endl;
00344 cout << "psize = " << psize << endl;
00345
00346 controller->SetSingleMethod(MyMain, reinterpret_cast<void*>(argv[1]));
00347
00348
00349 orb = CorbaTools::startORB(argc,argv);
00350
00351
00352 controller->SingleMethodExecute();
00353 controller->Barrier();
00354
00355
00356 CorbaTools::killORB();
00357 controller->Finalize();
00358 controller->Delete();
00359 cout << "return OK" << endl;
00360
00361 return 0;
00362 }
00363
00364
00365
00366
00367
00368