X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Regular_1D.cxx;h=f13f1cbce7006c94025f0a9a0f38868b06117c60;hp=be3e69f1d9fcc6549ec165fc5308af920f886309;hb=104ff7b2818ce4d0f8a38d840abd3e5c70190668;hpb=8672ad3e7621ac25fffa8517599afa84ffea509a diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index be3e69f1d..f13f1cbce 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -17,7 +17,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // // @@ -30,19 +30,22 @@ using namespace std; #include "StdMeshers_Regular_1D.hxx" +#include "StdMeshers_Distribution.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" +#include "SMESH_HypoFilter.hxx" +#include "SMESH_subMesh.hxx" #include "StdMeshers_LocalLength.hxx" #include "StdMeshers_NumberOfSegments.hxx" #include "StdMeshers_Arithmetic1D.hxx" #include "StdMeshers_StartEndLength.hxx" #include "StdMeshers_Deflection1D.hxx" +#include "StdMeshers_AutomaticLength.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" #include "SMDS_EdgePosition.hxx" -#include "SMESH_subMesh.hxx" #include "Utils_SALOME_Exception.hxx" #include "utilities.h" @@ -62,10 +65,13 @@ using namespace std; #include #include #include +#include #include #include +using namespace std; + //============================================================================= /*! * @@ -84,6 +90,9 @@ StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId, _compatibleHypothesis.push_back("StartEndLength"); _compatibleHypothesis.push_back("Deflection1D"); _compatibleHypothesis.push_back("Arithmetic1D"); + _compatibleHypothesis.push_back("AutomaticLength"); + + _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!! } //============================================================================= @@ -103,22 +112,37 @@ StdMeshers_Regular_1D::~StdMeshers_Regular_1D() //============================================================================= bool StdMeshers_Regular_1D::CheckHypothesis - (SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, SMESH_Hypothesis::Hypothesis_Status& aStatus) { _hypType = NONE; + _quadraticMesh = false; + + const bool ignoreAuxiliaryHyps = false; + const list & hyps = + GetUsedHypothesis(aMesh, aShape, ignoreAuxiliaryHyps); + + // find non-auxiliary hypothesis + const SMESHDS_Hypothesis *theHyp = 0; + list ::const_iterator h = hyps.begin(); + for ( ; h != hyps.end(); ++h ) { + if ( static_cast(*h)->IsAuxiliary() ) { + if ( strcmp( "QuadraticMesh", (*h)->GetName() ) == 0 ) + _quadraticMesh = true; + } + else { + if ( !theHyp ) + theHyp = *h; // use only the first non-auxiliary hypothesis + } + } - const list &hyps = GetUsedHypothesis(aMesh, aShape); - if (hyps.size() == 0) + if ( !theHyp ) { aStatus = SMESH_Hypothesis::HYP_MISSING; return false; // can't work without a hypothesis } - // use only the first hypothesis - const SMESHDS_Hypothesis *theHyp = hyps.front(); - string hypName = theHyp->GetName(); if (hypName == "LocalLength") @@ -159,7 +183,7 @@ bool StdMeshers_Regular_1D::CheckHypothesis } if (_ivalue[ DISTR_TYPE_IND ] == StdMeshers_NumberOfSegments::DT_TabFunc || _ivalue[ DISTR_TYPE_IND ] == StdMeshers_NumberOfSegments::DT_ExprFunc) - _ivalue[ EXP_MODE_IND ] = (int) hyp->IsExponentMode(); + _ivalue[ CONV_MODE_IND ] = hyp->ConversionMode(); _hypType = NB_SEGMENTS; aStatus = SMESH_Hypothesis::HYP_OK; } @@ -198,6 +222,17 @@ bool StdMeshers_Regular_1D::CheckHypothesis _hypType = DEFLECTION; aStatus = SMESH_Hypothesis::HYP_OK; } + + else if (hypName == "AutomaticLength") + { + StdMeshers_AutomaticLength * hyp = const_cast + (dynamic_cast (theHyp)); + ASSERT(hyp); + _value[ BEG_LENGTH_IND ] = _value[ END_LENGTH_IND ] = hyp->GetLength( &aMesh, aShape ); + ASSERT( _value[ BEG_LENGTH_IND ] > 0 ); + _hypType = LOCAL_LENGTH; + aStatus = SMESH_Hypothesis::HYP_OK; + } else aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; @@ -247,240 +282,34 @@ static void compensateError(double a1, double an, } } -/*! - * \brief This class provides interface for a density function - */ -class Function -{ -public: - Function(bool expMode) : _expMode(expMode) {} - double operator() (double t) const; - virtual bool IsReady() const = 0; -protected: - virtual double compute(double t) const = 0; -private: - bool _expMode; -}; - -/*! - * \brief This class provides computation of density function given by a table - */ -class TabFunction: public Function -{ -public: - TabFunction(const vector& table, bool expMode); - virtual bool IsReady() const; -protected: - virtual double compute(double t) const; -private: - const vector& _table; -}; - -/*! - * \brief This class provides computation of density function given by an expression - */ -class ExprFunction: public Function -{ -public: - ExprFunction(const char* expr, bool expMode); - virtual bool IsReady() const; -protected: - virtual double compute(double t) const; -private: - Handle(Expr_GeneralExpression) _expression; - Expr_Array1OfNamedUnknown _var; - mutable TColStd_Array1OfReal _val; -}; - -double Function::operator() (double t) const -{ - double res = compute(t); - if (_expMode) - res = pow(10, res); - return res; -} - -TabFunction::TabFunction(const vector& table, bool expMode) - : Function(expMode), - _table(table) -{ -} - -bool TabFunction::IsReady() const -{ - return true; -} - -double TabFunction::compute (double t) const -{ - //find place of in table - int i; - for (i=0; i < _table.size()/2; i++) - if (_table[i*2] > t) - break; - if (i >= _table.size()/2) - i = _table.size()/2 - 1; - - if (i == 0) - return _table[1]; - - // interpolate function value on found interval - // (t - x[i-1]) / (x[i] - x[i-1]) = (y - f[i-1]) / (f[i] - f[i-1]) - // => y = f[i-1] + (f[i] - f[i-1]) * (t - x[i-1]) / (x[i] - x[i-1]) - double x1 = _table[(i-1)*2]; - double x2 = _table[i*2]; - double y1 = _table[(i-1)*2+1]; - double y2 = _table[i*2+1]; - if (x2 - x1 < Precision::Confusion()) - throw SALOME_Exception("TabFunction::compute : confused points"); - return y1 + (y2 - y1) * ((t - x1) / (x2 - x1)); -} - -ExprFunction::ExprFunction(const char* expr, bool expMode) - : Function(expMode), - _var(1,1), - _val(1,1) -{ - Handle( ExprIntrp_GenExp ) gen = ExprIntrp_GenExp::Create(); - gen->Process(TCollection_AsciiString((char*)expr)); - if (gen->IsDone()) - { - _expression = gen->Expression(); - _var(1) = new Expr_NamedUnknown("t"); - } -} - -bool ExprFunction::IsReady() const -{ - return !_expression.IsNull(); -} - -double ExprFunction::compute (double t) const -{ - ASSERT(!_expression.IsNull()); - _val(1) = t; - return _expression->Evaluate(_var, _val); -} - -//================================================================================ -/*! - * \brief Compute next abscissa when two previous ones are given - * \param sm2 - before previous abscissa - * \param sm1 - previous abscissa - * \param func - function of density - * \param reverse - the direction of next abscissa, increase (0) or decrease (1) - * \retval double - the new abscissa - * - * The abscissa s is given by the formulae - * - * ....|--------|----------------|..... - * sm2 sm1 s - * - * func(sm2) / func(sm1) = (sm1-sm2) / (s-sm1) - * => (s-sm1) * func(sm2) = (sm1-sm2) * func(sm1) - * => s = sm1 + (sm1-sm2) * func(sm1) / func(sm2) - */ -//================================================================================ - -static double nextAbscissa(double sm2, double sm1, const Function& func, int reverse) -{ - if (reverse) - { - sm1 = 1.0 - sm1; - sm2 = 1.0 - sm2; - } - return sm1 + (sm1-sm2) * func(sm1) / func(sm2); -} - -//================================================================================ -/*! - * \brief Compute distribution of points on a curve following the law of a function - * \param C3d - the curve to discretize - * \param first - the first parameter on the curve - * \param last - the last parameter on the curve - * \param theReverse - flag indicating that the curve must be reversed - * \param nbSeg - number of output segments - * \param func - the function f(t) - * \param theParams - output points - * \retval bool - true if success - */ -//================================================================================ - static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last, double length, bool theReverse, - int nbSeg, const Function& func, + int nbSeg, Function& func, list& theParams) { - if (!func.IsReady()) - return false; - vector xxx[2]; - int nbPnt = 1 + nbSeg; - int rev, i; - for (rev=0; rev < 2; rev++) - { - // curv abscisses initialisation - vector x(nbPnt, 0.); - // the first abscissa is 0.0 - - // The aim of the algorithm is to find a second abscisse x[1] such as the last - // one x[nbSeg] is very close to 1.0 with the epsilon precision - - double x1_too_small = 0.0; - double x1_too_large = RealLast(); - double x1 = 1.0/nbSeg; - while (1) - { - x[1] = x1; - - // Check if the abscissa of the point 2 to N-1 - // are in the segment ... - - bool ok = true; - for (i=2; i <= nbSeg; i++) - { - x[i] = nextAbscissa(x[i-2], x[i-1], func, rev); - if (x[i] - 1.0 > Precision::Confusion()) - { - x[nbSeg] = x[i]; - ok = false; - break; - } - } - if (!ok) - { - // The segments are to large - // Decrease x1 ... - x1_too_large = x1; - x1 = (x1_too_small+x1_too_large)/2; - continue; - } - - // Look at the abscissa of the point N - // which is to be close to 1.0 + // never do this way + //OSD::SetSignal( true ); - // break condition --> algo converged !! - - if (1.0 - x[nbSeg] < Precision::Confusion()) - break; + if( nbSeg<=0 ) + return false; - // not ok ... + MESSAGE( "computeParamByFunc" ); - x1_too_small = x1; + int nbPnt = 1 + nbSeg; + vector x(nbPnt, 0.); - // Modify x1 value + if( !buildDistribution( func, 0.0, 1.0, nbSeg, x, 1E-4 ) ) + return false; - if (x1_too_large > 1e100) - x1 = 2*x1; - else - x1 = (x1_too_small+x1_too_large)/2; - } - xxx[rev] = x; + MESSAGE( "Points:\n" ); + char buf[1024]; + for( int i=0; i<=nbSeg; i++ ) + { + sprintf( buf, "%f\n", float(x[i] ) ); + MESSAGE( buf ); } + - // average - vector x(nbPnt, 0.); - for (i=0; i < nbPnt; i++) - x[i] = (xxx[0][i] + (1.0 - xxx[1][nbPnt-i])) / 2; // apply parameters in range [0,1] to the space of the curve double prevU = first; @@ -490,7 +319,7 @@ static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last, prevU = last; sign = -1.; } - for (i = 1; i < nbSeg; i++) + for( int i = 1; i < nbSeg; i++ ) { double curvLength = length * (x[i] - x[i-1]) * sign; GCPnts_AbscissaPoint Discret( C3d, curvLength, prevU ); @@ -503,7 +332,7 @@ static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last, return false; prevU = U; } - return false; + return true; } //============================================================================= @@ -519,7 +348,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge double f, l; Handle(Geom_Curve) Curve = BRep_Tool::Curve(theEdge, f, l); - GeomAdaptor_Curve C3d(Curve); + GeomAdaptor_Curve C3d (Curve, f, l); double length = EdgeLength(theEdge); @@ -540,28 +369,41 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge else { // Number Of Segments hypothesis + int NbSegm = _ivalue[ NB_SEGMENTS_IND ]; + if ( NbSegm < 1 ) return false; + if ( NbSegm == 1 ) return true; + switch (_ivalue[ DISTR_TYPE_IND ]) { case StdMeshers_NumberOfSegments::DT_Scale: { double scale = _value[ SCALE_FACTOR_IND ]; - if ( theReverse ) - scale = 1. / scale; - double alpha = pow( scale , 1.0 / (_ivalue[ NB_SEGMENTS_IND ] - 1)); - double factor = (l - f) / (1 - pow( alpha,_ivalue[ NB_SEGMENTS_IND ])); - - int i, NbPoints = 1 + _ivalue[ NB_SEGMENTS_IND ]; - for ( i = 2; i < NbPoints; i++ ) - { - double param = f + factor * (1 - pow(alpha, i - 1)); - theParams.push_back( param ); + + if (fabs(scale - 1.0) < Precision::Confusion()) { + // special case to avoid division on zero + for (int i = 1; i < NbSegm; i++) { + double param = f + (l - f) * i / NbSegm; + theParams.push_back( param ); + } + } else { + // general case of scale distribution + if ( theReverse ) + scale = 1.0 / scale; + + double alpha = pow(scale, 1.0 / (NbSegm - 1)); + double factor = (l - f) / (1.0 - pow(alpha, NbSegm)); + + for (int i = 1; i < NbSegm; i++) { + double param = f + factor * (1.0 - pow(alpha, i)); + theParams.push_back( param ); + } } return true; } break; case StdMeshers_NumberOfSegments::DT_TabFunc: { - TabFunction func(_vvalue[ TAB_FUNC_IND ], (bool)_ivalue[ EXP_MODE_IND ]); + FunctionTable func(_vvalue[ TAB_FUNC_IND ], _ivalue[ CONV_MODE_IND ]); return computeParamByFunc(C3d, f, l, length, theReverse, _ivalue[ NB_SEGMENTS_IND ], func, theParams); @@ -569,7 +411,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge break; case StdMeshers_NumberOfSegments::DT_ExprFunc: { - ExprFunction func(_svalue[ EXPR_FUNC_IND ].c_str(), (bool)_ivalue[ EXP_MODE_IND ]); + FunctionExpr func(_svalue[ EXPR_FUNC_IND ].c_str(), _ivalue[ CONV_MODE_IND ]); return computeParamByFunc(C3d, f, l, length, theReverse, _ivalue[ NB_SEGMENTS_IND ], func, theParams); @@ -582,7 +424,6 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge return false; } } - GCPnts_UniformAbscissa Discret(C3d, eltSize, f, l); if ( !Discret.IsDone() ) return false; @@ -593,6 +434,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge double param = Discret.Parameter(i); theParams.push_back( param ); } + compensateError( eltSize, eltSize, f, l, length, C3d, theParams ); // for PAL9899 return true; } @@ -661,7 +503,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge case DEFLECTION: { - GCPnts_UniformDeflection Discret(C3d, _value[ DEFLECTION_IND ], true); + GCPnts_UniformDeflection Discret(C3d, _value[ DEFLECTION_IND ], f, l, true); if ( !Discret.IsDone() ) return false; @@ -699,6 +541,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh const TopoDS_Edge & EE = TopoDS::Edge(aShape); TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD)); + int shapeID = meshDS->ShapeToIndex( E ); double f, l; Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, f, l); @@ -717,24 +560,25 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh ASSERT(!VLast.IsNull()); lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes(); - if (!lid->more()) - { + if (!lid->more()) { MESSAGE (" NO NODE BUILT ON VERTEX "); return false; } const SMDS_MeshNode * idLast = lid->next(); - if (!Curve.IsNull()) - { + if (!Curve.IsNull()) { list< double > params; bool reversed = false; if ( !_mainEdge.IsNull() ) reversed = aMesh.IsReversedInChain( EE, _mainEdge ); try { - if ( ! computeInternalParameters( E, params, reversed )) + if ( ! computeInternalParameters( E, params, reversed )) { + //cout << "computeInternalParameters() failed" <::iterator itU = params.begin(); itU != params.end(); itU++) - { + for (list::iterator itU = params.begin(); itU != params.end(); itU++) { double param = *itU; gp_Pnt P = Curve->Value(param); //Add the Node in the DataStructure SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); - meshDS->SetNodeOnEdge(node, E); - - // **** edgePosition associe au point = param. - SMDS_EdgePosition* epos = - dynamic_cast(node->GetPosition().get()); - epos->SetUParameter(param); + meshDS->SetNodeOnEdge(node, shapeID, param); + + if(_quadraticMesh) { + // create medium node + double prm = ( parPrev + param )/2; + gp_Pnt PM = Curve->Value(prm); + SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z()); + meshDS->SetNodeOnEdge(NM, shapeID, prm); + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + meshDS->SetMeshElementOnShape(edge, shapeID); + } - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); - meshDS->SetMeshElementOnShape(edge, E); idPrev = node; + parPrev = param; + } + if(_quadraticMesh) { + double prm = ( parPrev + parLast )/2; + gp_Pnt PM = Curve->Value(prm); + SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z()); + meshDS->SetNodeOnEdge(NM, shapeID, prm); + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); + meshDS->SetMeshElementOnShape(edge, shapeID); } - SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); - meshDS->SetMeshElementOnShape(edge, E); } - else - { + else { // Edge is a degenerated Edge : We put n = 5 points on the edge. - int NbPoints = 5; + const int NbPoints = 5; BRep_Tool::Range(E, f, l); double du = (l - f) / (NbPoints - 1); //MESSAGE("************* Degenerated edge! *****************"); @@ -777,22 +643,36 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh gp_Pnt P = BRep_Tool::Pnt(V1); const SMDS_MeshNode * idPrev = idFirst; - for (int i = 2; i < NbPoints; i++) - { + for (int i = 2; i < NbPoints; i++) { double param = f + (i - 1) * du; SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); - meshDS->SetNodeOnEdge(node, E); - - SMDS_EdgePosition* epos = - dynamic_cast(node->GetPosition().get()); - epos->SetUParameter(param); - - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); - meshDS->SetMeshElementOnShape(edge, E); + if(_quadraticMesh) { + // create medium node + double prm = param - du/2.; + SMDS_MeshNode * NM = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnEdge(NM, shapeID, prm); + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + meshDS->SetNodeOnEdge(node, shapeID, param); idPrev = node; } - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast); - meshDS->SetMeshElementOnShape(edge, E); + if(_quadraticMesh) { + // create medium node + double prm = l - du/2.; + SMDS_MeshNode * NM = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnEdge(NM, shapeID, prm); + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else { + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast); + meshDS->SetMeshElementOnShape(edge, shapeID); + } } return true; } @@ -803,40 +683,47 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh */ //============================================================================= -const list & StdMeshers_Regular_1D::GetUsedHypothesis( - SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +const list & +StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const bool ignoreAuxiliary) { _usedHypList.clear(); - _usedHypList = GetAppliedHypothesis(aMesh, aShape); // copy - int nbHyp = _usedHypList.size(); _mainEdge.Nullify(); + + SMESH_HypoFilter auxiliaryFilter, compatibleFilter; + auxiliaryFilter.Init( SMESH_HypoFilter::IsAuxiliary() ); + const bool ignoreAux = true; + InitCompatibleHypoFilter( compatibleFilter, ignoreAux ); + + // get non-auxiliary assigned to aShape + int nbHyp = aMesh.GetHypotheses( aShape, compatibleFilter, _usedHypList, false ); + if (nbHyp == 0) { // Check, if propagated from some other edge if (aShape.ShapeType() == TopAbs_EDGE && aMesh.IsPropagatedHypothesis(aShape, _mainEdge)) { - // Propagation of 1D hypothesis from on this edge - //_usedHypList = GetAppliedHypothesis(aMesh, _mainEdge); // copy - // use a general method in order not to nullify _mainEdge - _usedHypList = SMESH_Algo::GetUsedHypothesis(aMesh, _mainEdge); // copy - nbHyp = _usedHypList.size(); + // Propagation of 1D hypothesis from on this edge; + // get non-auxiliary assigned to _mainEdge + nbHyp = aMesh.GetHypotheses( _mainEdge, compatibleFilter, _usedHypList, true ); } } - if (nbHyp == 0) + + if (nbHyp == 0) // nothing propagated nor assigned to aShape { - TopTools_ListIteratorOfListOfShape ancIt( aMesh.GetAncestors( aShape )); - for (; ancIt.More(); ancIt.Next()) - { - const TopoDS_Shape& ancestor = ancIt.Value(); - _usedHypList = GetAppliedHypothesis(aMesh, ancestor); // copy - nbHyp = _usedHypList.size(); - if (nbHyp == 1) - break; - } + SMESH_Algo::GetUsedHypothesis( aMesh, aShape, ignoreAuxiliary ); + nbHyp = _usedHypList.size(); } - if (nbHyp > 1) - _usedHypList.clear(); //only one compatible hypothesis allowed + else + { + // get auxiliary hyps from aShape + aMesh.GetHypotheses( aShape, auxiliaryFilter, _usedHypList, true ); + } + if ( nbHyp > 1 && ignoreAuxiliary ) + _usedHypList.clear(); //only one compatible non-auxiliary hypothesis allowed + return _usedHypList; }