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 SMESH_MesherHelper(aMesh);
221 _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
223 if ( _quadraticMesh && _hypLengthFromEdges )
226 myOuterWire = BRepTools::OuterWire(F);
227 nbpnt += NumberOfPoints(aMesh, myOuterWire);
228 if ( nbpnt < 3 ) { // ex: a circle with 2 segments
229 delete myTool; myTool = 0;
232 nudslf[iw++] = nbpnt;
234 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) {
235 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
236 if (!myOuterWire.IsSame(W)) {
237 nbpnt += NumberOfPoints(aMesh, W);
238 nudslf[iw++] = nbpnt;
242 // avoid passing same uv points for a vertex common to 2 wires
243 TopTools_IndexedDataMapOfShapeListOfShape VWMap;
244 if ( iw - 1 > 1 ) // nbofWires > 1
245 TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap );
247 uvslf = new R2[nudslf[nblf]];
250 double scalex, scaley;
251 ComputeScaleOnFace(aMesh, F, scalex, scaley);
253 map<int, const SMDS_MeshNode*> mefistoToDS; // correspondence mefisto index--> points IDNodes
254 if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m,
255 mefistoToDS, scalex, scaley, VWMap) ) {
256 delete myTool; myTool = 0;
260 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
262 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
263 if (!myOuterWire.IsSame(W))
265 if (! LoadPoints(aMesh, F, W, uvslf, m,
266 mefistoToDS, scalex, scaley, VWMap )) {
267 delete myTool; myTool = 0;
275 aptrte(nutysu, aretmx,
276 nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
280 MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
281 MESSAGE(" Node Number " << nbst);
282 StoreResult(aMesh, nbst, uvst, nbt, nust, F,
283 faceIsForward, mefistoToDS, scalex, scaley);
288 MESSAGE("Error in Triangulation");
299 delete myTool; myTool = 0;
304 //=======================================================================
305 //function : fixOverlappedLinkUV
306 //purpose : prevent failure due to overlapped adjacent links
307 //=======================================================================
309 static bool fixOverlappedLinkUV( R2& uv0, const R2& uv1, const R2& uv2 )
311 gp_XY v1( uv0.x - uv1.x, uv0.y - uv1.y );
312 gp_XY v2( uv2.x - uv1.x, uv2.y - uv1.y );
314 double tol2 = DBL_MIN * DBL_MIN;
315 double sqMod1 = v1.SquareModulus();
316 if ( sqMod1 <= tol2 ) return false;
317 double sqMod2 = v2.SquareModulus();
318 if ( sqMod2 <= tol2 ) return false;
322 // check sinus >= 1.e-3
323 const double minSin = 1.e-3;
324 if ( dot > 0 && 1 - dot * dot / ( sqMod1 * sqMod2 ) < minSin * minSin ) {
325 MESSAGE(" ___ FIX UV ____" << uv0.x << " " << uv0.y);
326 v1.SetCoord( -v1.Y(), v1.X() );
327 double delta = sqrt( sqMod1 ) * minSin;
337 // MESSAGE(" -> " << uv0.x << " " << uv0.y << " ");
338 // MESSAGE("v1( " << v1.X() << " " << v1.Y() << " ) " <<
339 // "v2( " << v2.X() << " " << v2.Y() << " ) ");
340 // MESSAGE("SIN: " << sqrt(1 - dot * dot / (sqMod1 * sqMod2)));
341 // v1.SetCoord( uv0.x - uv1.x, uv0.y - uv1.y );
342 // v2.SetCoord( uv2.x - uv1.x, uv2.y - uv1.y );
343 // gp_XY v3( uv2.x - uv0.x, uv2.y - uv0.y );
344 // sqMod1 = v1.SquareModulus();
345 // sqMod2 = v2.SquareModulus();
347 // double sin = sqrt(1 - dot * dot / (sqMod1 * sqMod2));
348 // MESSAGE("NEW SIN: " << sin);
355 //=======================================================================
356 //function : fixCommonVertexUV
358 //=======================================================================
360 static bool fixCommonVertexUV (gp_Pnt2d & theUV,
361 const TopoDS_Vertex& theV,
362 const TopoDS_Wire& theW,
363 const TopoDS_Wire& theOW,
364 const TopoDS_Face& theF,
365 const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
366 SMESH_Mesh & theMesh,
367 bool CreateQuadratic)
369 if( theW.IsSame( theOW ) ||
370 !theVWMap.Contains( theV )) return false;
372 // check if there is another wire sharing theV
373 const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV );
374 TopTools_ListIteratorOfListOfShape aWIt;
375 for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() )
376 if ( !theW.IsSame( aWIt.Value() ))
378 if ( !aWIt.More() ) return false;
380 TopTools_ListOfShape EList;
381 list< double > UList;
383 // find edges of theW sharing theV
384 // and find 2d normal to them at theV
386 TopoDS_Iterator itE( theW );
387 for ( ; itE.More(); itE.Next() )
389 const TopoDS_Edge& E = TopoDS::Edge( itE.Value() );
390 TopoDS_Iterator itV( E );
391 for ( ; itV.More(); itV.Next() )
393 const TopoDS_Vertex & V = TopoDS::Vertex( itV.Value() );
394 if ( !V.IsSame( theV ))
397 Standard_Real u = BRep_Tool::Parameter( V, E );
398 UList.push_back( u );
400 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
404 gp_Vec2d n( d1.Y(), -d1.X() );
405 if ( E.Orientation() == TopAbs_REVERSED )
411 // define step size by which to move theUV
413 gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four
414 double maxDist = -DBL_MAX;
415 TopTools_ListIteratorOfListOfShape aEIt (EList);
416 list< double >::iterator aUIt = UList.begin();
417 for ( ; aEIt.More(); aEIt.Next(), aUIt++ )
419 const TopoDS_Edge& E = TopoDS::Edge( aEIt.Value() );
421 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
423 double umin = DBL_MAX, umax = -DBL_MAX;
424 SMDS_NodeIteratorPtr nIt = theMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
425 if ( !nIt->more() ) // no nodes on edge, only on vertices
431 while ( nIt->more() ) {
432 const SMDS_MeshNode* node = nIt->next();
433 // check if node is medium
434 if ( CreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
436 const SMDS_EdgePosition* epos =
437 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
438 double u = epos->GetUParameter();
445 bool isFirstCommon = ( *aUIt == f );
446 gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax );
447 double dist = theUV.SquareDistance( uv );
448 if ( dist > maxDist ) {
454 uv0.x = theUV.X(); uv0.y = theUV.Y();
455 uv1.x = nextUV.X(); uv1.y = nextUV.Y();
456 uv2.x = uv0.x; uv2.y = uv0.y;
457 if ( fixOverlappedLinkUV( uv0, uv1, uv2 ))
459 double step = theUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
461 // move theUV along the normal by the step
465 MESSAGE("--fixCommonVertexUV move(" << theUV.X() << " " << theUV.Y()
466 << ") by (" << N.X() << " " << N.Y() << ")"
467 << endl << "--- MAX DIST " << maxDist);
469 theUV.SetXY( theUV.XY() + N.XY() );
476 //=============================================================================
480 //=============================================================================
482 bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh,
483 const TopoDS_Face & FF,
484 const TopoDS_Wire & WW,
487 map<int, const SMDS_MeshNode*>&mefistoToDS,
490 const TopTools_IndexedDataMapOfShapeListOfShape& VWMap)
492 // MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints");
494 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
496 list< int > mOnVertex;
498 gp_XY scale( scalex, scaley );
500 TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
501 BRepTools_WireExplorer wexp(W, F);
502 for ( wexp.Init(W, F); wexp.More(); wexp.Next() )
504 const TopoDS_Edge & E = wexp.Current();
505 bool isForward = (E.Orientation() == TopAbs_FORWARD);
507 // --- IDNodes of first and last Vertex
509 TopoDS_Vertex VFirst, VLast, V;
510 TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
511 V = isForward ? VFirst : VLast;
514 SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(V)->GetSubMeshDS()->GetNodes();
515 if ( !lid->more() ) {
516 MESSAGE (" NO NODE BUILT ON VERTEX ");
519 const SMDS_MeshNode* idFirst = lid->next();
521 // --- edge internal IDNodes (relies on good order storage, not checked)
523 map<double, const SMDS_MeshNode*> params;
524 const SMDS_MeshNode * node;
526 SMDS_NodeIteratorPtr nodeIt= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
527 while ( nodeIt->more() )
529 node = nodeIt->next();
530 if ( _quadraticMesh && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
532 const SMDS_EdgePosition* epos =
533 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
534 double param = epos->GetUParameter();
535 if ( !isForward ) param = -param;
536 if ( !params.insert( make_pair( param, node )).second )
538 MESSAGE( "BAD NODE ON EDGE POSITIONS" );
543 // --- load 2D values into MEFISTO structure,
544 // add IDNodes in mefistoToDS map
546 double f, l, uFirst, u;
547 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
548 uFirst = isForward ? f : l;
551 gp_Pnt2d p = C2d->Value( uFirst ).XY().Multiplied( scale );
552 if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh, _quadraticMesh ))
553 myNodesOnCommonV.push_back( idFirst );
554 mOnVertex.push_back( m );
557 mefistoToDS[m + 1] = idFirst;
558 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
559 //MESSAGE("__ f "<<uFirst<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
563 map<double, const SMDS_MeshNode*>::iterator u_n = params.begin();
564 for ( int i = 0; u_n != params.end(); ++u_n, ++i )
566 u = isForward ? u_n->first : - u_n->first;
567 gp_Pnt2d p = C2d->Value( u ).XY().Multiplied( scale );
570 mefistoToDS[m + 1] = u_n->second;
571 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
572 //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
577 // prevent failure on overlapped adjacent links,
578 // check only links ending in vertex nodes
579 int mFirst = mOnVertex.front(), mLast = m - 1;
580 list< int >::iterator mIt = mOnVertex.begin();
581 for ( ; mIt != mOnVertex.end(); ++mIt ) {
583 int iB = i - 1, iA = i + 1; // indices Before and After
584 if ( iB < mFirst ) iB = mLast;
585 if ( iA > mLast ) iA = mFirst;
586 fixOverlappedLinkUV (uvslf[ iB ], uvslf[ i ], uvslf[ iA ]);
592 //=============================================================================
596 //=============================================================================
598 void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
599 const TopoDS_Face & aFace, double &scalex, double &scaley)
601 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeScaleOnFace");
602 TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD));
603 TopoDS_Wire W = BRepTools::OuterWire(F);
605 double xmin = 1.e300; // min & max of face 2D parametric coord.
606 double xmax = -1.e300;
607 double ymin = 1.e300;
608 double ymax = -1.e300;
613 TopExp_Explorer wexp(W, TopAbs_EDGE);
614 for ( ; wexp.More(); wexp.Next())
616 const TopoDS_Edge & E = TopoDS::Edge( wexp.Current() );
618 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
619 if ( C2d.IsNull() ) continue;
620 double du = (l - f) / double (nbp);
621 for (int i = 0; i <= nbp; i++)
623 double param = f + double (i) * du;
624 gp_Pnt2d p = C2d->Value(param);
633 // MESSAGE(" "<< f<<" "<<l<<" "<<param<<" "<<xmin<<" "<<xmax<<" "<<ymin<<" "<<ymax);
640 double xmoy = (xmax + xmin) / 2.;
641 double ymoy = (ymax + ymin) / 2.;
642 double xsize = xmax - xmin;
643 double ysize = ymax - ymin;
645 Handle(Geom_Surface) S = BRep_Tool::Surface(F); // 3D surface
649 gp_Pnt PX0 = S->Value(xmin, ymoy);
650 gp_Pnt PY0 = S->Value(xmoy, ymin);
651 double dx = xsize / double (nbp);
652 double dy = ysize / double (nbp);
653 for (int i = 1; i <= nbp; i++)
655 double x = xmin + double (i) * dx;
656 gp_Pnt PX = S->Value(x, ymoy);
657 double y = ymin + double (i) * dy;
658 gp_Pnt PY = S->Value(xmoy, y);
659 length_x += PX.Distance(PX0);
660 length_y += PY.Distance(PY0);
664 scalex = length_x / xsize;
665 scaley = length_y / ysize;
668 double xyratio = xsize*scalex/(ysize*scaley);
669 const double maxratio = 1.e2;
671 if (xyratio > maxratio) {
673 scaley *= xyratio / maxratio;
676 else if (xyratio < 1./maxratio) {
678 scalex *= 1 / xyratio / maxratio;
685 //=============================================================================
689 //=============================================================================
691 void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
692 Z nbst, R2 * uvst, Z nbt, Z * nust,
693 const TopoDS_Face & F, bool faceIsForward,
694 map<int, const SMDS_MeshNode*>&mefistoToDS,
695 double scalex, double scaley)
697 SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
698 int faceID = meshDS->ShapeToIndex( F );
701 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
703 for (n = 0; n < nbst; n++)
705 if (mefistoToDS.find(n + 1) == mefistoToDS.end())
707 double u = uvst[n][0] / scalex;
708 double v = uvst[n][1] / scaley;
709 gp_Pnt P = S->Value(u, v);
711 SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
712 meshDS->SetNodeOnFace(node, faceID, u, v);
714 //MESSAGE(P.X()<<" "<<P.Y()<<" "<<P.Z());
715 mefistoToDS[n + 1] = node;
716 //MESSAGE("NEW: "<<n<<" "<<mefistoToDS[n+1]);
722 // triangle points must be in trigonometric order if face is Forward
723 // else they must be put clockwise
725 bool triangleIsWellOriented = faceIsForward;
727 for (n = 1; n <= nbt; n++)
729 const SMDS_MeshNode * n1 = mefistoToDS[ nust[m++] ];
730 const SMDS_MeshNode * n2 = mefistoToDS[ nust[m++] ];
731 const SMDS_MeshNode * n3 = mefistoToDS[ nust[m++] ];
733 SMDS_MeshElement * elt;
734 if (triangleIsWellOriented)
735 //elt = meshDS->AddFace(n1, n2, n3);
736 elt = myTool->AddFace(n1, n2, n3);
738 //elt = meshDS->AddFace(n1, n3, n2);
739 elt = myTool->AddFace(n1, n3, n2);
741 meshDS->SetMeshElementOnShape(elt, faceID);
745 // remove bad elements built on vertices shared by wires
747 list<const SMDS_MeshNode*>::iterator itN = myNodesOnCommonV.begin();
748 for ( ; itN != myNodesOnCommonV.end(); itN++ )
750 const SMDS_MeshNode* node = *itN;
751 SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
752 while ( invElemIt->more() )
754 const SMDS_MeshElement* elem = invElemIt->next();
755 SMDS_ElemIteratorPtr itN = elem->nodesIterator();
757 while ( itN->more() )
758 if ( itN->next() == node)
761 MESSAGE( "RM bad element " << elem->GetID());
762 meshDS->RemoveElement( elem );
769 //=============================================================================
773 //=============================================================================
775 double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
776 const TopoDS_Shape & aShape)
778 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength");
779 // **** a mettre dans SMESH_2D_Algo ?
781 //const TopoDS_Face & FF = TopoDS::Face(aShape);
782 //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
783 //TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
785 double meanElementLength = 100;
786 double wireLength = 0;
787 int wireElementsNumber = 0;
788 for (TopExp_Explorer expe(aShape, TopAbs_EDGE); expe.More(); expe.Next())
790 const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
791 int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
792 double length = EdgeLength(E);
793 wireLength += length;
794 wireElementsNumber += nb;
796 if (wireElementsNumber)
797 meanElementLength = wireLength / wireElementsNumber;
798 //SCRUTE(meanElementLength);
799 return meanElementLength;
802 //=============================================================================
806 //=============================================================================
808 ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save)
813 //=============================================================================
817 //=============================================================================
819 istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load)
824 //=============================================================================
828 //=============================================================================
830 ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp)
832 return hyp.SaveTo( save );
835 //=============================================================================
839 //=============================================================================
841 istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp)
843 return hyp.LoadFrom( load );