Salome HOME
Add support for tetra, pyramid and prism
[modules/smesh.git] / src / SMESH / SMESH_MEFISTO_2D.cxx
1 //  SMESH SMESH : implementaion of SMESH idl descriptions
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_MEFISTO_2D.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SMESH
27 //  $Header$
28
29 using namespace std;
30 #include "SMESH_MEFISTO_2D.hxx"
31 #include "SMESH_Gen.hxx"
32 #include "SMESH_Mesh.hxx"
33
34 #include "SMESH_MaxElementArea.hxx"
35 #include "SMESH_LengthFromEdges.hxx"
36
37 #include "Rn.h"
38 #include "aptrte.h"
39
40 #include "SMDS_MeshElement.hxx"
41 #include "SMDS_MeshNode.hxx"
42 #include "SMDS_EdgePosition.hxx"
43 #include "SMDS_FacePosition.hxx"
44
45 #include "utilities.h"
46
47 #include <TopoDS_Face.hxx>
48 #include <TopoDS_Edge.hxx>
49 #include <TopoDS_Shape.hxx>
50 #include <Geom_Surface.hxx>
51 #include <GeomAdaptor_Curve.hxx>
52 #include <Geom2d_Curve.hxx>
53 #include <gp_Pnt2d.hxx>
54 #include <BRep_Tool.hxx>
55 #include <BRepTools.hxx>
56 #include <BRepTools_WireExplorer.hxx>
57 #include <GCPnts_AbscissaPoint.hxx>
58 #include <GCPnts_UniformAbscissa.hxx>
59 #include <TColStd_ListIteratorOfListOfInteger.hxx>
60
61 #include <string>
62 #include <algorithm>
63
64 //=============================================================================
65 /*!
66  *  
67  */
68 //=============================================================================
69
70 SMESH_MEFISTO_2D::SMESH_MEFISTO_2D(int hypId, int studyId,
71         SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
72 {
73         MESSAGE("SMESH_MEFISTO_2D::SMESH_MEFISTO_2D");
74         _name = "MEFISTO_2D";
75 //   _shapeType = TopAbs_FACE;
76         _shapeType = (1 << TopAbs_FACE);
77         _compatibleHypothesis.push_back("MaxElementArea");
78         _compatibleHypothesis.push_back("LengthFromEdges");
79
80         _edgeLength = 0;
81         _maxElementArea = 0;
82         _hypMaxElementArea = NULL;
83         _hypLengthFromEdges = NULL;
84 }
85
86 //=============================================================================
87 /*!
88  *  
89  */
90 //=============================================================================
91
92 SMESH_MEFISTO_2D::~SMESH_MEFISTO_2D()
93 {
94         MESSAGE("SMESH_MEFISTO_2D::~SMESH_MEFISTO_2D");
95 }
96
97 //=============================================================================
98 /*!
99  *  
100  */
101 //=============================================================================
102
103 bool SMESH_MEFISTO_2D::CheckHypothesis(SMESH_Mesh & aMesh,
104         const TopoDS_Shape & aShape)
105 {
106         //MESSAGE("SMESH_MEFISTO_2D::CheckHypothesis");
107
108         _hypMaxElementArea = NULL;
109         _hypLengthFromEdges = NULL;
110
111         list <const SMESHDS_Hypothesis * >::const_iterator itl;
112         const SMESHDS_Hypothesis *theHyp;
113
114         const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
115         int nbHyp = hyps.size();
116         if (nbHyp != 1) return false;// only one compatible hypothesis allowed
117
118         itl = hyps.begin();
119         theHyp = (*itl);
120
121         string hypName = theHyp->GetName();
122         int hypId = theHyp->GetID();
123         //SCRUTE(hypName);
124
125         bool isOk = false;
126
127         if (hypName == "MaxElementArea")
128         {
129                 _hypMaxElementArea = static_cast<const SMESH_MaxElementArea *>(theHyp);
130                 ASSERT(_hypMaxElementArea);
131                 _maxElementArea = _hypMaxElementArea->GetMaxArea();
132                 _edgeLength = 0;
133                 isOk = true;
134         }
135
136         if (hypName == "LengthFromEdges")
137         {
138                 _hypLengthFromEdges = static_cast<const SMESH_LengthFromEdges *>(theHyp);
139                 ASSERT(_hypLengthFromEdges);
140                 _edgeLength = 0;
141                 _maxElementArea = 0;
142                 isOk = true;
143         }
144
145         if (isOk)
146         {
147                 isOk = false;
148                 if (_maxElementArea > 0)
149                 {
150                         _edgeLength = 2 * sqrt(_maxElementArea);        // triangles : minorant
151                         isOk = true;
152                 }
153                 else
154                         isOk = (_hypLengthFromEdges != NULL);   // **** check mode
155         }
156
157         //SCRUTE(_edgeLength);
158         //SCRUTE(_maxElementArea);
159         return isOk;
160 }
161
162 //=============================================================================
163 /*!
164  *  
165  */
166 //=============================================================================
167
168 bool SMESH_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
169 {
170         MESSAGE("SMESH_MEFISTO_2D::Compute");
171
172         if (_hypLengthFromEdges)
173                 _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
174
175         bool isOk = false;
176         const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
177         SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
178
179         const TopoDS_Face & FF = TopoDS::Face(aShape);
180         bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
181         TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
182
183         Z nblf;                                         //nombre de lignes fermees (enveloppe en tete)
184         Z *nudslf = NULL;                       //numero du dernier sommet de chaque ligne fermee
185         R2 *uvslf = NULL;
186         Z nbpti = 0;                            //nombre points internes futurs sommets de la triangulation
187         R2 *uvpti = NULL;
188
189         Z nbst;
190         R2 *uvst = NULL;
191         Z nbt;
192         Z *nust = NULL;
193         Z ierr = 0;
194
195         Z nutysu = 1;                           // 1: il existe un fonction areteideale_()
196         // Z  nutysu=0;              // 0: on utilise aretmx
197         R aretmx = _edgeLength;         // longueur max aretes future triangulation
198         //SCRUTE(aretmx);
199
200         nblf = NumberOfWires(F);
201         //SCRUTE(nblf);
202
203         nudslf = new Z[1 + nblf];
204         nudslf[0] = 0;
205         int iw = 1;
206         int nbpnt = 0;
207
208         const TopoDS_Wire OW1 = BRepTools::OuterWire(F);
209         nbpnt += NumberOfPoints(aMesh, OW1);
210         nudslf[iw++] = nbpnt;
211         //SCRUTE(nbpnt);
212
213         for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
214         {
215                 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
216                 if (!OW1.IsSame(W))
217                 {
218                         nbpnt += NumberOfPoints(aMesh, W);
219                         nudslf[iw++] = nbpnt;
220                         //SCRUTE(nbpnt);
221                 }
222         }
223
224         uvslf = new R2[nudslf[nblf]];
225         //SCRUTE(nudslf[nblf]);
226         int m = 0;
227
228         map<int, const SMDS_MeshNode*> mefistoToDS;     // correspondence mefisto index--> points IDNodes
229         TopoDS_Wire OW = BRepTools::OuterWire(F);
230         LoadPoints(aMesh, F, OW, uvslf, m, mefistoToDS);
231         //SCRUTE(m);
232
233         for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
234         {
235                 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
236                 if (!OW.IsSame(W))
237                 {
238                         LoadPoints(aMesh, F, W, uvslf, m, mefistoToDS);
239                         //SCRUTE(m);
240                 }
241         }
242 //   SCRUTE(nudslf[nblf]);
243 //   for (int i=0; i<=nblf; i++)
244 //     {
245 //       MESSAGE(" -+- " <<i<< " "<< nudslf[i]);
246 //     }
247 //   for (int i=0; i<nudslf[nblf]; i++)
248 //     {
249 //       MESSAGE(" -+- " <<i<< " "<< uvslf[i]);
250 //     }
251 //   SCRUTE(nutysu);
252 //   SCRUTE(aretmx);
253 //   SCRUTE(nblf);
254
255         MESSAGE("MEFISTO triangulation ...");
256         uvst = NULL;
257         nust = NULL;
258         aptrte(nutysu, aretmx,
259                 nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
260
261         if (ierr == 0)
262         {
263                 MESSAGE("... End Triangulation");
264                 //SCRUTE(nbst);
265                 //SCRUTE(nbt);
266                 StoreResult(aMesh, nbst, uvst, nbt, nust, F,
267                         faceIsForward, mefistoToDS);
268                 isOk = true;
269         }
270         else
271         {
272                 MESSAGE("Error in Triangulation");
273                 isOk = false;
274         }
275         if (nudslf != NULL)
276                 delete[]nudslf;
277         if (uvslf != NULL)
278                 delete[]uvslf;
279         if (uvst != NULL)
280                 delete[]uvst;
281         if (nust != NULL)
282                 delete[]nust;
283         return isOk;
284 }
285
286 //=============================================================================
287 /*!
288  *  
289  */
290 //=============================================================================
291
292 void SMESH_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh,
293         const TopoDS_Face & FF,
294         const TopoDS_Wire & WW, R2 * uvslf, int &m,
295         map<int, const SMDS_MeshNode*>&mefistoToDS)
296 {
297         MESSAGE("SMESH_MEFISTO_2D::LoadPoints");
298
299         SMDS_Mesh * meshDS = aMesh.GetMeshDS();
300
301         double scalex;
302         double scaley;
303         TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
304         ComputeScaleOnFace(aMesh, F, scalex, scaley);
305
306         TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
307         BRepTools_WireExplorer wexp(W, F);
308         for (wexp.Init(W, F); wexp.More(); wexp.Next())
309         {
310                 const TopoDS_Edge & E = wexp.Current();
311
312                 // --- IDNodes of first and last Vertex
313
314                 TopoDS_Vertex VFirst, VLast;
315                 TopExp::Vertices(E, VFirst, VLast);     // corresponds to f and l
316
317             ASSERT(!VFirst.IsNull());
318                 SMDS_Iterator<const SMDS_MeshNode *> * lid=
319                 aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
320                 const SMDS_MeshNode* idFirst = lid->next();
321                 delete lid;
322
323                 ASSERT(!VLast.IsNull());
324                 lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
325                 const SMDS_MeshNode* idLast = lid->next();
326                 delete lid;
327
328                 // --- edge internal IDNodes (relies on good order storage, not checked)
329
330                 int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
331                 //SCRUTE(nbPoints);
332
333                 double f, l;
334                 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
335
336                 SMDS_Iterator<const SMDS_MeshNode *> * ite=
337                         aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
338
339                 bool isForward = (E.Orientation() == TopAbs_FORWARD);
340                 map<double, const SMDS_MeshNode*> params;
341
342                 while(ite->more())
343                 {
344                         const SMDS_MeshNode * node = ite->next();
345                         const SMDS_EdgePosition* epos
346                                 = static_cast<const SMDS_EdgePosition*>(node->GetPosition());
347                         double param = epos->GetUParameter();
348                         params[param] = node;
349                 }
350                 delete ite;
351                 // --- load 2D values into MEFISTO structure,
352                 //     add IDNodes in mefistoToDS map
353
354                 if (E.Orientation() == TopAbs_FORWARD)
355                 {
356                         gp_Pnt2d p = C2d->Value(f);     // first point = Vertex Forward
357                         uvslf[m].x = scalex * p.X();
358                         uvslf[m].y = scaley * p.Y();
359                         mefistoToDS[m + 1] = idFirst;
360                         //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
361                         //MESSAGE("__ f "<<f<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
362                         m++;
363                         map<double, const SMDS_MeshNode*>::iterator itp = params.begin();
364                         for (int i = 1; i <= nbPoints; i++)     // nbPoints internal
365                         {
366                                 double param = (*itp).first;
367                                 gp_Pnt2d p = C2d->Value(param);
368                                 uvslf[m].x = scalex * p.X();
369                                 uvslf[m].y = scaley * p.Y();
370                                 mefistoToDS[m + 1] = (*itp).second;
371 //        MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
372 //        MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
373                                 m++;
374                                 itp++;
375                         }
376                 }
377                 else
378                 {
379                         gp_Pnt2d p = C2d->Value(l);     // last point = Vertex Reversed
380                         uvslf[m].x = scalex * p.X();
381                         uvslf[m].y = scaley * p.Y();
382                         mefistoToDS[m + 1] = idLast;
383 //    MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
384 //    MESSAGE("__ l "<<l<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
385                         m++;
386                         map<double, const SMDS_MeshNode*>::reverse_iterator itp = params.rbegin();
387                         for (int i = nbPoints; i >= 1; i--)
388                         {
389                                 double param = (*itp).first;
390                                 gp_Pnt2d p = C2d->Value(param);
391                                 uvslf[m].x = scalex * p.X();
392                                 uvslf[m].y = scaley * p.Y();
393                                 mefistoToDS[m + 1] = (*itp).second;
394 //        MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
395 //            MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
396                                 m++;
397                                 itp++;
398                         }
399                 }
400         }
401 }
402
403 //=============================================================================
404 /*!
405  *  
406  */
407 //=============================================================================
408
409 // **** a mettre dans SMESH_Algo ou SMESH_2D_Algo
410
411 void SMESH_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
412         const TopoDS_Face & aFace, double &scalex, double &scaley)
413 {
414         //MESSAGE("SMESH_MEFISTO_2D::ComputeScaleOnFace");
415         TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD));
416         TopoDS_Wire W = BRepTools::OuterWire(F);
417
418         BRepTools_WireExplorer wexp(W, F);
419
420         double xmin = 1.e300;           // min & max of face 2D parametric coord.
421         double xmax = -1.e300;
422         double ymin = 1.e300;
423         double ymax = -1.e300;
424         int nbp = 50;
425         scalex = 1;
426         scaley = 1;
427         for (wexp.Init(W, F); wexp.More(); wexp.Next())
428         {
429                 const TopoDS_Edge & E = wexp.Current();
430                 double f, l;
431                 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
432                 for (int i = 0; i <= nbp; i++)
433                 {
434                         double param = f + (double (i) / double (nbp))*(l - f);
435                         gp_Pnt2d p = C2d->Value(param);
436                         if (p.X() < xmin)
437                                 xmin = p.X();
438                         if (p.X() > xmax)
439                                 xmax = p.X();
440                         if (p.Y() < ymin)
441                                 ymin = p.Y();
442                         if (p.Y() > ymax)
443                                 ymax = p.Y();
444 //    MESSAGE(" "<< f<<" "<<l<<" "<<param<<" "<<xmin<<" "<<xmax<<" "<<ymin<<" "<<ymax);
445                 }
446         }
447 //   SCRUTE(xmin);
448 //   SCRUTE(xmax);
449 //   SCRUTE(ymin);
450 //   SCRUTE(ymax);
451         double xmoy = (xmax + xmin) / 2.;
452         double ymoy = (ymax + ymin) / 2.;
453
454         Handle(Geom_Surface) S = BRep_Tool::Surface(F); // 3D surface
455
456         double length_x = 0;
457         double length_y = 0;
458         gp_Pnt PX0 = S->Value(xmin, ymoy);
459         gp_Pnt PY0 = S->Value(xmoy, ymin);
460         for (int i = 1; i <= nbp; i++)
461         {
462                 double x = xmin + (double (i) / double (nbp))*(xmax - xmin);
463                 gp_Pnt PX = S->Value(x, ymoy);
464                 double y = ymin + (double (i) / double (nbp))*(ymax - ymin);
465                 gp_Pnt PY = S->Value(xmoy, y);
466                 length_x += PX.Distance(PX0);
467                 length_y += PY.Distance(PY0);
468                 PX0.SetCoord(PX.X(), PX.Y(), PX.Z());
469                 PY0.SetCoord(PY.X(), PY.Y(), PY.Z());
470         }
471 //   SCRUTE(length_x);
472 //   SCRUTE(length_y);
473         scalex = length_x / (xmax - xmin);
474         scaley = length_y / (ymax - ymin);
475 //   SCRUTE(scalex);
476 //   SCRUTE(scaley);
477         ASSERT(scalex);
478         ASSERT(scaley);
479 }
480
481 //=============================================================================
482 /*!
483  *  
484  */
485 //=============================================================================
486
487 void SMESH_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
488         Z nbst, R2 * uvst, Z nbt, Z * nust,
489         const TopoDS_Face & F, bool faceIsForward,
490         map<int, const SMDS_MeshNode*>&mefistoToDS)
491 {
492         double scalex;
493         double scaley;
494         ComputeScaleOnFace(aMesh, F, scalex, scaley);
495
496         SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
497
498         Z n, m;
499         Handle(Geom_Surface) S = BRep_Tool::Surface(F);
500
501         for (n = 0; n < nbst; n++)
502         {
503                 double u = uvst[n][0] / scalex;
504                 double v = uvst[n][1] / scaley;
505                 gp_Pnt P = S->Value(u, v);
506
507                 if (mefistoToDS.find(n + 1) == mefistoToDS.end())
508                 {
509                         SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
510                         meshDS->SetNodeOnFace(node, F);
511
512                         //MESSAGE(nodeId<<" "<<P.X()<<" "<<P.Y()<<" "<<P.Z());
513                         mefistoToDS[n + 1] = node;
514                         //MESSAGE(" "<<n<<" "<<mefistoToDS[n+1]);
515                         SMDS_FacePosition* fpos
516                                 = static_cast<SMDS_FacePosition*>(node->GetPosition());
517                         fpos->SetUParameter(u);
518                         fpos->SetVParameter(v);
519                 }
520         }
521
522         m = 0;
523         int mt = 0;
524
525         //SCRUTE(faceIsForward);
526         for (n = 1; n <= nbt; n++)
527         {
528                 int inode1 = nust[m++];
529                 int inode2 = nust[m++];
530                 int inode3 = nust[m++];
531
532                 const SMDS_MeshNode *n1, *n2, *n3;
533                 n1 = mefistoToDS[inode1];
534                 n2 = mefistoToDS[inode2];
535                 n3 = mefistoToDS[inode3];
536                 //MESSAGE("-- "<<inode1<<" "<<inode2<<" "<<inode3<<" ++ "<<nodeId1<<" "<<nodeId2<<" "<<nodeId3);
537
538                 // triangle points must be in trigonometric order if face is Forward
539                 // else they must be put clockwise
540
541                 bool triangleIsWellOriented = faceIsForward;
542
543         SMDS_MeshElement * elt;
544                 if (triangleIsWellOriented)
545                         elt = meshDS->AddFace(n1, n2, n3);
546                 else
547                         elt = meshDS->AddFace(n1, n3, n2);
548         
549                 meshDS->SetMeshElementOnShape(elt, F);
550                 m++;
551         }
552 }
553
554 //=============================================================================
555 /*!
556  *  
557  */
558 //=============================================================================
559
560 double SMESH_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
561         const TopoDS_Shape & aShape)
562 {
563         MESSAGE("SMESH_MEFISTO_2D::ComputeEdgeElementLength");
564         // **** a mettre dans SMESH_2D_Algo ?
565
566         const TopoDS_Face & FF = TopoDS::Face(aShape);
567         bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
568         TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
569
570         double meanElementLength = 100;
571         double wireLength = 0;
572         int wireElementsNumber = 0;
573         for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
574         {
575                 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
576                 for (TopExp_Explorer expe(W, TopAbs_EDGE); expe.More(); expe.Next())
577                 {
578                         const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
579                         int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
580                         double length = EdgeLength(E);
581                         wireLength += length;
582                         wireElementsNumber += nb;
583                 }
584         }
585         if (wireElementsNumber)
586                 meanElementLength = wireLength / wireElementsNumber;
587         //SCRUTE(meanElementLength);
588         return meanElementLength;
589 }
590
591 //=============================================================================
592 /*!
593  *  
594  */
595 //=============================================================================
596
597 ostream & SMESH_MEFISTO_2D::SaveTo(ostream & save)
598 {
599         return save << this;
600 }
601
602 //=============================================================================
603 /*!
604  *  
605  */
606 //=============================================================================
607
608 istream & SMESH_MEFISTO_2D::LoadFrom(istream & load)
609 {
610         return load >> (*this);
611 }
612
613 //=============================================================================
614 /*!
615  *  
616  */
617 //=============================================================================
618
619 ostream & operator <<(ostream & save, SMESH_MEFISTO_2D & hyp)
620 {
621         return save;
622 }
623
624 //=============================================================================
625 /*!
626  *  
627  */
628 //=============================================================================
629
630 istream & operator >>(istream & load, SMESH_MEFISTO_2D & hyp)
631 {
632         return load;
633 }