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>
66 //#include <algorithm>
68 //=============================================================================
72 //=============================================================================
74 StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId,
75 SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
77 MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D");
79 // _shapeType = TopAbs_FACE;
80 _shapeType = (1 << TopAbs_FACE);
81 _compatibleHypothesis.push_back("MaxElementArea");
82 _compatibleHypothesis.push_back("LengthFromEdges");
86 _hypMaxElementArea = NULL;
87 _hypLengthFromEdges = NULL;
90 //=============================================================================
94 //=============================================================================
96 StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D()
98 MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D");
101 //=============================================================================
105 //=============================================================================
107 bool StdMeshers_MEFISTO_2D::CheckHypothesis
109 const TopoDS_Shape& aShape,
110 SMESH_Hypothesis::Hypothesis_Status& aStatus)
112 //MESSAGE("StdMeshers_MEFISTO_2D::CheckHypothesis");
114 _hypMaxElementArea = NULL;
115 _hypLengthFromEdges = NULL;
117 list <const SMESHDS_Hypothesis * >::const_iterator itl;
118 const SMESHDS_Hypothesis *theHyp;
120 const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
121 int nbHyp = hyps.size();
124 aStatus = SMESH_Hypothesis::HYP_MISSING;
125 return false; // can't work with no hypothesis
129 theHyp = (*itl); // use only the first hypothesis
131 string hypName = theHyp->GetName();
132 //int hypId = theHyp->GetID();
137 if (hypName == "MaxElementArea")
139 _hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea *>(theHyp);
140 ASSERT(_hypMaxElementArea);
141 _maxElementArea = _hypMaxElementArea->GetMaxArea();
144 aStatus = SMESH_Hypothesis::HYP_OK;
147 else if (hypName == "LengthFromEdges")
149 _hypLengthFromEdges = static_cast<const StdMeshers_LengthFromEdges *>(theHyp);
150 ASSERT(_hypLengthFromEdges);
154 aStatus = SMESH_Hypothesis::HYP_OK;
157 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
162 if (_maxElementArea > 0)
164 // _edgeLength = 2 * sqrt(_maxElementArea); // triangles : minorant
165 _edgeLength = 2 * sqrt(_maxElementArea/sqrt(3.0));
169 isOk = (_hypLengthFromEdges != NULL); // **** check mode
171 aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
174 //SCRUTE(_edgeLength);
175 //SCRUTE(_maxElementArea);
179 //=============================================================================
183 //=============================================================================
185 bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
187 MESSAGE("StdMeshers_MEFISTO_2D::Compute");
189 if (_hypLengthFromEdges)
190 _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
193 //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
194 //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
196 const TopoDS_Face & FF = TopoDS::Face(aShape);
197 bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
198 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
200 Z nblf; //nombre de lignes fermees (enveloppe en tete)
201 Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee
203 Z nbpti = 0; //nombre points internes futurs sommets de la triangulation
212 Z nutysu = 1; // 1: il existe un fonction areteideale_()
213 // Z nutysu=0; // 0: on utilise aretmx
214 R aretmx = _edgeLength; // longueur max aretes future triangulation
216 nblf = NumberOfWires(F);
218 nudslf = new Z[1 + nblf];
223 myOuterWire = BRepTools::OuterWire(F);
224 nbpnt += NumberOfPoints(aMesh, myOuterWire);
225 if ( nbpnt < 3 ) // ex: a circle with 2 segments
227 nudslf[iw++] = nbpnt;
229 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
231 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
232 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))
255 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
257 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
258 if (!myOuterWire.IsSame(W))
260 if (! LoadPoints(aMesh, F, W, uvslf, m,
261 mefistoToDS, scalex, scaley, VWMap ))
268 aptrte(nutysu, aretmx,
269 nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
273 MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
274 MESSAGE(" Node Number " << nbst);
275 StoreResult(aMesh, nbst, uvst, nbt, nust, F,
276 faceIsForward, mefistoToDS, scalex, scaley);
281 MESSAGE("Error in Triangulation");
295 //=======================================================================
296 //function : fixOverlappedLinkUV
297 //purpose : prevent failure due to overlapped adjacent links
298 //=======================================================================
300 static bool fixOverlappedLinkUV( R2& uv0, const R2& uv1, const R2& uv2 )
302 gp_XY v1( uv0.x - uv1.x, uv0.y - uv1.y );
303 gp_XY v2( uv2.x - uv1.x, uv2.y - uv1.y );
305 double tol2 = DBL_MIN * DBL_MIN;
306 double sqMod1 = v1.SquareModulus();
307 if ( sqMod1 <= tol2 ) return false;
308 double sqMod2 = v2.SquareModulus();
309 if ( sqMod2 <= tol2 ) return false;
313 // check sinus >= 1.e-3
314 const double minSin = 1.e-3;
315 if ( dot > 0 && 1 - dot * dot / ( sqMod1 * sqMod2 ) < minSin * minSin ) {
316 MESSAGE(" ___ FIX UV ____" << uv0.x << " " << uv0.y);
317 v1.SetCoord( -v1.Y(), v1.X() );
318 double delta = sqrt( sqMod1 ) * minSin;
328 // MESSAGE(" -> " << uv0.x << " " << uv0.y << " ");
329 // MESSAGE("v1( " << v1.X() << " " << v1.Y() << " ) " <<
330 // "v2( " << v2.X() << " " << v2.Y() << " ) ");
331 // MESSAGE("SIN: " << sqrt(1 - dot * dot / (sqMod1 * sqMod2)));
332 // v1.SetCoord( uv0.x - uv1.x, uv0.y - uv1.y );
333 // v2.SetCoord( uv2.x - uv1.x, uv2.y - uv1.y );
334 // gp_XY v3( uv2.x - uv0.x, uv2.y - uv0.y );
335 // sqMod1 = v1.SquareModulus();
336 // sqMod2 = v2.SquareModulus();
338 // double sin = sqrt(1 - dot * dot / (sqMod1 * sqMod2));
339 // MESSAGE("NEW SIN: " << sin);
346 //=======================================================================
347 //function : fixCommonVertexUV
349 //=======================================================================
351 static bool fixCommonVertexUV (gp_Pnt2d & theUV,
352 const TopoDS_Vertex& theV,
353 const TopoDS_Wire& theW,
354 const TopoDS_Wire& theOW,
355 const TopoDS_Face& theF,
356 const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
357 SMESH_Mesh & theMesh)
359 if( theW.IsSame( theOW ) ||
360 !theVWMap.Contains( theV )) return false;
362 // check if there is another wire sharing theV
363 const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV );
364 TopTools_ListIteratorOfListOfShape aWIt;
365 for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() )
366 if ( !theW.IsSame( aWIt.Value() ))
368 if ( !aWIt.More() ) return false;
370 TopTools_ListOfShape EList;
371 list< double > UList;
373 // find edges of theW sharing theV
374 // and find 2d normal to them at theV
376 TopoDS_Iterator itE( theW );
377 for ( ; itE.More(); itE.Next() )
379 const TopoDS_Edge& E = TopoDS::Edge( itE.Value() );
380 TopoDS_Iterator itV( E );
381 for ( ; itV.More(); itV.Next() )
383 const TopoDS_Vertex & V = TopoDS::Vertex( itV.Value() );
384 if ( !V.IsSame( theV ))
387 Standard_Real u = BRep_Tool::Parameter( V, E );
388 UList.push_back( u );
390 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
394 gp_Vec2d n( d1.Y(), -d1.X() );
395 if ( E.Orientation() == TopAbs_REVERSED )
401 // define step size by which to move theUV
403 gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four
404 double maxDist = -DBL_MAX;
405 TopTools_ListIteratorOfListOfShape aEIt (EList);
406 list< double >::iterator aUIt = UList.begin();
407 for ( ; aEIt.More(); aEIt.Next(), aUIt++ )
409 const TopoDS_Edge& E = TopoDS::Edge( aEIt.Value() );
411 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
413 double umin = DBL_MAX, umax = -DBL_MAX;
414 SMDS_NodeIteratorPtr nIt = theMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
415 if ( !nIt->more() ) // no nodes on edge, only on vertices
422 while ( nIt->more() ) {
423 const SMDS_MeshNode* node = nIt->next();
424 const SMDS_EdgePosition* epos =
425 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
426 double u = epos->GetUParameter();
433 bool isFirstCommon = ( *aUIt == f );
434 gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax );
435 double dist = theUV.SquareDistance( uv );
436 if ( dist > maxDist ) {
442 uv0.x = theUV.X(); uv0.y = theUV.Y();
443 uv1.x = nextUV.X(); uv1.y = nextUV.Y();
444 uv2.x = uv0.x; uv2.y = uv0.y;
445 if ( fixOverlappedLinkUV( uv0, uv1, uv2 ))
447 double step = theUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
449 // move theUV along the normal by the step
453 MESSAGE("--fixCommonVertexUV move(" << theUV.X() << " " << theUV.Y()
454 << ") by (" << N.X() << " " << N.Y() << ")"
455 << endl << "--- MAX DIST " << maxDist);
457 theUV.SetXY( theUV.XY() + N.XY() );
464 //=============================================================================
468 //=============================================================================
470 bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh,
471 const TopoDS_Face & FF,
472 const TopoDS_Wire & WW,
475 map<int, const SMDS_MeshNode*>&mefistoToDS,
478 const TopTools_IndexedDataMapOfShapeListOfShape& VWMap)
480 // MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints");
482 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
484 list< int > mOnVertex;
486 gp_XY scale( scalex, scaley );
488 TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
489 BRepTools_WireExplorer wexp(W, F);
490 for ( wexp.Init(W, F); wexp.More(); wexp.Next() )
492 const TopoDS_Edge & E = wexp.Current();
493 bool isForward = (E.Orientation() == TopAbs_FORWARD);
495 // --- IDNodes of first and last Vertex
497 TopoDS_Vertex VFirst, VLast, V;
498 TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
499 V = isForward ? VFirst : VLast;
502 SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(V)->GetSubMeshDS()->GetNodes();
503 if ( !lid->more() ) {
504 MESSAGE (" NO NODE BUILT ON VERTEX ");
507 const SMDS_MeshNode* idFirst = lid->next();
509 // --- edge internal IDNodes (relies on good order storage, not checked)
511 map<double, const SMDS_MeshNode*> params;
512 const SMDS_MeshNode * node;
514 SMDS_NodeIteratorPtr nodeIt= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
515 while ( nodeIt->more() )
517 node = nodeIt->next();
518 const SMDS_EdgePosition* epos =
519 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
520 params[ epos->GetUParameter() ] = node;
522 int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
523 if ( nbPoints != params.size())
525 MESSAGE( "BAD NODE ON EDGE POSITIONS" );
529 // --- load 2D values into MEFISTO structure,
530 // add IDNodes in mefistoToDS map
532 double f, l, uFirst, u;
533 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
534 uFirst = isForward ? f : l;
537 gp_Pnt2d p = C2d->Value( uFirst ).XY().Multiplied( scale );
538 if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh ))
539 myNodesOnCommonV.push_back( idFirst );
540 mOnVertex.push_back( m );
543 mefistoToDS[m + 1] = idFirst;
544 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
545 //MESSAGE("__ f "<<uFirst<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
549 map<double, const SMDS_MeshNode*>::iterator u_n = params.begin();
550 map<double, const SMDS_MeshNode*>::reverse_iterator u_n_rev = params.rbegin();
551 for ( int i = 0; i < nbPoints; ++i )
559 node = u_n_rev->second;
562 gp_Pnt2d p = C2d->Value( u ).XY().Multiplied( scale );
565 mefistoToDS[m + 1] = node;
566 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
567 //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
572 // prevent failure on overlapped adjacent links,
573 // check only links ending in vertex nodes
574 int mFirst = mOnVertex.front(), mLast = m - 1;
575 list< int >::iterator mIt = mOnVertex.begin();
576 for ( ; mIt != mOnVertex.end(); ++mIt ) {
578 int iB = i - 1, iA = i + 1; // indices Before and After
579 if ( iB < mFirst ) iB = mLast;
580 if ( iA > mLast ) iA = mFirst;
581 fixOverlappedLinkUV (uvslf[ iB ], uvslf[ i ], uvslf[ iA ]);
587 //=============================================================================
591 //=============================================================================
593 void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
594 const TopoDS_Face & aFace, double &scalex, double &scaley)
596 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeScaleOnFace");
597 TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD));
598 TopoDS_Wire W = BRepTools::OuterWire(F);
600 double xmin = 1.e300; // min & max of face 2D parametric coord.
601 double xmax = -1.e300;
602 double ymin = 1.e300;
603 double ymax = -1.e300;
608 TopExp_Explorer wexp(W, TopAbs_EDGE);
609 for ( ; wexp.More(); wexp.Next())
611 const TopoDS_Edge & E = TopoDS::Edge( wexp.Current() );
613 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
614 if ( C2d.IsNull() ) continue;
615 double du = (l - f) / double (nbp);
616 for (int i = 0; i <= nbp; i++)
618 double param = f + double (i) * du;
619 gp_Pnt2d p = C2d->Value(param);
628 // MESSAGE(" "<< f<<" "<<l<<" "<<param<<" "<<xmin<<" "<<xmax<<" "<<ymin<<" "<<ymax);
635 double xmoy = (xmax + xmin) / 2.;
636 double ymoy = (ymax + ymin) / 2.;
637 double xsize = xmax - xmin;
638 double ysize = ymax - ymin;
640 Handle(Geom_Surface) S = BRep_Tool::Surface(F); // 3D surface
644 gp_Pnt PX0 = S->Value(xmin, ymoy);
645 gp_Pnt PY0 = S->Value(xmoy, ymin);
646 double dx = xsize / double (nbp);
647 double dy = ysize / double (nbp);
648 for (int i = 1; i <= nbp; i++)
650 double x = xmin + double (i) * dx;
651 gp_Pnt PX = S->Value(x, ymoy);
652 double y = ymin + double (i) * dy;
653 gp_Pnt PY = S->Value(xmoy, y);
654 length_x += PX.Distance(PX0);
655 length_y += PY.Distance(PY0);
659 scalex = length_x / xsize;
660 scaley = length_y / ysize;
663 double xyratio = xsize*scalex/(ysize*scaley);
664 const double maxratio = 1.e2;
666 if (xyratio > maxratio) {
668 scaley *= xyratio / maxratio;
671 else if (xyratio < 1./maxratio) {
673 scalex *= 1 / xyratio / maxratio;
680 //=============================================================================
684 //=============================================================================
686 void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
687 Z nbst, R2 * uvst, Z nbt, Z * nust,
688 const TopoDS_Face & F, bool faceIsForward,
689 map<int, const SMDS_MeshNode*>&mefistoToDS,
690 double scalex, double scaley)
692 SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
693 int faceID = meshDS->ShapeToIndex( F );
696 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
698 for (n = 0; n < nbst; n++)
700 if (mefistoToDS.find(n + 1) == mefistoToDS.end())
702 double u = uvst[n][0] / scalex;
703 double v = uvst[n][1] / scaley;
704 gp_Pnt P = S->Value(u, v);
706 SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
707 meshDS->SetNodeOnFace(node, faceID, u, v);
709 //MESSAGE(P.X()<<" "<<P.Y()<<" "<<P.Z());
710 mefistoToDS[n + 1] = node;
711 //MESSAGE("NEW: "<<n<<" "<<mefistoToDS[n+1]);
718 //SCRUTE(faceIsForward);
719 for (n = 1; n <= nbt; n++)
721 int inode1 = nust[m++];
722 int inode2 = nust[m++];
723 int inode3 = nust[m++];
725 const SMDS_MeshNode *n1, *n2, *n3;
726 n1 = mefistoToDS[inode1];
727 n2 = mefistoToDS[inode2];
728 n3 = mefistoToDS[inode3];
729 //MESSAGE("-- "<<inode1<<" "<<inode2<<" "<<inode3);
731 // triangle points must be in trigonometric order if face is Forward
732 // else they must be put clockwise
734 bool triangleIsWellOriented = faceIsForward;
736 SMDS_MeshElement * elt;
737 if (triangleIsWellOriented)
738 elt = meshDS->AddFace(n1, n2, n3);
740 elt = meshDS->AddFace(n1, n3, n2);
742 meshDS->SetMeshElementOnShape(elt, faceID);
746 // remove bad elements build on vertices shared by wires
748 list<const SMDS_MeshNode*>::iterator itN = myNodesOnCommonV.begin();
749 for ( ; itN != myNodesOnCommonV.end(); itN++ )
751 const SMDS_MeshNode* node = *itN;
752 SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
753 while ( invElemIt->more() )
755 const SMDS_MeshElement* elem = invElemIt->next();
756 SMDS_ElemIteratorPtr itN = elem->nodesIterator();
758 while ( itN->more() )
759 if ( itN->next() == node)
762 MESSAGE( "RM bad element " << elem->GetID());
763 meshDS->RemoveElement( elem );
770 //=============================================================================
774 //=============================================================================
776 double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
777 const TopoDS_Shape & aShape)
779 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength");
780 // **** a mettre dans SMESH_2D_Algo ?
782 const TopoDS_Face & FF = TopoDS::Face(aShape);
783 //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
784 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
786 double meanElementLength = 100;
787 double wireLength = 0;
788 int wireElementsNumber = 0;
789 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
791 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
792 for (TopExp_Explorer expe(W, TopAbs_EDGE); expe.More(); expe.Next())
794 const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
795 int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
796 double length = EdgeLength(E);
797 wireLength += length;
798 wireElementsNumber += nb;
801 if (wireElementsNumber)
802 meanElementLength = wireLength / wireElementsNumber;
803 //SCRUTE(meanElementLength);
804 return meanElementLength;
807 //=============================================================================
811 //=============================================================================
813 ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save)
818 //=============================================================================
822 //=============================================================================
824 istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load)
829 //=============================================================================
833 //=============================================================================
835 ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp)
837 return hyp.SaveTo( save );
840 //=============================================================================
844 //=============================================================================
846 istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp)
848 return hyp.LoadFrom( load );