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 = (1 << TopAbs_FACE);
80 _compatibleHypothesis.push_back("MaxElementArea");
81 _compatibleHypothesis.push_back("LengthFromEdges");
85 _hypMaxElementArea = NULL;
86 _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 myTool = new StdMeshers_Helper(aMesh);
224 _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
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;
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);
353 //=======================================================================
354 //function : fixCommonVertexUV
356 //=======================================================================
358 static bool fixCommonVertexUV (gp_Pnt2d & theUV,
359 const TopoDS_Vertex& theV,
360 const TopoDS_Wire& theW,
361 const TopoDS_Wire& theOW,
362 const TopoDS_Face& theF,
363 const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
364 SMESH_Mesh & theMesh,
365 bool CreateQuadratic)
367 if( theW.IsSame( theOW ) ||
368 !theVWMap.Contains( theV )) return false;
370 // check if there is another wire sharing theV
371 const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV );
372 TopTools_ListIteratorOfListOfShape aWIt;
373 for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() )
374 if ( !theW.IsSame( aWIt.Value() ))
376 if ( !aWIt.More() ) return false;
378 TopTools_ListOfShape EList;
379 list< double > UList;
381 // find edges of theW sharing theV
382 // and find 2d normal to them at theV
384 TopoDS_Iterator itE( theW );
385 for ( ; itE.More(); itE.Next() )
387 const TopoDS_Edge& E = TopoDS::Edge( itE.Value() );
388 TopoDS_Iterator itV( E );
389 for ( ; itV.More(); itV.Next() )
391 const TopoDS_Vertex & V = TopoDS::Vertex( itV.Value() );
392 if ( !V.IsSame( theV ))
395 Standard_Real u = BRep_Tool::Parameter( V, E );
396 UList.push_back( u );
398 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
402 gp_Vec2d n( d1.Y(), -d1.X() );
403 if ( E.Orientation() == TopAbs_REVERSED )
409 // define step size by which to move theUV
411 gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four
412 double maxDist = -DBL_MAX;
413 TopTools_ListIteratorOfListOfShape aEIt (EList);
414 list< double >::iterator aUIt = UList.begin();
415 for ( ; aEIt.More(); aEIt.Next(), aUIt++ )
417 const TopoDS_Edge& E = TopoDS::Edge( aEIt.Value() );
419 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
421 double umin = DBL_MAX, umax = -DBL_MAX;
422 SMDS_NodeIteratorPtr nIt = theMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
423 if ( !nIt->more() ) // no nodes on edge, only on vertices
429 while ( nIt->more() ) {
430 const SMDS_MeshNode* node = nIt->next();
431 // check if node is medium
432 if ( CreateQuadratic && StdMeshers_Helper::IsMedium( node, SMDSAbs_Edge ))
434 const SMDS_EdgePosition* epos =
435 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
436 double u = epos->GetUParameter();
443 bool isFirstCommon = ( *aUIt == f );
444 gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax );
445 double dist = theUV.SquareDistance( uv );
446 if ( dist > maxDist ) {
452 uv0.x = theUV.X(); uv0.y = theUV.Y();
453 uv1.x = nextUV.X(); uv1.y = nextUV.Y();
454 uv2.x = uv0.x; uv2.y = uv0.y;
455 if ( fixOverlappedLinkUV( uv0, uv1, uv2 ))
457 double step = theUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
459 // move theUV along the normal by the step
463 MESSAGE("--fixCommonVertexUV move(" << theUV.X() << " " << theUV.Y()
464 << ") by (" << N.X() << " " << N.Y() << ")"
465 << endl << "--- MAX DIST " << maxDist);
467 theUV.SetXY( theUV.XY() + N.XY() );
474 //=============================================================================
478 //=============================================================================
480 bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh & aMesh,
481 const TopoDS_Face & FF,
482 const TopoDS_Wire & WW,
485 map<int, const SMDS_MeshNode*>&mefistoToDS,
488 const TopTools_IndexedDataMapOfShapeListOfShape& VWMap)
490 // MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints");
492 //SMDS_Mesh * meshDS = aMesh.GetMeshDS();
494 TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
496 int mInit = m, mFirst, iEdge;
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), iEdge = 0; wexp.More(); wexp.Next(), iEdge++) {
502 const TopoDS_Edge & E = wexp.Current();
504 // --- IDNodes of first and last Vertex
506 TopoDS_Vertex VFirst, VLast;
507 TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
509 ASSERT(!VFirst.IsNull());
510 SMDS_NodeIteratorPtr lid =
511 aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
512 if ( !lid->more() ) {
513 MESSAGE (" NO NODE BUILT ON VERTEX ");
516 const SMDS_MeshNode* idFirst = lid->next();
518 ASSERT(!VLast.IsNull());
519 lid = aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
520 if ( !lid->more() ) {
521 MESSAGE (" NO NODE BUILT ON VERTEX ");
524 const SMDS_MeshNode* idLast = lid->next();
526 int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
527 if ( _quadraticMesh )
531 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
533 SMDS_NodeIteratorPtr ite= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
535 //bool isForward = (E.Orientation() == TopAbs_FORWARD);
536 map<double, const SMDS_MeshNode*> params;
539 const SMDS_MeshNode * node = ite->next();
540 if ( _quadraticMesh && StdMeshers_Helper::IsMedium( node, SMDSAbs_Edge ))
542 const SMDS_EdgePosition* epos =
543 static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
544 double param = epos->GetUParameter();
545 params[param] = node;
548 if ( nbPoints != params.size()) {
549 MESSAGE( "BAD NODE ON EDGE POSITIONS" );
555 // --- load 2D values into MEFISTO structure,
556 // add IDNodes in mefistoToDS map
557 if (E.Orientation() == TopAbs_FORWARD) {
558 gp_Pnt2d p = C2d->Value(f).XY().Multiplied( scale ); // first point = Vertex Forward
559 if ( fixCommonVertexUV( p, VFirst, W, myOuterWire, F, VWMap, aMesh, _quadraticMesh ))
560 myNodesOnCommonV.push_back( idFirst );
563 mefistoToDS[m + 1] = idFirst;
564 // MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
565 // MESSAGE("__ f "<<f<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
567 map<double, const SMDS_MeshNode*>::iterator itp = params.begin();
568 for (int i = 1; i <= nbPoints; i++) { // nbPoints internal
569 double param = (*itp).first;
570 gp_Pnt2d p = C2d->Value(param).XY().Multiplied( scale );
573 mefistoToDS[m + 1] = (*itp).second;
574 // MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
575 // MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
581 gp_Pnt2d p = C2d->Value(l).XY().Multiplied( scale ); // last point = Vertex Reversed
582 if ( fixCommonVertexUV( p, VLast, W, myOuterWire, F, VWMap, aMesh, _quadraticMesh ))
583 myNodesOnCommonV.push_back( idLast );
586 mefistoToDS[m + 1] = idLast;
587 // MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
588 // MESSAGE("__ l "<<l<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
590 map<double, const SMDS_MeshNode*>::reverse_iterator itp = params.rbegin();
591 for (int i = nbPoints; i >= 1; i--)
593 double param = (*itp).first;
594 gp_Pnt2d p = C2d->Value(param).XY().Multiplied( scale );
597 mefistoToDS[m + 1] = (*itp).second;
598 // MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
599 // MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
604 /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
605 /// !!!!!!! HERE IS A BUG with fixOverlappedLinkUV !!!!!!!!!!!
606 // !!!!!!! Correct version is in the CVS head !!!!!!!!!!
607 /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
608 // prevent failure on overlapped adjacent links
610 // fixOverlappedLinkUV (uvslf[ mFirst - 1],
612 // uvslf[ mFirst + 1 ]);
616 // fixOverlappedLinkUV (uvslf[ m - 1],
618 // uvslf[ mInit + 1 ]);
623 //=============================================================================
627 //=============================================================================
629 void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
630 const TopoDS_Face & aFace, double &scalex, double &scaley)
632 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeScaleOnFace");
633 TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD));
634 TopoDS_Wire W = BRepTools::OuterWire(F);
636 double xmin = 1.e300; // min & max of face 2D parametric coord.
637 double xmax = -1.e300;
638 double ymin = 1.e300;
639 double ymax = -1.e300;
644 TopExp_Explorer wexp(W, TopAbs_EDGE);
645 for ( ; wexp.More(); wexp.Next())
647 const TopoDS_Edge & E = TopoDS::Edge( wexp.Current() );
649 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
650 if ( C2d.IsNull() ) continue;
651 double du = (l - f) / double (nbp);
652 for (int i = 0; i <= nbp; i++)
654 double param = f + double (i) * du;
655 gp_Pnt2d p = C2d->Value(param);
664 // MESSAGE(" "<< f<<" "<<l<<" "<<param<<" "<<xmin<<" "<<xmax<<" "<<ymin<<" "<<ymax);
671 double xmoy = (xmax + xmin) / 2.;
672 double ymoy = (ymax + ymin) / 2.;
673 double xsize = xmax - xmin;
674 double ysize = ymax - ymin;
676 Handle(Geom_Surface) S = BRep_Tool::Surface(F); // 3D surface
680 gp_Pnt PX0 = S->Value(xmin, ymoy);
681 gp_Pnt PY0 = S->Value(xmoy, ymin);
682 double dx = xsize / double (nbp);
683 double dy = ysize / double (nbp);
684 for (int i = 1; i <= nbp; i++)
686 double x = xmin + double (i) * dx;
687 gp_Pnt PX = S->Value(x, ymoy);
688 double y = ymin + double (i) * dy;
689 gp_Pnt PY = S->Value(xmoy, y);
690 length_x += PX.Distance(PX0);
691 length_y += PY.Distance(PY0);
695 scalex = length_x / xsize;
696 scaley = length_y / ysize;
699 double xyratio = xsize*scalex/(ysize*scaley);
700 const double maxratio = 1.e2;
702 if (xyratio > maxratio) {
704 scaley *= xyratio / maxratio;
707 else if (xyratio < 1./maxratio) {
709 scalex *= 1 / xyratio / maxratio;
716 //=============================================================================
720 //=============================================================================
722 void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
723 Z nbst, R2 * uvst, Z nbt, Z * nust,
724 const TopoDS_Face & F, bool faceIsForward,
725 map<int, const SMDS_MeshNode*>&mefistoToDS,
726 double scalex, double scaley)
728 SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
729 int faceID = meshDS->ShapeToIndex( F );
732 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
734 for (n = 0; n < nbst; n++)
736 if (mefistoToDS.find(n + 1) == mefistoToDS.end())
738 double u = uvst[n][0] / scalex;
739 double v = uvst[n][1] / scaley;
740 gp_Pnt P = S->Value(u, v);
742 SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
743 meshDS->SetNodeOnFace(node, faceID, u, v);
745 //MESSAGE(P.X()<<" "<<P.Y()<<" "<<P.Z());
746 mefistoToDS[n + 1] = node;
747 //MESSAGE("NEW: "<<n<<" "<<mefistoToDS[n+1]);
754 //SCRUTE(faceIsForward);
755 for (n = 1; n <= nbt; n++)
757 int inode1 = nust[m++];
758 int inode2 = nust[m++];
759 int inode3 = nust[m++];
761 const SMDS_MeshNode *n1, *n2, *n3;
762 n1 = mefistoToDS[inode1];
763 n2 = mefistoToDS[inode2];
764 n3 = mefistoToDS[inode3];
765 //MESSAGE("-- "<<inode1<<" "<<inode2<<" "<<inode3);
767 // triangle points must be in trigonometric order if face is Forward
768 // else they must be put clockwise
770 bool triangleIsWellOriented = faceIsForward;
772 SMDS_MeshElement * elt;
773 if (triangleIsWellOriented)
774 //elt = meshDS->AddFace(n1, n2, n3);
775 elt = myTool->AddFace(n1, n2, n3);
777 //elt = meshDS->AddFace(n1, n3, n2);
778 elt = myTool->AddFace(n1, n3, n2);
780 meshDS->SetMeshElementOnShape(elt, faceID);
784 // remove bad elements build on vertices shared by wires
786 list<const SMDS_MeshNode*>::iterator itN = myNodesOnCommonV.begin();
787 for ( ; itN != myNodesOnCommonV.end(); itN++ )
789 const SMDS_MeshNode* node = *itN;
790 SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
791 while ( invElemIt->more() )
793 const SMDS_MeshElement* elem = invElemIt->next();
794 SMDS_ElemIteratorPtr itN = elem->nodesIterator();
796 while ( itN->more() )
797 if ( itN->next() == node)
800 MESSAGE( "RM bad element " << elem->GetID());
801 meshDS->RemoveElement( elem );
808 //=============================================================================
812 //=============================================================================
814 double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
815 const TopoDS_Shape & aShape)
817 //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength");
818 // **** a mettre dans SMESH_2D_Algo ?
820 //const TopoDS_Face & FF = TopoDS::Face(aShape);
821 //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
822 //TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
824 double meanElementLength = 100;
825 double wireLength = 0;
826 int wireElementsNumber = 0;
827 for (TopExp_Explorer expe(aShape, TopAbs_EDGE); expe.More(); expe.Next())
829 const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
830 int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
831 double length = EdgeLength(E);
832 wireLength += length;
833 wireElementsNumber += nb;
835 if (wireElementsNumber)
836 meanElementLength = wireLength / wireElementsNumber;
837 //SCRUTE(meanElementLength);
838 return meanElementLength;
841 //=============================================================================
845 //=============================================================================
847 ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save)
852 //=============================================================================
856 //=============================================================================
858 istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load)
863 //=============================================================================
867 //=============================================================================
869 ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp)
871 return hyp.SaveTo( save );
874 //=============================================================================
878 //=============================================================================
880 istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp)
882 return hyp.LoadFrom( load );