1 // Copyright (C) 2010-2012 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 = 0;
189 if(this->Entity.GeometryType == MED_POLYHEDRON || this->Entity.GeometryType == MED_POLYGON)
191 if(!this->NodeIndex || !this->FaceIndex)
193 for(med_int i = 0; i < this->NumberOfEntity; i++ )
195 med_int start = this->FaceIndex->GetValue(i)-1;
196 med_int end = this->FaceIndex->GetValue(i+1)-1;
197 for(med_int fi = start ; fi < end; fi++ )
199 med_int fstart = this->NodeIndex->GetValue(fi)-1;
200 med_int fend = this->NodeIndex->GetValue(fi+1)-1;
201 connSize += (fend-fstart);
206 connSize = this->NumberOfEntity *
207 vtkMedUtilities::GetNumberOfPoint(this->Entity.GeometryType);
209 return connSize == this->ConnectivityArray->GetNumberOfTuples();
211 else if (this->Connectivity == MED_NODAL && this->Entity.EntityType == MED_STRUCT_ELEMENT)
213 if(this->StructElement == NULL)
216 vtkIdType connSize = this->NumberOfEntity
217 * this->StructElement->GetConnectivitySize();
219 return connSize == this->ConnectivityArray->GetNumberOfTuples();
223 vtkIdType connSize = this->NumberOfEntity
224 * vtkMedUtilities::GetNumberOfSubEntity(this->Entity.GeometryType);
226 return connSize == this->ConnectivityArray->GetNumberOfTuples();
230 int vtkMedEntityArray::IsFamilyIdsLoaded()
232 return this->FamilyIdStatus != vtkMedEntityArray::FAMILY_ID_NOT_LOADED;;
235 int vtkMedEntityArray::IsGlobalIdsLoaded()
237 return this->GlobalIds != NULL && this->GlobalIds->GetNumberOfTuples()
238 == this->NumberOfEntity;
241 void vtkMedEntityArray::GetCellVertices(vtkIdType index, vtkIdList* ids)
245 if(this->Entity.EntityType == MED_NODE)
247 ids->InsertNextId(index);
251 if( this->Entity.EntityType != MED_CELL &&
252 this->Entity.EntityType != MED_DESCENDING_FACE &&
253 this->Entity.EntityType != MED_DESCENDING_EDGE &&
254 this->Entity.EntityType != MED_STRUCT_ELEMENT)
256 vtkErrorMacro("This reader is not compatible with those entities (yet)...");
260 if(vtkMedUnstructuredGrid::SafeDownCast(this->ParentGrid) == NULL)
262 // this is a structured grid, connectivity is implicit...
264 if(this->Entity.GeometryType == MED_POINT1)
266 // degenerate case if there is only one point
267 ids->InsertNextId(0);
270 if(this->Entity.GeometryType == MED_SEG2)
273 ids->InsertNextId(index);
274 ids->InsertNextId(index+1);
277 vtkMedRegularGrid* vtkrgrid = vtkMedRegularGrid::SafeDownCast(
278 this->GetParentGrid());
279 vtkMedCurvilinearGrid* vtkcgrid = vtkMedCurvilinearGrid::SafeDownCast(
280 this->GetParentGrid());
281 vtkIdType xncell = 0;
282 vtkIdType yncell = 0;
283 vtkIdType zncell = 0;
289 xncell = vtkrgrid->GetAxisSize(0)-1;
290 yncell = vtkrgrid->GetAxisSize(1)-1;
291 zncell = vtkrgrid->GetAxisSize(2)-1;
292 xnpts = vtkrgrid->GetAxisSize(0);
293 ynpts = vtkrgrid->GetAxisSize(1);
294 znpts = vtkrgrid->GetAxisSize(2);
298 xncell = vtkcgrid->GetAxisSize(0)-1;
299 yncell = vtkcgrid->GetAxisSize(1)-1;
300 zncell = vtkcgrid->GetAxisSize(2)-1;
301 xnpts = vtkcgrid->GetAxisSize(0);
302 ynpts = vtkcgrid->GetAxisSize(1);
303 znpts = vtkcgrid->GetAxisSize(2);
305 vtkIdType xindex = index % xncell;
309 vtkIdType yindex = index / xncell;
311 if(this->Entity.GeometryType == MED_QUAD4)
315 ids->InsertNextId(xindex + yindex*xnpts);
316 ids->InsertNextId(xindex + 1 + yindex*xnpts);
317 ids->InsertNextId(xindex + yindex*xnpts);
318 ids->InsertNextId(xindex + 1 + (yindex + 1)*xnpts);
325 vtkIdType zindex = index / (xncell*yncell);
327 if(this->Entity.GeometryType == MED_HEXA8)
330 ids->InsertNextId(xindex + (yindex )*xnpts + (zindex )*xnpts*ynpts);
331 ids->InsertNextId(xindex+1 + (yindex )*xnpts + (zindex )*xnpts*ynpts);
332 ids->InsertNextId(xindex + (yindex+1)*xnpts + (zindex )*xnpts*ynpts);
333 ids->InsertNextId(xindex+1 + (yindex+1)*xnpts + (zindex )*xnpts*ynpts);
334 ids->InsertNextId(xindex + (yindex )*xnpts + (zindex+1)*xnpts*ynpts);
335 ids->InsertNextId(xindex+1 + (yindex )*xnpts + (zindex+1)*xnpts*ynpts);
336 ids->InsertNextId(xindex + (yindex+1)*xnpts + (zindex+1)*xnpts*ynpts);
337 ids->InsertNextId(xindex+1 + (yindex+1)*xnpts + (zindex+1)*xnpts*ynpts);
343 this->LoadConnectivity();
345 if (this->GetEntity().GeometryType==MED_POLYHEDRON)
347 vtkMedIntArray* conn = this->GetConnectivityArray();
348 vtkMedIntArray* faceIndex = this->GetFaceIndex();
349 vtkMedIntArray* nodeIndex = this->GetNodeIndex();
350 med_int start = faceIndex->GetValue(index)-1;
351 med_int end = faceIndex->GetValue(index+1)-1;
352 // the use of a set loses the order, but VTK do not support this order anyway.
353 if (this->GetConnectivity()==MED_NODAL)
355 for (int ff = start; ff<end; ff++)
357 med_int fstart = nodeIndex->GetValue(ff)-1;
358 med_int fend = nodeIndex->GetValue(ff+1)-1;
359 for (int pt = fstart; pt<fend; pt++)
361 med_int ptid = conn->GetValue(pt)-1;
362 ids->InsertNextId(ptid);
366 else // MED_DESCENDING
368 vtkMedUnstructuredGrid* ugrid =
369 vtkMedUnstructuredGrid::SafeDownCast(this->ParentGrid);
373 "MED_DESCENDING connectivity is only supported on unstructured grids");
377 vtkIdList* subIds = vtkIdList::New();
378 for (int ff = start; ff<end; ff++)
380 med_int fid = conn->GetValue(ff)-1;
382 entity.GeometryType = (med_geometry_type) NodeIndex->GetValue(ff);
383 entity.EntityType = MED_DESCENDING_FACE;
384 vtkMedEntityArray* subarray = ugrid->GetEntityArray(entity);
385 subarray->GetCellVertices(fid, subIds);
386 for (int id = 0; id<subIds->GetNumberOfIds(); id++)
388 med_int ptid = subIds->GetId(id);
389 if(pts.find(ptid) == pts.end())
391 ids->InsertNextId(ptid);
399 else if (this->GetEntity().GeometryType==MED_POLYGON)
401 vtkMedIntArray* conn = this->GetConnectivityArray();
402 vtkMedIntArray* nids = this->GetFaceIndex();
403 med_int start = nids->GetValue(index)-1;
404 med_int end = nids->GetValue(index+1)-1;
405 if (this->GetConnectivity()==MED_NODAL)
407 for (int pt = start; pt<end; pt++)
409 ids->InsertNextId(conn->GetValue(pt)-1);
412 else // MED_DESCENDING
414 vtkIdList* subpts=vtkIdList::New();
415 vtkMedUnstructuredGrid* ugrid =
416 vtkMedUnstructuredGrid::SafeDownCast(this->ParentGrid);
419 vtkErrorMacro("MED_DESCENDING connectivity is only "
420 << "supported on unstructured grids");
424 for (int sub = start; sub<end; sub++)
426 med_int subid = conn->GetValue(sub)-1;
427 vtkMedEntity subentity;
428 subentity.GeometryType = MED_SEG2;
429 subentity.EntityType = MED_DESCENDING_EDGE;
430 vtkMedEntityArray* subarray = ugrid->GetEntityArray(subentity);
431 subarray->GetCellVertices(subid, subpts);
432 for(int id=0; id<subpts->GetNumberOfIds(); id++)
434 med_int ptid = subpts->GetId(id);
435 if(pts.find(ptid) != pts.end())
438 ids->InsertNextId(ptid);
445 else if (this->GetConnectivity()==MED_NODAL ||
446 vtkMedUtilities::GetDimension(this->GetEntity().GeometryType)<1)
449 if(this->GetEntity().EntityType == MED_STRUCT_ELEMENT)
451 if(this->StructElement != NULL)
453 npts = this->StructElement->GetConnectivitySize();
458 npts = vtkMedUtilities::GetNumberOfPoint(this->GetEntity().GeometryType);
460 vtkMedIntArray* conn = this->GetConnectivityArray();
461 for (int i = 0; i<npts; i++)
463 vtkIdType ptid = conn->GetValue(npts*index+i)-1;
464 ids->InsertNextId(ptid);
469 vtkIdList* subpts=vtkIdList::New();
470 int nsub=vtkMedUtilities::GetNumberOfSubEntity(
471 this->GetEntity().GeometryType);
472 vtkMedUnstructuredGrid* ugrid =
473 vtkMedUnstructuredGrid::SafeDownCast(this->ParentGrid);
477 "MED_DESCENDING connectivity is only supported on unstructured grids");
480 vtkMedIntArray* conn=this->GetConnectivityArray();
481 ids->SetNumberOfIds(vtkMedUtilities::GetNumberOfPoint(
482 this->GetEntity().GeometryType));
483 for (int sub = 0; sub<nsub; sub++)
485 med_int subid = conn->GetValue(nsub*index+sub)-1;
493 vtkMedEntity subentity;
494 subentity.GeometryType = vtkMedUtilities::GetSubGeometry(
495 this->GetEntity().GeometryType, sub);
496 subentity.EntityType = vtkMedUtilities::GetSubType(
497 this->GetEntity().EntityType);
498 vtkMedEntityArray* subarray = ugrid->GetEntityArray(subentity);
501 subentity.EntityType = MED_CELL;
502 subarray = ugrid->GetEntityArray(subentity);
506 vtkDebugMacro( << "Missing sub entity array " << subentity.GeometryType);
510 subarray->GetCellVertices(subid, subpts);
511 vtkMedUtilities::ProjectConnectivity(this->GetEntity().GeometryType, ids, subpts,
518 void vtkMedEntityArray::LoadConnectivity()
520 if(this->IsConnectivityLoaded())
523 this->GetParentGrid()->GetParentMesh()->GetParentFile()->GetMedDriver()
524 ->LoadConnectivity(this);
527 void vtkMedEntityArray::SetVariableAttributeValues(
528 vtkMedVariableAttribute* varatt, vtkAbstractArray* value)
530 this->VariableAttributeValue[varatt] = value;
533 vtkAbstractArray* vtkMedEntityArray::GetVariableAttributeValue(
534 vtkMedVariableAttribute* varatt)
536 if(this->VariableAttributeValue.find(varatt)
537 == this->VariableAttributeValue.end())
540 return this->VariableAttributeValue[varatt];
543 void vtkMedEntityArray::PrintSelf(ostream& os, vtkIndent indent)
545 this->Superclass::PrintSelf(os, indent);
546 PRINT_IVAR(os, indent, NumberOfEntity)
547 PRINT_IVAR(os, indent, Connectivity)
548 PRINT_IVAR(os, indent, InitialGlobalId)