Back to index

salome-paravis  6.5.0
vtkMedEntityArray.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 "vtkMedEntityArray.h"
00021 
00022 #include "vtkObjectFactory.h"
00023 #include "vtkMedIntArray.h"
00024 #include "vtkMedUtilities.h"
00025 #include "vtkMedFamily.h"
00026 #include "vtkMedFamilyOnEntity.h"
00027 #include "vtkMedMesh.h"
00028 #include "vtkMedGrid.h"
00029 #include "vtkMedUnstructuredGrid.h"
00030 #include "vtkMedRegularGrid.h"
00031 #include "vtkMedCurvilinearGrid.h"
00032 #include "vtkMedFile.h"
00033 #include "vtkMedDriver.h"
00034 #include "vtkMedStructElement.h"
00035 
00036 #include "vtkIdList.h"
00037 
00038 #include <set>
00039 using std::set;
00040 
00041 vtkCxxSetObjectVectorMacro(vtkMedEntityArray, FamilyOnEntity, vtkMedFamilyOnEntity);
00042 vtkCxxGetObjectVectorMacro(vtkMedEntityArray, FamilyOnEntity, vtkMedFamilyOnEntity);
00043 vtkCxxSetObjectMacro(vtkMedEntityArray,FamilyIds,vtkMedIntArray);
00044 vtkCxxSetObjectMacro(vtkMedEntityArray,GlobalIds,vtkMedIntArray);
00045 vtkCxxSetObjectMacro(vtkMedEntityArray,ConnectivityArray,vtkMedIntArray);
00046 vtkCxxSetObjectMacro(vtkMedEntityArray,FaceIndex,vtkMedIntArray);
00047 vtkCxxSetObjectMacro(vtkMedEntityArray,NodeIndex,vtkMedIntArray);
00048 
00049 vtkCxxSetObjectMacro(vtkMedEntityArray,ParentGrid,vtkMedGrid);
00050 vtkCxxSetObjectMacro(vtkMedEntityArray,StructElement,vtkMedStructElement);
00051 
00052 vtkCxxRevisionMacro(vtkMedEntityArray, "$Revision: 1.1.4.7.2.1 $");
00053 vtkStandardNewMacro(vtkMedEntityArray);
00054 
00055 vtkMedEntityArray::vtkMedEntityArray()
00056 {
00057   this->NumberOfEntity = 0;
00058   this->Connectivity = MED_NODAL;
00059   this->FamilyIds = NULL;
00060   this->GlobalIds = NULL;
00061   this->ConnectivityArray = NULL;
00062   this->FaceIndex = NULL;
00063   this->NodeIndex = NULL;
00064   this->InitialGlobalId = 0;
00065   this->FamilyOnEntity = new vtkObjectVector<vtkMedFamilyOnEntity> ();
00066   this->FamilyIdStatus = vtkMedEntityArray::FAMILY_ID_NOT_LOADED;
00067   this->ParentGrid = NULL;
00068   this->StructElement = NULL;
00069   //this->Filter = NULL;
00070 }
00071 
00072 vtkMedEntityArray::~vtkMedEntityArray()
00073 {
00074   this->SetFamilyIds(NULL);
00075   this->SetGlobalIds(NULL);
00076   this->SetConnectivityArray(NULL);
00077   this->SetFaceIndex(NULL);
00078   this->SetNodeIndex(NULL);
00079   delete this->FamilyOnEntity;
00080   this->SetParentGrid(NULL);
00081   this->SetStructElement(NULL);
00082   //this->SetFilter(NULL);
00083 }
00084 
00085 void vtkMedEntityArray::Initialize()
00086 {
00087   this->SetFamilyIds(NULL);
00088   this->SetGlobalIds(NULL);
00089   this->SetConnectivityArray(NULL);
00090   this->SetFaceIndex(NULL);
00091   this->SetNodeIndex(NULL);
00092   this->FamilyOnEntity->clear();
00093   this->FamilyIdStatus = FAMILY_ID_NOT_LOADED;
00094 }
00095 
00096 void vtkMedEntityArray::ComputeFamilies()
00097 {
00098   this->FamilyOnEntity->clear();
00099   vtkMedMesh* mesh = this->ParentGrid->GetParentMesh();
00100 
00101   if(this->FamilyIds == NULL)
00102     {
00103     vtkMedFamilyOnEntity* foe = vtkMedFamilyOnEntity::New();
00104     foe->SetParentGrid(this->ParentGrid);
00105     this->AppendFamilyOnEntity(foe);
00106     foe->Delete();
00107     if(this->GetEntity().EntityType != MED_NODE)
00108       {
00109       foe->SetFamily(mesh->GetOrCreateCellFamilyById(0));
00110       }
00111     else
00112       {
00113       foe->SetFamily(mesh->GetOrCreatePointFamilyById(0));
00114       }
00115     foe->SetEntityArray(this);
00116     this->FamilyIdStatus = vtkMedEntityArray::FAMILY_ID_IMPLICIT;
00117     return;
00118     }
00119 
00120   this->FamilyIdStatus = vtkMedEntityArray::FAMILY_ID_EXPLICIT;
00121 
00122   set<med_int> idset;
00123   for (vtkIdType index = 0; index < this->FamilyIds->GetNumberOfTuples(); index++)
00124     {
00125     med_int id = this->FamilyIds->GetValue(index);
00126     idset.insert(id);
00127     }
00128 
00129   for (set<med_int>::iterator it = idset.begin(); it != idset.end(); it++)
00130     {
00131     vtkMedFamilyOnEntity* foe = vtkMedFamilyOnEntity::New();
00132     foe->SetParentGrid(this->ParentGrid);
00133     this->AppendFamilyOnEntity(foe);
00134     foe->Delete();
00135     if(this->GetEntity().EntityType != MED_NODE)
00136       {
00137       foe->SetFamily(mesh->GetOrCreateCellFamilyById(*it));
00138       }
00139     else
00140       {
00141       foe->SetFamily(mesh->GetOrCreatePointFamilyById(*it));
00142       }
00143     foe->SetEntityArray(this);
00144     }
00145 }
00146 
00147 med_int vtkMedEntityArray::GetFamilyId(med_int id)
00148 {
00149   if(this->FamilyIdStatus == FAMILY_ID_IMPLICIT)
00150     return 0;
00151   if(this->FamilyIdStatus == FAMILY_ID_NOT_LOADED)
00152     {
00153     vtkErrorMacro("You have to load family ids before asking for it!");
00154     }
00155   return this->FamilyIds->GetValue(id);
00156 }
00157 
00158 int vtkMedEntityArray::HasFamily(vtkMedFamily* family)
00159 {
00160   for (int i = 0; i < this->FamilyOnEntity->size(); i++)
00161     {
00162     vtkMedFamilyOnEntity* foe = this->FamilyOnEntity->at(i);
00163     if(foe->GetFamily() == family)
00164       return 1;
00165     }
00166   return 0;
00167 }
00168 
00169 int vtkMedEntityArray::IsConnectivityLoaded()
00170 {
00171   // Entity Arrays representing something else than cells
00172   // have no connectivity
00173 
00174   if(vtkMedUnstructuredGrid::SafeDownCast(this->GetParentGrid()) == NULL)
00175     return 1;
00176 
00177   if( this->Entity.EntityType != MED_CELL &&
00178       this->Entity.EntityType != MED_DESCENDING_FACE &&
00179       this->Entity.EntityType != MED_DESCENDING_EDGE &&
00180       this->Entity.EntityType != MED_STRUCT_ELEMENT)
00181     return 1;
00182 
00183   if(this->ConnectivityArray == NULL)
00184     return 0;
00185 
00186   if(this->Connectivity == MED_NODAL && this->Entity.EntityType != MED_STRUCT_ELEMENT)
00187     {
00188     vtkIdType connSize = this->NumberOfEntity
00189         * vtkMedUtilities::GetNumberOfPoint(this->Entity.GeometryType);
00190 
00191     return connSize == this->ConnectivityArray->GetNumberOfTuples();
00192     }
00193   else if (this->Connectivity == MED_NODAL && this->Entity.EntityType == MED_STRUCT_ELEMENT)
00194     {
00195     if(this->StructElement == NULL)
00196       return 1;
00197 
00198     vtkIdType connSize = this->NumberOfEntity
00199                          * this->StructElement->GetConnectivitySize();
00200 
00201     return connSize == this->ConnectivityArray->GetNumberOfTuples();
00202     }
00203   else
00204     {
00205     vtkIdType connSize = this->NumberOfEntity
00206         * vtkMedUtilities::GetNumberOfSubEntity(this->Entity.GeometryType);
00207 
00208     return connSize == this->ConnectivityArray->GetNumberOfTuples();
00209     }
00210 }
00211 
00212 int vtkMedEntityArray::IsFamilyIdsLoaded()
00213 {
00214   return this->FamilyIdStatus != vtkMedEntityArray::FAMILY_ID_NOT_LOADED;;
00215 }
00216 
00217 int vtkMedEntityArray::IsGlobalIdsLoaded()
00218 {
00219   return this->GlobalIds != NULL && this->GlobalIds->GetNumberOfTuples()
00220       == this->NumberOfEntity;
00221 }
00222 
00223 void vtkMedEntityArray::GetCellVertices(vtkIdType index, vtkIdList* ids)
00224 {
00225   ids->Initialize();
00226 
00227   if(this->Entity.EntityType == MED_NODE)
00228     {
00229     ids->InsertNextId(index);
00230     return;
00231     }
00232 
00233   if( this->Entity.EntityType != MED_CELL &&
00234       this->Entity.EntityType != MED_DESCENDING_FACE &&
00235       this->Entity.EntityType != MED_DESCENDING_EDGE &&
00236       this->Entity.EntityType != MED_STRUCT_ELEMENT)
00237     {
00238     vtkErrorMacro("This reader is not compatible with those entities (yet)...");
00239     return;
00240     }
00241 
00242   if(vtkMedUnstructuredGrid::SafeDownCast(this->ParentGrid) == NULL)
00243     {
00244     // this is a structured grid, connectivity is implicit...
00245 
00246     if(this->Entity.GeometryType == MED_POINT1)
00247       {
00248       // degenerate case if there is only one point
00249       ids->InsertNextId(0);
00250       return;
00251       }
00252     if(this->Entity.GeometryType == MED_SEG2)
00253       {
00254       // line
00255       ids->InsertNextId(index);
00256       ids->InsertNextId(index+1);
00257       return;
00258       }
00259     vtkMedRegularGrid* vtkrgrid = vtkMedRegularGrid::SafeDownCast(
00260         this->GetParentGrid());
00261     vtkMedCurvilinearGrid* vtkcgrid = vtkMedCurvilinearGrid::SafeDownCast(
00262         this->GetParentGrid());
00263     vtkIdType xncell = 0;
00264     vtkIdType yncell = 0;
00265     vtkIdType zncell = 0;
00266     vtkIdType xnpts = 1;
00267     vtkIdType ynpts = 1;
00268     vtkIdType znpts = 1;
00269     if(vtkrgrid!=NULL)
00270       {
00271       xncell = vtkrgrid->GetAxisSize(0)-1;
00272       yncell = vtkrgrid->GetAxisSize(1)-1;
00273       zncell = vtkrgrid->GetAxisSize(2)-1;
00274       xnpts = vtkrgrid->GetAxisSize(0);
00275       ynpts = vtkrgrid->GetAxisSize(1);
00276       znpts = vtkrgrid->GetAxisSize(2);
00277       }
00278     if(vtkcgrid != NULL)
00279       {
00280       xncell = vtkcgrid->GetAxisSize(0)-1;
00281       yncell = vtkcgrid->GetAxisSize(1)-1;
00282       zncell = vtkcgrid->GetAxisSize(2)-1;
00283       xnpts = vtkcgrid->GetAxisSize(0);
00284       ynpts = vtkcgrid->GetAxisSize(1);
00285       znpts = vtkcgrid->GetAxisSize(2);
00286       }
00287     vtkIdType xindex = index % xncell;
00288     if(xncell <= 0)
00289       return;
00290 
00291     vtkIdType yindex = index / xncell;
00292 
00293     if(this->Entity.GeometryType == MED_QUAD4)
00294       {
00295       // plane
00296 
00297       ids->InsertNextId(xindex + yindex*xnpts);
00298       ids->InsertNextId(xindex + 1 + yindex*xnpts);
00299       ids->InsertNextId(xindex + yindex*xnpts);
00300       ids->InsertNextId(xindex + 1 + (yindex + 1)*xnpts);
00301       return;
00302       }
00303 
00304     if(yncell <= 0)
00305       return;
00306 
00307     vtkIdType zindex = index / (xncell*yncell);
00308 
00309     if(this->Entity.GeometryType == MED_HEXA8)
00310       {
00311       // volume
00312       ids->InsertNextId(xindex   + (yindex  )*xnpts + (zindex  )*xnpts*ynpts);
00313       ids->InsertNextId(xindex+1 + (yindex  )*xnpts + (zindex  )*xnpts*ynpts);
00314       ids->InsertNextId(xindex   + (yindex+1)*xnpts + (zindex  )*xnpts*ynpts);
00315       ids->InsertNextId(xindex+1 + (yindex+1)*xnpts + (zindex  )*xnpts*ynpts);
00316       ids->InsertNextId(xindex   + (yindex  )*xnpts + (zindex+1)*xnpts*ynpts);
00317       ids->InsertNextId(xindex+1 + (yindex  )*xnpts + (zindex+1)*xnpts*ynpts);
00318       ids->InsertNextId(xindex   + (yindex+1)*xnpts + (zindex+1)*xnpts*ynpts);
00319       ids->InsertNextId(xindex+1 + (yindex+1)*xnpts + (zindex+1)*xnpts*ynpts);
00320       return;
00321       }
00322     return;
00323     }
00324 
00325   this->LoadConnectivity();
00326 
00327   if (this->GetEntity().GeometryType==MED_POLYHEDRON)
00328     {
00329     vtkMedIntArray* conn = this->GetConnectivityArray();
00330     vtkMedIntArray* faceIndex = this->GetFaceIndex();
00331     vtkMedIntArray* nodeIndex = this->GetNodeIndex();
00332     med_int start = faceIndex->GetValue(index)-1;
00333     med_int end = faceIndex->GetValue(index+1)-1;
00334     // the use of a set loses the order, but VTK do not support this order anyway.
00335     if (this->GetConnectivity()==MED_NODAL)
00336       {
00337       for (int ff = start; ff<end; ff++)
00338         {
00339         med_int fstart = nodeIndex->GetValue(ff)-1;
00340         med_int fend = nodeIndex->GetValue(ff+1)-1;
00341         for (int pt = fstart; pt<fend; pt++)
00342           {
00343           med_int ptid = conn->GetValue(pt)-1;
00344           ids->InsertNextId(ptid);
00345           }
00346         }
00347       }
00348     else // MED_DESCENDING
00349       {
00350       vtkMedUnstructuredGrid* ugrid =
00351           vtkMedUnstructuredGrid::SafeDownCast(this->ParentGrid);
00352       if (!ugrid)
00353         {
00354         vtkErrorMacro(
00355         "MED_DESCENDING connectivity is only supported on unstructured grids");
00356         return;
00357         }
00358       set<med_int> pts;
00359       vtkIdList* subIds = vtkIdList::New();
00360       for (int ff = start; ff<end; ff++)
00361         {
00362         med_int fid = conn->GetValue(ff)-1;
00363         vtkMedEntity entity;
00364         entity.GeometryType = (med_geometry_type) NodeIndex->GetValue(ff);
00365         entity.EntityType = MED_DESCENDING_FACE;
00366         vtkMedEntityArray* subarray = ugrid->GetEntityArray(entity);
00367         subarray->GetCellVertices(fid, subIds);
00368         for (int id = 0; id<subIds->GetNumberOfIds(); id++)
00369           {
00370           med_int ptid = subIds->GetId(id);
00371           if(pts.find(ptid) == pts.end())
00372             {
00373             ids->InsertNextId(ptid);
00374             pts.insert(ptid);
00375             }
00376           }
00377         }
00378       subIds->Delete();
00379       }
00380     }//end polyhedron
00381   else if (this->GetEntity().GeometryType==MED_POLYGON)
00382     {
00383     vtkMedIntArray* conn = this->GetConnectivityArray();
00384     vtkMedIntArray* nids = this->GetFaceIndex();
00385     med_int start = nids->GetValue(index)-1;
00386     med_int end = nids->GetValue(index+1)-1;
00387     if (this->GetConnectivity()==MED_NODAL)
00388       {
00389       for (int pt = start; pt<end; pt++)
00390         {
00391         ids->InsertNextId(conn->GetValue(pt)-1);
00392         }
00393       }
00394     else // MED_DESCENDING
00395       {
00396       vtkIdList* subpts=vtkIdList::New();
00397       vtkMedUnstructuredGrid* ugrid =
00398           vtkMedUnstructuredGrid::SafeDownCast(this->ParentGrid);
00399       if (!ugrid)
00400         {
00401         vtkErrorMacro("MED_DESCENDING connectivity is only "
00402                       << "supported on unstructured grids");
00403         return;
00404         }
00405       set<med_int> pts;
00406       for (int sub = start; sub<end; sub++)
00407         {
00408         med_int subid = conn->GetValue(sub)-1;
00409         vtkMedEntity subentity;
00410         subentity.GeometryType = MED_SEG2;
00411         subentity.EntityType = MED_DESCENDING_EDGE;
00412         vtkMedEntityArray* subarray = ugrid->GetEntityArray(subentity);
00413         subarray->GetCellVertices(subid, subpts);
00414         for(int id=0; id<subpts->GetNumberOfIds(); id++)
00415           {
00416           med_int ptid = subpts->GetId(id);
00417           if(pts.find(ptid) != pts.end())
00418             {
00419             pts.insert(ptid);
00420             ids->InsertNextId(ptid);
00421             }
00422           }
00423         }
00424       subpts->Delete();
00425       }
00426     }//end poygon
00427   else if (this->GetConnectivity()==MED_NODAL ||
00428            vtkMedUtilities::GetDimension(this->GetEntity().GeometryType)<1)
00429     {
00430     int npts = 0;
00431     if(this->GetEntity().EntityType == MED_STRUCT_ELEMENT)
00432       {
00433       if(this->StructElement != NULL)
00434         {
00435         npts = this->StructElement->GetConnectivitySize();
00436         }
00437       }
00438     else
00439       {
00440       npts = vtkMedUtilities::GetNumberOfPoint(this->GetEntity().GeometryType);
00441       }
00442     vtkMedIntArray* conn = this->GetConnectivityArray();
00443     for (int i = 0; i<npts; i++)
00444       {
00445       vtkIdType ptid = conn->GetValue(npts*index+i)-1;
00446       ids->InsertNextId(ptid);
00447       }
00448     }//end nodal case
00449   else
00450     {
00451     vtkIdList* subpts=vtkIdList::New();
00452     int nsub=vtkMedUtilities::GetNumberOfSubEntity(
00453         this->GetEntity().GeometryType);
00454     vtkMedUnstructuredGrid* ugrid =
00455         vtkMedUnstructuredGrid::SafeDownCast(this->ParentGrid);
00456     if (!ugrid)
00457       {
00458       vtkErrorMacro(
00459         "MED_DESCENDING connectivity is only supported on unstructured grids");
00460       return;
00461       }
00462     vtkMedIntArray* conn=this->GetConnectivityArray();
00463     ids->SetNumberOfIds(vtkMedUtilities::GetNumberOfPoint(
00464         this->GetEntity().GeometryType));
00465     for (int sub = 0; sub<nsub; sub++)
00466       {
00467       med_int subid = conn->GetValue(nsub*index+sub)-1;
00468       bool invert = false;
00469       if(subid < 0)
00470         {
00471         subid = -subid;
00472         invert = true;
00473         }
00474 
00475       vtkMedEntity subentity;
00476       subentity.GeometryType = vtkMedUtilities::GetSubGeometry(
00477           this->GetEntity().GeometryType, sub);
00478       subentity.EntityType = vtkMedUtilities::GetSubType(
00479           this->GetEntity().EntityType);
00480       vtkMedEntityArray* subarray = ugrid->GetEntityArray(subentity);
00481       if(subarray == NULL)
00482         {
00483         subentity.EntityType = MED_CELL;
00484         subarray = ugrid->GetEntityArray(subentity);
00485         }
00486       if(subarray == NULL)
00487         {
00488         vtkDebugMacro( << "Missing sub entity array " << subentity.GeometryType);
00489         this->Valid = false;
00490         break;
00491         }
00492       subarray->GetCellVertices(subid, subpts);
00493       vtkMedUtilities::ProjectConnectivity(this->GetEntity().GeometryType, ids, subpts,
00494           sub, invert);
00495       }
00496     subpts->Delete();
00497     }
00498 }
00499 
00500 void  vtkMedEntityArray::LoadConnectivity()
00501 {
00502   if(this->IsConnectivityLoaded())
00503     return;
00504 
00505   this->GetParentGrid()->GetParentMesh()->GetParentFile()->GetMedDriver()
00506       ->LoadConnectivity(this);
00507 }
00508 
00509 void  vtkMedEntityArray::SetVariableAttributeValues(
00510     vtkMedVariableAttribute* varatt, vtkAbstractArray* value)
00511 {
00512   this->VariableAttributeValue[varatt] = value;
00513 }
00514 
00515 vtkAbstractArray* vtkMedEntityArray::GetVariableAttributeValue(
00516     vtkMedVariableAttribute* varatt)
00517 {
00518   if(this->VariableAttributeValue.find(varatt)
00519     == this->VariableAttributeValue.end())
00520     return NULL;
00521 
00522   return this->VariableAttributeValue[varatt];
00523 }
00524 
00525 void vtkMedEntityArray::PrintSelf(ostream& os, vtkIndent indent)
00526 {
00527   this->Superclass::PrintSelf(os, indent);
00528   PRINT_IVAR(os, indent, NumberOfEntity)
00529   PRINT_IVAR(os, indent, Connectivity)
00530   PRINT_IVAR(os, indent, InitialGlobalId)
00531 }