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"
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>
65 //#include <algorithm>
67 //=============================================================================
71 //=============================================================================
73 StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId,
74 SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
76 MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D");
78 // _shapeType = TopAbs_FACE;
79 _shapeType = (1 << TopAbs_FACE);
80 _compatibleHypothesis.push_back("MaxElementArea");
81 _compatibleHypothesis.push_back("LengthFromEdges");
85 _hypMaxElementArea = NULL;
86 _hypLengthFromEdges = NULL;
89 //=============================================================================
93 //=============================================================================
95 StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D()
97 MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D");
100 //=============================================================================
104 //=============================================================================
106 bool StdMeshers_MEFISTO_2D::CheckHypothesis
108 const TopoDS_Shape& aShape,
109 SMESH_Hypothesis::Hypothesis_Status& aStatus)
111 //MESSAGE("StdMeshers_MEFISTO_2D::CheckHypothesis");
113 _hypMaxElementArea = NULL;
114 _hypLengthFromEdges = NULL;
116 list <const SMESHDS_Hypothesis * >::const_iterator itl;
117 const SMESHDS_Hypothesis *theHyp;
119 const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
120 int nbHyp = hyps.size();
123 aStatus = SMESH_Hypothesis::HYP_MISSING;
124 return false; // can't work with no hypothesis
128 theHyp = (*itl); // use only the first hypothesis
130 string hypName = theHyp->GetName();
131 int hypId = theHyp->GetID();
136 if (hypName == "MaxElementArea")
138 _hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea *>(theHyp);
139 ASSERT(_hypMaxElementArea);
140 _maxElementArea = _hypMaxElementArea->GetMaxArea();
143 aStatus = SMESH_Hypothesis::HYP_OK;
146 else if (hypName == "LengthFromEdges")
148 _hypLengthFromEdges = static_cast<const StdMeshers_LengthFromEdges *>(theHyp);
149 ASSERT(_hypLengthFromEdges);
153 aStatus = SMESH_Hypothesis::HYP_OK;
156 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
161 if (_maxElementArea > 0)
163 // _edgeLength = 2 * sqrt(_maxElementArea); // triangles : minorant
164 _edgeLength = 2 * sqrt(_maxElementArea/sqrt(3.0));
168 isOk = (_hypLengthFromEdges != NULL); // **** check mode
170 aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
173 //SCRUTE(_edgeLength);
174 //SCRUTE(_maxElementArea);
178 //=============================================================================
182 //=============================================================================
184 bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
186 MESSAGE("StdMeshers_MEFISTO_2D::Compute");
188 if (_hypLengthFromEdges)
189 _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
192 const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
193 SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
195 const TopoDS_Face & FF = TopoDS::Face(aShape);
196 bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
197 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
199 Z nblf; //nombre de lignes fermees (enveloppe en tete)
200 Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee
202 Z nbpti = 0; //nombre points internes futurs sommets de la triangulation
211 Z nutysu = 1; // 1: il existe un fonction areteideale_()
212 // Z nutysu=0; // 0: on utilise aretmx
213 R aretmx = _edgeLength; // longueur max aretes future triangulation
215 nblf = NumberOfWires(F);
217 nudslf = new Z[1 + nblf];
222 myOuterWire = BRepTools::OuterWire(F);
223 nbpnt += NumberOfPoints(aMesh, myOuterWire);
224 if ( nbpnt < 3 ) // ex: a circle with 2 segments
226 nudslf[iw++] = nbpnt;
228 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
230 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
231 if (!myOuterWire.IsSame(W))
233 nbpnt += NumberOfPoints(aMesh, W);
234 nudslf[iw++] = nbpnt;
238 // avoid passing same uv points for a vertex common to 2 wires
239 TopTools_IndexedDataMapOfShapeListOfShape VWMap;
240 if ( iw - 1 > 1 ) // nbofWires > 1
241 TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap );
243 uvslf = new R2[nudslf[nblf]];
246 double scalex, scaley;
247 ComputeScaleOnFace(aMesh, F, scalex, scaley);
249 map<int, const SMDS_MeshNode*> mefistoToDS; // correspondence mefisto index--> points IDNodes
250 if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m,
251 mefistoToDS, scalex, scaley, VWMap))
254 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
256 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
257 if (!myOuterWire.IsSame(W))
259 if (! LoadPoints(aMesh, F, W, uvslf, m,
260 mefistoToDS, scalex, scaley, VWMap ))
267 aptrte(nutysu, aretmx,
268 nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
272 MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
273 MESSAGE(" Node Number " << nbst);
274 StoreResult(aMesh, nbst, uvst, nbt, nust, F,
275 faceIsForward, mefistoToDS, scalex, scaley);
280 MESSAGE("Error in Triangulation");
294 //=======================================================================
295 //function : fixOverlappedLinkUV
296 //purpose : prevent failure due to overlapped adjacent links
297 //=======================================================================
299 static bool fixOverlappedLinkUV( R2& uv0, const R2& uv1, const R2& uv2 )
301 gp_XY v1( uv0.x - uv1.x, uv0.y - uv1.y );
302 gp_XY v2( uv2.x - uv1.x, uv2.y - uv1.y );
304 double tol2 = DBL_MIN * DBL_MIN;
305 double sqMod1 = v1.SquareModulus();
306 if ( sqMod1 <= tol2 ) return false;
307 double sqMod2 = v2.SquareModulus();
308 if ( sqMod2 <= tol2 ) return false;
312 // check sinus >= 1.e-3
313 const double minSin = 1.e-3;
314 if ( dot > 0 && 1 - dot * dot / ( sqMod1 * sqMod2 ) < minSin * minSin ) {
315 MESSAGE(" ___ FIX UV ____" << uv0.x << " " << uv0.y);
316 v1.SetCoord( -v1.Y(), v1.X() );
317 double delta = sqrt( sqMod1 ) * minSin;
326 // MESSAGE(" -> " << uv0.x << " " << uv0.y << " ");
327 // MESSAGE("v1( " << v1.X() << " " << v1.Y() << " ) " <<
328 // "v2( " << v2.X() << " " << v2.Y() << " ) ");
329 // MESSAGE("SIN: " << sqrt(1 - dot * dot / (sqMod1 * sqMod2)));
330 // v1.SetCoord( uv0.x - uv1.x, uv0.y - uv1.y );
331 // v2.SetCoord( uv2.x - uv1.x, uv2.y - uv1.y );
332 // gp_XY v3( uv2.x - uv0.x, uv2.y - uv0.y );
333 // sqMod1 = v1.SquareModulus();
334 // sqMod2 = v2.SquareModulus();
336 // double sin = sqrt(1 - dot * dot / (sqMod1 * sqMod2));
337 // MESSAGE("NEW SIN: " << sin);
343 //=======================================================================
344 //function : fixCommonVertexUV
346 //=======================================================================
348 static bool fixCommonVertexUV (gp_Pnt2d & theUV,
349 const TopoDS_Vertex& theV,
350 const TopoDS_Wire& theW,
351 const TopoDS_Wire& theOW,
352 const TopoDS_Face& theF,
353 const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
354 SMESH_Mesh & theMesh)
356 if( theW.IsSame( theOW ) ||
357 !theVWMap.Contains( theV )) return false;
359 // check if there is another wire sharing theV
360 const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV );
361 TopTools_ListIteratorOfListOfShape aWIt;
362 for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() )
363 if ( !theW.IsSame( aWIt.Value() ))
365 if ( !aWIt.More() ) return false;
367 TopTools_ListOfShape EList;
368 list< double > UList;
370 // find edges of theW sharing theV
371 // and find 2d normal to them at theV
373 TopoDS_Iterator itE( theW );
374 for ( ; itE.More(); itE.Next() )
376 const TopoDS_Edge& E = TopoDS::Edge( itE.Value() );
377 TopoDS_Iterator itV( E );
378 for ( ; itV.More(); itV.Next() )
380 const TopoDS_Vertex & V = TopoDS::Vertex( itV.Value() );
381 if ( !V.IsSame( theV ))
384 Standard_Real u = BRep_Tool::Parameter( V, E );
385 UList.push_back( u );
387 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
391 gp_Vec2d n( d1.Y(), -d1.X() );
392 if ( E.Orientation() == TopAbs_REVERSED )
398 // define step size by which to move theUV
400 gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four
401 double maxDist = -DBL_MAX;
402 TopTools_ListIteratorOfListOfShape aEIt (EList);
403 list< double >::iterator aUIt = UList.begin();
404 for ( ; aEIt.More(); aEIt.Next(), aUIt++ )
406 const TopoDS_Edge& E = TopoDS::Edge( aEIt.Value() );
408 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
410 double umin = DBL_MAX, umax = -DBL_MAX;
411 SMDS_NodeIteratorPtr nIt = theMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
412 if ( !nIt->more() ) // no nodes on edge, only on vertices
419 while ( nIt->more() ) {
420 const SMDS_MeshNode* node = nIt->next();
421 const SMDS_EdgePosition* epos =
422 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
423 double u = epos->GetUParameter();
430 bool isFirstCommon = ( *aUIt == f );
431 gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax );
432 double dist = theUV.SquareDistance( uv );
433 if ( dist > maxDist ) {
439 uv0.x = theUV.X(); uv0.y = theUV.Y();
440 uv1.x = nextUV.X(); uv1.y = nextUV.Y();
441 uv2.x = uv0.x; uv2.y = uv0.y;
442 if ( fixOverlappedLinkUV( uv0, uv1, uv2 ))
444 double step = theUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
446 // move theUV along the normal by the step
450 MESSAGE("--fixCommonVertexUV move(" << theUV.X() << " " << theUV.Y()
451 << ") by (" << N.X() << " " << N.Y() << ")"
452 << endl << "--- MAX DIST " << maxDist);
454 theUV.SetXY( theUV.XY() + N.XY() );
461 //=============================================================================
465 //=============================================================================
467 bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh,
468 const TopoDS_Face & FF,
469 const TopoDS_Wire & WW,
472 map<int, const SMDS_MeshNode*>&mefistoToDS,
475 const TopTools_IndexedDataMapOfShapeListOfShape& VWMap)
477 // MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints");
479 SMDS_Mesh * meshDS = aMesh.GetMeshDS();
481 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
483 int mInit = m, mFirst, iEdge;
484 gp_XY scale( scalex, scaley );
486 TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
487 BRepTools_WireExplorer wexp(W, F);
488 for (wexp.Init(W, F), iEdge = 0; wexp.More(); wexp.Next(), iEdge++)
490 const TopoDS_Edge & E = wexp.Current();
492 // --- IDNodes of first and last Vertex
494 TopoDS_Vertex VFirst, VLast;
495 TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
497 ASSERT(!VFirst.IsNull());
498 SMDS_NodeIteratorPtr lid=
499 aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
500 if ( !lid->more() ) {
501 MESSAGE (" NO NODE BUILT ON VERTEX ");
504 const SMDS_MeshNode* idFirst = lid->next();
506 ASSERT(!VLast.IsNull());
507 lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
508 if ( !lid->more() ) {
509 MESSAGE (" NO NODE BUILT ON VERTEX ");
512 const SMDS_MeshNode* idLast = lid->next();
514 // --- edge internal IDNodes (relies on good order storage, not checked)
516 int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
519 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
521 SMDS_NodeIteratorPtr ite= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
523 bool isForward = (E.Orientation() == TopAbs_FORWARD);
524 map<double, const SMDS_MeshNode*> params;
528 const SMDS_MeshNode * node = ite->next();
529 const SMDS_EdgePosition* epos =
530 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
531 double param = epos->GetUParameter();
532 params[param] = node;
534 if ( nbPoints != params.size())
536 MESSAGE( "BAD NODE ON EDGE POSITIONS" );
542 // --- load 2D values into MEFISTO structure,
543 // add IDNodes in mefistoToDS map
544 if (E.Orientation() == TopAbs_FORWARD)
546 gp_Pnt2d p = C2d->Value(f).XY().Multiplied( scale ); // first point = Vertex Forward
547 if ( fixCommonVertexUV( p, VFirst, W, myOuterWire, F, VWMap, aMesh ))
548 myNodesOnCommonV.push_back( idFirst );
551 mefistoToDS[m + 1] = idFirst;
552 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
553 //MESSAGE("__ f "<<f<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
555 map<double, const SMDS_MeshNode*>::iterator itp = params.begin();
556 for (int i = 1; i <= nbPoints; i++) // nbPoints internal
558 double param = (*itp).first;
559 gp_Pnt2d p = C2d->Value(param).XY().Multiplied( scale );
562 mefistoToDS[m + 1] = (*itp).second;
563 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
564 //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
571 gp_Pnt2d p = C2d->Value(l).XY().Multiplied( scale ); // last point = Vertex Reversed
572 if ( fixCommonVertexUV( p, VLast, W, myOuterWire, F, VWMap, aMesh ))
573 myNodesOnCommonV.push_back( idLast );
576 mefistoToDS[m + 1] = idLast;
577 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
578 //MESSAGE("__ l "<<l<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
580 map<double, const SMDS_MeshNode*>::reverse_iterator itp = params.rbegin();
581 for (int i = nbPoints; i >= 1; i--)
583 double param = (*itp).first;
584 gp_Pnt2d p = C2d->Value(param).XY().Multiplied( scale );
587 mefistoToDS[m + 1] = (*itp).second;
588 //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
589 //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
594 // prevent failure on overlapped adjacent links
596 fixOverlappedLinkUV (uvslf[ mFirst - 1],
598 uvslf[ mFirst + 1 ]);
602 fixOverlappedLinkUV (uvslf[ m - 1],
609 //=============================================================================
613 //=============================================================================
615 void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
616 const TopoDS_Face & aFace, double &scalex, double &scaley)
618 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeScaleOnFace");
619 TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD));
620 TopoDS_Wire W = BRepTools::OuterWire(F);
622 double xmin = 1.e300; // min & max of face 2D parametric coord.
623 double xmax = -1.e300;
624 double ymin = 1.e300;
625 double ymax = -1.e300;
630 TopExp_Explorer wexp(W, TopAbs_EDGE);
631 for ( ; wexp.More(); wexp.Next())
633 const TopoDS_Edge & E = TopoDS::Edge( wexp.Current() );
635 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
636 if ( C2d.IsNull() ) continue;
637 double du = (l - f) / double (nbp);
638 for (int i = 0; i <= nbp; i++)
640 double param = f + double (i) * du;
641 gp_Pnt2d p = C2d->Value(param);
650 // MESSAGE(" "<< f<<" "<<l<<" "<<param<<" "<<xmin<<" "<<xmax<<" "<<ymin<<" "<<ymax);
657 double xmoy = (xmax + xmin) / 2.;
658 double ymoy = (ymax + ymin) / 2.;
659 double xsize = xmax - xmin;
660 double ysize = ymax - ymin;
662 Handle(Geom_Surface) S = BRep_Tool::Surface(F); // 3D surface
666 gp_Pnt PX0 = S->Value(xmin, ymoy);
667 gp_Pnt PY0 = S->Value(xmoy, ymin);
668 double dx = xsize / double (nbp);
669 double dy = ysize / double (nbp);
670 for (int i = 1; i <= nbp; i++)
672 double x = xmin + double (i) * dx;
673 gp_Pnt PX = S->Value(x, ymoy);
674 double y = ymin + double (i) * dy;
675 gp_Pnt PY = S->Value(xmoy, y);
676 length_x += PX.Distance(PX0);
677 length_y += PY.Distance(PY0);
681 scalex = length_x / xsize;
682 scaley = length_y / ysize;
685 double xyratio = xsize*scalex/(ysize*scaley);
686 const double maxratio = 1.e2;
688 if (xyratio > maxratio) {
690 scaley *= xyratio / maxratio;
693 else if (xyratio < 1./maxratio) {
695 scalex *= 1 / xyratio / maxratio;
702 //=============================================================================
706 //=============================================================================
708 void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
709 Z nbst, R2 * uvst, Z nbt, Z * nust,
710 const TopoDS_Face & F, bool faceIsForward,
711 map<int, const SMDS_MeshNode*>&mefistoToDS,
712 double scalex, double scaley)
714 SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
717 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
719 for (n = 0; n < nbst; n++)
721 if (mefistoToDS.find(n + 1) == mefistoToDS.end())
723 double u = uvst[n][0] / scalex;
724 double v = uvst[n][1] / scaley;
725 gp_Pnt P = S->Value(u, v);
727 SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
728 meshDS->SetNodeOnFace(node, F);
730 //MESSAGE(P.X()<<" "<<P.Y()<<" "<<P.Z());
731 mefistoToDS[n + 1] = node;
732 //MESSAGE("NEW: "<<n<<" "<<mefistoToDS[n+1]);
733 SMDS_FacePosition* fpos =
734 static_cast<SMDS_FacePosition*>(node->GetPosition().get());
735 fpos->SetUParameter(u);
736 fpos->SetVParameter(v);
743 //SCRUTE(faceIsForward);
744 for (n = 1; n <= nbt; n++)
746 int inode1 = nust[m++];
747 int inode2 = nust[m++];
748 int inode3 = nust[m++];
750 const SMDS_MeshNode *n1, *n2, *n3;
751 n1 = mefistoToDS[inode1];
752 n2 = mefistoToDS[inode2];
753 n3 = mefistoToDS[inode3];
754 //MESSAGE("-- "<<inode1<<" "<<inode2<<" "<<inode3);
756 // triangle points must be in trigonometric order if face is Forward
757 // else they must be put clockwise
759 bool triangleIsWellOriented = faceIsForward;
761 SMDS_MeshElement * elt;
762 if (triangleIsWellOriented)
763 elt = meshDS->AddFace(n1, n2, n3);
765 elt = meshDS->AddFace(n1, n3, n2);
767 meshDS->SetMeshElementOnShape(elt, F);
771 // remove bad elements build on vertices shared by wires
773 list<const SMDS_MeshNode*>::iterator itN = myNodesOnCommonV.begin();
774 for ( ; itN != myNodesOnCommonV.end(); itN++ )
776 const SMDS_MeshNode* node = *itN;
777 SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
778 while ( invElemIt->more() )
780 const SMDS_MeshElement* elem = invElemIt->next();
781 SMDS_ElemIteratorPtr itN = elem->nodesIterator();
783 while ( itN->more() )
784 if ( itN->next() == node)
787 MESSAGE( "RM bad element " << elem->GetID());
788 meshDS->RemoveElement( elem );
795 //=============================================================================
799 //=============================================================================
801 double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
802 const TopoDS_Shape & aShape)
804 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength");
805 // **** a mettre dans SMESH_2D_Algo ?
807 const TopoDS_Face & FF = TopoDS::Face(aShape);
808 bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
809 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
811 double meanElementLength = 100;
812 double wireLength = 0;
813 int wireElementsNumber = 0;
814 for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
816 const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
817 for (TopExp_Explorer expe(W, TopAbs_EDGE); expe.More(); expe.Next())
819 const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
820 int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
821 double length = EdgeLength(E);
822 wireLength += length;
823 wireElementsNumber += nb;
826 if (wireElementsNumber)
827 meanElementLength = wireLength / wireElementsNumber;
828 //SCRUTE(meanElementLength);
829 return meanElementLength;
832 //=============================================================================
836 //=============================================================================
838 ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save)
843 //=============================================================================
847 //=============================================================================
849 istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load)
854 //=============================================================================
858 //=============================================================================
860 ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp)
862 return hyp.SaveTo( save );
865 //=============================================================================
869 //=============================================================================
871 istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp)
873 return hyp.LoadFrom( load );