1 // Copyright (C) 2010-2011 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "vtkMedEntityArray.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkMedIntArray.h"
24 #include "vtkMedUtilities.h"
25 #include "vtkMedFamily.h"
26 #include "vtkMedFamilyOnEntity.h"
27 #include "vtkMedMesh.h"
28 #include "vtkMedGrid.h"
29 #include "vtkMedUnstructuredGrid.h"
30 #include "vtkMedRegularGrid.h"
31 #include "vtkMedCurvilinearGrid.h"
32 #include "vtkMedFile.h"
33 #include "vtkMedDriver.h"
34 #include "vtkMedStructElement.h"
36 #include "vtkIdList.h"
41 vtkCxxSetObjectVectorMacro(vtkMedEntityArray, FamilyOnEntity, vtkMedFamilyOnEntity);
42 vtkCxxGetObjectVectorMacro(vtkMedEntityArray, FamilyOnEntity, vtkMedFamilyOnEntity);
43 vtkCxxSetObjectMacro(vtkMedEntityArray,FamilyIds,vtkMedIntArray);
44 vtkCxxSetObjectMacro(vtkMedEntityArray,GlobalIds,vtkMedIntArray);
45 vtkCxxSetObjectMacro(vtkMedEntityArray,ConnectivityArray,vtkMedIntArray);
46 vtkCxxSetObjectMacro(vtkMedEntityArray,FaceIndex,vtkMedIntArray);
47 vtkCxxSetObjectMacro(vtkMedEntityArray,NodeIndex,vtkMedIntArray);
49 vtkCxxSetObjectMacro(vtkMedEntityArray,ParentGrid,vtkMedGrid);
50 vtkCxxSetObjectMacro(vtkMedEntityArray,StructElement,vtkMedStructElement);
52 // vtkCxxRevisionMacro(vtkMedEntityArray, "$Revision$");
53 vtkStandardNewMacro(vtkMedEntityArray);
55 vtkMedEntityArray::vtkMedEntityArray()
57 this->NumberOfEntity = 0;
58 this->Connectivity = MED_NODAL;
59 this->FamilyIds = NULL;
60 this->GlobalIds = NULL;
61 this->ConnectivityArray = NULL;
62 this->FaceIndex = NULL;
63 this->NodeIndex = NULL;
64 this->InitialGlobalId = 0;
65 this->FamilyOnEntity = new vtkObjectVector<vtkMedFamilyOnEntity> ();
66 this->FamilyIdStatus = vtkMedEntityArray::FAMILY_ID_NOT_LOADED;
67 this->ParentGrid = NULL;
68 this->StructElement = NULL;
69 //this->Filter = NULL;
72 vtkMedEntityArray::~vtkMedEntityArray()
74 this->SetFamilyIds(NULL);
75 this->SetGlobalIds(NULL);
76 this->SetConnectivityArray(NULL);
77 this->SetFaceIndex(NULL);
78 this->SetNodeIndex(NULL);
79 delete this->FamilyOnEntity;
80 this->SetParentGrid(NULL);
81 this->SetStructElement(NULL);
82 //this->SetFilter(NULL);
85 void vtkMedEntityArray::Initialize()
87 this->SetFamilyIds(NULL);
88 this->SetGlobalIds(NULL);
89 this->SetConnectivityArray(NULL);
90 this->SetFaceIndex(NULL);
91 this->SetNodeIndex(NULL);
92 this->FamilyOnEntity->clear();
93 this->FamilyIdStatus = FAMILY_ID_NOT_LOADED;
96 void vtkMedEntityArray::ComputeFamilies()
98 this->FamilyOnEntity->clear();
99 vtkMedMesh* mesh = this->ParentGrid->GetParentMesh();
101 if(this->FamilyIds == NULL)
103 vtkMedFamilyOnEntity* foe = vtkMedFamilyOnEntity::New();
104 foe->SetParentGrid(this->ParentGrid);
105 this->AppendFamilyOnEntity(foe);
107 if(this->GetEntity().EntityType != MED_NODE)
109 foe->SetFamily(mesh->GetOrCreateCellFamilyById(0));
113 foe->SetFamily(mesh->GetOrCreatePointFamilyById(0));
115 foe->SetEntityArray(this);
116 this->FamilyIdStatus = vtkMedEntityArray::FAMILY_ID_IMPLICIT;
120 this->FamilyIdStatus = vtkMedEntityArray::FAMILY_ID_EXPLICIT;
123 for (vtkIdType index = 0; index < this->FamilyIds->GetNumberOfTuples(); index++)
125 med_int id = this->FamilyIds->GetValue(index);
129 for (set<med_int>::iterator it = idset.begin(); it != idset.end(); it++)
131 vtkMedFamilyOnEntity* foe = vtkMedFamilyOnEntity::New();
132 foe->SetParentGrid(this->ParentGrid);
133 this->AppendFamilyOnEntity(foe);
135 if(this->GetEntity().EntityType != MED_NODE)
137 foe->SetFamily(mesh->GetOrCreateCellFamilyById(*it));
141 foe->SetFamily(mesh->GetOrCreatePointFamilyById(*it));
143 foe->SetEntityArray(this);
147 med_int vtkMedEntityArray::GetFamilyId(med_int id)
149 if(this->FamilyIdStatus == FAMILY_ID_IMPLICIT)
151 if(this->FamilyIdStatus == FAMILY_ID_NOT_LOADED)
153 vtkErrorMacro("You have to load family ids before asking for it!");
155 return this->FamilyIds->GetValue(id);
158 int vtkMedEntityArray::HasFamily(vtkMedFamily* family)
160 for (int i = 0; i < this->FamilyOnEntity->size(); i++)
162 vtkMedFamilyOnEntity* foe = this->FamilyOnEntity->at(i);
163 if(foe->GetFamily() == family)
169 int vtkMedEntityArray::IsConnectivityLoaded()
171 // Entity Arrays representing something else than cells
172 // have no connectivity
174 if(vtkMedUnstructuredGrid::SafeDownCast(this->GetParentGrid()) == NULL)
177 if( this->Entity.EntityType != MED_CELL &&
178 this->Entity.EntityType != MED_DESCENDING_FACE &&
179 this->Entity.EntityType != MED_DESCENDING_EDGE &&
180 this->Entity.EntityType != MED_STRUCT_ELEMENT)
183 if(this->ConnectivityArray == NULL)
186 if(this->Connectivity == MED_NODAL && this->Entity.EntityType != MED_STRUCT_ELEMENT)
188 vtkIdType connSize = this->NumberOfEntity
189 * vtkMedUtilities::GetNumberOfPoint(this->Entity.GeometryType);
191 return connSize == this->ConnectivityArray->GetNumberOfTuples();
193 else if (this->Connectivity == MED_NODAL && this->Entity.EntityType == MED_STRUCT_ELEMENT)
195 if(this->StructElement == NULL)
198 vtkIdType connSize = this->NumberOfEntity
199 * this->StructElement->GetConnectivitySize();
201 return connSize == this->ConnectivityArray->GetNumberOfTuples();
205 vtkIdType connSize = this->NumberOfEntity
206 * vtkMedUtilities::GetNumberOfSubEntity(this->Entity.GeometryType);
208 return connSize == this->ConnectivityArray->GetNumberOfTuples();
212 int vtkMedEntityArray::IsFamilyIdsLoaded()
214 return this->FamilyIdStatus != vtkMedEntityArray::FAMILY_ID_NOT_LOADED;;
217 int vtkMedEntityArray::IsGlobalIdsLoaded()
219 return this->GlobalIds != NULL && this->GlobalIds->GetNumberOfTuples()
220 == this->NumberOfEntity;
223 void vtkMedEntityArray::GetCellVertices(vtkIdType index, vtkIdList* ids)
227 if(this->Entity.EntityType == MED_NODE)
229 ids->InsertNextId(index);
233 if( this->Entity.EntityType != MED_CELL &&
234 this->Entity.EntityType != MED_DESCENDING_FACE &&
235 this->Entity.EntityType != MED_DESCENDING_EDGE &&
236 this->Entity.EntityType != MED_STRUCT_ELEMENT)
238 vtkErrorMacro("This reader is not compatible with those entities (yet)...");
242 if(vtkMedUnstructuredGrid::SafeDownCast(this->ParentGrid) == NULL)
244 // this is a structured grid, connectivity is implicit...
246 if(this->Entity.GeometryType == MED_POINT1)
248 // degenerate case if there is only one point
249 ids->InsertNextId(0);
252 if(this->Entity.GeometryType == MED_SEG2)
255 ids->InsertNextId(index);
256 ids->InsertNextId(index+1);
259 vtkMedRegularGrid* vtkrgrid = vtkMedRegularGrid::SafeDownCast(
260 this->GetParentGrid());
261 vtkMedCurvilinearGrid* vtkcgrid = vtkMedCurvilinearGrid::SafeDownCast(
262 this->GetParentGrid());
263 vtkIdType xncell = 0;
264 vtkIdType yncell = 0;
265 vtkIdType zncell = 0;
271 xncell = vtkrgrid->GetAxisSize(0)-1;
272 yncell = vtkrgrid->GetAxisSize(1)-1;
273 zncell = vtkrgrid->GetAxisSize(2)-1;
274 xnpts = vtkrgrid->GetAxisSize(0);
275 ynpts = vtkrgrid->GetAxisSize(1);
276 znpts = vtkrgrid->GetAxisSize(2);
280 xncell = vtkcgrid->GetAxisSize(0)-1;
281 yncell = vtkcgrid->GetAxisSize(1)-1;
282 zncell = vtkcgrid->GetAxisSize(2)-1;
283 xnpts = vtkcgrid->GetAxisSize(0);
284 ynpts = vtkcgrid->GetAxisSize(1);
285 znpts = vtkcgrid->GetAxisSize(2);
287 vtkIdType xindex = index % xncell;
291 vtkIdType yindex = index / xncell;
293 if(this->Entity.GeometryType == MED_QUAD4)
297 ids->InsertNextId(xindex + yindex*xnpts);
298 ids->InsertNextId(xindex + 1 + yindex*xnpts);
299 ids->InsertNextId(xindex + yindex*xnpts);
300 ids->InsertNextId(xindex + 1 + (yindex + 1)*xnpts);
307 vtkIdType zindex = index / (xncell*yncell);
309 if(this->Entity.GeometryType == MED_HEXA8)
312 ids->InsertNextId(xindex + (yindex )*xnpts + (zindex )*xnpts*ynpts);
313 ids->InsertNextId(xindex+1 + (yindex )*xnpts + (zindex )*xnpts*ynpts);
314 ids->InsertNextId(xindex + (yindex+1)*xnpts + (zindex )*xnpts*ynpts);
315 ids->InsertNextId(xindex+1 + (yindex+1)*xnpts + (zindex )*xnpts*ynpts);
316 ids->InsertNextId(xindex + (yindex )*xnpts + (zindex+1)*xnpts*ynpts);
317 ids->InsertNextId(xindex+1 + (yindex )*xnpts + (zindex+1)*xnpts*ynpts);
318 ids->InsertNextId(xindex + (yindex+1)*xnpts + (zindex+1)*xnpts*ynpts);
319 ids->InsertNextId(xindex+1 + (yindex+1)*xnpts + (zindex+1)*xnpts*ynpts);
325 this->LoadConnectivity();
327 if (this->GetEntity().GeometryType==MED_POLYHEDRON)
329 vtkMedIntArray* conn = this->GetConnectivityArray();
330 vtkMedIntArray* faceIndex = this->GetFaceIndex();
331 vtkMedIntArray* nodeIndex = this->GetNodeIndex();
332 med_int start = faceIndex->GetValue(index)-1;
333 med_int end = faceIndex->GetValue(index+1)-1;
334 // the use of a set loses the order, but VTK do not support this order anyway.
335 if (this->GetConnectivity()==MED_NODAL)
337 for (int ff = start; ff<end; ff++)
339 med_int fstart = nodeIndex->GetValue(ff)-1;
340 med_int fend = nodeIndex->GetValue(ff+1)-1;
341 for (int pt = fstart; pt<fend; pt++)
343 med_int ptid = conn->GetValue(pt)-1;
344 ids->InsertNextId(ptid);
348 else // MED_DESCENDING
350 vtkMedUnstructuredGrid* ugrid =
351 vtkMedUnstructuredGrid::SafeDownCast(this->ParentGrid);
355 "MED_DESCENDING connectivity is only supported on unstructured grids");
359 vtkIdList* subIds = vtkIdList::New();
360 for (int ff = start; ff<end; ff++)
362 med_int fid = conn->GetValue(ff)-1;
364 entity.GeometryType = (med_geometry_type) NodeIndex->GetValue(ff);
365 entity.EntityType = MED_DESCENDING_FACE;
366 vtkMedEntityArray* subarray = ugrid->GetEntityArray(entity);
367 subarray->GetCellVertices(fid, subIds);
368 for (int id = 0; id<subIds->GetNumberOfIds(); id++)
370 med_int ptid = subIds->GetId(id);
371 if(pts.find(ptid) == pts.end())
373 ids->InsertNextId(ptid);
381 else if (this->GetEntity().GeometryType==MED_POLYGON)
383 vtkMedIntArray* conn = this->GetConnectivityArray();
384 vtkMedIntArray* nids = this->GetFaceIndex();
385 med_int start = nids->GetValue(index)-1;
386 med_int end = nids->GetValue(index+1)-1;
387 if (this->GetConnectivity()==MED_NODAL)
389 for (int pt = start; pt<end; pt++)
391 ids->InsertNextId(conn->GetValue(pt)-1);
394 else // MED_DESCENDING
396 vtkIdList* subpts=vtkIdList::New();
397 vtkMedUnstructuredGrid* ugrid =
398 vtkMedUnstructuredGrid::SafeDownCast(this->ParentGrid);
401 vtkErrorMacro("MED_DESCENDING connectivity is only "
402 << "supported on unstructured grids");
406 for (int sub = start; sub<end; sub++)
408 med_int subid = conn->GetValue(sub)-1;
409 vtkMedEntity subentity;
410 subentity.GeometryType = MED_SEG2;
411 subentity.EntityType = MED_DESCENDING_EDGE;
412 vtkMedEntityArray* subarray = ugrid->GetEntityArray(subentity);
413 subarray->GetCellVertices(subid, subpts);
414 for(int id=0; id<subpts->GetNumberOfIds(); id++)
416 med_int ptid = subpts->GetId(id);
417 if(pts.find(ptid) != pts.end())
420 ids->InsertNextId(ptid);
427 else if (this->GetConnectivity()==MED_NODAL ||
428 vtkMedUtilities::GetDimension(this->GetEntity().GeometryType)<1)
431 if(this->GetEntity().EntityType == MED_STRUCT_ELEMENT)
433 if(this->StructElement != NULL)
435 npts = this->StructElement->GetConnectivitySize();
440 npts = vtkMedUtilities::GetNumberOfPoint(this->GetEntity().GeometryType);
442 vtkMedIntArray* conn = this->GetConnectivityArray();
443 for (int i = 0; i<npts; i++)
445 vtkIdType ptid = conn->GetValue(npts*index+i)-1;
446 ids->InsertNextId(ptid);
451 vtkIdList* subpts=vtkIdList::New();
452 int nsub=vtkMedUtilities::GetNumberOfSubEntity(
453 this->GetEntity().GeometryType);
454 vtkMedUnstructuredGrid* ugrid =
455 vtkMedUnstructuredGrid::SafeDownCast(this->ParentGrid);
459 "MED_DESCENDING connectivity is only supported on unstructured grids");
462 vtkMedIntArray* conn=this->GetConnectivityArray();
463 ids->SetNumberOfIds(vtkMedUtilities::GetNumberOfPoint(
464 this->GetEntity().GeometryType));
465 for (int sub = 0; sub<nsub; sub++)
467 med_int subid = conn->GetValue(nsub*index+sub)-1;
475 vtkMedEntity subentity;
476 subentity.GeometryType = vtkMedUtilities::GetSubGeometry(
477 this->GetEntity().GeometryType, sub);
478 subentity.EntityType = vtkMedUtilities::GetSubType(
479 this->GetEntity().EntityType);
480 vtkMedEntityArray* subarray = ugrid->GetEntityArray(subentity);
483 subentity.EntityType = MED_CELL;
484 subarray = ugrid->GetEntityArray(subentity);
488 vtkDebugMacro( << "Missing sub entity array " << subentity.GeometryType);
492 subarray->GetCellVertices(subid, subpts);
493 vtkMedUtilities::ProjectConnectivity(this->GetEntity().GeometryType, ids, subpts,
500 void vtkMedEntityArray::LoadConnectivity()
502 if(this->IsConnectivityLoaded())
505 this->GetParentGrid()->GetParentMesh()->GetParentFile()->GetMedDriver()
506 ->LoadConnectivity(this);
509 void vtkMedEntityArray::SetVariableAttributeValues(
510 vtkMedVariableAttribute* varatt, vtkAbstractArray* value)
512 this->VariableAttributeValue[varatt] = value;
515 vtkAbstractArray* vtkMedEntityArray::GetVariableAttributeValue(
516 vtkMedVariableAttribute* varatt)
518 if(this->VariableAttributeValue.find(varatt)
519 == this->VariableAttributeValue.end())
522 return this->VariableAttributeValue[varatt];
525 void vtkMedEntityArray::PrintSelf(ostream& os, vtkIndent indent)
527 this->Superclass::PrintSelf(os, indent);
528 PRINT_IVAR(os, indent, NumberOfEntity)
529 PRINT_IVAR(os, indent, Connectivity)
530 PRINT_IVAR(os, indent, InitialGlobalId)