tutorials/medical/parallel-render/viewer_compos.cc

00001 // RedGRID by Orel & Mick & Nico
00002 // Parallel VTK Viewer for Medical Tutorial
00003 // Parallel Rendering with VTK
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; // default
00052 
00053 //===========================================================================//
00054 
00055 // This will be called by all processes
00056 void MyMain( vtkMultiProcessController *controller, void *arg )
00057 {
00058   vtkImageData * imagedata;
00059   
00060   try {
00061     
00062     // ==== create node & proxy ==== //    
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     // ==== connection  ==== //    
00069     if(prank == 0) 
00070       connection = proxy->connect(sourceID);
00071     node->waitConnection(sourceID); 
00072     controller->Barrier();
00073     
00074     // ==== get remote domain ==== //
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     // RedSYM::BlockInt domain(0, 0, 0, 255, 255, 149);    
00083     
00084     // ==== create distribution ==== //
00085     
00086     // define topology
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     // overlap
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     // rs_typecode = RedSYM::_unsigned_short;
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     // ==== image data ==== //    
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     // ==== create grid 3D ==== //
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     //  ==== set ready ==== //
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     // ==== create channel ==== //
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     // get request
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   // Iso-surface Filter
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   // Create Lookup Table
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   // nb triangles
00256   int nb_triangles = isoMapper->GetInput()->GetNumberOfCells();
00257   cerr << nb_triangles << " triangles on process " << prank << endl;
00258     
00259   // Create the rendering part of the pipeline
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   //  renMan->SetTileDimensions(2, 2);
00273   renMan->SetMaxImageReductionFactor(4);
00274   renMan->AutoImageReductionFactorOn();
00275 
00276   // Initialize the event loop and then start it.
00277   renMan->InitializeRMIs();
00278   cout << "start parallel iso-surface calculation and parallel rendering, wait few seconds..." << endl;
00279   renMan->StartInteractor();
00280 
00281   // Clean up
00282   ren->Delete();
00283   renWindow->Delete();
00284   renMan->Delete();
00285   iren->Delete();
00286   cam->Delete();
00287   timer->Delete();
00288   
00289   
00290   try {
00291     
00292     // ==== shutdown ==== //    
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   // ====  start ORB ==== //
00349   orb = CorbaTools::startORB(argc,argv);
00350   
00351   // ====  start Controller ==== //
00352   controller->SingleMethodExecute();
00353   controller->Barrier(); 
00354   
00355   // ==== goodbye ==== //    
00356   CorbaTools::killORB();
00357   controller->Finalize();
00358   controller->Delete();
00359   cout << "return OK" << endl;
00360   
00361   return 0;
00362 }
00363 
00364 //===========================================================================//
00365 
00366 // EOF
00367 
00368 

Generated on Mon Sep 25 14:55:53 2006 for RedGRID by  doxygen 1.4.6