Back to index

salome-paravis  6.5.0
vtkMedUnstructuredGrid.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2010-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "vtkMedUnstructuredGrid.h"
00021 
00022 #include "vtkObjectFactory.h"
00023 #include "vtkSmartPointer.h"
00024 #include "vtkDataArray.h"
00025 #include "vtkUnstructuredGrid.h"
00026 #include "vtkPointData.h"
00027 #include "vtkCellData.h"
00028 #include "vtkIdList.h"
00029 #include "vtkCellType.h"
00030 #include "vtkInformation.h"
00031 
00032 #include "vtkMedUtilities.h"
00033 #include "vtkMedEntityArray.h"
00034 #include "vtkMedMesh.h"
00035 #include "vtkMedFile.h"
00036 #include "vtkMedDriver.h"
00037 #include "vtkMedFamilyOnEntityOnProfile.h"
00038 #include "vtkMedFamilyOnEntity.h"
00039 #include "vtkMedProfile.h"
00040 #include "vtkMedUtilities.h"
00041 #include "vtkMedStructElement.h"
00042 #include "vtkMedVariableAttribute.h"
00043 
00044 #include "vtkMultiProcessController.h"
00045 
00046 vtkCxxSetObjectMacro(vtkMedUnstructuredGrid,Coordinates,vtkDataArray);
00047 
00048 vtkCxxRevisionMacro(vtkMedUnstructuredGrid, "$Revision: 1.1.4.11.2.1 $")
00049 vtkStandardNewMacro(vtkMedUnstructuredGrid)
00050 
00051 vtkMedUnstructuredGrid::vtkMedUnstructuredGrid()
00052 {
00053   this->Coordinates = NULL;
00054   this->NumberOfPoints = 0;
00055 }
00056 
00057 vtkMedUnstructuredGrid::~vtkMedUnstructuredGrid()
00058 {
00059   this->SetCoordinates(NULL);
00060 }
00061 
00062 int vtkMedUnstructuredGrid::IsCoordinatesLoaded()
00063 {
00064   return this->Coordinates != NULL && this->Coordinates->GetNumberOfTuples()
00065      == this->NumberOfPoints;
00066 }
00067 
00068 void  vtkMedUnstructuredGrid::InitializeCellGlobalIds()
00069 {
00070   vtkIdType ncells = 0;
00071   
00072   for(int id = 0; id < this->EntityArray->size(); id++)
00073     {
00074     vtkMedEntityArray* array = this->EntityArray->at(id);
00075     
00076     if(array == NULL)
00077       continue;
00078     
00079     if(array->GetEntity().EntityType == MED_NODE)
00080       continue;
00081     
00082     array->SetInitialGlobalId(ncells + 1);
00083     ncells += array->GetNumberOfEntity();
00084     }
00085 }
00086 
00087 void  vtkMedUnstructuredGrid::ClearMedSupports()
00088 {
00089   this->Superclass::ClearMedSupports();
00090   for(int id = 0; id < this->EntityArray->size(); id++)
00091     {
00092     vtkMedEntityArray* array = this->EntityArray->at(id);
00093     array->Initialize();
00094     }
00095 }
00096 
00097 void  vtkMedUnstructuredGrid::LoadCoordinates()
00098 {
00099   this->GetParentMesh()->GetParentFile()->GetMedDriver()->LoadCoordinates(this);
00100 }
00101 
00102 double* vtkMedUnstructuredGrid::GetCoordTuple(med_int index)
00103 {
00104   return this->Coordinates->GetTuple(index);
00105 }
00106 
00107 vtkDataSet* vtkMedUnstructuredGrid::CreateVTKDataSet(
00108     vtkMedFamilyOnEntityOnProfile* foep)
00109 {
00110   vtkMultiProcessController* controller =
00111       vtkMultiProcessController::GetGlobalController();
00112 
00113   vtkMedFamilyOnEntity* foe = foep->GetFamilyOnEntity();
00114   vtkMedEntityArray* array = foe->GetEntityArray();
00115   if(foep->GetValid() == 0)
00116     {
00117     return NULL;
00118     }
00119 
00120   vtkUnstructuredGrid* vtkugrid = vtkUnstructuredGrid::New();
00121 
00122   // now we copy all the flagged nodes in the grid, shallow copy if possible
00123   bool shallowCopyPoints=true;
00124 
00125   if(this->GetParentMesh()->GetSpaceDimension()!=3)
00126     {
00127     shallowCopyPoints=false;
00128     }
00129 
00130   shallowCopyPoints = shallowCopyPoints && foep->CanShallowCopyPointField(NULL);
00131 
00132   foe->GetParentGrid()->LoadCoordinates();
00133 
00134   vtkIdType numberOfPoints;
00135   vtkPoints* points=vtkPoints::New(this->GetCoordinates()->GetDataType());
00136   vtkugrid->SetPoints(points);
00137   points->Delete();
00138 
00139   vtkIdTypeArray* pointGlobalIds=vtkIdTypeArray::New();
00140   pointGlobalIds->SetName("MED_POINT_ID");
00141   pointGlobalIds->SetNumberOfComponents(1);
00142   vtkugrid->GetPointData()->SetGlobalIds(pointGlobalIds);
00143   pointGlobalIds->Delete();
00144 
00145   vtkIdTypeArray* cellGlobalIds=vtkIdTypeArray::New();
00146   cellGlobalIds->SetName("MED_CELL_ID");
00147   cellGlobalIds->SetNumberOfComponents(1);
00148   vtkugrid->GetCellData()->SetGlobalIds(cellGlobalIds);
00149   cellGlobalIds->Delete();
00150 
00151   if (shallowCopyPoints)
00152     {
00153     vtkugrid->GetPoints()->SetDataType(this->GetCoordinates()->GetDataType());
00154     vtkugrid->GetPoints()->SetData(this->GetCoordinates());
00155     // add global ids
00156     numberOfPoints=this->GetNumberOfPoints();
00157     pointGlobalIds->SetNumberOfTuples(numberOfPoints);
00158     vtkIdType* ptr=pointGlobalIds->GetPointer(0);
00159     for(int pid=0; pid<numberOfPoints; pid++)
00160       ptr[pid]=pid+1;
00161     }
00162   else
00163     {
00164     vtkIdType currentIndex=0;
00165     for(vtkIdType index=0; index<this->GetNumberOfPoints(); index++)
00166       {
00167       if(!foep->KeepPoint(index))
00168         continue;
00169 
00170       double coord[3]={0.0, 0.0, 0.0};
00171       double * tuple=this->GetCoordinates()->GetTuple(index);
00172       for(int dim=0; dim<this->GetParentMesh()->GetSpaceDimension()&&dim<3; dim++)
00173         {
00174         coord[dim]=tuple[dim];
00175         }
00176       vtkugrid->GetPoints()->InsertPoint(currentIndex, coord);
00177       pointGlobalIds->InsertNextValue(index+1);
00178       currentIndex++;
00179       }
00180     vtkugrid->GetPoints()->Squeeze();
00181     pointGlobalIds->Squeeze();
00182     numberOfPoints=currentIndex;
00183     }
00184 
00185   vtkMedStructElement* structelem = NULL;
00186   int vtkType = VTK_EMPTY_CELL;
00187   int nsupportcell = 1;
00188   vtkSmartPointer<vtkIdTypeArray> supportIndex = vtkSmartPointer<vtkIdTypeArray>::New();
00189   supportIndex->SetName("STRUCT_ELEMENT_INDEX");
00190   supportIndex->SetNumberOfComponents(2);
00191   supportIndex->GetInformation()->Set(vtkMedUtilities::STRUCT_ELEMENT_INDEX(), 1);
00192   supportIndex->GetInformation()->Set(vtkAbstractArray::GUI_HIDE(), 1);
00193   supportIndex->SetComponentName(0, "GLOBAL_ID");
00194   supportIndex->SetComponentName(1, "LOCAL_ID");
00195 
00196   if(array->GetEntity().EntityType == MED_STRUCT_ELEMENT)
00197     {
00198     structelem = array->GetStructElement();
00199     if(structelem == NULL)
00200       {
00201       foep->SetValid(0);
00202       }
00203     else
00204       {
00205       vtkType = vtkMedUtilities::GetVTKCellType(
00206           structelem->GetSupportGeometryType());
00207       nsupportcell = structelem->GetSupportNumberOfCell();
00208       if(structelem->GetSupportEntityType() != MED_CELL
00209          || strcmp(structelem->GetName(), MED_PARTICLE_NAME) == 0)
00210         {
00211         // Special case : the support connectivity is implicit
00212         // (for particles)
00213         // map this to points
00214         vtkType = VTK_VERTEX;
00215         nsupportcell = structelem->GetSupportNumberOfNode();
00216         }
00217 
00218       vtkugrid->GetInformation()->Set(vtkMedUtilities::STRUCT_ELEMENT(), structelem);
00219       for(int varattid = 0; varattid<structelem->GetNumberOfVariableAttribute(); varattid++)
00220         {
00221         vtkMedVariableAttribute* varatt = structelem->GetVariableAttribute(varattid);
00222         varatt->Load(array);
00223         vtkAbstractArray* values = array->GetVariableAttributeValue(varatt);
00224         vtkugrid->GetFieldData()->AddArray(values);
00225         }
00226       vtkugrid->GetCellData()->AddArray(supportIndex);
00227       }
00228     }
00229   else
00230     {
00231     vtkType = vtkMedUtilities::GetVTKCellType(
00232         array->GetEntity().GeometryType);
00233     }
00234 
00235   vtkSmartPointer<vtkIdList> pts = vtkSmartPointer<vtkIdList>::New();
00236   vtkSmartPointer<vtkIdList> vtkpts = vtkSmartPointer<vtkIdList>::New();
00237   vtkIdType intialGlobalId = array->GetInitialGlobalId();
00238   vtkMedIntArray* pids = (foep->GetProfile()!=NULL?
00239                            foep->GetProfile()->GetIds() : NULL);
00240   vtkIdType maxId = (pids!=NULL?
00241                      pids->GetNumberOfTuples():
00242                      array->GetNumberOfEntity());
00243 
00244   int valid = foep->GetValid();
00245   if (controller != NULL)
00246     if (controller->GetNumberOfProcesses() > 1)
00247     valid = 1;
00248 
00249   for (vtkIdType pindex = 0; pindex<maxId && valid; pindex++)
00250     {
00251     vtkIdType realIndex = (pids!=NULL?
00252                            pids->GetValue(pindex)-1:
00253                            pindex);
00254 
00255     if (!foep->KeepCell(realIndex))
00256       continue;
00257 
00258     array->GetCellVertices(realIndex, pts);
00259 
00260     for(int sid = 0; sid < nsupportcell; sid++)
00261       {
00262       cellGlobalIds->InsertNextValue(intialGlobalId+pindex);
00263       }
00264 
00265     // The supportIndex array has 2 component, the first to give the index
00266     // of the med cell in the variable attributes array, the second to give
00267     // the index of the cell in the n cells composing the structural element
00268     if(array->GetEntity().EntityType == MED_STRUCT_ELEMENT)
00269       {
00270       for(int sid = 0; sid < nsupportcell; sid++)
00271         {
00272         supportIndex->InsertNextTuple2(pindex, sid);
00273         }
00274       }
00275 
00276     if (array->GetEntity().GeometryType==MED_POLYHEDRON)
00277       {
00278       if(vtkMedUtilities::FormatPolyhedronForVTK(foep, pindex, pts))
00279         {
00280         vtkugrid->InsertNextCell(VTK_POLYHEDRON, pts);
00281         }
00282       else
00283         {
00284         foep->SetValid(0);
00285         vtkugrid->Delete();
00286         return NULL;
00287         }
00288       }
00289     else
00290       {
00291       vtkpts->Initialize();
00292       vtkpts->SetNumberOfIds(pts->GetNumberOfIds());
00293 
00294       for(vtkIdType node=0; node<pts->GetNumberOfIds(); node++)
00295         {
00296         vtkIdType pid = pts->GetId(node);
00297         vtkIdType ptid=foep->GetVTKPointIndex(pid);
00298         if(ptid < 0 || ptid >= vtkugrid->GetNumberOfPoints())
00299           {
00300           vtkDebugMacro("Index error, this cell"  <<
00301                         " is not on this profile");
00302 #ifndef MedReader_HAVE_PARALLEL_INFRASTRUCTURE
00303           vtkugrid->Delete();
00304           foep->SetValid(0);
00305           return NULL;
00306 #else
00307           return vtkugrid;
00308 #endif
00309           }
00310         vtkpts->SetId(vtkMedUtilities::MedToVTKIndex(vtkType, node), ptid);
00311         }
00312 
00313       // for strutural elements, insert nsupportcell instead of only one
00314       if(nsupportcell > 1)
00315         {
00316         vtkIdType npts = vtkpts->GetNumberOfIds() / nsupportcell;
00317         for(int sid=0; sid < nsupportcell; sid++)
00318           {
00319           vtkIdType* ptids = vtkpts->GetPointer(sid * npts);
00320           vtkugrid->InsertNextCell(vtkType, npts, ptids);
00321           }
00322         }
00323       else
00324         {
00325         vtkugrid->InsertNextCell(vtkType, vtkpts);
00326         }
00327       }
00328     }
00329 
00330   if(vtkugrid->GetNumberOfCells() == vtkugrid->GetNumberOfPoints())
00331     {
00332     for(int fieldId = 0; fieldId < vtkugrid->GetFieldData()->GetNumberOfArrays(); fieldId++)
00333       {
00334       vtkDataArray* fieldData = vtkugrid->GetFieldData()->GetArray(fieldId);
00335     
00336       if(fieldData->GetNumberOfTuples() == vtkugrid->GetNumberOfCells())
00337         {
00338         vtkugrid->GetPointData()->AddArray(fieldData);
00339         }
00340       else
00341         {
00342         vtkDataArray* real_fieldData = fieldData->NewInstance();
00343         real_fieldData->SetName(fieldData->GetName());
00344         real_fieldData->SetNumberOfComponents(fieldData->GetNumberOfComponents());
00345 
00346         for(vtkIdType cellId = 0; cellId < vtkugrid->GetNumberOfPoints(); cellId++)
00347           {
00348           vtkIdType supportId = static_cast<int>(supportIndex->GetTuple2(cellId)[0]);
00349           real_fieldData->InsertNextTuple(fieldData->GetTuple(supportId));
00350           }
00351 
00352         vtkugrid->GetPointData()->AddArray(real_fieldData);
00353         real_fieldData->Delete();
00354         }
00355       }
00356     }
00357 
00358   return vtkugrid;
00359 }
00360 
00361 void vtkMedUnstructuredGrid::PrintSelf(ostream& os, vtkIndent indent)
00362 {
00363   this->Superclass::PrintSelf(os, indent);
00364   PRINT_IVAR(os, indent, NumberOfPoints);
00365 }