Salome HOME
54d179a3668b5c79df5df849b2b13e14f556f18e
[modules/smesh.git] / src / DriverGMF / DriverGMF_Write.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File      : DriverGMF_Write.cxx
23 // Created   : Mon Sep 17 17:03:02 2012
24 // Author    : Edward AGAPOV (eap)
25
26 #include "DriverGMF_Write.hxx"
27 #include "DriverGMF.hxx"
28
29 #include "SMESHDS_GroupBase.hxx"
30 #include "SMESHDS_Mesh.hxx"
31 #include "SMESH_Comment.hxx"
32
33 #include <Basics_Utils.hxx>
34
35 #include "utilities.h"
36
37 extern "C"
38 {
39 #include "libmesh5.h"
40 }
41
42 #include <vector>
43
44 #define BEGIN_ELEM_WRITE( SMDSEntity, GmfKwd, elem )                    \
45   elemIt = elementIterator( SMDSEntity );                               \
46   if ( elemIt->more() )                                                 \
47   {                                                                     \
48   GmfSetKwd(meshID, GmfKwd, myMesh->GetMeshInfo().NbElements( SMDSEntity )); \
49   for ( int gmfID = 1; elemIt->more(); ++gmfID )                        \
50   {                                                                     \
51   const SMDS_MeshElement* elem = elemIt->next();                        \
52   GmfSetLin(meshID, GmfKwd,
53
54 #define BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom, LinType, GmfKwd, elem )   \
55   elemIt = elementIterator( SMDSGeom );                                 \
56   if ( elemIt->more() )                                                 \
57   {                                                                     \
58   int totalNbElems  = myMesh->GetMeshInfo().NbElements( SMDSGeom );     \
59   int nbLinearElems = myMesh->GetMeshInfo().NbElements( LinType );      \
60   if ( totalNbElems - nbLinearElems > 0 )                               \
61   {                                                                     \
62   GmfSetKwd(meshID, GmfKwd, totalNbElems - nbLinearElems);              \
63   for ( int gmfID = 1; elemIt->more(); ++gmfID )                        \
64   {                                                                     \
65   const SMDS_MeshElement* elem = elemIt->next();                        \
66   if ( elem->IsQuadratic() ) {                                          \
67   GmfSetLin(meshID, GmfKwd, gmfID, elem->NbNodes() - elem->NbCornerNodes(),
68
69 #define END_ELEM_WRITE( elem )                  \
70   elem->getshapeId() );                         \
71   }}
72
73 #define END_ELEM_WRITE_ADD_TO_MAP( elem, e2id )         \
74   elem->getshapeId() );                                 \
75   e2id.insert( e2id.end(), make_pair( elem, gmfID ));   \
76   }}
77
78 #define END_EXTRA_VERTICES_WRITE()           \
79   );                                         \
80   }}}}
81   
82   
83 DriverGMF_Write::DriverGMF_Write():
84   Driver_SMESHDS_Mesh(), _exportRequiredGroups( true ), mySizeMapVerticesNumber( 0 ), mySizeMapMeshes(), myLocalSizes()//, mySizeMaps()
85 {
86 }
87 DriverGMF_Write::~DriverGMF_Write()
88 {
89 }
90
91 //================================================================================
92 /*!
93  * \brief Reads a GMF file
94  */
95 //================================================================================
96
97 Driver_Mesh::Status DriverGMF_Write::Perform()
98 {
99   Kernel_Utils::Localizer loc;
100
101   const int dim = 3, version = sizeof(long) == 4 ? 2 : 3;
102
103   int meshID = GmfOpenMesh( myFile.c_str(), GmfWrite, version, dim );
104   if ( !meshID )
105   {
106     if ( DriverGMF::isExtensionCorrect( myFile ))
107       return addMessage( SMESH_Comment("Can't open for writing ") << myFile, /*fatal=*/true );
108     else
109       return addMessage( SMESH_Comment("Not '.mesh' or '.meshb' extension of file ") << myFile, /*fatal=*/true );
110   }
111
112   DriverGMF::MeshCloser aMeshCloser( meshID ); // An object closing GMF mesh at destruction
113
114   // nodes
115   std::map< const SMDS_MeshNode* , int > node2IdMap;
116   int iN = 0, nbNodes = myMesh->NbNodes();
117   GmfSetKwd( meshID, GmfVertices, nbNodes );
118   double xyz[3];
119   SMDS_NodeIteratorPtr nodeIt = myMesh->nodesIterator();
120   while ( nodeIt->more() )
121   {
122     const SMDS_MeshNode* n = nodeIt->next();
123     n->GetXYZ( xyz );
124     GmfSetLin( meshID, GmfVertices, xyz[0], xyz[1], xyz[2], n->getshapeId() );
125     node2IdMap.insert( node2IdMap.end(), make_pair( n, ++iN ));
126   }
127   if ( iN != nbNodes )
128     return addMessage("Wrong nb of nodes returned by nodesIterator", /*fatal=*/true);
129
130
131   SMDS_ElemIteratorPtr elemIt;
132   typedef std::map< const SMDS_MeshElement*, size_t, TIDCompare > TElem2IDMap;
133
134   // edges
135   TElem2IDMap edge2IDMap;
136   BEGIN_ELEM_WRITE( SMDSGeom_EDGE, GmfEdges, edge )
137     node2IdMap[ edge->GetNode( 0 )],
138     node2IdMap[ edge->GetNode( 1 )],
139     END_ELEM_WRITE_ADD_TO_MAP( edge, edge2IDMap );
140
141   // nodes of quadratic edges
142   BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_EDGE, SMDSEntity_Edge,
143                               GmfExtraVerticesAtEdges, edge )
144     node2IdMap[ edge->GetNode( 2 )]
145     END_EXTRA_VERTICES_WRITE();
146
147   // triangles
148   TElem2IDMap tria2IDMap;
149   BEGIN_ELEM_WRITE( SMDSGeom_TRIANGLE, GmfTriangles, tria )
150     node2IdMap[ tria->GetNode( 0 )],
151     node2IdMap[ tria->GetNode( 1 )],
152     node2IdMap[ tria->GetNode( 2 )],
153     END_ELEM_WRITE_ADD_TO_MAP( tria, tria2IDMap );
154
155   // nodes of quadratic triangles
156   BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_TRIANGLE, SMDSEntity_Triangle,
157                               GmfExtraVerticesAtTriangles, tria )
158     node2IdMap[ tria->GetNode( 3 )],
159     node2IdMap[ tria->GetNode( 4 )],
160     node2IdMap[ tria->GetNode( 5 )],
161     node2IdMap[ tria->GetNodeWrap( 6 )] // for TRIA7
162     END_EXTRA_VERTICES_WRITE();
163
164   // quadrangles
165   TElem2IDMap quad2IDMap;
166   BEGIN_ELEM_WRITE( SMDSGeom_QUADRANGLE, GmfQuadrilaterals, quad )
167     node2IdMap[ quad->GetNode( 0 )],
168     node2IdMap[ quad->GetNode( 1 )],
169     node2IdMap[ quad->GetNode( 2 )],
170     node2IdMap[ quad->GetNode( 3 )],
171     END_ELEM_WRITE_ADD_TO_MAP( quad, quad2IDMap );
172
173   // nodes of quadratic quadrangles
174   BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_QUADRANGLE, SMDSEntity_Quadrangle,
175                               GmfExtraVerticesAtQuadrilaterals, quad )
176     node2IdMap[ quad->GetNode( 4 )],
177     node2IdMap[ quad->GetNode( 5 )],
178     node2IdMap[ quad->GetNode( 6 )],
179     node2IdMap[ quad->GetNode( 7 )],
180     node2IdMap[ quad->GetNodeWrap( 8 )] // for QUAD9
181     END_EXTRA_VERTICES_WRITE();
182
183   // terahedra
184   BEGIN_ELEM_WRITE( SMDSGeom_TETRA, GmfTetrahedra, tetra )
185     node2IdMap[ tetra->GetNode( 0 )],
186     node2IdMap[ tetra->GetNode( 2 )],
187     node2IdMap[ tetra->GetNode( 1 )],
188     node2IdMap[ tetra->GetNode( 3 )],
189     END_ELEM_WRITE( tetra );
190
191   // nodes of quadratic terahedra
192   BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_TETRA, SMDSEntity_Tetra,
193                               GmfExtraVerticesAtTetrahedra, tetra )
194     node2IdMap[ tetra->GetNode( 6 )],
195     node2IdMap[ tetra->GetNode( 5 )],
196     node2IdMap[ tetra->GetNode( 4 )],
197     node2IdMap[ tetra->GetNode( 7 )],
198     node2IdMap[ tetra->GetNode( 9 )],
199     node2IdMap[ tetra->GetNode( 8 )]
200     //node2IdMap[ tetra->GetNodeWrap( 10 )], // for TETRA11
201     END_EXTRA_VERTICES_WRITE();
202
203   // pyramids
204   BEGIN_ELEM_WRITE( SMDSEntity_Pyramid, GmfPyramids, pyra )
205     node2IdMap[ pyra->GetNode( 0 )],
206     node2IdMap[ pyra->GetNode( 2 )],
207     node2IdMap[ pyra->GetNode( 1 )],
208     node2IdMap[ pyra->GetNode( 3 )],
209     node2IdMap[ pyra->GetNode( 4 )],
210     END_ELEM_WRITE( pyra );
211
212   // hexahedra
213   BEGIN_ELEM_WRITE( SMDSGeom_HEXA, GmfHexahedra, hexa )
214     node2IdMap[ hexa->GetNode( 0 )],
215     node2IdMap[ hexa->GetNode( 3 )],
216     node2IdMap[ hexa->GetNode( 2 )],
217     node2IdMap[ hexa->GetNode( 1 )],
218     node2IdMap[ hexa->GetNode( 4 )],
219     node2IdMap[ hexa->GetNode( 7 )],
220     node2IdMap[ hexa->GetNode( 6 )],
221     node2IdMap[ hexa->GetNode( 5 )],
222     END_ELEM_WRITE( hexa );
223
224   // nodes of quadratic hexahedra
225   BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_HEXA, SMDSEntity_Hexa,
226                               GmfExtraVerticesAtHexahedra, hexa )
227     node2IdMap[ hexa->GetNode( 11 )], // HEXA20
228     node2IdMap[ hexa->GetNode( 10 )],
229     node2IdMap[ hexa->GetNode(  9 )],
230     node2IdMap[ hexa->GetNode(  8 )],
231     node2IdMap[ hexa->GetNode( 15 )],
232     node2IdMap[ hexa->GetNode( 14 )],
233     node2IdMap[ hexa->GetNode( 13 )],
234     node2IdMap[ hexa->GetNode( 12 )],
235     node2IdMap[ hexa->GetNode( 16 )],
236     node2IdMap[ hexa->GetNode( 19 )],
237     node2IdMap[ hexa->GetNodeWrap( 18 )], // + HEXA27
238     node2IdMap[ hexa->GetNodeWrap( 17 )],
239     node2IdMap[ hexa->GetNodeWrap( 20 )],
240     node2IdMap[ hexa->GetNodeWrap( 24 )],
241     node2IdMap[ hexa->GetNodeWrap( 23 )],
242     node2IdMap[ hexa->GetNodeWrap( 22 )],
243     node2IdMap[ hexa->GetNodeWrap( 21 )],
244     node2IdMap[ hexa->GetNodeWrap( 25 )],
245     node2IdMap[ hexa->GetNodeWrap( 26 )]
246     END_EXTRA_VERTICES_WRITE();
247
248   // prism
249   BEGIN_ELEM_WRITE( SMDSEntity_Penta, GmfPrisms, prism )
250     node2IdMap[ prism->GetNode( 0 )],
251     node2IdMap[ prism->GetNode( 2 )],
252     node2IdMap[ prism->GetNode( 1 )],
253     node2IdMap[ prism->GetNode( 3 )],
254     node2IdMap[ prism->GetNode( 5 )],
255     node2IdMap[ prism->GetNode( 4 )],
256     END_ELEM_WRITE( prism );
257
258
259   if ( _exportRequiredGroups )
260   {
261     // required entities
262     SMESH_Comment badGroups;
263     const std::set<SMESHDS_GroupBase*>&      groupSet = myMesh->GetGroups();
264     std::set<SMESHDS_GroupBase*>::const_iterator grIt = groupSet.begin();
265     for ( ; grIt != groupSet.end(); ++grIt )
266     {
267       const SMESHDS_GroupBase* group = *grIt;
268       std::string          groupName = group->GetStoreName();
269       std::string::size_type     pos = groupName.find( "_required_" );
270       if ( pos == std::string::npos ) continue;
271
272       int                    gmfKwd;
273       SMDSAbs_EntityType smdsEntity;
274       std::string entity = groupName.substr( pos + strlen("_required_"));
275       if      ( entity == "Vertices" ) {
276         gmfKwd   = GmfRequiredVertices;
277         smdsEntity = SMDSEntity_Node;
278       }
279       else if ( entity == "Edges" ) {
280         gmfKwd   = GmfRequiredEdges;
281         smdsEntity = SMDSEntity_Edge;
282       }
283       else if ( entity == "Triangles" ) {
284         gmfKwd   = GmfRequiredTriangles;
285         smdsEntity = SMDSEntity_Triangle;
286       }
287       else if ( entity == "Quadrilaterals" ) {
288         gmfKwd   = GmfRequiredQuadrilaterals;
289         smdsEntity = SMDSEntity_Quadrangle;
290       }
291       else {
292         addMessage( SMESH_Comment("Invalig gmf entity name: ") << entity, /*fatal=*/false );
293         continue;
294       }
295
296       // check elem type in the group
297       int nbOkElems = 0;
298       SMDS_ElemIteratorPtr elemIt = group->GetElements();
299       while ( elemIt->more() )
300         nbOkElems += ( elemIt->next()->GetEntityType() == smdsEntity );
301
302       if ( nbOkElems != group->Extent() && nbOkElems == 0 )
303       {
304         badGroups << " " << groupName;
305         continue;
306       }
307
308       // choose a TElem2IDMap
309       TElem2IDMap* elem2IDMap = 0;
310       if ( smdsEntity == SMDSEntity_Quadrangle && nbOkElems != myMesh->NbFaces() )
311         elem2IDMap = & quad2IDMap;
312       else if ( smdsEntity == SMDSEntity_Triangle && nbOkElems != myMesh->NbFaces() )
313         elem2IDMap = & tria2IDMap;
314       else if ( smdsEntity == SMDSEntity_Edge && nbOkElems != myMesh->NbEdges() )
315         elem2IDMap = & edge2IDMap;
316
317       // write the group
318       GmfSetKwd( meshID, gmfKwd, nbOkElems );
319       elemIt = group->GetElements();
320       if ( elem2IDMap )
321         for ( ; elemIt->more(); )
322         {
323           const SMDS_MeshElement* elem = elemIt->next();
324           if ( elem->GetEntityType() == smdsEntity )
325             GmfSetLin( meshID, gmfKwd, (*elem2IDMap)[ elem ] );
326         }
327       else
328         for ( int gmfID = 1; elemIt->more(); ++gmfID)
329         {
330           const SMDS_MeshElement* elem = elemIt->next();
331           if ( elem->GetEntityType() == smdsEntity )
332             GmfSetLin( meshID, gmfKwd, gmfID );
333         }
334
335     } // loop on groups
336
337     if ( !badGroups.empty() )
338       addMessage( SMESH_Comment("Groups of elements of inappropriate geometry:")
339                   << badGroups, /*fatal=*/false );
340   }
341
342   return DRS_OK;
343 }
344
345 // void DriverGMF_Write::AddSizeMapSection(int meshID, int nbControlPoints)
346 // {
347 // //   const int dim = 3, version = sizeof(long) == 4 ? 2 : 3;
348 // //   int meshID = GmfOpenMesh( myFile.c_str(), GmfWrite, version, dim );
349 //   int TypTab[] = {GmfSca};
350 //   GmfSetKwd(meshID, GmfSolAtVertices, nbControlPoints, 1, TypTab);
351 // //   GmfCloseMesh(meshID);
352 // //   return DRS_OK;
353 // }
354 // 
355 // void DriverGMF_Write::AppendSize(int meshID, double size)
356 // {
357 // //   const int dim = 3, version = sizeof(long) == 4 ? 2 : 3;
358 // //   int meshID = GmfOpenMesh( myFile.c_str(), GmfWrite, version, dim );
359 // //   int nbPoints = GmfStatKwd( meshID, GmfSolAtVertices);
360 // //   GmfSetKwd( meshID, GmfSolAtVertices, nbPoints+1, 1, 1 );
361 //   double ValTab[] = {size};
362 //   GmfSetLin( meshID, GmfSolAtVertices, ValTab);
363 // //   return DRS_OK;
364 // }
365 // 
366 // int DriverGMF_Write::NbVerticesInFile()
367 // {
368 //   int dim, version;
369 //   // open the file
370 //   int meshID = GmfOpenMesh( myFile.c_str(), GmfRead, &version, &dim );
371 //   int nbVertices = GmfStatKwd( meshID, GmfVertices);
372 //   return nbVertices;
373 // }
374 // 
375 // int DriverGMF_Write::BeginSizeMap()
376 // {
377 //   const int dim = 3, version = sizeof(long) == 4 ? 2 : 3;
378 //   myGmfID = GmfOpenMesh( myFile.c_str(), GmfWrite, version, dim );
379 // }
380 //  
381 // void DriverGMF_Write::EndSizeMap()
382 // {
383 //   GmfCloseMesh( myGmfID );
384 // }
385 void DriverGMF_Write::AddSizeMapFromMesh( SMESHDS_Mesh* mesh, double size)
386 {
387   mySizeMapMeshes.push_back( mesh );
388   mySizeMapVerticesNumber += mesh->NbNodes();
389   myLocalSizes.push_back(TLocalSize(mesh->NbNodes(), size));
390 }
391
392 void DriverGMF_Write::AddSizeMap( const std::vector<gp_Pnt>& points, double size )
393 {
394 //   TSizeMap aMap( points, size );
395 //   mySizeMaps.push_back( aMap );
396   std::vector<gp_Pnt>::const_iterator it;
397   for( it = points.begin(); it != points.end(); it++)
398   {
399     myPoints.push_back( *it );
400   }
401   mySizeMapVerticesNumber += points.size();
402   myLocalSizes.push_back(TLocalSize(points.size(), size));
403 }
404
405 Driver_Mesh::Status DriverGMF_Write::PerformSizeMap()
406 {
407 //   const int dim = 3, version = sizeof(long) == 4 ? 2 : 3;
408   const int dim = 3, version = 2; // Version 3 not supported by mg-hexa
409   std::string aVerticesFile = mySizeMapPrefix + ".mesh";
410   std::string aSolFile = mySizeMapPrefix + ".sol";
411   
412   // Open files
413   int verticesFileID = GmfOpenMesh( aVerticesFile.c_str(), GmfWrite, version, dim );  
414   int solFileID = GmfOpenMesh( aSolFile.c_str(), GmfWrite, version, dim );
415   
416   // Vertices Keyword
417   GmfSetKwd( verticesFileID, GmfVertices, mySizeMapVerticesNumber );
418   
419   std::vector<gp_Pnt>::iterator points_it;
420   // Iterate on sizeMaps
421   for (points_it = myPoints.begin(); points_it != myPoints.end(); points_it++ )
422   {
423 //     MESSAGE("Point : X = "<<points_it->X()<<", Y ="<<points_it->Y()<<", Z = "<<points_it->Z())
424     GmfSetLin( verticesFileID, GmfVertices, points_it->X(), points_it->Y(), points_it->Z(), 0 );
425   }
426   
427   // SolAtVertices Keyword
428   int TypTab[] = {GmfSca};
429   GmfSetKwd(solFileID, GmfSolAtVertices, mySizeMapVerticesNumber, 1, TypTab);
430   std::vector<TLocalSize>::iterator sizes_it; 
431   for ( sizes_it = myLocalSizes.begin(); sizes_it != myLocalSizes.end(); sizes_it++ )
432   {
433     for ( int i = 1; i <= sizes_it->nbPoints ; i++ )
434     {
435       double ValTab[] = {sizes_it->size};
436       GmfSetLin( solFileID, GmfSolAtVertices, ValTab);
437     }
438   }
439   
440   // Close Files
441   GmfCloseMesh( verticesFileID );
442   GmfCloseMesh( solFileID );
443 }
444
445 // Driver_Mesh::Status DriverGMF_Write::PerformSizeMap()
446 // {
447 // //   const int dim = 3, version = sizeof(long) == 4 ? 2 : 3;
448 //   const int dim = 3, version = 2; // Version 3 not supported by mg-hexa
449 //   std::string aVerticesFile = mySizeMapPrefix + ".mesh";
450 //   std::string aSolFile = mySizeMapPrefix + ".sol";
451 //   
452 //   // Open files
453 //   int verticesFileID = GmfOpenMesh( aVerticesFile.c_str(), GmfWrite, version, dim );  
454 //   int solFileID = GmfOpenMesh( aSolFile.c_str(), GmfWrite, version, dim );
455 //   
456 //   // Vertices Keyword
457 //   GmfSetKwd( verticesFileID, GmfVertices, mySizeMapVerticesNumber );
458 //   double xyz[3];
459 //   std::vector<SMESHDS_Mesh*>::iterator meshes_it;
460 //   SMESHDS_Mesh* aMesh;
461 //   
462 //   // Iterate on size map meshes
463 //   for (meshes_it = mySizeMapMeshes.begin(); meshes_it != mySizeMapMeshes.end(); meshes_it++ )
464 //   {
465 //     aMesh= *meshes_it;
466 //     SMDS_NodeIteratorPtr nodeIt = aMesh->nodesIterator();
467 //     
468 //     // Iterate on the nodes of the mesh and write their coordinates under the GmfVertices keyword
469 //     while ( nodeIt->more() )
470 //     {
471 //       const SMDS_MeshNode* n = nodeIt->next();
472 //       n->GetXYZ( xyz );
473 //       GmfSetLin( verticesFileID, GmfVertices, xyz[0], xyz[1], xyz[2], n->getshapeId() );
474 //     }
475 //   }
476 //  
477 //   // SolAtVertices Keyword
478 //   int TypTab[] = {GmfSca};
479 //   GmfSetKwd(solFileID, GmfSolAtVertices, mySizeMapVerticesNumber, 1, TypTab);
480 //   
481 //   std::vector<TLocalSize>::iterator sizes_it; 
482 //   for ( sizes_it = myLocalSizes.begin(); sizes_it != myLocalSizes.end(); sizes_it++ )
483 //   {
484 //     for ( int i = 1; i <= sizes_it->nbNodes; i++ )
485 //     {
486 //       double ValTab[] = {sizes_it->size};
487 //       GmfSetLin( solFileID, GmfSolAtVertices, ValTab);
488 //     }
489 //   }
490 //   
491 //   // Close Files
492 //   GmfCloseMesh( verticesFileID );
493 //   GmfCloseMesh( solFileID );
494 // }
495
496 // void DriverGMF_Write::WriteSizeMapFromMesh( double size )
497 // {
498 //   // Open file
499 //   const int dim = 3, version = sizeof(long) == 4 ? 2 : 3;
500 //   int meshID = GmfOpenMesh( myFile.c_str(), GmfWrite, version, dim );  
501 //   
502 //   // Vertices Keyword
503 //   int iN = 0, nbNodes = myMesh->NbNodes();
504 //   GmfSetKwd( meshID, GmfVertices, nbNodes );
505 //   double xyz[3];
506 //   SMDS_NodeIteratorPtr nodeIt = myMesh->nodesIterator();
507 //   while ( nodeIt->more() )
508 //   {
509 //     const SMDS_MeshNode* n = nodeIt->next();
510 //     n->GetXYZ( xyz );
511 //     GmfSetLin( meshID, GmfVertices, xyz[0], xyz[1], xyz[2], n->getshapeId() );
512 //   }
513 //   
514 //   // solAtVertices Keyword
515 //   int TypTab[] = {GmfSca};
516 //   GmfSetKwd(meshID, GmfSolAtVertices, nbNodes, 1, TypTab);
517 //   for ( int i=1; i<= nbNodes; i++)
518 //   {
519 //     double ValTab[] = {size};
520 //     GmfSetLin( meshID, GmfSolAtVertices, ValTab);
521 //   }
522 //   
523 //   // Close File
524 //   GmfCloseMesh( meshID );
525 // }
526
527 //================================================================================
528 /*!
529  * \brief Returns an iterator on elements of a certain type
530  */
531 //================================================================================
532
533 SMDS_ElemIteratorPtr DriverGMF_Write::elementIterator(SMDSAbs_ElementType type)
534 {
535   return myMesh->elementsIterator(type);
536 }
537 SMDS_ElemIteratorPtr DriverGMF_Write::elementIterator(SMDSAbs_EntityType type) 
538 {
539   return myMesh->elementEntityIterator(type);
540 }
541 SMDS_ElemIteratorPtr DriverGMF_Write::elementIterator(SMDSAbs_GeometryType type)
542 {
543   return myMesh->elementGeomIterator(type);
544 }