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 "vtkMedUtilities.h"
22 #include "vtkMedMesh.h"
23 #include "vtkMedFamily.h"
24 #include "vtkMedGroup.h"
25 #include "vtkMedFamilyOnEntityOnProfile.h"
26 #include "vtkMedFamilyOnEntity.h"
27 #include "vtkMedEntityArray.h"
28 #include "vtkMedIntArray.h"
29 #include "vtkMedGrid.h"
31 #include "vtkObjectFactory.h"
32 #include "vtkInformation.h"
33 #include "vtkDoubleArray.h"
34 #include "vtkIntArray.h"
35 #include "vtkLongLongArray.h"
36 #include "vtkLongArray.h"
37 #include "vtkIdTypeArray.h"
38 #include "vtkCellType.h"
39 #include "vtkIdList.h"
40 #include "vtkMutableDirectedGraph.h"
41 #include "vtkStringArray.h"
42 #include "vtkDataSetAttributes.h"
43 #include "vtkOutEdgeIterator.h"
44 #include "vtkInformationIntegerKey.h"
45 #include "vtkInformationStringVectorKey.h"
46 #include "vtkInformationObjectBaseKey.h"
50 char vtkMedUtilities::Separator='/';
52 const char* vtkMedUtilities::NoGroupName="No Group";
53 const char* vtkMedUtilities::OnPointName="OnPoint";
54 const char* vtkMedUtilities::OnCellName="OnCell";
56 const int MED_TRIA_CHILD_TO_PARENT_INDEX[3][3]=
57 {{0, 1, 3}, {1, 2, 4}, {2, 0, 5}};
59 const int MED_QUAD_CHILD_TO_PARENT_INDEX[4][3]=
60 {{0, 1, 4}, {1, 2, 5}, {2, 3, 6}, {3, 0, 7}};
62 const int MED_TETRA_CHILD_TO_PARENT_INDEX[4][6]=
68 const int MED_HEXA_CHILD_TO_PARENT_INDEX[6][8]=
69 {{0, 1, 2, 3, 8, 9, 10, 11},
70 {4, 7, 6, 5, 15, 14, 13, 12},
71 {0, 4, 5, 1, 16, 12, 17, 8},
72 {1, 5, 6, 2, 17, 13, 18, 9},
73 {2, 6, 7, 3, 18, 14, 19, 10},
74 {3, 7, 4, 0, 19, 15, 16, 11}};
76 const int MED_PYRA_CHILD_TO_PARENT_INDEX[5][8]=
77 {{0, 1, 2, 3, 5, 6, 7, 8},
78 {0, 4, 1, -1, 9, 10, 5, -1},
79 {1, 4, 2, -1, 10, 11, 6, -1},
80 {2, 4, 3, -1, 11, 12, 7, -1},
81 {3, 4, 0, -1, 12, 9, 8, -1}};
83 const int MED_PENTA_CHILD_TO_PARENT_INDEX[5][8]=
84 {{0, 1, 2, -1, 6, 7, 8, -1},
85 {3, 5, 4, -1, 11, 10, 9, -1},
86 {0, 3, 4, 1, 12, 9, 13, 6},
87 {1, 4, 5, 2, 13, 10, 14, 7},
88 {2, 5, 3, 0, 14, 11, 12, 8}};
90 vtkInformationKeyMacro(vtkMedUtilities, ELNO, Integer);
91 vtkInformationKeyMacro(vtkMedUtilities, ELGA, Integer);
92 vtkInformationKeyMacro(vtkMedUtilities, BLOCK_NAME, StringVector);
93 vtkInformationKeyMacro(vtkMedUtilities, STRUCT_ELEMENT, ObjectBase);
94 vtkInformationKeyMacro(vtkMedUtilities, STRUCT_ELEMENT_INDEX, Integer);
96 vtkDataArray* vtkMedUtilities::NewCoordArray()
98 return vtkMedUtilities::NewArray(MED_FLOAT64);
101 vtkDataArray* vtkMedUtilities::NewArray(med_field_type type)
106 if(sizeof(double)==8 && sizeof(med_float)==8)
107 return vtkDoubleArray::New();
108 vtkGenericWarningMacro("double type do not match med_float, aborting")
111 if(sizeof(vtkIdType)==4)
112 return vtkIdTypeArray::New();
114 return vtkIntArray::New();
116 return vtkLongArray::New();
117 vtkGenericWarningMacro("No vtk type matches MED_INT32, aborting")
120 if(sizeof(vtkIdType)==8)
121 return vtkIdTypeArray::New();
123 return vtkLongArray::New();
124 if(sizeof(long long)==8)
125 return vtkLongLongArray::New();
126 vtkGenericWarningMacro("No vtk type matches MED_INT64, aborting")
130 if(sizeof(med_int)==4)
131 return vtkMedUtilities::NewArray(MED_INT32);
132 if(sizeof(med_int)==8)
133 return vtkMedUtilities::NewArray(MED_INT64);
134 vtkGenericWarningMacro("No vtk type matches MED_INT, aborting")
137 vtkGenericWarningMacro("the array type is not known, aborting.")
142 vtkAbstractArray* vtkMedUtilities::NewArray(med_attribute_type type)
146 case MED_ATT_FLOAT64 :
147 if(sizeof(double) == sizeof(med_float))
148 return vtkDoubleArray::New();
149 vtkGenericWarningMacro("double type do not match med_float, aborting");
152 if(sizeof(vtkIdType) == sizeof(med_int))
153 return vtkIdTypeArray::New();
154 if(sizeof(int) == sizeof(med_int))
155 return vtkIntArray::New();
156 if(sizeof(long) == sizeof(med_int))
157 return vtkLongArray::New();
158 if(sizeof(long long) == sizeof(med_int))
159 return vtkLongLongArray::New();
160 vtkGenericWarningMacro("med_int type does not match known VTK type, aborting");
163 return vtkStringArray::New();
168 const char* vtkMedUtilities::GeometryName(med_geometry_type geometry)
201 return "MED_TETRA10";
207 return "MED_PENTA15";
213 return "MED_POLYGON";
215 return "MED_POLYHEDRON";
216 case MED_STRUCT_GEO_INTERNAL:
217 return "MED_STRUCT_GEO_INTERNAL";
219 return "MED_NO_GEOTYPE";
221 return "UNKNOWN_GEOMETRY";
225 const char* vtkMedUtilities::EntityName(med_entity_type type)
231 case MED_DESCENDING_FACE:
232 return "MED_DESCENDING_FACE";
233 case MED_DESCENDING_EDGE:
234 return "MED_DESCENDING_EDGE";
237 case MED_NODE_ELEMENT:
238 return "MED_NODE_ELEMENT";
239 case MED_STRUCT_ELEMENT:
240 return "MED_STRUCT_ELEMENT";
241 case MED_UNDEF_ENTITY_TYPE:
242 return "MED_UNDEF_ENTITY_TYPE";
244 return "UNKNOWN_ENTITY_TYPE ";
248 const char* vtkMedUtilities::ConnectivityName(med_connectivity_mode conn)
255 return "MED_DESCENDING";
257 return "MED_NO_CMODE";
259 return "UNKNOWN_CONNECTIVITY_MODE";
263 const std::string vtkMedUtilities::SimplifyName(const char* medName)
266 bool underscore=false;
268 int l=strlen(medName);
269 for(int cc=0; cc<l; cc++)
276 else if(medName[cc]=='_')
283 if(underscore||space)
293 const std::string vtkMedUtilities::FamilyKey(const char* meshName,
294 int pointOrCell, const char* familyName)
297 sstr<<"FAMILY"<<Separator<<SimplifyName(meshName)<<Separator;
298 if(pointOrCell==OnCell)
299 sstr<<vtkMedUtilities::OnCellName;
301 sstr<<vtkMedUtilities::OnPointName;
302 sstr<<Separator<<SimplifyName(familyName);
306 const std::string vtkMedUtilities::GroupKey(const char* meshName,
307 int pointOrCell, const char* groupName)
310 sstr << "GROUP" << vtkMedUtilities::Separator
311 << vtkMedUtilities::SimplifyName(meshName)
312 << vtkMedUtilities::Separator;
313 if(pointOrCell==OnCell)
314 sstr << vtkMedUtilities::OnCellName;
316 sstr << vtkMedUtilities::OnPointName;
318 sstr << vtkMedUtilities::Separator
319 << vtkMedUtilities::NoGroupName;
321 sstr << vtkMedUtilities::Separator
322 << vtkMedUtilities::SimplifyName(groupName);
327 const std::string vtkMedUtilities::EntityKey(const vtkMedEntity& entity)
330 sstr << "CELL_TYPE" << Separator << EntityName(entity.EntityType)
331 << Separator<<entity.GeometryName;
335 int vtkMedUtilities::GetNumberOfPoint(med_geometry_type geometry)
340 int vtkMedUtilities::GetDimension(med_geometry_type geometry)
345 int vtkMedUtilities::GetVTKCellType(med_geometry_type geometry)
355 return VTK_QUADRATIC_EDGE;
357 return VTK_CUBIC_LINE;
363 return VTK_QUADRATIC_TRIANGLE;
365 return VTK_BIQUADRATIC_TRIANGLE;
367 return VTK_QUADRATIC_QUAD;
369 return VTK_BIQUADRATIC_QUAD;
377 return VTK_HEXAHEDRON;
379 return VTK_QUADRATIC_TETRA;
381 return VTK_HEXAGONAL_PRISM;
383 return VTK_QUADRATIC_PYRAMID;
385 return VTK_QUADRATIC_WEDGE;
387 return VTK_QUADRATIC_HEXAHEDRON;
389 return VTK_TRIQUADRATIC_HEXAHEDRON;
393 return VTK_POLYHEDRON;
395 return VTK_EMPTY_CELL;
397 vtkGenericWarningMacro("No vtk type matches " << geometry << ", aborting")
399 return VTK_EMPTY_CELL;
403 int vtkMedUtilities::MedToVTKIndex(int vtktype, int node)
405 if(vtktype != VTK_TRIQUADRATIC_HEXAHEDRON)
408 static int VTK_TRIQUADRATIC_HEXAHEDRON_MED_TO_VTK_INDEX[27] =
409 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
410 24, 22, 21, 23, 20, 25, 26};
412 return VTK_TRIQUADRATIC_HEXAHEDRON_MED_TO_VTK_INDEX[node % 27] + static_cast<int>(27 * floor((double)node / 27));
415 int vtkMedUtilities::GetNumberOfNodes(med_geometry_type geometry)
466 vtkGenericWarningMacro("No vtk type matches "
467 << vtkMedUtilities::GeometryName(geometry)
473 int vtkMedUtilities::GetNumberOfSubEntity(med_geometry_type geometry)
524 vtkGenericWarningMacro("No vtk type matches "
531 med_entity_type vtkMedUtilities::GetSubType(med_entity_type type)
536 return MED_DESCENDING_FACE;
537 case MED_DESCENDING_FACE:
538 return MED_DESCENDING_EDGE;
539 case MED_DESCENDING_EDGE:
546 med_geometry_type vtkMedUtilities::GetSubGeometry(
547 med_geometry_type geometry, int index)
593 if(index==0||index==1)
600 if(index==0||index==1)
617 int vtkMedUtilities::FormatPolyhedronForVTK(
618 vtkMedFamilyOnEntityOnProfile* foep, vtkIdType index,
621 vtkMedEntityArray* array = foep->GetFamilyOnEntity()->GetEntityArray();
622 vtkMedIntArray* conn = array->GetConnectivityArray();
623 vtkMedIntArray* faceIndex = array->GetFaceIndex();
624 vtkMedIntArray* nodeIndex = array->GetNodeIndex();
625 med_int start = faceIndex->GetValue(index)-1;
626 med_int end = faceIndex->GetValue(index+1)-1;
628 // The format for the Polyhedrons is:
629 //(numCellFaces, numFace0Pts, id1, id2, id3, numFace1Pts,id1, id2, id3, ...)
632 if (array->GetConnectivity()==MED_NODAL)
634 ids->InsertNextId(end-start);
635 for (int ff = start; ff<end; ff++)
637 med_int fstart = nodeIndex->GetValue(ff)-1;
638 med_int fend = nodeIndex->GetValue(ff+1)-1;
639 ids->InsertNextId(fend-fstart);
640 for (med_int pt = fstart; pt<fend; pt++)
642 vtkIdType realIndex = foep->GetVTKPointIndex(conn->GetValue(pt)-1);
645 vtkGenericWarningMacro("this polyhedron is not on this profile");
649 ids->InsertNextId(realIndex);
654 if (array->GetConnectivity()==MED_DESCENDING)
656 ids->InsertNextId(end-start);
657 vtkSmartPointer<vtkIdList> subIds = vtkSmartPointer<vtkIdList>::New();
659 for (int i = 0 ; i<nodeIndex->GetSize(); i++)
662 vtkMedUtilities::GetNumberOfSubEntity(nodeIndex->GetValue(i));
663 ids->InsertNextId(numPoints);
666 entity.EntityType = MED_DESCENDING_FACE;
667 entity.GeometryType = nodeIndex->GetValue(i);
669 vtkMedEntityArray* theFaces =
670 array->GetParentGrid()->GetEntityArray(entity);
672 theFaces->GetCellVertices(conn->GetValue(i)-1, subIds);
674 for (int j = 0 ; j< numPoints; j++)
676 vtkIdType realIndex = foep->GetVTKPointIndex(subIds->GetId(j));
679 vtkGenericWarningMacro("this polyhedron is not on this profile");
682 ids->InsertNextId(realIndex);
689 void vtkMedUtilities::SplitGroupKey(const char* name, vtkstd::string& mesh,
690 vtkstd::string& entity, vtkstd::string& group)
692 vtkstd::string remain;
697 vtkstd::string header="*";
703 vtkstd::string::size_type pos;
704 // First get the header, which must be "GROUP"
705 pos=remain.find_first_of(vtkMedUtilities::Separator);
706 header=remain.substr(0, pos);
707 remain=remain.substr(pos+1, remain.size()-pos-1);
709 // then get the mesh name
710 pos=remain.find_first_of(vtkMedUtilities::Separator);
711 mesh=remain.substr(0, pos);
712 if(mesh=="*"||pos==remain.size()-1)
714 remain=remain.substr(pos+1, remain.size()-pos-1);
716 // then the entity name (OnPoint or OnCell)
717 pos=remain.find_first_of(vtkMedUtilities::Separator);
718 entity=remain.substr(0, pos);
719 if(entity=="*"||pos==remain.size()-1)
723 group=remain.substr(pos+1, remain.size()-pos-1);
726 int vtkMedUtilities::GetParentNodeIndex(med_geometry_type parentGeometry,
727 int subEntityIndex, int subEntityNodeIndex)
729 switch(parentGeometry)
734 return MED_TRIA_CHILD_TO_PARENT_INDEX[subEntityIndex][subEntityNodeIndex];
738 return MED_QUAD_CHILD_TO_PARENT_INDEX[subEntityIndex][subEntityNodeIndex];
741 return MED_TETRA_CHILD_TO_PARENT_INDEX[subEntityIndex][subEntityNodeIndex];
744 return MED_PYRA_CHILD_TO_PARENT_INDEX[subEntityIndex][subEntityNodeIndex];
747 return MED_PENTA_CHILD_TO_PARENT_INDEX[subEntityIndex][subEntityNodeIndex];
751 return MED_HEXA_CHILD_TO_PARENT_INDEX[subEntityIndex][subEntityNodeIndex];
756 void vtkMedUtilities::ProjectConnectivity(med_geometry_type parentGeometry,
757 vtkIdList* parentIds, vtkIdList* subEntityIds, int subEntityIndex, bool invert)
759 for(int subEntityNodeIndex=0; subEntityNodeIndex
760 <subEntityIds->GetNumberOfIds(); subEntityNodeIndex++)
762 int realIndex = subEntityNodeIndex;
764 realIndex = subEntityIds->GetNumberOfIds() - subEntityNodeIndex - 1;
765 parentIds->SetId(GetParentNodeIndex(parentGeometry, subEntityIndex,
766 subEntityNodeIndex), subEntityIds->GetId(realIndex));
770 std::string vtkMedUtilities::GetModeKey(int index, double frequency, int maxindex)
772 std::ostringstream key;
776 int maxdecim = (int)floor(log(1.0*maxindex)/log(10.0));
780 decim = (int)floor(log(1.0*index)/log(10.0));
782 for(int i=decim; i<maxdecim; i++)
788 key<<index<<"] "<<frequency;
792 int vtkMedUtilities::GetModeFromKey(const char* key, int& index,
795 const std::string k(key);
796 size_t index_start=k.find("[");
797 size_t index_end=k.find("]");
798 const string index_string=k.substr(index_start, index_end);
799 stringstream indexsstr;
800 indexsstr<<index_string;
802 const string freq_string=k.substr(index_end+1, string::npos);
803 stringstream freqsstr;
804 freqsstr<<freq_string;
809 vtkMultiBlockDataSet* vtkMedUtilities::GetParent(vtkMultiBlockDataSet* root,
810 vtkStringArray* path)
812 vtkMultiBlockDataSet* output=root;
813 vtkMultiBlockDataSet* parent=output;
814 for(int depth = 0; depth<path->GetNumberOfValues(); depth++)
816 vtkStdString parentName = path->GetValue(depth);
818 for(int blockId=0; blockId<parent->GetNumberOfBlocks(); blockId++)
820 vtkInformation* metaData=parent->GetMetaData(blockId);
821 if(metaData->Has(vtkCompositeDataSet::NAME()))
823 const char* blockName=metaData->Get(vtkCompositeDataSet::NAME());
824 if(parentName==blockName &&
825 vtkMultiBlockDataSet::SafeDownCast(
826 parent->GetBlock(blockId))!=NULL)
828 parent=vtkMultiBlockDataSet::SafeDownCast(parent->GetBlock(blockId));
836 // If I am here, it means that I did not find any block with the good name, create one
837 int nb=parent->GetNumberOfBlocks();
838 vtkMultiBlockDataSet* block=vtkMultiBlockDataSet::New();
839 parent->SetBlock(nb, block);
841 parent->GetMetaData(nb)->Set(vtkCompositeDataSet::NAME(),
849 int vtkMedUtilities::SizeOf(med_attribute_type type)
853 case MED_ATT_FLOAT64 : return sizeof(med_float);
854 case MED_ATT_INT : return sizeof(med_int);
855 case MED_ATT_NAME : return MED_NAME_SIZE * sizeof(char);
860 bool operator==(const vtkMedComputeStep& cs0, const vtkMedComputeStep& cs1)
862 return cs0.IterationIt == cs1.IterationIt && cs0.TimeIt == cs1.TimeIt;
865 bool operator!=(const vtkMedComputeStep& cs0, const vtkMedComputeStep& cs1)
867 return cs0.IterationIt != cs1.IterationIt || cs0.TimeIt != cs1.TimeIt;
870 bool operator<(const vtkMedComputeStep& cs0, const vtkMedComputeStep& cs1)
872 if(cs0.IterationIt != cs1.IterationIt)
873 return cs0.IterationIt < cs1.IterationIt;
874 return cs0.TimeIt < cs1.TimeIt;
877 bool operator==(const vtkMedEntity& e0, const vtkMedEntity& e1)
879 return e0.EntityType == e1.EntityType && e0.GeometryType == e1.GeometryType;
882 bool operator!=(const vtkMedEntity& e0, const vtkMedEntity& e1)
884 return e0.EntityType != e1.EntityType || e0.GeometryType != e1.GeometryType;
887 bool operator<(const vtkMedEntity& e0, const vtkMedEntity& e1)
889 if(e0.EntityType != e1.EntityType)
890 return e0.EntityType < e1.EntityType;
891 return e0.GeometryType < e1.GeometryType;