X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_Algo.cxx;h=4de1879f1c231c776c864765bf238f28eebaab66;hp=e31bf02d9ee800e26adf002705c08c46f7399ac4;hb=1fb3ff621ac19da15742a5e8b9253b594977d14a;hpb=466da2436e3a2de79c6c79edafc0d4cac819f839 diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index e31bf02d9..4de1879f1 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -20,7 +20,7 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions +// SMESH SMESH : implementation of SMESH idl descriptions // File : SMESH_Algo.cxx // Author : Paul RASCLE, EDF // Module : SMESH @@ -42,8 +42,6 @@ #include "SMESH_TypeDefs.hxx" #include "SMESH_subMesh.hxx" -#include - #include #include #include @@ -87,7 +85,7 @@ using namespace std; bool SMESH_Algo::Features::IsCompatible( const SMESH_Algo::Features& algo2 ) const { if ( _dim > algo2._dim ) return algo2.IsCompatible( *this ); - // algo2 is of highter dimension + // algo2 is of higher dimension if ( _outElemTypes.empty() || algo2._inElemTypes.empty() ) return false; bool compatible = true; @@ -175,8 +173,8 @@ const SMESH_Algo::Features& SMESH_Algo::GetFeatures( const std::string& algoType */ //============================================================================= -SMESH_Algo::SMESH_Algo (int hypId, int studyId, SMESH_Gen * gen) - : SMESH_Hypothesis(hypId, studyId, gen) +SMESH_Algo::SMESH_Algo (int hypId, SMESH_Gen * gen) + : SMESH_Hypothesis(hypId, gen) { _compatibleAllHypFilter = _compatibleNoAuxHypFilter = NULL; _onlyUnaryInput = _requireDiscreteBoundary = _requireShape = true; @@ -204,26 +202,26 @@ SMESH_Algo::~SMESH_Algo() */ //============================================================================= -SMESH_0D_Algo::SMESH_0D_Algo(int hypId, int studyId, SMESH_Gen* gen) - : SMESH_Algo(hypId, studyId, gen) +SMESH_0D_Algo::SMESH_0D_Algo(int hypId, SMESH_Gen* gen) + : SMESH_Algo(hypId, gen) { _shapeType = (1 << TopAbs_VERTEX); _type = ALGO_0D; } -SMESH_1D_Algo::SMESH_1D_Algo(int hypId, int studyId, SMESH_Gen* gen) - : SMESH_Algo(hypId, studyId, gen) +SMESH_1D_Algo::SMESH_1D_Algo(int hypId, SMESH_Gen* gen) + : SMESH_Algo(hypId, gen) { _shapeType = (1 << TopAbs_EDGE); _type = ALGO_1D; } -SMESH_2D_Algo::SMESH_2D_Algo(int hypId, int studyId, SMESH_Gen* gen) - : SMESH_Algo(hypId, studyId, gen) +SMESH_2D_Algo::SMESH_2D_Algo(int hypId, SMESH_Gen* gen) + : SMESH_Algo(hypId, gen) { _shapeType = (1 << TopAbs_FACE); _type = ALGO_2D; } -SMESH_3D_Algo::SMESH_3D_Algo(int hypId, int studyId, SMESH_Gen* gen) - : SMESH_Algo(hypId, studyId, gen) +SMESH_3D_Algo::SMESH_3D_Algo(int hypId, SMESH_Gen* gen) + : SMESH_Algo(hypId, gen) { _shapeType = (1 << TopAbs_SOLID); _type = ALGO_3D; @@ -231,7 +229,7 @@ SMESH_3D_Algo::SMESH_3D_Algo(int hypId, int studyId, SMESH_Gen* gen) //============================================================================= /*! - * Usually an algoritm has nothing to save + * Usually an algorithm has nothing to save */ //============================================================================= @@ -265,6 +263,10 @@ SMESH_Algo::GetUsedHypothesis(SMESH_Mesh & aMesh, const bool ignoreAuxiliary) const { SMESH_Algo* me = const_cast< SMESH_Algo* >( this ); + + std::list savedHyps; // don't delete the list if + savedHyps.swap( me->_usedHypList ); // it does not change (#16578) + me->_usedHypList.clear(); if ( const SMESH_HypoFilter* filter = GetCompatibleHypoFilter( ignoreAuxiliary )) { @@ -272,6 +274,9 @@ SMESH_Algo::GetUsedHypothesis(SMESH_Mesh & aMesh, if ( ignoreAuxiliary && _usedHypList.size() > 1 ) me->_usedHypList.clear(); //only one compatible hypothesis allowed } + if ( _usedHypList == savedHyps ) + savedHyps.swap( me->_usedHypList ); + return _usedHypList; } @@ -289,10 +294,17 @@ SMESH_Algo::GetAppliedHypothesis(SMESH_Mesh & aMesh, const bool ignoreAuxiliary) const { SMESH_Algo* me = const_cast< SMESH_Algo* >( this ); + + std::list savedHyps; // don't delete the list if + savedHyps.swap( me->_appliedHypList ); // it does not change (#16578) + me->_appliedHypList.clear(); if ( const SMESH_HypoFilter* filter = GetCompatibleHypoFilter( ignoreAuxiliary )) aMesh.GetHypotheses( aShape, *filter, me->_appliedHypList, false ); + if ( _appliedHypList == savedHyps ) + savedHyps.swap( me->_appliedHypList ); + return _appliedHypList; } @@ -360,12 +372,9 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh, SMDS_NodeIteratorPtr nIt = eSubMesh->GetNodes(); while ( nIt->more() ) { - const SMDS_MeshNode* node = nIt->next(); - const SMDS_PositionPtr& pos = node->GetPosition(); - if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE ) + SMDS_EdgePositionPtr epos = nIt->next()->GetPosition(); + if ( !epos ) return false; - const SMDS_EdgePosition* epos = - static_cast(node->GetPosition()); if ( !paramSet.insert( epos->GetUParameter() ).second ) return false; // equal parameters } @@ -426,11 +435,9 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theM const SMDS_MeshNode* node = nIt->next(); if ( ignoreMediumNodes && SMESH_MesherHelper::IsMedium( node, typeToCheck )) continue; - const SMDS_PositionPtr& pos = node->GetPosition(); - if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE ) + SMDS_EdgePositionPtr epos = node->GetPosition(); + if ( ! epos ) return false; - const SMDS_EdgePosition* epos = - static_cast(node->GetPosition()); theNodes.insert( theNodes.end(), make_pair( epos->GetUParameter(), node )); ++nbNodes; } @@ -440,13 +447,15 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theM TopExp::Vertices(theEdge, v1, v2); const SMDS_MeshNode* n1 = VertexNode( v1, eSubMesh, 0 ); const SMDS_MeshNode* n2 = VertexNode( v2, eSubMesh, 0 ); + const SMDS_MeshNode* nEnd[2] = { nbNodes ? theNodes.begin()->second : 0, + nbNodes ? theNodes.rbegin()->second : 0 }; Standard_Real f, l; BRep_Tool::Range(theEdge, f, l); if ( v1.Orientation() != TopAbs_FORWARD ) std::swap( f, l ); - if ( n1 && ++nbNodes ) + if ( n1 && n1 != nEnd[0] && n1 != nEnd[1] && ++nbNodes ) theNodes.insert( make_pair( f, n1 )); - if ( n2 && ++nbNodes ) + if ( n2 && n2 != nEnd[0] && n2 != nEnd[1] && ++nbNodes ) theNodes.insert( make_pair( l, n2 )); return (int)theNodes.size() == nbNodes; @@ -494,10 +503,11 @@ SMESH_Algo::GetCompatibleHypoFilter(const bool ignoreAuxiliary) const */ //================================================================================ -GeomAbs_Shape SMESH_Algo::Continuity(TopoDS_Edge E1, - TopoDS_Edge E2) +GeomAbs_Shape SMESH_Algo::Continuity(const TopoDS_Edge& theE1, + const TopoDS_Edge& theE2) { - //E1.Orientation(TopAbs_FORWARD), E2.Orientation(TopAbs_FORWARD); // avoid pb with internal edges + // avoid pb with internal edges + TopoDS_Edge E1 = theE1, E2 = theE2; if (E1.Orientation() > TopAbs_REVERSED) // INTERNAL E1.Orientation( TopAbs_FORWARD ); if (E2.Orientation() > TopAbs_REVERSED) // INTERNAL @@ -550,28 +560,35 @@ bool SMESH_Algo::IsStraight( const TopoDS_Edge & E, case GeomAbs_Hyperbola: case GeomAbs_Parabola: return false; - // case GeomAbs_BezierCurve: - // case GeomAbs_BSplineCurve: - // case GeomAbs_OtherCurve: + // case GeomAbs_BezierCurve: + // case GeomAbs_BSplineCurve: + // case GeomAbs_OtherCurve: default:; } - const double f = curve.FirstParameter(); - const double l = curve.LastParameter(); - const gp_Pnt pf = curve.Value( f ); - const gp_Pnt pl = curve.Value( l ); - const gp_Vec v1( pf, pl ); - const double v1Len = v1.Magnitude(); - if ( v1Len < std::numeric_limits< double >::min() ) + + // evaluate how far from a straight line connecting the curve ends + // stand internal points of the curve + double f = curve.FirstParameter(); + double l = curve.LastParameter(); + gp_Pnt pf = curve.Value( f ); + gp_Pnt pl = curve.Value( l ); + gp_Vec lineVec( pf, pl ); + double lineLen2 = lineVec.SquareMagnitude(); + if ( lineLen2 < std::numeric_limits< double >::min() ) return false; // E seems closed - const double tol = Min( 10 * curve.Tolerance(), v1Len * 1e-2 ); + + double edgeTol = 10 * curve.Tolerance(); + double lenTol2 = lineLen2 * 1e-4; + double tol2 = Min( edgeTol * edgeTol, lenTol2 ); + const double nbSamples = 7; for ( int i = 0; i < nbSamples; ++i ) { - const double r = ( i + 1 ) / nbSamples; - const gp_Pnt pi = curve.Value( f * r + l * ( 1 - r )); - const gp_Vec vi( pf, pi ); - const double h = 0.5 * v1.Crossed( vi ).Magnitude() / v1Len; - if ( h > tol ) + double r = ( i + 1 ) / nbSamples; + gp_Pnt pi = curve.Value( f * r + l * ( 1 - r )); + gp_Vec vi( pf, pi ); + double h2 = lineVec.Crossed( vi ).SquareMagnitude() / lineLen2; + if ( h2 > tol2 ) return false; } return true; @@ -583,8 +600,10 @@ bool SMESH_Algo::IsStraight( const TopoDS_Edge & E, */ //================================================================================ -bool SMESH_Algo::isDegenerated( const TopoDS_Edge & E ) +bool SMESH_Algo::isDegenerated( const TopoDS_Edge & E, const bool checkLength ) { + if ( checkLength ) + return EdgeLength( E ) == 0; double f,l; TopLoc_Location loc; Handle(Geom_Curve) C = BRep_Tool::Curve( E, loc, f,l ); @@ -746,7 +765,7 @@ SMESH_Algo::EMeshError SMESH_Algo::GetMeshError(SMESH_subMesh* subMesh) if ( !fIt->more() ) return MEr_EMPTY; - // We check that olny links on EDGEs encouter once, the rest links, twice + // We check that only links on EDGEs encounter once, the rest links, twice set< SMESH_TLink > links; while ( fIt->more() ) { @@ -847,6 +866,16 @@ bool SMESH_Algo::Compute(SMESH_Mesh & /*aMesh*/, SMESH_MesherHelper* /*aHelper*/ return error( COMPERR_BAD_INPUT_MESH, "Mesh built on shape expected"); } +//======================================================================= +//function : IsApplicableToShape +//purpose : Return true if the algorithm can mesh a given shape +//======================================================================= + +bool SMESH_Algo::IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const +{ + return true; +} + //======================================================================= //function : CancelCompute //purpose : Sets _computeCanceled to true. It's usage depends on @@ -894,7 +923,12 @@ bool SMESH_Algo::error(SMESH_ComputeErrorPtr error) if ( error ) { _error = error->myName; _comment = error->myComment; - _badInputElements = error->myBadElements; + if ( error->HasBadElems() ) + { + SMESH_BadInputElements* badElems = static_cast( error.get() ); + _badInputElements = badElems->GetElements(); + _mesh = badElems->GetMesh(); + } return error->IsOK(); } return true; @@ -908,11 +942,15 @@ bool SMESH_Algo::error(SMESH_ComputeErrorPtr error) SMESH_ComputeErrorPtr SMESH_Algo::GetComputeError() const { - SMESH_ComputeErrorPtr err = SMESH_ComputeError::New( _error, _comment, this ); - // hope this method is called by only SMESH_subMesh after this->Compute() - err->myBadElements.splice( err->myBadElements.end(), - (list&) _badInputElements ); - return err; + if ( !_badInputElements.empty() && _mesh ) + { + SMESH_BadInputElements* err = new SMESH_BadInputElements( _mesh, _error, _comment, this ); + // hope this method is called by only SMESH_subMesh after this->Compute() + err->myBadElements.splice( err->myBadElements.end(), + (list&) _badInputElements ); + return SMESH_ComputeErrorPtr( err ); + } + return SMESH_ComputeError::New( _error, _comment, this ); } //================================================================================ @@ -930,6 +968,7 @@ void SMESH_Algo::InitComputeError() if ( (*elem)->GetID() < 1 ) delete *elem; _badInputElements.clear(); + _mesh = 0; _computeCanceled = false; _progressTic = 0; @@ -1223,7 +1262,7 @@ bool SMESH_2D_Algo::FixInternalNodes(const SMESH_ProxyMesh& mesh, gp_Pnt p = S->Value( uv.Coord(1), uv.Coord(2)); const SMDS_MeshNode* n = nodeRows[iRow][iCol]; meshDS->MoveNode( n, p.X(), p.Y(), p.Z() ); - if ( SMDS_FacePosition* pos = dynamic_cast< SMDS_FacePosition*>( n->GetPosition() )) + if ( SMDS_FacePositionPtr pos = n->GetPosition() ) pos->SetParameters( uv.Coord(1), uv.Coord(2) ); } }