]> SALOME platform Git repositories - plugins/netgenplugin.git/blob - src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx
Salome HOME
Fix Bug IPAL8776: compute if nbShells > 1; remove annoing messages and unused variables
[plugins/netgenplugin.git] / src / NETGENPlugin / NETGENPlugin_NETGEN_3D.cxx
1 //=============================================================================
2 // File      : NETGENPlugin_NETGEN_3D.cxx
3 //             Moved here from SMESH_NETGEN_3D.cxx
4 // Created   : lundi 27 Janvier 2003
5 // Author    : Nadir BOUHAMOU (CEA)
6 // Project   : SALOME
7 // Copyright : CEA 2003
8 // $Header$
9 //=============================================================================
10 using namespace std;
11
12 #include "NETGENPlugin_NETGEN_3D.hxx"
13 #include "SMESH_Gen.hxx"
14 #include "SMESH_Mesh.hxx"
15 #include "SMESH_subMesh.hxx"
16
17 #include "SMDS_MeshElement.hxx"
18 #include "SMDS_MeshNode.hxx"
19 #include "SMDS_FacePosition.hxx"
20
21 #include <TopExp.hxx>
22 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
23 #include <TopTools_ListOfShape.hxx>
24 #include <TopTools_ListIteratorOfListOfShape.hxx>
25 #include <TColStd_ListIteratorOfListOfInteger.hxx>
26
27 #include <BRep_Tool.hxx>
28 #include <Geom_Surface.hxx>
29 #include <Geom_Curve.hxx>
30 #include <Geom2d_Curve.hxx>
31
32 #include "utilities.h"
33
34 /*
35   Netgen include files
36 */
37
38 #include "nglib.h"
39
40 //=============================================================================
41 /*!
42  *  
43  */
44 //=============================================================================
45
46 NETGENPlugin_NETGEN_3D::NETGENPlugin_NETGEN_3D(int hypId, int studyId,
47                              SMESH_Gen* gen)
48   : SMESH_3D_Algo(hypId, studyId, gen)
49 {
50   MESSAGE("NETGENPlugin_NETGEN_3D::NETGENPlugin_NETGEN_3D");
51   _name = "NETGEN_3D";
52 //   _shapeType = TopAbs_SOLID;
53   _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
54 //   MESSAGE("_shapeType octal " << oct << _shapeType);
55   _compatibleHypothesis.push_back("MaxElementVolume");
56
57   _maxElementVolume = 0.;
58
59   _hypMaxElementVolume = NULL;
60 }
61
62 //=============================================================================
63 /*!
64  *  
65  */
66 //=============================================================================
67
68 NETGENPlugin_NETGEN_3D::~NETGENPlugin_NETGEN_3D()
69 {
70   MESSAGE("NETGENPlugin_NETGEN_3D::~NETGENPlugin_NETGEN_3D");
71 }
72
73 //=============================================================================
74 /*!
75  *  
76  */
77 //=============================================================================
78
79 bool NETGENPlugin_NETGEN_3D::CheckHypothesis
80                          (SMESH_Mesh& aMesh,
81                           const TopoDS_Shape& aShape,
82                           SMESH_Hypothesis::Hypothesis_Status& aStatus)
83 {
84   MESSAGE("NETGENPlugin_NETGEN_3D::CheckHypothesis");
85
86   _hypMaxElementVolume = NULL;
87
88   list<const SMESHDS_Hypothesis*>::const_iterator itl;
89   const SMESHDS_Hypothesis* theHyp;
90
91   const list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
92   int nbHyp = hyps.size();
93   if (!nbHyp)
94   {
95     aStatus = SMESH_Hypothesis::HYP_MISSING;
96     return false;  // can't work with no hypothesis
97   }
98
99   itl = hyps.begin();
100   theHyp = (*itl); // use only the first hypothesis
101
102   string hypName = theHyp->GetName();
103 //   int hypId = theHyp->GetID();
104 //   SCRUTE(hypName);
105
106   bool isOk = false;
107
108   if (hypName == "MaxElementVolume")
109   {
110     _hypMaxElementVolume = static_cast<const StdMeshers_MaxElementVolume*> (theHyp);
111     ASSERT(_hypMaxElementVolume);
112     _maxElementVolume = _hypMaxElementVolume->GetMaxVolume();
113     isOk =true;
114     aStatus = SMESH_Hypothesis::HYP_OK;
115   }
116   else
117     aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
118
119   return isOk;
120 }
121
122 //=============================================================================
123 /*!
124  *Here we are going to use the NETGEN mesher
125  */
126 //=============================================================================
127
128 bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh&         aMesh,
129                                      const TopoDS_Shape& aShape)
130 {
131   MESSAGE("NETGENPlugin_NETGEN_3D::Compute with maxElmentsize = " << _maxElementVolume);
132
133   SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
134
135   map<int, const SMDS_MeshNode*> netgenToDS;
136
137   // check if all faces were meshed by a triangle mesher (here MESFISTO_2D)
138
139   vector<SMESH_subMesh*> meshFaces;
140   vector<TopoDS_Shape> shapeFaces;
141
142   for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next())
143     {
144       TopoDS_Shape aShapeFace = exp.Current();
145       SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
146       ASSERT (aSubMesh);
147       int internal_size = meshFaces.size();
148       int index = 0;
149       for (int i = 0;i<internal_size;i++)
150         {
151           if (aSubMesh == meshFaces[i]) index = 1;
152         }
153       if (index == 0) meshFaces.push_back(aSubMesh);
154
155       internal_size = shapeFaces.size();
156       index = 0;
157       for (int i = 0;i<internal_size;i++)
158         {
159           if (aShapeFace == shapeFaces[i]) index = 1;
160         }
161       if (index == 0) shapeFaces.push_back(aShapeFace);
162     }
163
164   int numberOfFaces = meshFaces.size();
165
166   int NbTotOfTria = 0;
167   int NbTotOfNodesFaces = 0;
168
169   for (int i=0; i<numberOfFaces; i++)
170     {
171       TopoDS_Shape aShapeFace = meshFaces[i]->GetSubShape();
172       TopoDS_Shape aFace = shapeFaces[i];
173       SMESH_Algo* algoFace = _gen->GetAlgo(aMesh, aShapeFace);
174       string algoFaceName = algoFace->GetName();
175       if (algoFaceName != "MEFISTO_2D")
176         {
177           INFOS(algoFaceName);
178           return false;
179         }
180
181       const SMESHDS_SubMesh* aSubMeshDSFace = meshFaces[i]->GetSubMeshDS();
182
183       int nbNodes = aSubMeshDSFace->NbNodes();
184       NbTotOfNodesFaces += nbNodes;
185       int nbTria = aSubMeshDSFace->NbElements();
186       NbTotOfTria += nbTria;
187       int index = 0;
188
189       SMDS_ElemIteratorPtr iteratorTriangle = aSubMeshDSFace->GetElements();
190
191       index = 0;
192       int numberOfDegeneratedTriangle = 0;
193       while(iteratorTriangle->more())
194         {
195           index++;
196           const SMDS_MeshElement * triangle = iteratorTriangle->next();
197
198           SMDS_ElemIteratorPtr triangleNodesIt = triangle->nodesIterator();
199
200           const SMDS_MeshNode * node1 = static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
201           double node1X = node1->X();
202           double node1Y = node1->Y();
203           double node1Z = node1->Z();
204
205           const SMDS_MeshNode * node2 = static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
206           double node2X = node2->X();
207           double node2Y = node2->Y();
208           double node2Z = node2->Z();
209
210           const SMDS_MeshNode * node3 = static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
211           double node3X = node3->X();
212           double node3Y = node3->Y();
213           double node3Z = node3->Z();
214
215           // Compute the triangle surface
216
217           double vect1 = ((node2Y - node1Y)*(node3Z - node1Z) - (node2Z - node1Z)*(node3Y - node1Y));
218           double vect2 = - ((node2X - node1X)*(node3Z - node1Z) - (node2Z - node1Z)*(node3X - node1X));
219           double vect3 = ((node2X - node1X)*(node3Y - node1Y) - (node2Y - node1Y)*(node3X - node1X));
220           double epsilon = 1.0e-6;
221
222           bool triangleIsDegenerated = ((abs(vect1)<epsilon) && (abs(vect2)<epsilon) && (abs(vect3)<epsilon));
223
224           if (triangleIsDegenerated)
225             {
226               numberOfDegeneratedTriangle++;
227             }
228         }
229
230       if (numberOfDegeneratedTriangle > 0)
231         MESSAGE("WARNING THERE IS(ARE) " << numberOfDegeneratedTriangle << " degenerated triangle on this face");
232
233     }
234
235   // check if all edges were meshed by a edge mesher (here Regular_1D)
236
237   vector<SMESH_subMesh*> meshEdges;
238   for (TopExp_Explorer exp(aShape,TopAbs_EDGE);exp.More();exp.Next())
239     {
240       SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
241       ASSERT (aSubMesh);
242       int internal_size = meshEdges.size();
243       int index = 0;
244       for (int i = 0;i<internal_size;i++)
245         {
246           if (aSubMesh == meshEdges[i]) index = 1;
247         }
248       if (index == 0) meshEdges.push_back(aSubMesh);
249     }
250
251   int numberOfEdges = meshEdges.size();
252
253   int NbTotOfNodesEdges = 0;
254   int NbTotOfSegs = 0;
255
256   for (int i=0; i<numberOfEdges; i++)
257     {
258       TopoDS_Shape aShapeEdge = meshEdges[i]->GetSubShape();
259       SMESH_Algo* algoEdge = _gen->GetAlgo(aMesh, aShapeEdge);
260       string algoEdgeName = algoEdge->GetName();
261       if (algoEdgeName != "Regular_1D")
262         {
263           INFOS(algoEdgeName);
264           ASSERT(0);
265           return false;
266         }
267
268       const SMESHDS_SubMesh* aSubMeshDSEdge = meshEdges[i]->GetSubMeshDS();
269
270       int nbNodes = aSubMeshDSEdge->NbNodes();
271       NbTotOfNodesEdges += nbNodes;
272       int nbSegs = aSubMeshDSEdge->NbElements();
273       NbTotOfSegs += nbSegs;
274     }
275
276   vector<SMESH_subMesh*> meshVertices;
277   for (TopExp_Explorer exp(aShape,TopAbs_VERTEX);exp.More();exp.Next())
278     {
279       SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
280       ASSERT (aSubMesh);
281       int internal_size = meshVertices.size();
282       int index = 0;
283       for (int i = 0;i<internal_size;i++)
284         {
285           if (aSubMesh == meshVertices[i]) index = 1;
286         }
287       if (index == 0) meshVertices.push_back(aSubMesh);
288     }
289
290   int numberOfVertices = meshVertices.size();
291
292   int NbTotOfNodesVertices = 0;
293
294   for (int i=0; i<numberOfVertices; i++)
295     {
296       TopoDS_Shape aShapeVertex = meshVertices[i]->GetSubShape();
297
298       const SMESHDS_SubMesh * aSubMeshDSVertex = meshVertices[i]->GetSubMeshDS();
299
300       int nbNodes = aSubMeshDSVertex->NbNodes();
301       NbTotOfNodesVertices += nbNodes;
302     }
303
304   vector<SMESH_subMesh*> meshShells;
305   TopoDS_Shell aShell;
306
307   for (TopExp_Explorer exp(aShape,TopAbs_SHELL);exp.More();exp.Next())
308     {
309       SMESH_subMesh* aSubMesh = aMesh.GetSubMesh(exp.Current());
310       ASSERT(aSubMesh);
311       aShell = TopoDS::Shell(exp.Current());
312       meshShells.push_back(aSubMesh);
313     }
314
315   int numberOfShells = meshShells.size();
316
317   if (numberOfShells > 0)
318     {
319       /*
320         Prepare the Netgen surface mesh from the SMESHDS
321       */
322       int spaceDimension = 3;
323       int nbNodesByTri = 3;
324       int nbNodesByTetra = 4;
325
326       int Netgen_NbOfNodes = NbTotOfNodesFaces +
327                              NbTotOfNodesEdges +
328                              NbTotOfNodesVertices;
329       int Netgen_NbOfTria = NbTotOfTria;
330       int Netgen_param2ndOrder = 0;
331       double Netgen_paramFine = 1.;
332       double Netgen_paramSize = _maxElementVolume;
333
334       double * Netgen_Coordinates = new double [spaceDimension*
335                                                 Netgen_NbOfNodes];
336       int * listNodeCoresNetgenSmesh = new int [Netgen_NbOfNodes];
337       int * Netgen_Connectivity = new int [nbNodesByTri*Netgen_NbOfTria];
338       double * Netgen_point = new double [spaceDimension];
339       int * Netgen_triangle = new int [nbNodesByTri];
340       int * Netgen_tetrahedron = new int [nbNodesByTetra];
341
342       for (int i=0; i<Netgen_NbOfTria; i++)
343         {
344           for (int j=0; j<nbNodesByTri; j++)
345             Netgen_Connectivity[i*nbNodesByTri+j] = 0;
346         }
347
348       double bigNumber = 1.e20;
349
350       for (int i=0; i<Netgen_NbOfNodes; i++)
351         {
352           listNodeCoresNetgenSmesh[i] = 0;
353           for (int j=0; j<spaceDimension; j++)
354             Netgen_Coordinates[i*spaceDimension+j] = bigNumber;
355         }
356
357       int indexNodes = 0;
358       for (int i=0; i<numberOfVertices; i++)
359         {
360           const SMESHDS_SubMesh * aSubMeshDSVertex =
361             meshVertices[i]->GetSubMeshDS();
362
363           SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSVertex->GetNodes();
364
365           while(iteratorNodes->more())
366             {
367               const SMDS_MeshNode * node = iteratorNodes->next();
368               int nodeId = node->GetID();
369               double nodeX = node->X();
370               double nodeY = node->Y();
371               double nodeZ = node->Z();
372               listNodeCoresNetgenSmesh[indexNodes] = nodeId;
373               int index = indexNodes*spaceDimension;
374               Netgen_Coordinates[index] = nodeX;
375               Netgen_Coordinates[index+1] = nodeY;
376               Netgen_Coordinates[index+2] = nodeZ;
377               netgenToDS[indexNodes] = node;
378               indexNodes++;
379             }
380         }
381
382       for (int i=0; i<numberOfEdges; i++)
383         {
384           const SMESHDS_SubMesh *  aSubMeshDSEdge =
385             meshEdges[i]->GetSubMeshDS();
386
387           SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSEdge->GetNodes();
388
389           while(iteratorNodes->more())
390             {
391               const SMDS_MeshNode * node = iteratorNodes->next();
392               listNodeCoresNetgenSmesh[indexNodes] = node->GetID();
393               int index = indexNodes*spaceDimension;
394               Netgen_Coordinates[index] = node->X();
395               Netgen_Coordinates[index+1] = node->Y();
396               Netgen_Coordinates[index+2] = node->Z();
397               netgenToDS[indexNodes] = node;
398               indexNodes++;
399             }
400         }
401
402       for (int i=0; i<numberOfFaces; i++)
403         {
404           const SMESHDS_SubMesh * aSubMeshDSFace =
405             meshFaces[i]->GetSubMeshDS();
406
407           SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSFace->GetNodes();
408
409           while(iteratorNodes->more())
410             {
411               const SMDS_MeshNode * node = iteratorNodes->next();
412               int nodeId = node->GetID();
413               double nodeX = node->X();
414               double nodeY = node->Y();
415               double nodeZ = node->Z();
416 //            MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
417               listNodeCoresNetgenSmesh[indexNodes] = nodeId;
418               int index = indexNodes*spaceDimension;
419               Netgen_Coordinates[index] = nodeX;
420               Netgen_Coordinates[index+1] = nodeY;
421               Netgen_Coordinates[index+2] = nodeZ;
422               netgenToDS[indexNodes] = node;
423               indexNodes++;
424             }
425         }
426
427       for (int i=0; i<Netgen_NbOfNodes; i++)
428         {
429           ASSERT(listNodeCoresNetgenSmesh[i] != 0);
430
431           for (int j=0; j<Netgen_NbOfNodes && j!=i; j++)
432             ASSERT(listNodeCoresNetgenSmesh[i] != listNodeCoresNetgenSmesh[j]);
433
434           for (int j=0; j<spaceDimension; j++)
435             ASSERT(Netgen_Coordinates[i*spaceDimension+j] != bigNumber);
436         }
437
438       int indexTrias = 0;
439       for (int i=0; i<numberOfFaces; i++)
440         {
441           const SMESHDS_SubMesh * aSubMeshDSFace =
442             meshFaces[i]->GetSubMeshDS();
443
444           TopoDS_Shape aFace = shapeFaces[i];
445
446           SMDS_ElemIteratorPtr iteratorTriangle = aSubMeshDSFace->GetElements();
447
448           TopoDS_Shape aShapeFace = meshFaces[i]->GetSubShape();
449
450           bool orientationMeshFace = (aFace.Orientation() == aShapeFace.Orientation());
451
452           if (orientationMeshFace)
453             {
454               while(iteratorTriangle->more())
455                 {
456                   const SMDS_MeshElement * triangle = iteratorTriangle->next();
457
458                   SMDS_ElemIteratorPtr triangleNodesIt = triangle->nodesIterator();
459
460                   int triangleNode1 = (triangleNodesIt->next())->GetID();
461                   int triangleNode2 = (triangleNodesIt->next())->GetID();
462                   int triangleNode3 = (triangleNodesIt->next())->GetID();
463
464                   int N1New = 0;
465                   int N2New = 0;
466                   int N3New = 0;
467                   int index = indexTrias*nbNodesByTri;
468
469                   for (int j=0; j<Netgen_NbOfNodes; j++)
470                     {
471                       int jp1 = j+1;
472
473                       if (triangleNode1 == listNodeCoresNetgenSmesh[j])
474                         N1New = jp1;
475                       else if (triangleNode2 == listNodeCoresNetgenSmesh[j])
476                         N2New = jp1;
477                       else if (triangleNode3 == listNodeCoresNetgenSmesh[j])
478                         N3New = jp1;
479                     }
480
481                   triangleNode1 = N1New;
482                   triangleNode2 = N2New;
483                   triangleNode3 = N3New;
484
485                   Netgen_Connectivity[index] = triangleNode1;
486                   Netgen_Connectivity[index+1] = triangleNode2;
487                   Netgen_Connectivity[index+2] = triangleNode3;
488
489                   indexTrias++;
490                 }
491             }
492           else
493             {
494               while(iteratorTriangle->more())
495                 {
496                   const SMDS_MeshElement * triangle = iteratorTriangle->next();
497
498                   SMDS_ElemIteratorPtr triangleNodesIt = triangle->nodesIterator();
499
500                   int triangleNode1 = (triangleNodesIt->next())->GetID();
501                   int triangleNode3 = (triangleNodesIt->next())->GetID();
502                   int triangleNode2 = (triangleNodesIt->next())->GetID();
503
504                   int N1New = 0;
505                   int N2New = 0;
506                   int N3New = 0;
507                   int index = indexTrias*nbNodesByTri;
508
509                   for (int j=0; j<Netgen_NbOfNodes; j++)
510                     {
511                       int jp1 = j+1;
512
513                       if (triangleNode1 == listNodeCoresNetgenSmesh[j])
514                         N1New = jp1;
515                       else if (triangleNode2 == listNodeCoresNetgenSmesh[j])
516                         N2New = jp1;
517                       else if (triangleNode3 == listNodeCoresNetgenSmesh[j])
518                         N3New = jp1;
519                     }
520
521                   triangleNode1 = N1New;
522                   triangleNode2 = N2New;
523                   triangleNode3 = N3New;
524
525                   Netgen_Connectivity[index] = triangleNode1;
526                   Netgen_Connectivity[index+1] = triangleNode2;
527                   Netgen_Connectivity[index+2] = triangleNode3;
528
529                   indexTrias++;
530                 }
531             }
532         }
533
534       int * nodesUsed = new int[Netgen_NbOfNodes];
535
536       for (int i=0; i<Netgen_NbOfNodes; i++) nodesUsed[i] = 0;
537
538       for (int i=0; i<Netgen_NbOfTria; i++)
539         for (int j=0; j<nbNodesByTri; j++)
540           {
541             int Nij = Netgen_Connectivity[i*nbNodesByTri+j];
542
543             ASSERT((Nij>=1) && (Nij<=Netgen_NbOfNodes));
544
545             nodesUsed[Nij-1] = 1;
546             Netgen_Connectivity[i*nbNodesByTri+j] = Nij;
547           }
548
549       for (int i=0; i<Netgen_NbOfNodes; i++)
550         {
551           ASSERT(nodesUsed[i] != 0);
552         }
553
554       delete [] nodesUsed;
555
556       /*
557         Feed the Netgen surface mesh
558       */
559       Ng_Mesh * Netgen_mesh;
560
561       Ng_Init();
562
563       Netgen_mesh = Ng_NewMesh();
564
565       Ng_Meshing_Parameters Netgen_param;
566
567       for (int i=0; i<Netgen_NbOfNodes; i++)
568         {
569           for (int j=0; j<spaceDimension; j++)
570             Netgen_point[j] = Netgen_Coordinates[i*spaceDimension+j];
571
572           Ng_AddPoint(Netgen_mesh, Netgen_point);
573         }
574
575       for (int i=0; i<Netgen_NbOfTria; i++)
576         {
577           for (int j=0; j<nbNodesByTri; j++)
578             Netgen_triangle[j] = Netgen_Connectivity[i*nbNodesByTri+j];
579
580           Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle);
581         }
582
583       Netgen_param.secondorder = Netgen_param2ndOrder;
584       Netgen_param.fineness = Netgen_paramFine;
585       Netgen_param.maxh = Netgen_paramSize;
586
587       /*
588         Generate the volume mesh
589       */
590
591       ASSERT(Netgen_NbOfNodes == Ng_GetNP(Netgen_mesh));
592       ASSERT(Ng_GetNE(Netgen_mesh) == 0);
593       ASSERT(Netgen_NbOfTria == Ng_GetNSE(Netgen_mesh));
594
595       Ng_Result status;
596
597       try {
598         status = Ng_GenerateVolumeMesh(Netgen_mesh, &Netgen_param);
599       } catch (...) {
600         MESSAGE("An exception has been caught during the Volume Mesh Generation ...");
601         status = NG_VOLUME_FAILURE;
602       }
603
604       int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh);
605
606       int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh);
607
608       MESSAGE("End of Volume Mesh Generation. status=" << status <<
609               ", nb new nodes: " << Netgen_NbOfNodesNew - Netgen_NbOfNodes <<
610               ", nb tetra: " << Netgen_NbOfTetra);
611
612       if ((status != NG_OK) ||
613           (Netgen_NbOfTetra <= 0))
614         {
615           /*
616             Free the memory needed by to generate the Netgen Mesh
617           */
618
619           delete [] Netgen_Coordinates;
620           delete [] Netgen_Connectivity;
621           delete [] Netgen_point;
622           delete [] Netgen_triangle;
623           delete [] Netgen_tetrahedron;
624
625           delete [] listNodeCoresNetgenSmesh;
626
627           Ng_DeleteMesh(Netgen_mesh);
628           Ng_Exit();
629
630           return false;
631         }
632
633
634       double * Netgen_CoordinatesNew = new double [spaceDimension*Netgen_NbOfNodesNew];
635       int * Netgen_ConnectivityNew = new int [nbNodesByTetra*Netgen_NbOfTetra];
636
637       for (int i=0; i<Netgen_NbOfNodesNew; i++)
638         {
639           Ng_GetPoint(Netgen_mesh, (i+1), Netgen_point);
640
641           for (int j=0; j<spaceDimension; j++)
642             Netgen_CoordinatesNew[i*spaceDimension+j] = Netgen_point[j];
643         }
644
645       for (int i=0; i<Netgen_NbOfNodes; i++)
646         for (int j=0; j<spaceDimension; j++)
647           ASSERT(Netgen_CoordinatesNew[i*spaceDimension+j] == Netgen_Coordinates[i*spaceDimension+j])
648
649       for (int i=0; i<Netgen_NbOfTetra; i++)
650         {
651           Ng_GetVolumeElement(Netgen_mesh, (i+1), Netgen_tetrahedron);
652
653           for (int j=0; j<nbNodesByTetra; j++)
654             Netgen_ConnectivityNew[i*nbNodesByTetra+j] = Netgen_tetrahedron[j];
655         }
656
657       /*
658         Feed back the SMESHDS with the generated Nodes and Volume Elements
659       */
660
661       int NbTotOfNodesShell = Netgen_NbOfNodesNew - Netgen_NbOfNodes;
662
663       int * listNodeShellCoresNetgenSmesh = new int [NbTotOfNodesShell];
664
665       for (int i=0; i<NbTotOfNodesShell; i++)
666         listNodeShellCoresNetgenSmesh[i] = 0;
667
668       for (int i=0; i<NbTotOfNodesShell; i++)
669         {
670           int index = (i+Netgen_NbOfNodes)*spaceDimension;
671
672           SMDS_MeshNode * node =
673             meshDS->AddNode(Netgen_CoordinatesNew[index],
674                             Netgen_CoordinatesNew[index+1],
675                             Netgen_CoordinatesNew[index+2]);
676
677           meshDS->SetNodeInVolume(node, aShell);
678
679           index = i+Netgen_NbOfNodes;
680           netgenToDS[index] = node;
681
682           listNodeShellCoresNetgenSmesh[i] = node->GetID();
683         }
684
685       for (int i=0; i<NbTotOfNodesShell; i++)
686         {
687           ASSERT(listNodeShellCoresNetgenSmesh[i] != 0);
688
689           for (int j=0; j<NbTotOfNodesShell && j!=i; j++)
690             ASSERT(listNodeShellCoresNetgenSmesh[i] != listNodeShellCoresNetgenSmesh[j]);
691         }
692
693       for (int i=0; i<Netgen_NbOfTetra; i++)
694         {
695           int index = i*nbNodesByTetra;
696           int tetraNode1 = Netgen_ConnectivityNew[index];
697           int tetraNode2 = Netgen_ConnectivityNew[index+1];
698           int tetraNode3 = Netgen_ConnectivityNew[index+2];
699           int tetraNode4 = Netgen_ConnectivityNew[index+3];
700
701           const SMDS_MeshNode * node1 = netgenToDS[tetraNode1-1];
702           const SMDS_MeshNode * node2 = netgenToDS[tetraNode2-1];
703           const SMDS_MeshNode * node3 = netgenToDS[tetraNode3-1];
704           const SMDS_MeshNode * node4 = netgenToDS[tetraNode4-1];
705
706           index = tetraNode1;
707           if (index <= Netgen_NbOfNodes)
708             tetraNode1 = listNodeCoresNetgenSmesh[index-1];
709           else
710             tetraNode1 = listNodeShellCoresNetgenSmesh[index-Netgen_NbOfNodes-1];
711
712           index = tetraNode2;
713           if (index <= Netgen_NbOfNodes)
714             tetraNode2 = listNodeCoresNetgenSmesh[index-1];
715           else
716             tetraNode2 = listNodeShellCoresNetgenSmesh[index-Netgen_NbOfNodes-1];
717
718           index = tetraNode3;
719           if (index <= Netgen_NbOfNodes)
720             tetraNode3 = listNodeCoresNetgenSmesh[index-1];
721           else
722             tetraNode3 = listNodeShellCoresNetgenSmesh[index-Netgen_NbOfNodes-1];
723
724           index = tetraNode4;
725           if (index <= Netgen_NbOfNodes)
726             tetraNode4 = listNodeCoresNetgenSmesh[index-1];
727           else
728             tetraNode4 = listNodeShellCoresNetgenSmesh[index-Netgen_NbOfNodes-1];
729
730           SMDS_MeshVolume * elt =
731             meshDS->AddVolume(node1,node2,node3,node4);
732
733           meshDS->SetMeshElementOnShape(elt, aShell);
734         }
735
736       /*
737         Free the memory needed by to generate the Netgen Mesh
738       */
739
740       delete [] Netgen_Coordinates;
741       delete [] Netgen_Connectivity;
742       delete [] Netgen_CoordinatesNew;
743       delete [] Netgen_ConnectivityNew;
744       delete [] Netgen_point;
745       delete [] Netgen_triangle;
746       delete [] Netgen_tetrahedron;
747
748       delete [] listNodeCoresNetgenSmesh;
749       delete [] listNodeShellCoresNetgenSmesh;
750
751       Ng_DeleteMesh(Netgen_mesh);
752       Ng_Exit();
753
754       return true;
755     }
756
757   return false;
758 }
759
760
761 //=============================================================================
762 /*!
763  *  
764  */
765 //=============================================================================
766
767 ostream & NETGENPlugin_NETGEN_3D::SaveTo(ostream & save)
768 {
769   return save;
770 }
771
772 //=============================================================================
773 /*!
774  *  
775  */
776 //=============================================================================
777
778 istream & NETGENPlugin_NETGEN_3D::LoadFrom(istream & load)
779 {
780   return load;
781 }
782
783 //=============================================================================
784 /*!
785  *  
786  */
787 //=============================================================================
788
789 ostream & operator << (ostream & save, NETGENPlugin_NETGEN_3D & hyp)
790 {
791   return hyp.SaveTo( save );
792 }
793
794 //=============================================================================
795 /*!
796  *  
797  */
798 //=============================================================================
799
800 istream & operator >> (istream & load, NETGENPlugin_NETGEN_3D & hyp)
801 {
802   return hyp.LoadFrom( load );
803 }