1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, Read to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : DriverGMF_Read.cxx
23 // Created : Mon Sep 17 17:03:02 2012
24 // Author : Edward AGAPOV (eap)
26 #include "DriverGMF_Read.hxx"
27 #include "DriverGMF_Write.hxx"
29 #include "SMESHDS_Group.hxx"
30 #include "SMESHDS_Mesh.hxx"
31 #include "SMESH_Comment.hxx"
40 // --------------------------------------------------------------------------------
41 // Closing GMF mesh at destruction
42 DriverGMF_MeshCloser::~DriverGMF_MeshCloser()
45 GmfCloseMesh( _gmfMeshID );
47 // --------------------------------------------------------------------------------
48 DriverGMF_Read::DriverGMF_Read():
49 Driver_SMESHDS_Mesh(),
50 _makeRequiredGroups( true )
53 // --------------------------------------------------------------------------------
54 DriverGMF_Read::~DriverGMF_Read()
58 //================================================================================
60 * \brief Read a GMF file
62 //================================================================================
64 Driver_Mesh::Status DriverGMF_Read::Perform()
66 Status status = DRS_OK;
71 int meshID = GmfOpenMesh( myFile.c_str(), GmfRead, &version, &dim );
73 return addMessage( SMESH_Comment("Can't open for reading ") << myFile, /*fatal=*/true );
75 DriverGMF_MeshCloser aMeshCloser( meshID ); // An object closing GMF mesh at destruction
79 int nbNodes = GmfStatKwd(meshID, GmfVertices);
81 return addMessage( "No nodes in the mesh", /*fatal=*/true );
83 GmfGotoKwd(meshID, GmfVertices);
87 const int nodeIDShift = myMesh->GetMeshInfo().NbNodes();
88 if ( version != GmfFloat )
91 for ( int i = 1; i <= nbNodes; ++i )
93 GmfGetLin(meshID, GmfVertices, &x, &y, &z, &ref);
94 myMesh->AddNodeWithID( x,y,z, nodeIDShift + i);
100 for ( int i = 1; i <= nbNodes; ++i )
102 GmfGetLin(meshID, GmfVertices, &x, &y, &z, &ref);
103 myMesh->AddNodeWithID( x,y,z, nodeIDShift + i);
112 const int edgeIDShift = myMesh->GetMeshInfo().NbElements();
113 if ( int nbEdges = GmfStatKwd(meshID, GmfEdges))
115 GmfGotoKwd(meshID, GmfEdges);
116 for ( int i = 1; i <= nbEdges; ++i )
118 GmfGetLin(meshID, GmfEdges, &iN[0], &iN[1], &ref);
119 if ( !myMesh->AddEdgeWithID( iN[0], iN[1], edgeIDShift + i ))
120 status = storeBadNodeIds( "GmfEdges",i, 2, iN[0], iN[1] );
123 /* Read quadratic edges */
124 const int edge2IDShift = myMesh->GetMeshInfo().NbElements();
125 if ( int nbEdges = GmfStatKwd(meshID, GmfEdgesP2))
127 GmfGotoKwd(meshID, GmfEdgesP2);
128 for ( int i = 1; i <= nbEdges; ++i )
130 GmfGetLin(meshID, GmfEdgesP2, &iN[0], &iN[1], &iN[2], &ref);
131 if ( !myMesh->AddEdgeWithID( iN[0], iN[1], iN[2], edge2IDShift + i ))
132 status = storeBadNodeIds( "GmfEdgesP2",i, 3, iN[0], iN[1], iN[2] );
136 const int triaIDShift = myMesh->GetMeshInfo().NbElements();
137 if ( int nbTria = GmfStatKwd(meshID, GmfTriangles))
139 GmfGotoKwd(meshID, GmfTriangles);
140 for ( int i = 1; i <= nbTria; ++i )
142 GmfGetLin(meshID, GmfTriangles, &iN[0], &iN[1], &iN[2], &ref);
143 if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], triaIDShift + i ))
144 status = storeBadNodeIds( "GmfTriangles",i, 3, iN[0], iN[1], iN[2] );
147 /* Read quadratic triangles */
148 const int tria2IDShift = myMesh->GetMeshInfo().NbElements();
149 if ( int nbTria = GmfStatKwd(meshID, GmfTrianglesP2))
151 GmfGotoKwd(meshID, GmfTrianglesP2);
152 for ( int i = 1; i <= nbTria; ++i )
154 GmfGetLin(meshID, GmfTrianglesP2,
155 &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &ref);
156 if ( !myMesh->AddFaceWithID( iN[0],iN[1],iN[2],iN[3],iN[4],iN[5],
158 status = storeBadNodeIds( "GmfTrianglesP2",i, 6, iN[0],iN[1],iN[2],iN[3],iN[4],iN[5] );
161 /* Read quadrangles */
162 const int quadIDShift = myMesh->GetMeshInfo().NbElements();
163 if ( int nbQuad = GmfStatKwd(meshID, GmfQuadrilaterals))
165 GmfGotoKwd(meshID, GmfQuadrilaterals);
166 for ( int i = 1; i <= nbQuad; ++i )
168 GmfGetLin(meshID, GmfQuadrilaterals, &iN[0], &iN[1], &iN[2], &iN[3], &ref);
169 if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], iN[3], quadIDShift + i ))
170 status = storeBadNodeIds( "GmfQuadrilaterals",i, 4, iN[0], iN[1],iN[2], iN[3] );
173 /* Read bi-quadratic quadrangles */
174 const int quad2IDShift = myMesh->GetMeshInfo().NbElements();
175 if ( int nbQuad = GmfStatKwd(meshID, GmfQuadrilateralsQ2))
177 GmfGotoKwd(meshID, GmfQuadrilateralsQ2);
178 for ( int i = 1; i <= nbQuad; ++i )
180 GmfGetLin(meshID, GmfQuadrilateralsQ2,
181 &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6], &iN[7], &iN[8], &ref);
182 if ( !myMesh->AddFaceWithID( iN[0],iN[1],iN[2],iN[3],iN[4],iN[5],iN[6],iN[7],iN[8],
184 status = storeBadNodeIds( "GmfQuadrilateralsQ2",i,
185 9, iN[0],iN[1],iN[2],iN[3],iN[4],iN[5],iN[6],iN[7],iN[8] );
189 const int tetIDShift = myMesh->GetMeshInfo().NbElements();
190 if ( int nbTet = GmfStatKwd(meshID, GmfTetrahedra))
192 GmfGotoKwd(meshID, GmfTetrahedra);
193 for ( int i = 1; i <= nbTet; ++i )
195 GmfGetLin(meshID, GmfTetrahedra, &iN[0], &iN[1], &iN[2], &iN[3], &ref);
196 if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], tetIDShift + i ))
197 status = storeBadNodeIds( "GmfTetrahedra",i, 4, iN[0], iN[1],iN[2], iN[3] );
200 /* Read quadratic terahedra */
201 const int tet2IDShift = myMesh->GetMeshInfo().NbElements();
202 if ( int nbTet = GmfStatKwd(meshID, GmfTetrahedraP2))
204 GmfGotoKwd(meshID, GmfTetrahedraP2);
205 for ( int i = 1; i <= nbTet; ++i )
207 GmfGetLin(meshID, GmfTetrahedraP2, &iN[0], &iN[1], &iN[2],
208 &iN[3], &iN[4], &iN[5], &iN[6], &iN[7], &iN[8], &iN[9], &ref);
209 if ( !myMesh->AddVolumeWithID( iN[0],iN[2],iN[1],iN[3],
211 iN[7],iN[9],iN[8], tet2IDShift + i ))
212 status = storeBadNodeIds( "GmfTetrahedraP2",i, 10, iN[0],iN[1],iN[2],iN[3],
213 iN[4],iN[5],iN[6],iN[7],iN[8],iN[9] );
217 const int pyrIDShift = myMesh->GetMeshInfo().NbElements();
218 if ( int nbPyr = GmfStatKwd(meshID, GmfPyramids))
220 GmfGotoKwd(meshID, GmfPyramids);
221 for ( int i = 1; i <= nbPyr; ++i )
223 GmfGetLin(meshID, GmfPyramids, &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &ref);
224 if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], iN[4], pyrIDShift + i ))
225 status = storeBadNodeIds( "GmfPyramids",i, 5, iN[0], iN[1],iN[2], iN[3], iN[4] );
229 const int hexIDShift = myMesh->GetMeshInfo().NbElements();
230 if ( int nbHex = GmfStatKwd(meshID, GmfHexahedra))
232 GmfGotoKwd(meshID, GmfHexahedra);
233 for ( int i = 1; i <= nbHex; ++i )
235 GmfGetLin(meshID, GmfHexahedra,
236 &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6], &iN[7], &ref);
237 if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1], iN[4], iN[7], iN[6], iN[5],
239 status = storeBadNodeIds( "GmfHexahedra",i,
240 8, iN[0], iN[1],iN[2], iN[3], iN[4], iN[7], iN[6], iN[5] );
243 /* Read tri-quadratic hexahedra */
244 const int hex2IDShift = myMesh->GetMeshInfo().NbElements();
245 if ( int nbHex = GmfStatKwd(meshID, GmfHexahedraQ2))
247 GmfGotoKwd(meshID, GmfHexahedraQ2);
248 for ( int i = 1; i <= nbHex; ++i )
250 GmfGetLin(meshID, GmfHexahedraQ2, &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5],
251 &iN[6], &iN[7], &iN[8],&iN[9],&iN[10],&iN[11],&iN[12],&iN[13],&iN[14],
252 &iN[15],&iN[16],&iN[17],&iN[18],&iN[19],&iN[20],&iN[21],&iN[22],&iN[23],
253 &iN[24],&iN[25],&iN[26], &ref);
254 if ( !myMesh->AddVolumeWithID( iN[0],iN[3],iN[2],iN[1],iN[4],iN[7],iN[6],iN[5],iN[11],iN[10],
255 iN[9],iN[8],iN[12],iN[15],iN[14], iN[13],iN[19],iN[18],iN[17],
256 iN[16],iN[20],iN[24],iN[23],iN[22],iN[21], iN[25],iN[26],
258 status = storeBadNodeIds( "GmfHexahedraQ2",i, 27,
259 iN[0],iN[3],iN[2],iN[1],iN[4], iN[7],iN[6],iN[5],iN[11],iN[10],
260 iN[9],iN[8],iN[12],iN[15],iN[14], iN[13],iN[19],iN[18],iN[17],
261 iN[16],iN[20],iN[24],iN[23],iN[22],iN[21], iN[25],iN[26]);
265 const int prismIDShift = myMesh->GetMeshInfo().NbElements();
266 if ( int nbPrism = GmfStatKwd(meshID, GmfPrisms))
268 GmfGotoKwd(meshID, GmfPrisms);
269 for ( int i = 1; i <= nbPrism; ++i )
271 GmfGetLin(meshID, GmfPrisms,
272 &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &ref);
273 if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], iN[5], iN[4], prismIDShift + i))
274 status = storeBadNodeIds( "GmfPrisms",i,
275 6, iN[0], iN[1],iN[2], iN[3], iN[4], iN[5] );
279 // Read required entities into groups
281 if ( _makeRequiredGroups )
283 // get ids of existing groups
284 std::set< int > groupIDs;
285 const std::set<SMESHDS_GroupBase*>& groups = myMesh->GetGroups();
286 std::set<SMESHDS_GroupBase*>::const_iterator grIter = groups.begin();
287 for ( ; grIter != groups.end(); ++grIter )
288 groupIDs.insert( (*grIter)->GetID() );
289 if ( groupIDs.empty() ) groupIDs.insert( 0 );
291 const int kes[4][3] = { { GmfRequiredVertices, SMDSAbs_Node, nodeIDShift },
292 { GmfRequiredEdges, SMDSAbs_Edge, edgeIDShift },
293 { GmfRequiredTriangles, SMDSAbs_Face, triaIDShift },
294 { GmfRequiredQuadrilaterals,SMDSAbs_Face, quadIDShift }};
295 const char* names[4] = { "_required_Vertices" ,
297 "_required_Triangles" ,
298 "_required_Quadrilaterals" };
299 for ( int i = 0; i < 4; ++i )
301 int gmfKwd = kes[i][0];
302 SMDSAbs_ElementType entity = (SMDSAbs_ElementType) kes[i][1];
303 int shift = kes[i][2];
304 if ( int nb = GmfStatKwd(meshID, gmfKwd))
306 const int newID = *groupIDs.rbegin() + 1;
307 groupIDs.insert( newID );
308 SMESHDS_Group* group = new SMESHDS_Group( newID, myMesh, entity );
309 group->SetStoreName( names[i] );
310 myMesh->AddGroup( group );
312 GmfGotoKwd(meshID, gmfKwd);
313 for ( int i = 0; i < nb; ++i )
315 GmfGetLin(meshID, gmfKwd, &iN[0] );
316 group->Add( shift + iN[0] );
325 //================================================================================
327 * \brief Store a message about invalid IDs of nodes
329 //================================================================================
331 Driver_Mesh::Status DriverGMF_Read::storeBadNodeIds(const char* gmfKwd, int elemNb, int nb, ...)
333 if ( myStatus != DRS_OK )
339 va_start(VarArg, nb);
341 for ( int i = 0; i < nb; ++i )
343 int id = va_arg(VarArg, int );
344 if ( !myMesh->FindNode( id ))
352 const char* nbNames[] = { "1-st ", "2-nd ", "3-d " };
353 if ( elemNb < 3 ) nbStr = nbNames[ elemNb-1 ];
354 else nbStr = SMESH_Comment(elemNb) << "-th ";
357 ( SMESH_Comment("Wrong node IDs of ")<< nbStr << gmfKwd << ":" << msg,