1 // SMESH SMESH : implementaion of SMESH idl descriptions
3 // Copyright (C) 2003 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, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : StdMeshers_MEFISTO_2D.cxx
25 // Moved here from SMESH_MEFISTO_2D.cxx
26 // Author : Paul RASCLE, EDF
31 #include "StdMeshers_MEFISTO_2D.hxx"
32 #include "SMESH_Gen.hxx"
33 #include "SMESH_Mesh.hxx"
34 #include "SMESH_subMesh.hxx"
36 #include "StdMeshers_MaxElementArea.hxx"
37 #include "StdMeshers_LengthFromEdges.hxx"
42 #include "SMDS_MeshElement.hxx"
43 #include "SMDS_MeshNode.hxx"
44 #include "SMDS_EdgePosition.hxx"
45 #include "SMDS_FacePosition.hxx"
47 #include "utilities.h"
49 #include <TopoDS_Face.hxx>
50 #include <TopoDS_Edge.hxx>
51 #include <TopoDS_Shape.hxx>
52 #include <Geom_Surface.hxx>
53 #include <GeomAdaptor_Curve.hxx>
54 #include <Geom2d_Curve.hxx>
55 #include <gp_Pnt2d.hxx>
56 #include <BRep_Tool.hxx>
57 #include <BRepTools.hxx>
58 #include <BRepTools_WireExplorer.hxx>
59 #include <GCPnts_AbscissaPoint.hxx>
60 #include <GCPnts_UniformAbscissa.hxx>
61 #include <TColStd_ListIteratorOfListOfInteger.hxx>
62 #include <TopTools_ListIteratorOfListOfShape.hxx>
63 #include <TopTools_ListOfShape.hxx>
65 //=============================================================================
69 //=============================================================================
71 StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId,
72 SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
74 MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D");
76 _shapeType = (1 << TopAbs_FACE);
77 _compatibleHypothesis.push_back("MaxElementArea");
78 _compatibleHypothesis.push_back("LengthFromEdges");
82 _hypMaxElementArea = NULL;
83 _hypLengthFromEdges = NULL;
87 //=============================================================================
91 //=============================================================================
93 StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D()
95 MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D");
98 //=============================================================================
102 //=============================================================================
104 bool StdMeshers_MEFISTO_2D::CheckHypothesis
106 const TopoDS_Shape& aShape,
107 SMESH_Hypothesis::Hypothesis_Status& aStatus)
109 //MESSAGE("StdMeshers_MEFISTO_2D::CheckHypothesis");
111 _hypMaxElementArea = NULL;
112 _hypLengthFromEdges = NULL;
114 list <const SMESHDS_Hypothesis * >::const_iterator itl;
115 const SMESHDS_Hypothesis *theHyp;
117 const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
118 int nbHyp = hyps.size();
121 aStatus = SMESH_Hypothesis::HYP_MISSING;
122 return false; // can't work with no hypothesis
126 theHyp = (*itl); // use only the first hypothesis
128 string hypName = theHyp->GetName();
129 //int hypId = theHyp->GetID();
134 if (hypName == "MaxElementArea")
136 _hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea *>(theHyp);
137 ASSERT(_hypMaxElementArea);
138 _maxElementArea = _hypMaxElementArea->GetMaxArea();
141 aStatus = SMESH_Hypothesis::HYP_OK;
144 else if (hypName == "LengthFromEdges")
146 _hypLengthFromEdges = static_cast<const StdMeshers_LengthFromEdges *>(theHyp);
147 ASSERT(_hypLengthFromEdges);
151 aStatus = SMESH_Hypothesis::HYP_OK;
154 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
159 if (_maxElementArea > 0)
161 // _edgeLength = 2 * sqrt(_maxElementArea); // triangles : minorant
162 _edgeLength = 2 * sqrt(_maxElementArea/sqrt(3.0));
166 isOk = (_hypLengthFromEdges != NULL); // **** check mode
168 aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
171 //SCRUTE(_edgeLength);
172 //SCRUTE(_maxElementArea);
176 //=============================================================================
180 //=============================================================================
182 bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
184 MESSAGE("StdMeshers_MEFISTO_2D::Compute");
186 if (_hypLengthFromEdges)
187 _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
190 //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
191 //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
193 const TopoDS_Face & FF = TopoDS::Face(aShape);
194 bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
195 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
197 Z nblf; //nombre de lignes fermees (enveloppe en tete)
198 Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee
200 Z nbpti = 0; //nombre points internes futurs sommets de la triangulation
209 Z nutysu = 1; // 1: il existe un fonction areteideale_()
210 // Z nutysu=0; // 0: on utilise aretmx
211 R aretmx = _edgeLength; // longueur max aretes future triangulation
213 nblf = NumberOfWires(F);
215 nudslf = new Z[1 + nblf];
220 myTool = new StdMeshers_Helper(aMesh);
221 _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
223 myOuterWire = BRepTools::OuterWire(F);
224 nbpnt += NumberOfPoints(aMesh, myOuterWire);
225 if ( nbpnt < 3 ) { // ex: a circle with 2 segments
226 delete myTool; myTool = 0;
229 nudslf[iw++] = nbpnt;
231 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) {
232 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
233 if (!myOuterWire.IsSame(W)) {
234 nbpnt += NumberOfPoints(aMesh, W);
235 nudslf[iw++] = nbpnt;
239 // avoid passing same uv points for a vertex common to 2 wires
240 TopTools_IndexedDataMapOfShapeListOfShape VWMap;
241 if ( iw - 1 > 1 ) // nbofWires > 1
242 TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap );
244 uvslf = new R2[nudslf[nblf]];
247 double scalex, scaley;
248 ComputeScaleOnFace(aMesh, F, scalex, scaley);
250 map<int, const SMDS_MeshNode*> mefistoToDS; // correspondence mefisto index--> points IDNodes
251 if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m,
252 mefistoToDS, scalex, scaley, VWMap) ) {
253 delete myTool; myTool = 0;
257 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
259 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
260 if (!myOuterWire.IsSame(W))
262 if (! LoadPoints(aMesh, F, W, uvslf, m,
263 mefistoToDS, scalex, scaley, VWMap )) {
264 delete myTool; myTool = 0;
272 aptrte(nutysu, aretmx,
273 nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
277 MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
278 MESSAGE(" Node Number " << nbst);
279 StoreResult(aMesh, nbst, uvst, nbt, nust, F,
280 faceIsForward, mefistoToDS, scalex, scaley);
285 MESSAGE("Error in Triangulation");
296 delete myTool; myTool = 0;
301 //=======================================================================
302 //function : fixOverlappedLinkUV
303 //purpose : prevent failure due to overlapped adjacent links
304 //=======================================================================
306 static bool fixOverlappedLinkUV( R2& uv0, const R2& uv1, const R2& uv2 )
308 gp_XY v1( uv0.x - uv1.x, uv0.y - uv1.y );
309 gp_XY v2( uv2.x - uv1.x, uv2.y - uv1.y );
311 double tol2 = DBL_MIN * DBL_MIN;
312 double sqMod1 = v1.SquareModulus();
313 if ( sqMod1 <= tol2 ) return false;
314 double sqMod2 = v2.SquareModulus();
315 if ( sqMod2 <= tol2 ) return false;
319 // check sinus >= 1.e-3
320 const double minSin = 1.e-3;
321 if ( dot > 0 && 1 - dot * dot / ( sqMod1 * sqMod2 ) < minSin * minSin ) {
322 MESSAGE(" ___ FIX UV ____" << uv0.x << " " << uv0.y);
323 v1.SetCoord( -v1.Y(), v1.X() );
324 double delta = sqrt( sqMod1 ) * minSin;
334 // MESSAGE(" -> " << uv0.x << " " << uv0.y << " ");
335 // MESSAGE("v1( " << v1.X() << " " << v1.Y() << " ) " <<
336 // "v2( " << v2.X() << " " << v2.Y() << " ) ");
337 // MESSAGE("SIN: " << sqrt(1 - dot * dot / (sqMod1 * sqMod2)));
338 // v1.SetCoord( uv0.x - uv1.x, uv0.y - uv1.y );
339 // v2.SetCoord( uv2.x - uv1.x, uv2.y - uv1.y );
340 // gp_XY v3( uv2.x - uv0.x, uv2.y - uv0.y );
341 // sqMod1 = v1.SquareModulus();
342 // sqMod2 = v2.SquareModulus();
344 // double sin = sqrt(1 - dot * dot / (sqMod1 * sqMod2));
345 // MESSAGE("NEW SIN: " << sin);
352 //=======================================================================
353 //function : fixCommonVertexUV
355 //=======================================================================
357 static bool fixCommonVertexUV (gp_Pnt2d & theUV,
358 const TopoDS_Vertex& theV,
359 const TopoDS_Wire& theW,
360 const TopoDS_Wire& theOW,
361 const TopoDS_Face& theF,
362 const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
363 SMESH_Mesh & theMesh,
364 bool CreateQuadratic)
366 if( theW.IsSame( theOW ) ||
367 !theVWMap.Contains( theV )) return false;
369 // check if there is another wire sharing theV
370 const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV );
371 TopTools_ListIteratorOfListOfShape aWIt;
372 for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() )
373 if ( !theW.IsSame( aWIt.Value() ))
375 if ( !aWIt.More() ) return false;
377 TopTools_ListOfShape EList;
378 list< double > UList;
380 // find edges of theW sharing theV
381 // and find 2d normal to them at theV
383 TopoDS_Iterator itE( theW );
384 for ( ; itE.More(); itE.Next() )
386 const TopoDS_Edge& E = TopoDS::Edge( itE.Value() );
387 TopoDS_Iterator itV( E );
388 for ( ; itV.More(); itV.Next() )
390 const TopoDS_Vertex & V = TopoDS::Vertex( itV.Value() );
391 if ( !V.IsSame( theV ))
394 Standard_Real u = BRep_Tool::Parameter( V, E );
395 UList.push_back( u );
397 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
401 gp_Vec2d n( d1.Y(), -d1.X() );
402 if ( E.Orientation() == TopAbs_REVERSED )
408 // define step size by which to move theUV
410 gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four
411 double maxDist = -DBL_MAX;
412 TopTools_ListIteratorOfListOfShape aEIt (EList);
413 list< double >::iterator aUIt = UList.begin();
414 for ( ; aEIt.More(); aEIt.Next(), aUIt++ )
416 const TopoDS_Edge& E = TopoDS::Edge( aEIt.Value() );
418 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
420 double umin = DBL_MAX, umax = -DBL_MAX;
421 SMDS_NodeIteratorPtr nIt = theMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
422 if ( !nIt->more() ) // no nodes on edge, only on vertices
428 while ( nIt->more() ) {
429 const SMDS_MeshNode* node = nIt->next();
430 // check if node is medium
431 if ( CreateQuadratic && StdMeshers_Helper::IsMedium( node, SMDSAbs_Edge ))
433 const SMDS_EdgePosition* epos =
434 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
435 double u = epos->GetUParameter();
442 bool isFirstCommon = ( *aUIt == f );
443 gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax );
444 double dist = theUV.SquareDistance( uv );
445 if ( dist > maxDist ) {
451 uv0.x = theUV.X(); uv0.y = theUV.Y();
452 uv1.x = nextUV.X(); uv1.y = nextUV.Y();
453 uv2.x = uv0.x; uv2.y = uv0.y;
454 if ( fixOverlappedLinkUV( uv0, uv1, uv2 ))
456 double step = theUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
458 // move theUV along the normal by the step
462 MESSAGE("--fixCommonVertexUV move(" << theUV.X() << " " << theUV.Y()
463 << ") by (" << N.X() << " " << N.Y() << ")"
464 << endl << "--- MAX DIST " << maxDist);
466 theUV.SetXY( theUV.XY() + N.XY() );
473 //=============================================================================
477 //=============================================================================
479 bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh,
480 const TopoDS_Face & FF,
481 const TopoDS_Wire & WW,
484 map<int, const SMDS_MeshNode*>&mefistoToDS,
487 const TopTools_IndexedDataMapOfShapeListOfShape& VWMap)
489 // MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints");
491 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
493 list< int > mOnVertex;
495 gp_XY scale( scalex, scaley );
497 TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
498 BRepTools_WireExplorer wexp(W, F);
499 for ( wexp.Init(W, F); wexp.More(); wexp.Next() )
501 const TopoDS_Edge & E = wexp.Current();
502 bool isForward = (E.Orientation() == TopAbs_FORWARD);
504 // --- IDNodes of first and last Vertex
506 TopoDS_Vertex VFirst, VLast, V;
507 TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
508 V = isForward ? VFirst : VLast;
511 SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(V)->GetSubMeshDS()->GetNodes();
512 if ( !lid->more() ) {
513 MESSAGE (" NO NODE BUILT ON VERTEX ");
516 const SMDS_MeshNode* idFirst = lid->next();
518 // --- edge internal IDNodes (relies on good order storage, not checked)
520 map<double, const SMDS_MeshNode*> params;
521 const SMDS_MeshNode * node;
523 SMDS_NodeIteratorPtr nodeIt= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
524 while ( nodeIt->more() )
526 node = nodeIt->next();
527 if ( _quadraticMesh && StdMeshers_Helper::IsMedium( node, SMDSAbs_Edge ))
529 const SMDS_EdgePosition* epos =
530 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
531 double param = epos->GetUParameter();
532 if ( !isForward ) param = -param;
533 if ( !params.insert( make_pair( param, node )).second )
535 MESSAGE( "BAD NODE ON EDGE POSITIONS" );
540 // --- load 2D values into MEFISTO structure,
541 // add IDNodes in mefistoToDS map
543 double f, l, uFirst, u;
544 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
545 uFirst = isForward ? f : l;
548 gp_Pnt2d p = C2d->Value( uFirst ).XY().Multiplied( scale );
549 if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh, _quadraticMesh ))
550 myNodesOnCommonV.push_back( idFirst );
551 mOnVertex.push_back( m );
554 mefistoToDS[m + 1] = idFirst;
555 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
556 //MESSAGE("__ f "<<uFirst<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
560 map<double, const SMDS_MeshNode*>::iterator u_n = params.begin();
561 for ( int i = 0; u_n != params.end(); ++u_n, ++i )
563 u = isForward ? u_n->first : - u_n->first;
564 gp_Pnt2d p = C2d->Value( u ).XY().Multiplied( scale );
567 mefistoToDS[m + 1] = u_n->second;
568 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
569 //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
574 // prevent failure on overlapped adjacent links,
575 // check only links ending in vertex nodes
576 int mFirst = mOnVertex.front(), mLast = m - 1;
577 list< int >::iterator mIt = mOnVertex.begin();
578 for ( ; mIt != mOnVertex.end(); ++mIt ) {
580 int iB = i - 1, iA = i + 1; // indices Before and After
581 if ( iB < mFirst ) iB = mLast;
582 if ( iA > mLast ) iA = mFirst;
583 fixOverlappedLinkUV (uvslf[ iB ], uvslf[ i ], uvslf[ iA ]);
589 //=============================================================================
593 //=============================================================================
595 void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
596 const TopoDS_Face & aFace, double &scalex, double &scaley)
598 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeScaleOnFace");
599 TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD));
600 TopoDS_Wire W = BRepTools::OuterWire(F);
602 double xmin = 1.e300; // min & max of face 2D parametric coord.
603 double xmax = -1.e300;
604 double ymin = 1.e300;
605 double ymax = -1.e300;
610 TopExp_Explorer wexp(W, TopAbs_EDGE);
611 for ( ; wexp.More(); wexp.Next())
613 const TopoDS_Edge & E = TopoDS::Edge( wexp.Current() );
615 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
616 if ( C2d.IsNull() ) continue;
617 double du = (l - f) / double (nbp);
618 for (int i = 0; i <= nbp; i++)
620 double param = f + double (i) * du;
621 gp_Pnt2d p = C2d->Value(param);
630 // MESSAGE(" "<< f<<" "<<l<<" "<<param<<" "<<xmin<<" "<<xmax<<" "<<ymin<<" "<<ymax);
637 double xmoy = (xmax + xmin) / 2.;
638 double ymoy = (ymax + ymin) / 2.;
639 double xsize = xmax - xmin;
640 double ysize = ymax - ymin;
642 Handle(Geom_Surface) S = BRep_Tool::Surface(F); // 3D surface
646 gp_Pnt PX0 = S->Value(xmin, ymoy);
647 gp_Pnt PY0 = S->Value(xmoy, ymin);
648 double dx = xsize / double (nbp);
649 double dy = ysize / double (nbp);
650 for (int i = 1; i <= nbp; i++)
652 double x = xmin + double (i) * dx;
653 gp_Pnt PX = S->Value(x, ymoy);
654 double y = ymin + double (i) * dy;
655 gp_Pnt PY = S->Value(xmoy, y);
656 length_x += PX.Distance(PX0);
657 length_y += PY.Distance(PY0);
661 scalex = length_x / xsize;
662 scaley = length_y / ysize;
665 double xyratio = xsize*scalex/(ysize*scaley);
666 const double maxratio = 1.e2;
668 if (xyratio > maxratio) {
670 scaley *= xyratio / maxratio;
673 else if (xyratio < 1./maxratio) {
675 scalex *= 1 / xyratio / maxratio;
682 //=============================================================================
686 //=============================================================================
688 void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
689 Z nbst, R2 * uvst, Z nbt, Z * nust,
690 const TopoDS_Face & F, bool faceIsForward,
691 map<int, const SMDS_MeshNode*>&mefistoToDS,
692 double scalex, double scaley)
694 SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
695 int faceID = meshDS->ShapeToIndex( F );
698 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
700 for (n = 0; n < nbst; n++)
702 if (mefistoToDS.find(n + 1) == mefistoToDS.end())
704 double u = uvst[n][0] / scalex;
705 double v = uvst[n][1] / scaley;
706 gp_Pnt P = S->Value(u, v);
708 SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
709 meshDS->SetNodeOnFace(node, faceID, u, v);
711 //MESSAGE(P.X()<<" "<<P.Y()<<" "<<P.Z());
712 mefistoToDS[n + 1] = node;
713 //MESSAGE("NEW: "<<n<<" "<<mefistoToDS[n+1]);
719 // triangle points must be in trigonometric order if face is Forward
720 // else they must be put clockwise
722 bool triangleIsWellOriented = faceIsForward;
724 for (n = 1; n <= nbt; n++)
726 const SMDS_MeshNode * n1 = mefistoToDS[ nust[m++] ];
727 const SMDS_MeshNode * n2 = mefistoToDS[ nust[m++] ];
728 const SMDS_MeshNode * n3 = mefistoToDS[ nust[m++] ];
730 SMDS_MeshElement * elt;
731 if (triangleIsWellOriented)
732 //elt = meshDS->AddFace(n1, n2, n3);
733 elt = myTool->AddFace(n1, n2, n3);
735 //elt = meshDS->AddFace(n1, n3, n2);
736 elt = myTool->AddFace(n1, n3, n2);
738 meshDS->SetMeshElementOnShape(elt, faceID);
742 // remove bad elements built on vertices shared by wires
744 list<const SMDS_MeshNode*>::iterator itN = myNodesOnCommonV.begin();
745 for ( ; itN != myNodesOnCommonV.end(); itN++ )
747 const SMDS_MeshNode* node = *itN;
748 SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
749 while ( invElemIt->more() )
751 const SMDS_MeshElement* elem = invElemIt->next();
752 SMDS_ElemIteratorPtr itN = elem->nodesIterator();
754 while ( itN->more() )
755 if ( itN->next() == node)
758 MESSAGE( "RM bad element " << elem->GetID());
759 meshDS->RemoveElement( elem );
766 //=============================================================================
770 //=============================================================================
772 double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
773 const TopoDS_Shape & aShape)
775 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength");
776 // **** a mettre dans SMESH_2D_Algo ?
778 //const TopoDS_Face & FF = TopoDS::Face(aShape);
779 //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
780 //TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
782 double meanElementLength = 100;
783 double wireLength = 0;
784 int wireElementsNumber = 0;
785 for (TopExp_Explorer expe(aShape, TopAbs_EDGE); expe.More(); expe.Next())
787 const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
788 int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
789 double length = EdgeLength(E);
790 wireLength += length;
791 wireElementsNumber += nb;
793 if (wireElementsNumber)
794 meanElementLength = wireLength / wireElementsNumber;
795 //SCRUTE(meanElementLength);
796 return meanElementLength;
799 //=============================================================================
803 //=============================================================================
805 ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save)
810 //=============================================================================
814 //=============================================================================
816 istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load)
821 //=============================================================================
825 //=============================================================================
827 ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp)
829 return hyp.SaveTo( save );
832 //=============================================================================
836 //=============================================================================
838 istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp)
840 return hyp.LoadFrom( load );