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
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>
67 //#include <algorithm>
69 //=============================================================================
73 //=============================================================================
75 StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId,
76 SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
78 MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D");
80 // _shapeType = TopAbs_FACE;
81 _shapeType = (1 << TopAbs_FACE);
82 _compatibleHypothesis.push_back("MaxElementArea");
83 _compatibleHypothesis.push_back("LengthFromEdges");
87 _hypMaxElementArea = NULL;
88 _hypLengthFromEdges = NULL;
91 //=============================================================================
95 //=============================================================================
97 StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D()
99 MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D");
102 //=============================================================================
106 //=============================================================================
108 bool StdMeshers_MEFISTO_2D::CheckHypothesis
110 const TopoDS_Shape& aShape,
111 SMESH_Hypothesis::Hypothesis_Status& aStatus)
113 //MESSAGE("StdMeshers_MEFISTO_2D::CheckHypothesis");
115 _hypMaxElementArea = NULL;
116 _hypLengthFromEdges = NULL;
118 list <const SMESHDS_Hypothesis * >::const_iterator itl;
119 const SMESHDS_Hypothesis *theHyp;
121 const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
122 int nbHyp = hyps.size();
125 aStatus = SMESH_Hypothesis::HYP_MISSING;
126 return false; // can't work with no hypothesis
130 theHyp = (*itl); // use only the first hypothesis
132 string hypName = theHyp->GetName();
133 //int hypId = theHyp->GetID();
138 if (hypName == "MaxElementArea")
140 _hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea *>(theHyp);
141 ASSERT(_hypMaxElementArea);
142 _maxElementArea = _hypMaxElementArea->GetMaxArea();
145 aStatus = SMESH_Hypothesis::HYP_OK;
148 else if (hypName == "LengthFromEdges")
150 _hypLengthFromEdges = static_cast<const StdMeshers_LengthFromEdges *>(theHyp);
151 ASSERT(_hypLengthFromEdges);
155 aStatus = SMESH_Hypothesis::HYP_OK;
158 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
163 if (_maxElementArea > 0)
165 // _edgeLength = 2 * sqrt(_maxElementArea); // triangles : minorant
166 _edgeLength = 2 * sqrt(_maxElementArea/sqrt(3.0));
170 isOk = (_hypLengthFromEdges != NULL); // **** check mode
172 aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
175 //SCRUTE(_edgeLength);
176 //SCRUTE(_maxElementArea);
180 //=============================================================================
184 //=============================================================================
186 bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
188 MESSAGE("StdMeshers_MEFISTO_2D::Compute");
190 if (_hypLengthFromEdges)
191 _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
194 //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
195 //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
197 const TopoDS_Face & FF = TopoDS::Face(aShape);
198 bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
199 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
201 Z nblf; //nombre de lignes fermees (enveloppe en tete)
202 Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee
204 Z nbpti = 0; //nombre points internes futurs sommets de la triangulation
213 Z nutysu = 1; // 1: il existe un fonction areteideale_()
214 // Z nutysu=0; // 0: on utilise aretmx
215 R aretmx = _edgeLength; // longueur max aretes future triangulation
217 nblf = NumberOfWires(F);
219 nudslf = new Z[1 + nblf];
224 myOuterWire = BRepTools::OuterWire(F);
225 nbpnt += NumberOfPoints(aMesh, myOuterWire);
226 if ( nbpnt < 3 ) // ex: a circle with 2 segments
228 nudslf[iw++] = nbpnt;
230 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))
235 nbpnt += NumberOfPoints(aMesh, W);
236 nudslf[iw++] = nbpnt;
240 // avoid passing same uv points for a vertex common to 2 wires
241 TopTools_IndexedDataMapOfShapeListOfShape VWMap;
242 if ( iw - 1 > 1 ) // nbofWires > 1
243 TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap );
245 uvslf = new R2[nudslf[nblf]];
248 double scalex, scaley;
249 ComputeScaleOnFace(aMesh, F, scalex, scaley);
251 map<int, const SMDS_MeshNode*> mefistoToDS; // correspondence mefisto index--> points IDNodes
252 if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m,
253 mefistoToDS, scalex, scaley, VWMap))
256 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
258 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
259 if (!myOuterWire.IsSame(W))
261 if (! LoadPoints(aMesh, F, W, uvslf, m,
262 mefistoToDS, scalex, scaley, VWMap ))
269 aptrte(nutysu, aretmx,
270 nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
274 MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
275 MESSAGE(" Node Number " << nbst);
276 StoreResult(aMesh, nbst, uvst, nbt, nust, F,
277 faceIsForward, mefistoToDS, scalex, scaley);
282 MESSAGE("Error in Triangulation");
296 //=======================================================================
297 //function : fixOverlappedLinkUV
298 //purpose : prevent failure due to overlapped adjacent links
299 //=======================================================================
301 static bool fixOverlappedLinkUV( R2& uv0, const R2& uv1, const R2& uv2 )
303 gp_XY v1( uv0.x - uv1.x, uv0.y - uv1.y );
304 gp_XY v2( uv2.x - uv1.x, uv2.y - uv1.y );
306 double tol2 = DBL_MIN * DBL_MIN;
307 double sqMod1 = v1.SquareModulus();
308 if ( sqMod1 <= tol2 ) return false;
309 double sqMod2 = v2.SquareModulus();
310 if ( sqMod2 <= tol2 ) return false;
314 // check sinus >= 1.e-3
315 const double minSin = 1.e-3;
316 if ( dot > 0 && 1 - dot * dot / ( sqMod1 * sqMod2 ) < minSin * minSin ) {
317 MESSAGE(" ___ FIX UV ____" << uv0.x << " " << uv0.y);
318 v1.SetCoord( -v1.Y(), v1.X() );
319 double delta = sqrt( sqMod1 ) * minSin;
329 // MESSAGE(" -> " << uv0.x << " " << uv0.y << " ");
330 // MESSAGE("v1( " << v1.X() << " " << v1.Y() << " ) " <<
331 // "v2( " << v2.X() << " " << v2.Y() << " ) ");
332 // MESSAGE("SIN: " << sqrt(1 - dot * dot / (sqMod1 * sqMod2)));
333 // v1.SetCoord( uv0.x - uv1.x, uv0.y - uv1.y );
334 // v2.SetCoord( uv2.x - uv1.x, uv2.y - uv1.y );
335 // gp_XY v3( uv2.x - uv0.x, uv2.y - uv0.y );
336 // sqMod1 = v1.SquareModulus();
337 // sqMod2 = v2.SquareModulus();
339 // double sin = sqrt(1 - dot * dot / (sqMod1 * sqMod2));
340 // MESSAGE("NEW SIN: " << sin);
347 //=======================================================================
348 //function : fixCommonVertexUV
350 //=======================================================================
352 static bool fixCommonVertexUV (gp_Pnt2d & theUV,
353 const TopoDS_Vertex& theV,
354 const TopoDS_Wire& theW,
355 const TopoDS_Wire& theOW,
356 const TopoDS_Face& theF,
357 const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
358 SMESH_Mesh & theMesh)
360 if( theW.IsSame( theOW ) ||
361 !theVWMap.Contains( theV )) return false;
363 // check if there is another wire sharing theV
364 const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV );
365 TopTools_ListIteratorOfListOfShape aWIt;
366 for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() )
367 if ( !theW.IsSame( aWIt.Value() ))
369 if ( !aWIt.More() ) return false;
371 TopTools_ListOfShape EList;
372 list< double > UList;
374 // find edges of theW sharing theV
375 // and find 2d normal to them at theV
377 TopoDS_Iterator itE( theW );
378 for ( ; itE.More(); itE.Next() )
380 const TopoDS_Edge& E = TopoDS::Edge( itE.Value() );
381 TopoDS_Iterator itV( E );
382 for ( ; itV.More(); itV.Next() )
384 const TopoDS_Vertex & V = TopoDS::Vertex( itV.Value() );
385 if ( !V.IsSame( theV ))
388 Standard_Real u = BRep_Tool::Parameter( V, E );
389 UList.push_back( u );
391 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
395 gp_Vec2d n( d1.Y(), -d1.X() );
396 if ( E.Orientation() == TopAbs_REVERSED )
402 // define step size by which to move theUV
404 gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four
405 double maxDist = -DBL_MAX;
406 TopTools_ListIteratorOfListOfShape aEIt (EList);
407 list< double >::iterator aUIt = UList.begin();
408 for ( ; aEIt.More(); aEIt.Next(), aUIt++ )
410 const TopoDS_Edge& E = TopoDS::Edge( aEIt.Value() );
412 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
414 double umin = DBL_MAX, umax = -DBL_MAX;
415 SMDS_NodeIteratorPtr nIt = theMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
416 if ( !nIt->more() ) // no nodes on edge, only on vertices
423 while ( nIt->more() ) {
424 const SMDS_MeshNode* node = nIt->next();
425 const SMDS_EdgePosition* epos =
426 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
427 double u = epos->GetUParameter();
434 bool isFirstCommon = ( *aUIt == f );
435 gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax );
436 double dist = theUV.SquareDistance( uv );
437 if ( dist > maxDist ) {
443 uv0.x = theUV.X(); uv0.y = theUV.Y();
444 uv1.x = nextUV.X(); uv1.y = nextUV.Y();
445 uv2.x = uv0.x; uv2.y = uv0.y;
446 if ( fixOverlappedLinkUV( uv0, uv1, uv2 ))
448 double step = theUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
450 // move theUV along the normal by the step
454 MESSAGE("--fixCommonVertexUV move(" << theUV.X() << " " << theUV.Y()
455 << ") by (" << N.X() << " " << N.Y() << ")"
456 << endl << "--- MAX DIST " << maxDist);
458 theUV.SetXY( theUV.XY() + N.XY() );
465 //=============================================================================
469 //=============================================================================
471 bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh,
472 const TopoDS_Face & FF,
473 const TopoDS_Wire & WW,
476 map<int, const SMDS_MeshNode*>&mefistoToDS,
479 const TopTools_IndexedDataMapOfShapeListOfShape& VWMap)
481 // MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints");
483 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
485 list< int > mOnVertex;
487 gp_XY scale( scalex, scaley );
489 TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
490 BRepTools_WireExplorer wexp(W, F);
491 for ( wexp.Init(W, F); wexp.More(); wexp.Next() )
493 const TopoDS_Edge & E = wexp.Current();
494 bool isForward = (E.Orientation() == TopAbs_FORWARD);
496 // --- IDNodes of first and last Vertex
498 TopoDS_Vertex VFirst, VLast, V;
499 TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
500 V = isForward ? VFirst : VLast;
503 SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(V)->GetSubMeshDS()->GetNodes();
504 if ( !lid->more() ) {
505 MESSAGE (" NO NODE BUILT ON VERTEX ");
508 const SMDS_MeshNode* idFirst = lid->next();
510 // --- edge internal IDNodes (relies on good order storage, not checked)
512 map<double, const SMDS_MeshNode*> params;
513 const SMDS_MeshNode * node;
515 SMDS_NodeIteratorPtr nodeIt= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
516 while ( nodeIt->more() )
518 node = nodeIt->next();
519 const SMDS_EdgePosition* epos =
520 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
521 params[ epos->GetUParameter() ] = node;
523 int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
524 if ( nbPoints != params.size())
526 MESSAGE( "BAD NODE ON EDGE POSITIONS" );
530 // --- load 2D values into MEFISTO structure,
531 // add IDNodes in mefistoToDS map
533 double f, l, uFirst, u;
534 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
535 uFirst = isForward ? f : l;
538 gp_Pnt2d p = C2d->Value( uFirst ).XY().Multiplied( scale );
539 if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh ))
540 myNodesOnCommonV.push_back( idFirst );
541 mOnVertex.push_back( m );
544 mefistoToDS[m + 1] = idFirst;
545 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
546 //MESSAGE("__ f "<<uFirst<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
550 map<double, const SMDS_MeshNode*>::iterator u_n = params.begin();
551 map<double, const SMDS_MeshNode*>::reverse_iterator u_n_rev = params.rbegin();
552 for ( int i = 0; i < nbPoints; ++i )
560 node = u_n_rev->second;
563 gp_Pnt2d p = C2d->Value( u ).XY().Multiplied( scale );
566 mefistoToDS[m + 1] = node;
567 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
568 //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
573 // prevent failure on overlapped adjacent links,
574 // check only links ending in vertex nodes
575 int mFirst = mOnVertex.front(), mLast = m - 1;
576 list< int >::iterator mIt = mOnVertex.begin();
577 for ( ; mIt != mOnVertex.end(); ++mIt ) {
579 int iB = i - 1, iA = i + 1; // indices Before and After
580 if ( iB < mFirst ) iB = mLast;
581 if ( iA > mLast ) iA = mFirst;
582 fixOverlappedLinkUV (uvslf[ iB ], uvslf[ i ], uvslf[ iA ]);
588 //=============================================================================
592 //=============================================================================
594 void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
595 const TopoDS_Face & aFace, double &scalex, double &scaley)
597 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeScaleOnFace");
598 TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD));
599 TopoDS_Wire W = BRepTools::OuterWire(F);
601 double xmin = 1.e300; // min & max of face 2D parametric coord.
602 double xmax = -1.e300;
603 double ymin = 1.e300;
604 double ymax = -1.e300;
609 TopExp_Explorer wexp(W, TopAbs_EDGE);
610 for ( ; wexp.More(); wexp.Next())
612 const TopoDS_Edge & E = TopoDS::Edge( wexp.Current() );
614 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
615 if ( C2d.IsNull() ) continue;
616 double du = (l - f) / double (nbp);
617 for (int i = 0; i <= nbp; i++)
619 double param = f + double (i) * du;
620 gp_Pnt2d p = C2d->Value(param);
629 // MESSAGE(" "<< f<<" "<<l<<" "<<param<<" "<<xmin<<" "<<xmax<<" "<<ymin<<" "<<ymax);
636 double xmoy = (xmax + xmin) / 2.;
637 double ymoy = (ymax + ymin) / 2.;
638 double xsize = xmax - xmin;
639 double ysize = ymax - ymin;
641 Handle(Geom_Surface) S = BRep_Tool::Surface(F); // 3D surface
645 gp_Pnt PX0 = S->Value(xmin, ymoy);
646 gp_Pnt PY0 = S->Value(xmoy, ymin);
647 double dx = xsize / double (nbp);
648 double dy = ysize / double (nbp);
649 for (int i = 1; i <= nbp; i++)
651 double x = xmin + double (i) * dx;
652 gp_Pnt PX = S->Value(x, ymoy);
653 double y = ymin + double (i) * dy;
654 gp_Pnt PY = S->Value(xmoy, y);
655 length_x += PX.Distance(PX0);
656 length_y += PY.Distance(PY0);
660 scalex = length_x / xsize;
661 scaley = length_y / ysize;
664 double xyratio = xsize*scalex/(ysize*scaley);
665 const double maxratio = 1.e2;
667 if (xyratio > maxratio) {
669 scaley *= xyratio / maxratio;
672 else if (xyratio < 1./maxratio) {
674 scalex *= 1 / xyratio / maxratio;
681 //=============================================================================
685 //=============================================================================
687 void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
688 Z nbst, R2 * uvst, Z nbt, Z * nust,
689 const TopoDS_Face & F, bool faceIsForward,
690 map<int, const SMDS_MeshNode*>&mefistoToDS,
691 double scalex, double scaley)
693 SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
694 int faceID = meshDS->ShapeToIndex( F );
697 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
699 for (n = 0; n < nbst; n++)
701 if (mefistoToDS.find(n + 1) == mefistoToDS.end())
703 double u = uvst[n][0] / scalex;
704 double v = uvst[n][1] / scaley;
705 gp_Pnt P = S->Value(u, v);
707 SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
708 meshDS->SetNodeOnFace(node, faceID, u, v);
710 //MESSAGE(P.X()<<" "<<P.Y()<<" "<<P.Z());
711 mefistoToDS[n + 1] = node;
712 //MESSAGE("NEW: "<<n<<" "<<mefistoToDS[n+1]);
719 //SCRUTE(faceIsForward);
720 for (n = 1; n <= nbt; n++)
722 int inode1 = nust[m++];
723 int inode2 = nust[m++];
724 int inode3 = nust[m++];
726 const SMDS_MeshNode *n1, *n2, *n3;
727 n1 = mefistoToDS[inode1];
728 n2 = mefistoToDS[inode2];
729 n3 = mefistoToDS[inode3];
730 //MESSAGE("-- "<<inode1<<" "<<inode2<<" "<<inode3);
732 // triangle points must be in trigonometric order if face is Forward
733 // else they must be put clockwise
735 bool triangleIsWellOriented = faceIsForward;
737 SMDS_MeshElement * elt;
738 if (triangleIsWellOriented)
739 elt = meshDS->AddFace(n1, n2, n3);
741 elt = meshDS->AddFace(n1, n3, n2);
743 meshDS->SetMeshElementOnShape(elt, faceID);
747 // remove bad elements build on vertices shared by wires
749 list<const SMDS_MeshNode*>::iterator itN = myNodesOnCommonV.begin();
750 for ( ; itN != myNodesOnCommonV.end(); itN++ )
752 const SMDS_MeshNode* node = *itN;
753 SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
754 while ( invElemIt->more() )
756 const SMDS_MeshElement* elem = invElemIt->next();
757 SMDS_ElemIteratorPtr itN = elem->nodesIterator();
759 while ( itN->more() )
760 if ( itN->next() == node)
763 MESSAGE( "RM bad element " << elem->GetID());
764 meshDS->RemoveElement( elem );
771 //=============================================================================
775 //=============================================================================
777 double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
778 const TopoDS_Shape & aShape)
780 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength");
781 // **** a mettre dans SMESH_2D_Algo ?
783 const TopoDS_Face & FF = TopoDS::Face(aShape);
784 //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
785 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
787 double meanElementLength = 100;
788 double wireLength = 0;
789 int wireElementsNumber = 0;
790 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
792 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
793 for (TopExp_Explorer expe(W, TopAbs_EDGE); expe.More(); expe.Next())
795 const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
796 int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
797 double length = EdgeLength(E);
798 wireLength += length;
799 wireElementsNumber += nb;
802 if (wireElementsNumber)
803 meanElementLength = wireLength / wireElementsNumber;
804 //SCRUTE(meanElementLength);
805 return meanElementLength;
808 //=============================================================================
812 //=============================================================================
814 ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save)
819 //=============================================================================
823 //=============================================================================
825 istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load)
830 //=============================================================================
834 //=============================================================================
836 ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp)
838 return hyp.SaveTo( save );
841 //=============================================================================
845 //=============================================================================
847 istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp)
849 return hyp.LoadFrom( load );