1 // Copyright (C) 2010-2013 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";
217 return "MED_NO_GEOTYPE";
219 return "UNKNOWN_GEOMETRY";
223 const char* vtkMedUtilities::EntityName(med_entity_type type)
229 case MED_DESCENDING_FACE:
230 return "MED_DESCENDING_FACE";
231 case MED_DESCENDING_EDGE:
232 return "MED_DESCENDING_EDGE";
235 case MED_NODE_ELEMENT:
236 return "MED_NODE_ELEMENT";
237 case MED_STRUCT_ELEMENT:
238 return "MED_STRUCT_ELEMENT";
239 case MED_UNDEF_ENTITY_TYPE:
240 return "MED_UNDEF_ENTITY_TYPE";
242 return "UNKNOWN_ENTITY_TYPE ";
246 const char* vtkMedUtilities::ConnectivityName(med_connectivity_mode conn)
253 return "MED_DESCENDING";
255 return "MED_NO_CMODE";
257 return "UNKNOWN_CONNECTIVITY_MODE";
261 const std::string vtkMedUtilities::SimplifyName(const char* medName)
264 bool underscore=false;
266 int l=strlen(medName);
267 for(int cc=0; cc<l; cc++)
274 else if(medName[cc]=='_')
281 if(underscore||space)
291 const std::string vtkMedUtilities::FamilyKey(const char* meshName,
292 int pointOrCell, const char* familyName)
295 sstr<<"FAMILY"<<Separator<<SimplifyName(meshName)<<Separator;
296 if(pointOrCell==OnCell)
297 sstr<<vtkMedUtilities::OnCellName;
299 sstr<<vtkMedUtilities::OnPointName;
300 sstr<<Separator<<SimplifyName(familyName);
304 const std::string vtkMedUtilities::GroupKey(const char* meshName,
305 int pointOrCell, const char* groupName)
308 sstr << "GROUP" << vtkMedUtilities::Separator
309 << vtkMedUtilities::SimplifyName(meshName)
310 << vtkMedUtilities::Separator;
311 if(pointOrCell==OnCell)
312 sstr << vtkMedUtilities::OnCellName;
314 sstr << vtkMedUtilities::OnPointName;
316 sstr << vtkMedUtilities::Separator
317 << vtkMedUtilities::NoGroupName;
319 sstr << vtkMedUtilities::Separator
320 << vtkMedUtilities::SimplifyName(groupName);
325 const std::string vtkMedUtilities::EntityKey(const vtkMedEntity& entity)
328 sstr << "CELL_TYPE" << Separator << EntityName(entity.EntityType)
329 << Separator<<entity.GeometryName;
333 int vtkMedUtilities::GetNumberOfPoint(med_geometry_type geometry)
338 int vtkMedUtilities::GetDimension(med_geometry_type geometry)
343 int vtkMedUtilities::GetVTKCellType(med_geometry_type geometry)
353 return VTK_QUADRATIC_EDGE;
355 return VTK_CUBIC_LINE;
361 return VTK_QUADRATIC_TRIANGLE;
363 return VTK_BIQUADRATIC_TRIANGLE;
365 return VTK_QUADRATIC_QUAD;
367 return VTK_BIQUADRATIC_QUAD;
375 return VTK_HEXAHEDRON;
377 return VTK_QUADRATIC_TETRA;
379 return VTK_HEXAGONAL_PRISM;
381 return VTK_QUADRATIC_PYRAMID;
383 return VTK_QUADRATIC_WEDGE;
385 return VTK_QUADRATIC_HEXAHEDRON;
387 return VTK_TRIQUADRATIC_HEXAHEDRON;
391 return VTK_POLYHEDRON;
393 return VTK_EMPTY_CELL;
395 vtkGenericWarningMacro("No vtk type matches " << geometry << ", aborting")
397 return VTK_EMPTY_CELL;
401 int vtkMedUtilities::MedToVTKIndex(int vtktype, int node)
403 if(vtktype != VTK_TRIQUADRATIC_HEXAHEDRON)
406 static int VTK_TRIQUADRATIC_HEXAHEDRON_MED_TO_VTK_INDEX[27] =
407 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
408 24, 22, 21, 23, 20, 25, 26};
410 return VTK_TRIQUADRATIC_HEXAHEDRON_MED_TO_VTK_INDEX[node % 27] + static_cast<int>(27 * floor((double)node / 27));
413 int vtkMedUtilities::GetNumberOfNodes(med_geometry_type geometry)
464 vtkGenericWarningMacro("No vtk type matches "
465 << vtkMedUtilities::GeometryName(geometry)
471 int vtkMedUtilities::GetNumberOfSubEntity(med_geometry_type geometry)
522 vtkGenericWarningMacro("No vtk type matches "
529 med_entity_type vtkMedUtilities::GetSubType(med_entity_type type)
534 return MED_DESCENDING_FACE;
535 case MED_DESCENDING_FACE:
536 return MED_DESCENDING_EDGE;
537 case MED_DESCENDING_EDGE:
544 med_geometry_type vtkMedUtilities::GetSubGeometry(
545 med_geometry_type geometry, int index)
591 if(index==0||index==1)
598 if(index==0||index==1)
615 int vtkMedUtilities::FormatPolyhedronForVTK(
616 vtkMedFamilyOnEntityOnProfile* foep, vtkIdType index,
619 vtkMedEntityArray* array = foep->GetFamilyOnEntity()->GetEntityArray();
620 vtkMedIntArray* conn = array->GetConnectivityArray();
621 vtkMedIntArray* faceIndex = array->GetFaceIndex();
622 vtkMedIntArray* nodeIndex = array->GetNodeIndex();
623 med_int start = faceIndex->GetValue(index)-1;
624 med_int end = faceIndex->GetValue(index+1)-1;
626 // The format for the Polyhedrons is:
627 //(numCellFaces, numFace0Pts, id1, id2, id3, numFace1Pts,id1, id2, id3, ...)
630 if (array->GetConnectivity()==MED_NODAL)
632 ids->InsertNextId(end-start-1);
633 for (int ff = start; ff<end; ff++)
635 med_int fstart = nodeIndex->GetValue(ff)-1;
636 med_int fend = nodeIndex->GetValue(ff+1)-1;
637 ids->InsertNextId(fend-fstart);
638 for (med_int pt = fstart; pt<fend; pt++)
640 vtkIdType realIndex = foep->GetVTKPointIndex(conn->GetValue(pt)-1);
643 vtkGenericWarningMacro("this polyhedron is not on this profile");
647 ids->InsertNextId(realIndex);
652 if (array->GetConnectivity()==MED_DESCENDING)
654 ids->InsertNextId(end-start);
655 vtkSmartPointer<vtkIdList> subIds = vtkSmartPointer<vtkIdList>::New();
657 for (int i = 0 ; i<nodeIndex->GetSize(); i++)
660 vtkMedUtilities::GetNumberOfSubEntity(nodeIndex->GetValue(i));
661 ids->InsertNextId(numPoints);
664 entity.EntityType = MED_DESCENDING_FACE;
665 entity.GeometryType = nodeIndex->GetValue(i);
667 vtkMedEntityArray* theFaces =
668 array->GetParentGrid()->GetEntityArray(entity);
670 theFaces->GetCellVertices(conn->GetValue(i)-1, subIds);
672 for (int j = 0 ; j< numPoints; j++)
674 vtkIdType realIndex = foep->GetVTKPointIndex(subIds->GetId(j));
677 vtkGenericWarningMacro("this polyhedron is not on this profile");
680 ids->InsertNextId(realIndex);
687 void vtkMedUtilities::SplitGroupKey(const char* name, std::string& mesh,
688 std::string& entity, std::string& group)
695 std::string header="*";
701 std::string::size_type pos;
702 // First get the header, which must be "GROUP"
703 pos=remain.find_first_of(vtkMedUtilities::Separator);
704 header=remain.substr(0, pos);
705 remain=remain.substr(pos+1, remain.size()-pos-1);
707 // then get the mesh name
708 pos=remain.find_first_of(vtkMedUtilities::Separator);
709 mesh=remain.substr(0, pos);
710 if(mesh=="*"||pos==remain.size()-1)
712 remain=remain.substr(pos+1, remain.size()-pos-1);
714 // then the entity name (OnPoint or OnCell)
715 pos=remain.find_first_of(vtkMedUtilities::Separator);
716 entity=remain.substr(0, pos);
717 if(entity=="*"||pos==remain.size()-1)
721 group=remain.substr(pos+1, remain.size()-pos-1);
724 int vtkMedUtilities::GetParentNodeIndex(med_geometry_type parentGeometry,
725 int subEntityIndex, int subEntityNodeIndex)
727 switch(parentGeometry)
732 return MED_TRIA_CHILD_TO_PARENT_INDEX[subEntityIndex][subEntityNodeIndex];
736 return MED_QUAD_CHILD_TO_PARENT_INDEX[subEntityIndex][subEntityNodeIndex];
739 return MED_TETRA_CHILD_TO_PARENT_INDEX[subEntityIndex][subEntityNodeIndex];
742 return MED_PYRA_CHILD_TO_PARENT_INDEX[subEntityIndex][subEntityNodeIndex];
745 return MED_PENTA_CHILD_TO_PARENT_INDEX[subEntityIndex][subEntityNodeIndex];
749 return MED_HEXA_CHILD_TO_PARENT_INDEX[subEntityIndex][subEntityNodeIndex];
754 void vtkMedUtilities::ProjectConnectivity(med_geometry_type parentGeometry,
755 vtkIdList* parentIds, vtkIdList* subEntityIds, int subEntityIndex, bool invert)
757 for(int subEntityNodeIndex=0; subEntityNodeIndex
758 <subEntityIds->GetNumberOfIds(); subEntityNodeIndex++)
760 int realIndex = subEntityNodeIndex;
762 realIndex = subEntityIds->GetNumberOfIds() - subEntityNodeIndex - 1;
763 parentIds->SetId(GetParentNodeIndex(parentGeometry, subEntityIndex,
764 subEntityNodeIndex), subEntityIds->GetId(realIndex));
768 std::string vtkMedUtilities::GetModeKey(int index, double frequency, int maxindex)
770 std::ostringstream key;
774 int maxdecim = (int)floor(log(1.0*maxindex)/log(10.0));
778 decim = (int)floor(log(1.0*index)/log(10.0));
780 for(int i=decim; i<maxdecim; i++)
786 key<<index<<"] "<<frequency;
790 int vtkMedUtilities::GetModeFromKey(const char* key, int& index,
793 const std::string k(key);
794 size_t index_start=k.find("[");
795 size_t index_end=k.find("]");
796 const string index_string=k.substr(index_start, index_end);
797 stringstream indexsstr;
798 indexsstr<<index_string;
800 const string freq_string=k.substr(index_end+1, string::npos);
801 stringstream freqsstr;
802 freqsstr<<freq_string;
807 vtkMultiBlockDataSet* vtkMedUtilities::GetParent(vtkMultiBlockDataSet* root,
808 vtkStringArray* path)
810 vtkMultiBlockDataSet* output=root;
811 vtkMultiBlockDataSet* parent=output;
812 for(int depth = 0; depth<path->GetNumberOfValues(); depth++)
814 vtkStdString parentName = path->GetValue(depth);
816 for(int blockId=0; blockId<parent->GetNumberOfBlocks(); blockId++)
818 vtkInformation* metaData=parent->GetMetaData(blockId);
819 if(metaData->Has(vtkCompositeDataSet::NAME()))
821 const char* blockName=metaData->Get(vtkCompositeDataSet::NAME());
822 if(parentName==blockName &&
823 vtkMultiBlockDataSet::SafeDownCast(
824 parent->GetBlock(blockId))!=NULL)
826 parent=vtkMultiBlockDataSet::SafeDownCast(parent->GetBlock(blockId));
834 // If I am here, it means that I did not find any block with the good name, create one
835 int nb=parent->GetNumberOfBlocks();
836 vtkMultiBlockDataSet* block=vtkMultiBlockDataSet::New();
837 parent->SetBlock(nb, block);
839 parent->GetMetaData(nb)->Set(vtkCompositeDataSet::NAME(),
847 int vtkMedUtilities::SizeOf(med_attribute_type type)
851 case MED_ATT_FLOAT64 : return sizeof(med_float);
852 case MED_ATT_INT : return sizeof(med_int);
853 case MED_ATT_NAME : return MED_NAME_SIZE * sizeof(char);
858 bool operator==(const vtkMedComputeStep& cs0, const vtkMedComputeStep& cs1)
860 return cs0.IterationIt == cs1.IterationIt && cs0.TimeIt == cs1.TimeIt;
863 bool operator!=(const vtkMedComputeStep& cs0, const vtkMedComputeStep& cs1)
865 return cs0.IterationIt != cs1.IterationIt || cs0.TimeIt != cs1.TimeIt;
868 bool operator<(const vtkMedComputeStep& cs0, const vtkMedComputeStep& cs1)
870 if(cs0.IterationIt != cs1.IterationIt)
871 return cs0.IterationIt < cs1.IterationIt;
872 return cs0.TimeIt < cs1.TimeIt;
875 bool operator==(const vtkMedEntity& e0, const vtkMedEntity& e1)
877 return e0.EntityType == e1.EntityType && e0.GeometryType == e1.GeometryType;
880 bool operator!=(const vtkMedEntity& e0, const vtkMedEntity& e1)
882 return e0.EntityType != e1.EntityType || e0.GeometryType != e1.GeometryType;
885 bool operator<(const vtkMedEntity& e0, const vtkMedEntity& e1)
887 if(e0.EntityType != e1.EntityType)
888 return e0.EntityType < e1.EntityType;
889 return e0.GeometryType < e1.GeometryType;