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