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.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 // File : StdMeshers_MEFISTO_2D.cxx
25 // Moved here from SMESH_MEFISTO_2D.cxx
26 // Author : Paul RASCLE, EDF
30 #include "StdMeshers_MEFISTO_2D.hxx"
31 #include "SMESH_Gen.hxx"
32 #include "SMESH_Mesh.hxx"
33 #include "SMESH_subMesh.hxx"
35 #include "StdMeshers_MaxElementArea.hxx"
36 #include "StdMeshers_LengthFromEdges.hxx"
41 #include "SMDS_MeshElement.hxx"
42 #include "SMDS_MeshNode.hxx"
43 #include "SMDS_EdgePosition.hxx"
44 #include "SMDS_FacePosition.hxx"
46 #include "utilities.h"
48 #include <TopoDS_Face.hxx>
49 #include <TopoDS_Edge.hxx>
50 #include <TopoDS_Shape.hxx>
51 #include <Geom_Surface.hxx>
52 #include <GeomAdaptor_Curve.hxx>
53 #include <Geom2d_Curve.hxx>
54 #include <gp_Pnt2d.hxx>
55 #include <BRep_Tool.hxx>
56 #include <BRepTools.hxx>
57 #include <BRepTools_WireExplorer.hxx>
58 #include <GCPnts_AbscissaPoint.hxx>
59 #include <GCPnts_UniformAbscissa.hxx>
60 #include <TColStd_ListIteratorOfListOfInteger.hxx>
61 #include <TopTools_ListIteratorOfListOfShape.hxx>
62 #include <TopTools_ListOfShape.hxx>
64 //=============================================================================
68 //=============================================================================
70 StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId,
71 SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
73 MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D");
75 _shapeType = (1 << TopAbs_FACE);
76 _compatibleHypothesis.push_back("MaxElementArea");
77 _compatibleHypothesis.push_back("LengthFromEdges");
81 _hypMaxElementArea = NULL;
82 _hypLengthFromEdges = NULL;
86 //=============================================================================
90 //=============================================================================
92 StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D()
94 MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D");
97 //=============================================================================
101 //=============================================================================
103 bool StdMeshers_MEFISTO_2D::CheckHypothesis
105 const TopoDS_Shape& aShape,
106 SMESH_Hypothesis::Hypothesis_Status& aStatus)
108 //MESSAGE("StdMeshers_MEFISTO_2D::CheckHypothesis");
110 _hypMaxElementArea = NULL;
111 _hypLengthFromEdges = NULL;
113 list <const SMESHDS_Hypothesis * >::const_iterator itl;
114 const SMESHDS_Hypothesis *theHyp;
116 const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
117 int nbHyp = hyps.size();
120 aStatus = SMESH_Hypothesis::HYP_MISSING;
121 return false; // can't work with no hypothesis
125 theHyp = (*itl); // use only the first hypothesis
127 string hypName = theHyp->GetName();
128 //int hypId = theHyp->GetID();
133 if (hypName == "MaxElementArea")
135 _hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea *>(theHyp);
136 ASSERT(_hypMaxElementArea);
137 _maxElementArea = _hypMaxElementArea->GetMaxArea();
140 aStatus = SMESH_Hypothesis::HYP_OK;
143 else if (hypName == "LengthFromEdges")
145 _hypLengthFromEdges = static_cast<const StdMeshers_LengthFromEdges *>(theHyp);
146 ASSERT(_hypLengthFromEdges);
150 aStatus = SMESH_Hypothesis::HYP_OK;
153 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
158 if (_maxElementArea > 0)
160 // _edgeLength = 2 * sqrt(_maxElementArea); // triangles : minorant
161 _edgeLength = 2 * sqrt(_maxElementArea/sqrt(3.0));
165 isOk = (_hypLengthFromEdges != NULL); // **** check mode
167 aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
170 //SCRUTE(_edgeLength);
171 //SCRUTE(_maxElementArea);
175 //=============================================================================
179 //=============================================================================
181 bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
183 MESSAGE("StdMeshers_MEFISTO_2D::Compute");
185 if (_hypLengthFromEdges)
186 _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
189 //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
190 //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
192 const TopoDS_Face & FF = TopoDS::Face(aShape);
193 bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
194 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
196 Z nblf; //nombre de lignes fermees (enveloppe en tete)
197 Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee
199 Z nbpti = 0; //nombre points internes futurs sommets de la triangulation
208 Z nutysu = 1; // 1: il existe un fonction areteideale_()
209 // Z nutysu=0; // 0: on utilise aretmx
210 R aretmx = _edgeLength; // longueur max aretes future triangulation
212 nblf = NumberOfWires(F);
214 nudslf = new Z[1 + nblf];
219 myTool = new SMESH_MesherHelper(aMesh);
220 _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
222 if ( _quadraticMesh && _hypLengthFromEdges )
225 myOuterWire = BRepTools::OuterWire(F);
226 nbpnt += NumberOfPoints(aMesh, myOuterWire);
227 if ( nbpnt < 3 ) { // ex: a circle with 2 segments
228 delete myTool; myTool = 0;
231 nudslf[iw++] = nbpnt;
233 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) {
234 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
235 if (!myOuterWire.IsSame(W)) {
236 nbpnt += NumberOfPoints(aMesh, W);
237 nudslf[iw++] = nbpnt;
241 // avoid passing same uv points for a vertex common to 2 wires
242 TopTools_IndexedDataMapOfShapeListOfShape VWMap;
243 if ( iw - 1 > 1 ) // nbofWires > 1
244 TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap );
246 uvslf = new R2[nudslf[nblf]];
249 double scalex, scaley;
250 ComputeScaleOnFace(aMesh, F, scalex, scaley);
252 map<int, const SMDS_MeshNode*> mefistoToDS; // correspondence mefisto index--> points IDNodes
253 if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m,
254 mefistoToDS, scalex, scaley, VWMap) ) {
255 delete myTool; myTool = 0;
259 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
261 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
262 if (!myOuterWire.IsSame(W))
264 if (! LoadPoints(aMesh, F, W, uvslf, m,
265 mefistoToDS, scalex, scaley, VWMap )) {
266 delete myTool; myTool = 0;
274 aptrte(nutysu, aretmx,
275 nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
279 MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
280 MESSAGE(" Node Number " << nbst);
281 StoreResult(aMesh, nbst, uvst, nbt, nust, F,
282 faceIsForward, mefistoToDS, scalex, scaley);
287 MESSAGE("Error in Triangulation");
298 delete myTool; myTool = 0;
303 //=======================================================================
304 //function : fixOverlappedLinkUV
305 //purpose : prevent failure due to overlapped adjacent links
306 //=======================================================================
308 static bool fixOverlappedLinkUV( R2& uv0, const R2& uv1, const R2& uv2 )
310 gp_XY v1( uv0.x - uv1.x, uv0.y - uv1.y );
311 gp_XY v2( uv2.x - uv1.x, uv2.y - uv1.y );
313 double tol2 = DBL_MIN * DBL_MIN;
314 double sqMod1 = v1.SquareModulus();
315 if ( sqMod1 <= tol2 ) return false;
316 double sqMod2 = v2.SquareModulus();
317 if ( sqMod2 <= tol2 ) return false;
321 // check sinus >= 1.e-3
322 const double minSin = 1.e-3;
323 if ( dot > 0 && 1 - dot * dot / ( sqMod1 * sqMod2 ) < minSin * minSin ) {
324 MESSAGE(" ___ FIX UV ____" << uv0.x << " " << uv0.y);
325 v1.SetCoord( -v1.Y(), v1.X() );
326 double delta = sqrt( sqMod1 ) * minSin;
336 // MESSAGE(" -> " << uv0.x << " " << uv0.y << " ");
337 // MESSAGE("v1( " << v1.X() << " " << v1.Y() << " ) " <<
338 // "v2( " << v2.X() << " " << v2.Y() << " ) ");
339 // MESSAGE("SIN: " << sqrt(1 - dot * dot / (sqMod1 * sqMod2)));
340 // v1.SetCoord( uv0.x - uv1.x, uv0.y - uv1.y );
341 // v2.SetCoord( uv2.x - uv1.x, uv2.y - uv1.y );
342 // gp_XY v3( uv2.x - uv0.x, uv2.y - uv0.y );
343 // sqMod1 = v1.SquareModulus();
344 // sqMod2 = v2.SquareModulus();
346 // double sin = sqrt(1 - dot * dot / (sqMod1 * sqMod2));
347 // MESSAGE("NEW SIN: " << sin);
354 //=======================================================================
355 //function : fixCommonVertexUV
357 //=======================================================================
359 static bool fixCommonVertexUV (gp_Pnt2d & theUV,
360 const TopoDS_Vertex& theV,
361 const TopoDS_Wire& theW,
362 const TopoDS_Wire& theOW,
363 const TopoDS_Face& theF,
364 const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
365 SMESH_Mesh & theMesh,
366 bool CreateQuadratic)
368 if( theW.IsSame( theOW ) ||
369 !theVWMap.Contains( theV )) return false;
371 // check if there is another wire sharing theV
372 const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV );
373 TopTools_ListIteratorOfListOfShape aWIt;
374 for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() )
375 if ( !theW.IsSame( aWIt.Value() ))
377 if ( !aWIt.More() ) return false;
379 TopTools_ListOfShape EList;
380 list< double > UList;
382 // find edges of theW sharing theV
383 // and find 2d normal to them at theV
385 TopoDS_Iterator itE( theW );
386 for ( ; itE.More(); itE.Next() )
388 const TopoDS_Edge& E = TopoDS::Edge( itE.Value() );
389 TopoDS_Iterator itV( E );
390 for ( ; itV.More(); itV.Next() )
392 const TopoDS_Vertex & V = TopoDS::Vertex( itV.Value() );
393 if ( !V.IsSame( theV ))
396 Standard_Real u = BRep_Tool::Parameter( V, E );
397 UList.push_back( u );
399 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
403 gp_Vec2d n( d1.Y(), -d1.X() );
404 if ( E.Orientation() == TopAbs_REVERSED )
410 // define step size by which to move theUV
412 gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four
413 double maxDist = -DBL_MAX;
414 TopTools_ListIteratorOfListOfShape aEIt (EList);
415 list< double >::iterator aUIt = UList.begin();
416 for ( ; aEIt.More(); aEIt.Next(), aUIt++ )
418 const TopoDS_Edge& E = TopoDS::Edge( aEIt.Value() );
420 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
422 double umin = DBL_MAX, umax = -DBL_MAX;
423 SMDS_NodeIteratorPtr nIt = theMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
424 if ( !nIt->more() ) // no nodes on edge, only on vertices
430 while ( nIt->more() ) {
431 const SMDS_MeshNode* node = nIt->next();
432 // check if node is medium
433 if ( CreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
435 const SMDS_EdgePosition* epos =
436 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
437 double u = epos->GetUParameter();
444 bool isFirstCommon = ( *aUIt == f );
445 gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax );
446 double dist = theUV.SquareDistance( uv );
447 if ( dist > maxDist ) {
453 uv0.x = theUV.X(); uv0.y = theUV.Y();
454 uv1.x = nextUV.X(); uv1.y = nextUV.Y();
455 uv2.x = uv0.x; uv2.y = uv0.y;
456 if ( fixOverlappedLinkUV( uv0, uv1, uv2 ))
458 double step = theUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
460 // move theUV along the normal by the step
464 MESSAGE("--fixCommonVertexUV move(" << theUV.X() << " " << theUV.Y()
465 << ") by (" << N.X() << " " << N.Y() << ")"
466 << endl << "--- MAX DIST " << maxDist);
468 theUV.SetXY( theUV.XY() + N.XY() );
475 //=============================================================================
479 //=============================================================================
481 bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh,
482 const TopoDS_Face & FF,
483 const TopoDS_Wire & WW,
486 map<int, const SMDS_MeshNode*>&mefistoToDS,
489 const TopTools_IndexedDataMapOfShapeListOfShape& VWMap)
491 // MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints");
493 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
495 list< int > mOnVertex;
497 gp_XY scale( scalex, scaley );
499 TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
500 BRepTools_WireExplorer wexp(W, F);
501 for ( wexp.Init(W, F); wexp.More(); wexp.Next() )
503 const TopoDS_Edge & E = wexp.Current();
504 bool isForward = (E.Orientation() == TopAbs_FORWARD);
506 // --- IDNodes of first and last Vertex
508 TopoDS_Vertex VFirst, VLast, V;
509 TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
510 V = isForward ? VFirst : VLast;
513 SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(V)->GetSubMeshDS()->GetNodes();
514 if ( !lid->more() ) {
515 MESSAGE (" NO NODE BUILT ON VERTEX ");
518 const SMDS_MeshNode* idFirst = lid->next();
520 // --- edge internal IDNodes (relies on good order storage, not checked)
522 map<double, const SMDS_MeshNode*> params;
523 const SMDS_MeshNode * node;
525 SMDS_NodeIteratorPtr nodeIt= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
526 while ( nodeIt->more() )
528 node = nodeIt->next();
529 if ( _quadraticMesh && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
531 const SMDS_EdgePosition* epos =
532 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
533 double param = epos->GetUParameter();
534 if ( !isForward ) param = -param;
535 if ( !params.insert( make_pair( param, node )).second )
537 MESSAGE( "BAD NODE ON EDGE POSITIONS" );
542 // --- load 2D values into MEFISTO structure,
543 // add IDNodes in mefistoToDS map
545 double f, l, uFirst, u;
546 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
547 uFirst = isForward ? f : l;
550 gp_Pnt2d p = C2d->Value( uFirst ).XY().Multiplied( scale );
551 if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh, _quadraticMesh ))
552 myNodesOnCommonV.push_back( idFirst );
553 mOnVertex.push_back( m );
556 mefistoToDS[m + 1] = idFirst;
557 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
558 //MESSAGE("__ f "<<uFirst<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
562 map<double, const SMDS_MeshNode*>::iterator u_n = params.begin();
563 for ( int i = 0; u_n != params.end(); ++u_n, ++i )
565 u = isForward ? u_n->first : - u_n->first;
566 gp_Pnt2d p = C2d->Value( u ).XY().Multiplied( scale );
569 mefistoToDS[m + 1] = u_n->second;
570 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
571 //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
576 // prevent failure on overlapped adjacent links,
577 // check only links ending in vertex nodes
578 int mFirst = mOnVertex.front(), mLast = m - 1;
579 list< int >::iterator mIt = mOnVertex.begin();
580 for ( ; mIt != mOnVertex.end(); ++mIt ) {
582 int iB = i - 1, iA = i + 1; // indices Before and After
583 if ( iB < mFirst ) iB = mLast;
584 if ( iA > mLast ) iA = mFirst;
585 fixOverlappedLinkUV (uvslf[ iB ], uvslf[ i ], uvslf[ iA ]);
591 //=============================================================================
595 //=============================================================================
597 void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
598 const TopoDS_Face & aFace, double &scalex, double &scaley)
600 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeScaleOnFace");
601 TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD));
602 TopoDS_Wire W = BRepTools::OuterWire(F);
604 double xmin = 1.e300; // min & max of face 2D parametric coord.
605 double xmax = -1.e300;
606 double ymin = 1.e300;
607 double ymax = -1.e300;
612 TopExp_Explorer wexp(W, TopAbs_EDGE);
613 for ( ; wexp.More(); wexp.Next())
615 const TopoDS_Edge & E = TopoDS::Edge( wexp.Current() );
617 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
618 if ( C2d.IsNull() ) continue;
619 double du = (l - f) / double (nbp);
620 for (int i = 0; i <= nbp; i++)
622 double param = f + double (i) * du;
623 gp_Pnt2d p = C2d->Value(param);
632 // MESSAGE(" "<< f<<" "<<l<<" "<<param<<" "<<xmin<<" "<<xmax<<" "<<ymin<<" "<<ymax);
639 double xmoy = (xmax + xmin) / 2.;
640 double ymoy = (ymax + ymin) / 2.;
641 double xsize = xmax - xmin;
642 double ysize = ymax - ymin;
644 Handle(Geom_Surface) S = BRep_Tool::Surface(F); // 3D surface
648 gp_Pnt PX0 = S->Value(xmin, ymoy);
649 gp_Pnt PY0 = S->Value(xmoy, ymin);
650 double dx = xsize / double (nbp);
651 double dy = ysize / double (nbp);
652 for (int i = 1; i <= nbp; i++)
654 double x = xmin + double (i) * dx;
655 gp_Pnt PX = S->Value(x, ymoy);
656 double y = ymin + double (i) * dy;
657 gp_Pnt PY = S->Value(xmoy, y);
658 length_x += PX.Distance(PX0);
659 length_y += PY.Distance(PY0);
663 scalex = length_x / xsize;
664 scaley = length_y / ysize;
667 double xyratio = xsize*scalex/(ysize*scaley);
668 const double maxratio = 1.e2;
670 if (xyratio > maxratio) {
672 scaley *= xyratio / maxratio;
675 else if (xyratio < 1./maxratio) {
677 scalex *= 1 / xyratio / maxratio;
684 //=============================================================================
688 //=============================================================================
690 void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
691 Z nbst, R2 * uvst, Z nbt, Z * nust,
692 const TopoDS_Face & F, bool faceIsForward,
693 map<int, const SMDS_MeshNode*>&mefistoToDS,
694 double scalex, double scaley)
696 SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
697 int faceID = meshDS->ShapeToIndex( F );
700 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
702 for (n = 0; n < nbst; n++)
704 if (mefistoToDS.find(n + 1) == mefistoToDS.end())
706 double u = uvst[n][0] / scalex;
707 double v = uvst[n][1] / scaley;
708 gp_Pnt P = S->Value(u, v);
710 SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
711 meshDS->SetNodeOnFace(node, faceID, u, v);
713 //MESSAGE(P.X()<<" "<<P.Y()<<" "<<P.Z());
714 mefistoToDS[n + 1] = node;
715 //MESSAGE("NEW: "<<n<<" "<<mefistoToDS[n+1]);
721 // triangle points must be in trigonometric order if face is Forward
722 // else they must be put clockwise
724 bool triangleIsWellOriented = faceIsForward;
726 for (n = 1; n <= nbt; n++)
728 const SMDS_MeshNode * n1 = mefistoToDS[ nust[m++] ];
729 const SMDS_MeshNode * n2 = mefistoToDS[ nust[m++] ];
730 const SMDS_MeshNode * n3 = mefistoToDS[ nust[m++] ];
732 SMDS_MeshElement * elt;
733 if (triangleIsWellOriented)
734 //elt = meshDS->AddFace(n1, n2, n3);
735 elt = myTool->AddFace(n1, n2, n3);
737 //elt = meshDS->AddFace(n1, n3, n2);
738 elt = myTool->AddFace(n1, n3, n2);
740 meshDS->SetMeshElementOnShape(elt, faceID);
744 // remove bad elements built on vertices shared by wires
746 list<const SMDS_MeshNode*>::iterator itN = myNodesOnCommonV.begin();
747 for ( ; itN != myNodesOnCommonV.end(); itN++ )
749 const SMDS_MeshNode* node = *itN;
750 SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
751 while ( invElemIt->more() )
753 const SMDS_MeshElement* elem = invElemIt->next();
754 SMDS_ElemIteratorPtr itN = elem->nodesIterator();
756 while ( itN->more() )
757 if ( itN->next() == node)
760 MESSAGE( "RM bad element " << elem->GetID());
761 meshDS->RemoveElement( elem );
768 //=============================================================================
772 //=============================================================================
774 double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
775 const TopoDS_Shape & aShape)
777 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength");
778 // **** a mettre dans SMESH_2D_Algo ?
780 //const TopoDS_Face & FF = TopoDS::Face(aShape);
781 //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
782 //TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
784 double meanElementLength = 100;
785 double wireLength = 0;
786 int wireElementsNumber = 0;
787 for (TopExp_Explorer expe(aShape, TopAbs_EDGE); expe.More(); expe.Next())
789 const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
790 int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
791 double length = EdgeLength(E);
792 wireLength += length;
793 wireElementsNumber += nb;
795 if (wireElementsNumber)
796 meanElementLength = wireLength / wireElementsNumber;
797 //SCRUTE(meanElementLength);
798 return meanElementLength;
801 //=============================================================================
805 //=============================================================================
807 ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save)
812 //=============================================================================
816 //=============================================================================
818 istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load)
823 //=============================================================================
827 //=============================================================================
829 ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp)
831 return hyp.SaveTo( save );
834 //=============================================================================
838 //=============================================================================
840 istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp)
842 return hyp.LoadFrom( load );