Version: 6.3.1

src/StdMeshers/StdMeshers_Regular_1D.cxx

Go to the documentation of this file.
00001 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  SMESH SMESH : implementaion of SMESH idl descriptions
00024 //  File   : StdMeshers_Regular_1D.cxx
00025 //           Moved here from SMESH_Regular_1D.cxx
00026 //  Author : Paul RASCLE, EDF
00027 //  Module : SMESH
00028 //
00029 #include "StdMeshers_Regular_1D.hxx"
00030 #include "StdMeshers_Distribution.hxx"
00031 
00032 #include "StdMeshers_Arithmetic1D.hxx"
00033 #include "StdMeshers_AutomaticLength.hxx"
00034 #include "StdMeshers_Deflection1D.hxx"
00035 #include "StdMeshers_LocalLength.hxx"
00036 #include "StdMeshers_MaxLength.hxx"
00037 #include "StdMeshers_NumberOfSegments.hxx"
00038 #include "StdMeshers_Propagation.hxx"
00039 #include "StdMeshers_SegmentLengthAroundVertex.hxx"
00040 #include "StdMeshers_StartEndLength.hxx"
00041 
00042 #include "SMESH_Gen.hxx"
00043 #include "SMESH_Mesh.hxx"
00044 #include "SMESH_HypoFilter.hxx"
00045 #include "SMESH_subMesh.hxx"
00046 #include "SMESH_subMeshEventListener.hxx"
00047 #include "SMESH_Comment.hxx"
00048 
00049 #include "SMDS_MeshElement.hxx"
00050 #include "SMDS_MeshNode.hxx"
00051 
00052 #include "Utils_SALOME_Exception.hxx"
00053 #include "utilities.h"
00054 
00055 #include <BRepAdaptor_Curve.hxx>
00056 #include <BRep_Tool.hxx>
00057 #include <GCPnts_AbscissaPoint.hxx>
00058 #include <GCPnts_UniformAbscissa.hxx>
00059 #include <GCPnts_UniformDeflection.hxx>
00060 #include <Precision.hxx>
00061 #include <TopExp.hxx>
00062 #include <TopExp_Explorer.hxx>
00063 #include <TopoDS.hxx>
00064 #include <TopoDS_Edge.hxx>
00065 
00066 #include <string>
00067 #include <limits>
00068 
00069 using namespace std;
00070 
00071 //=============================================================================
00075 //=============================================================================
00076 
00077 StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId,
00078         SMESH_Gen * gen):SMESH_1D_Algo(hypId, studyId, gen)
00079 {
00080         MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D");
00081         _name = "Regular_1D";
00082         _shapeType = (1 << TopAbs_EDGE);
00083         _fpHyp = 0;
00084 
00085         _compatibleHypothesis.push_back("LocalLength");
00086         _compatibleHypothesis.push_back("MaxLength");
00087         _compatibleHypothesis.push_back("NumberOfSegments");
00088         _compatibleHypothesis.push_back("StartEndLength");
00089         _compatibleHypothesis.push_back("Deflection1D");
00090         _compatibleHypothesis.push_back("Arithmetic1D");
00091         _compatibleHypothesis.push_back("FixedPoints1D");
00092         _compatibleHypothesis.push_back("AutomaticLength");
00093 
00094         _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!!
00095         _compatibleHypothesis.push_back("Propagation"); // auxiliary !!!
00096 }
00097 
00098 //=============================================================================
00102 //=============================================================================
00103 
00104 StdMeshers_Regular_1D::~StdMeshers_Regular_1D()
00105 {
00106 }
00107 
00108 //=============================================================================
00112 //=============================================================================
00113 
00114 bool StdMeshers_Regular_1D::CheckHypothesis
00115                          (SMESH_Mesh&                          aMesh,
00116                           const TopoDS_Shape&                  aShape,
00117                           SMESH_Hypothesis::Hypothesis_Status& aStatus)
00118 {
00119   _hypType = NONE;
00120   _quadraticMesh = false;
00121 
00122   const list <const SMESHDS_Hypothesis * > & hyps =
00123     GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliaryHyps=*/false);
00124 
00125   // find non-auxiliary hypothesis
00126   const SMESHDS_Hypothesis *theHyp = 0;
00127   list <const SMESHDS_Hypothesis * >::const_iterator h = hyps.begin();
00128   for ( ; h != hyps.end(); ++h ) {
00129     if ( static_cast<const SMESH_Hypothesis*>(*h)->IsAuxiliary() ) {
00130       if ( strcmp( "QuadraticMesh", (*h)->GetName() ) == 0 )
00131         _quadraticMesh = true;
00132     }
00133     else {
00134       if ( !theHyp )
00135         theHyp = *h; // use only the first non-auxiliary hypothesis
00136     }
00137   }
00138 
00139   if ( !theHyp )
00140   {
00141     aStatus = SMESH_Hypothesis::HYP_MISSING;
00142     return false;  // can't work without a hypothesis
00143   }
00144 
00145   string hypName = theHyp->GetName();
00146 
00147   if (hypName == "LocalLength")
00148   {
00149     const StdMeshers_LocalLength * hyp =
00150       dynamic_cast <const StdMeshers_LocalLength * >(theHyp);
00151     ASSERT(hyp);
00152     _value[ BEG_LENGTH_IND ] = hyp->GetLength();
00153     _value[ PRECISION_IND ] = hyp->GetPrecision();
00154     ASSERT( _value[ BEG_LENGTH_IND ] > 0 );
00155     _hypType = LOCAL_LENGTH;
00156     aStatus = SMESH_Hypothesis::HYP_OK;
00157   }
00158 
00159   else if (hypName == "MaxLength")
00160   {
00161     const StdMeshers_MaxLength * hyp =
00162       dynamic_cast <const StdMeshers_MaxLength * >(theHyp);
00163     ASSERT(hyp);
00164     _value[ BEG_LENGTH_IND ] = hyp->GetLength();
00165     if ( hyp->GetUsePreestimatedLength() ) {
00166       if ( int nbSeg = aMesh.GetGen()->GetBoundaryBoxSegmentation() )
00167         _value[ BEG_LENGTH_IND ] = aMesh.GetShapeDiagonalSize() / nbSeg;
00168     }
00169     ASSERT( _value[ BEG_LENGTH_IND ] > 0 );
00170     _hypType = MAX_LENGTH;
00171     aStatus = SMESH_Hypothesis::HYP_OK;
00172   }
00173 
00174   else if (hypName == "NumberOfSegments")
00175   {
00176     const StdMeshers_NumberOfSegments * hyp =
00177       dynamic_cast <const StdMeshers_NumberOfSegments * >(theHyp);
00178     ASSERT(hyp);
00179     _ivalue[ NB_SEGMENTS_IND  ] = hyp->GetNumberOfSegments();
00180     ASSERT( _ivalue[ NB_SEGMENTS_IND ] > 0 );
00181     _ivalue[ DISTR_TYPE_IND ] = (int) hyp->GetDistrType();
00182     switch (_ivalue[ DISTR_TYPE_IND ])
00183     {
00184     case StdMeshers_NumberOfSegments::DT_Scale:
00185       _value[ SCALE_FACTOR_IND ] = hyp->GetScaleFactor();
00186       _revEdgesIDs = hyp->GetReversedEdges();
00187       break;
00188     case StdMeshers_NumberOfSegments::DT_TabFunc:
00189       _vvalue[ TAB_FUNC_IND ] = hyp->GetTableFunction();
00190       _revEdgesIDs = hyp->GetReversedEdges();
00191       break;
00192     case StdMeshers_NumberOfSegments::DT_ExprFunc:
00193       _svalue[ EXPR_FUNC_IND ] = hyp->GetExpressionFunction();
00194       _revEdgesIDs = hyp->GetReversedEdges();
00195       break;
00196     case StdMeshers_NumberOfSegments::DT_Regular:
00197       break;
00198     default:
00199       ASSERT(0);
00200       break;
00201     }
00202     if (_ivalue[ DISTR_TYPE_IND ] == StdMeshers_NumberOfSegments::DT_TabFunc ||
00203         _ivalue[ DISTR_TYPE_IND ] == StdMeshers_NumberOfSegments::DT_ExprFunc)
00204         _ivalue[ CONV_MODE_IND ] = hyp->ConversionMode();
00205     _hypType = NB_SEGMENTS;
00206     aStatus = SMESH_Hypothesis::HYP_OK;
00207   }
00208 
00209   else if (hypName == "Arithmetic1D")
00210   {
00211     const StdMeshers_Arithmetic1D * hyp =
00212       dynamic_cast <const StdMeshers_Arithmetic1D * >(theHyp);
00213     ASSERT(hyp);
00214     _value[ BEG_LENGTH_IND ] = hyp->GetLength( true );
00215     _value[ END_LENGTH_IND ] = hyp->GetLength( false );
00216     ASSERT( _value[ BEG_LENGTH_IND ] > 0 && _value[ END_LENGTH_IND ] > 0 );
00217     _hypType = ARITHMETIC_1D;
00218 
00219     _revEdgesIDs = hyp->GetReversedEdges();
00220 
00221     aStatus = SMESH_Hypothesis::HYP_OK;
00222   }
00223 
00224   else if (hypName == "FixedPoints1D") {
00225     _fpHyp = dynamic_cast <const StdMeshers_FixedPoints1D*>(theHyp);
00226     ASSERT(_fpHyp);
00227     _hypType = FIXED_POINTS_1D;
00228 
00229     _revEdgesIDs = _fpHyp->GetReversedEdges();
00230 
00231     aStatus = SMESH_Hypothesis::HYP_OK;
00232   }
00233 
00234   else if (hypName == "StartEndLength")
00235   {
00236     const StdMeshers_StartEndLength * hyp =
00237       dynamic_cast <const StdMeshers_StartEndLength * >(theHyp);
00238     ASSERT(hyp);
00239     _value[ BEG_LENGTH_IND ] = hyp->GetLength( true );
00240     _value[ END_LENGTH_IND ] = hyp->GetLength( false );
00241     ASSERT( _value[ BEG_LENGTH_IND ] > 0 && _value[ END_LENGTH_IND ] > 0 );
00242     _hypType = BEG_END_LENGTH;
00243 
00244     _revEdgesIDs = hyp->GetReversedEdges();
00245 
00246     aStatus = SMESH_Hypothesis::HYP_OK;
00247   }
00248 
00249   else if (hypName == "Deflection1D")
00250   {
00251     const StdMeshers_Deflection1D * hyp =
00252       dynamic_cast <const StdMeshers_Deflection1D * >(theHyp);
00253     ASSERT(hyp);
00254     _value[ DEFLECTION_IND ] = hyp->GetDeflection();
00255     ASSERT( _value[ DEFLECTION_IND ] > 0 );
00256     _hypType = DEFLECTION;
00257     aStatus = SMESH_Hypothesis::HYP_OK;
00258   }
00259 
00260   else if (hypName == "AutomaticLength")
00261   {
00262     StdMeshers_AutomaticLength * hyp = const_cast<StdMeshers_AutomaticLength *>
00263       (dynamic_cast <const StdMeshers_AutomaticLength * >(theHyp));
00264     ASSERT(hyp);
00265     _value[ BEG_LENGTH_IND ] = _value[ END_LENGTH_IND ] = hyp->GetLength( &aMesh, aShape );
00266 //     _value[ BEG_LENGTH_IND ] = hyp->GetLength( &aMesh, aShape );
00267 //     _value[ END_LENGTH_IND ] = Precision::Confusion(); // ?? or set to zero?
00268     ASSERT( _value[ BEG_LENGTH_IND ] > 0 );
00269     _hypType = MAX_LENGTH;
00270     aStatus = SMESH_Hypothesis::HYP_OK;
00271   }
00272   else
00273     aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
00274 
00275   return ( _hypType != NONE );
00276 }
00277 
00278 static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
00279                                double length, bool theReverse,
00280                                int nbSeg, Function& func,
00281                                list<double>& theParams)
00282 {
00283   // never do this way
00284   //OSD::SetSignal( true );
00285 
00286   if (nbSeg <= 0)
00287     return false;
00288 
00289   MESSAGE( "computeParamByFunc" );
00290 
00291   int nbPnt = 1 + nbSeg;
00292   vector<double> x(nbPnt, 0.);
00293 
00294   if (!buildDistribution(func, 0.0, 1.0, nbSeg, x, 1E-4))
00295      return false;
00296 
00297   MESSAGE( "Points:\n" );
00298   char buf[1024];
00299   for ( int i=0; i<=nbSeg; i++ )
00300   {
00301     sprintf(  buf, "%f\n", float(x[i] ) );
00302     MESSAGE( buf );
00303   }
00304 
00305 
00306 
00307   // apply parameters in range [0,1] to the space of the curve
00308   double prevU = first;
00309   double sign = 1.;
00310   if (theReverse)
00311   {
00312     prevU = last;
00313     sign = -1.;
00314   }
00315   for( int i = 1; i < nbSeg; i++ )
00316   {
00317     double curvLength = length * (x[i] - x[i-1]) * sign;
00318     GCPnts_AbscissaPoint Discret( C3d, curvLength, prevU );
00319     if ( !Discret.IsDone() )
00320       return false;
00321     double U = Discret.Parameter();
00322     if ( U > first && U < last )
00323       theParams.push_back( U );
00324     else
00325       return false;
00326     prevU = U;
00327   }
00328   if ( theReverse )
00329     theParams.reverse();
00330   return true;
00331 }
00332 
00333 
00334 //================================================================================
00347 //================================================================================
00348 
00349 static void compensateError(double a1, double an,
00350                             double U1, double Un,
00351                             double            length,
00352                             Adaptor3d_Curve&  C3d,
00353                             list<double> &    theParams,
00354                             bool              adjustNeighbors2an = false)
00355 {
00356   int i, nPar = theParams.size();
00357   if ( a1 + an < length && nPar > 1 )
00358   {
00359     bool reverse = ( U1 > Un );
00360     GCPnts_AbscissaPoint Discret(C3d, reverse ? an : -an, Un);
00361     if ( !Discret.IsDone() )
00362       return;
00363     double Utgt = Discret.Parameter(); // target value of the last parameter
00364     list<double>::reverse_iterator itU = theParams.rbegin();
00365     double Ul = *itU++; // real value of the last parameter
00366     double dUn = Utgt - Ul; // parametric error of <an>
00367     if ( Abs(dUn) <= Precision::Confusion() )
00368       return;
00369     double dU = Abs( Ul - *itU ); // parametric length of the last but one segment
00370     if ( adjustNeighbors2an || Abs(dUn) < 0.5 * dU ) { // last segment is a bit shorter than it should
00371       // move the last parameter to the edge beginning
00372     }
00373     else {  // last segment is much shorter than it should -> remove the last param and
00374       theParams.pop_back(); nPar--; // move the rest points toward the edge end
00375       dUn = Utgt - theParams.back();
00376     }
00377 
00378     double q  = dUn / ( nPar - 1 );
00379     if ( !adjustNeighbors2an )
00380     {
00381       q = dUn / ( Utgt - Un ); // (signed) factor of segment length change
00382       for ( itU = theParams.rbegin(), i = 1; i < nPar; i++ ) {
00383         double prevU = *itU;
00384         (*itU) += dUn;
00385         ++itU;
00386         dUn = q * (*itU - prevU) * (prevU-U1)/(Un-U1);
00387       }
00388     }
00389     else {
00390       theParams.back() += dUn;
00391       double sign = reverse ? -1 : 1;
00392       double prevU = theParams.back();
00393       itU = theParams.rbegin();
00394       for ( ++itU, i = 2; i < nPar; ++itU, i++ ) {
00395         double newU = *itU + dUn;
00396         if ( newU*sign < prevU*sign ) {
00397           prevU = *itU = newU;
00398           dUn -= q;
00399         }
00400         else { // set U between prevU and next valid param
00401           list<double>::reverse_iterator itU2 = itU;
00402           ++itU2;
00403           int nb = 2;
00404           while ( (*itU2)*sign > prevU*sign ) {
00405             ++itU2; ++nb;
00406           }
00407           dU = ( *itU2 - prevU ) / nb;
00408           while ( itU != itU2 ) {
00409             *itU += dU; ++itU;
00410           }
00411           break;
00412         }
00413       }
00414     }
00415   }
00416 }
00417 
00418 //================================================================================
00424 //================================================================================
00425 
00426 // struct VertexEventListener : public SMESH_subMeshEventListener
00427 // {
00428 //   VertexEventListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh
00429 //   {}
00430 //   /*!
00431 //    * \brief Clean mesh on edges
00432 //    * \param event - algo_event or compute_event itself (of SMESH_subMesh)
00433 //    * \param eventType - ALGO_EVENT or COMPUTE_EVENT (of SMESH_subMesh)
00434 //    * \param subMesh - the submesh where the event occures
00435 //    */
00436 //   void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh,
00437 //                     EventListenerData*, const SMESH_Hypothesis*)
00438 //   {
00439 //     if ( eventType == SMESH_subMesh::ALGO_EVENT) // all algo events
00440 //     {
00441 //       subMesh->ComputeStateEngine( SMESH_subMesh::MODIF_ALGO_STATE );
00442 //     }
00443 //   }
00444 // }; // struct VertexEventListener
00445 
00446 //=============================================================================
00454 //=============================================================================
00455 
00456 void StdMeshers_Regular_1D::SetEventListener(SMESH_subMesh* subMesh)
00457 {
00458   StdMeshers_Propagation::SetPropagationMgr( subMesh );
00459 }
00460 
00461 //=============================================================================
00468 //=============================================================================
00469 
00470 void StdMeshers_Regular_1D::SubmeshRestored(SMESH_subMesh* subMesh)
00471 {
00472 }
00473 
00474 //=============================================================================
00478 //=============================================================================
00479 
00480 const StdMeshers_SegmentLengthAroundVertex*
00481 StdMeshers_Regular_1D::getVertexHyp(SMESH_Mesh &          theMesh,
00482                                     const TopoDS_Vertex & theV)
00483 {
00484   static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName("SegmentAroundVertex_0D"));
00485   if ( const SMESH_Hypothesis * h = theMesh.GetHypothesis( theV, filter, true ))
00486   {
00487     SMESH_Algo* algo = const_cast< SMESH_Algo* >( static_cast< const SMESH_Algo* > ( h ));
00488     const list <const SMESHDS_Hypothesis *> & hypList = algo->GetUsedHypothesis( theMesh, theV, 0 );
00489     if ( !hypList.empty() && string("SegmentLengthAroundVertex") == hypList.front()->GetName() )
00490       return static_cast<const StdMeshers_SegmentLengthAroundVertex*>( hypList.front() );
00491   }
00492   return 0;
00493 }
00494 
00495 //================================================================================
00504 //================================================================================
00505 
00506 void StdMeshers_Regular_1D::redistributeNearVertices (SMESH_Mesh &          theMesh,
00507                                                       Adaptor3d_Curve &     theC3d,
00508                                                       double                theLength,
00509                                                       std::list< double > & theParameters,
00510                                                       const TopoDS_Vertex & theVf,
00511                                                       const TopoDS_Vertex & theVl)
00512 {
00513   double f = theC3d.FirstParameter(), l = theC3d.LastParameter();
00514   int nPar = theParameters.size();
00515   for ( int isEnd1 = 0; isEnd1 < 2; ++isEnd1 )
00516   {
00517     const TopoDS_Vertex & V = isEnd1 ? theVf : theVl;
00518     const StdMeshers_SegmentLengthAroundVertex* hyp = getVertexHyp (theMesh, V );
00519     if ( hyp ) {
00520       double vertexLength = hyp->GetLength();
00521       if ( vertexLength > theLength / 2.0 )
00522         continue;
00523       if ( isEnd1 ) { // to have a segment of interest at end of theParameters
00524         theParameters.reverse();
00525         std::swap( f, l );
00526       }
00527       if ( _hypType == NB_SEGMENTS )
00528       {
00529         compensateError(0, vertexLength, f, l, theLength, theC3d, theParameters, true );
00530       }
00531       else if ( nPar <= 3 )
00532       {
00533         if ( !isEnd1 )
00534           vertexLength = -vertexLength;
00535         GCPnts_AbscissaPoint Discret(theC3d, vertexLength, l);
00536         if ( Discret.IsDone() ) {
00537           if ( nPar == 0 )
00538             theParameters.push_back( Discret.Parameter());
00539           else {
00540             double L = GCPnts_AbscissaPoint::Length( theC3d, theParameters.back(), l);
00541             if ( vertexLength < L / 2.0 )
00542               theParameters.push_back( Discret.Parameter());
00543             else
00544               compensateError(0, vertexLength, f, l, theLength, theC3d, theParameters, true );
00545           }
00546         }
00547       }
00548       else
00549       {
00550         // recompute params between the last segment and a middle one.
00551         // find size of a middle segment
00552         int nHalf = ( nPar-1 ) / 2;
00553         list< double >::reverse_iterator itU = theParameters.rbegin();
00554         std::advance( itU, nHalf );
00555         double Um = *itU++;
00556         double Lm = GCPnts_AbscissaPoint::Length( theC3d, Um, *itU);
00557         double L = GCPnts_AbscissaPoint::Length( theC3d, *itU, l);
00558         StdMeshers_Regular_1D algo( *this );
00559         algo._hypType = BEG_END_LENGTH;
00560         algo._value[ BEG_LENGTH_IND ] = Lm;
00561         algo._value[ END_LENGTH_IND ] = vertexLength;
00562         double from = *itU, to = l;
00563         if ( isEnd1 ) {
00564           std::swap( from, to );
00565           std::swap( algo._value[ BEG_LENGTH_IND ], algo._value[ END_LENGTH_IND ]);
00566         }
00567         list<double> params;
00568         if ( algo.computeInternalParameters( theMesh, theC3d, L, from, to, params, false ))
00569         {
00570           if ( isEnd1 ) params.reverse();
00571           while ( 1 + nHalf-- )
00572             theParameters.pop_back();
00573           theParameters.splice( theParameters.end(), params );
00574         }
00575         else
00576         {
00577           compensateError(0, vertexLength, f, l, theLength, theC3d, theParameters, true );
00578         }
00579       }
00580       if ( isEnd1 )
00581         theParameters.reverse();
00582     }
00583   }
00584 }
00585 
00586 //=============================================================================
00590 //=============================================================================
00591 bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
00592                                                       Adaptor3d_Curve& theC3d,
00593                                                       double           theLength,
00594                                                       double           theFirstU,
00595                                                       double           theLastU,
00596                                                       list<double> &   theParams,
00597                                                       const bool       theReverse,
00598                                                       bool             theConsiderPropagation)
00599 {
00600   theParams.clear();
00601 
00602   double f = theFirstU, l = theLastU;
00603 
00604   switch( _hypType )
00605   {
00606   case LOCAL_LENGTH:
00607   case MAX_LENGTH:
00608   case NB_SEGMENTS: {
00609 
00610     double eltSize = 1;
00611     if ( _hypType == MAX_LENGTH )
00612     {
00613       double nbseg = ceil(theLength / _value[ BEG_LENGTH_IND ]); // integer sup
00614       if (nbseg <= 0)
00615         nbseg = 1;                        // degenerated edge
00616       eltSize = theLength / nbseg;
00617     }
00618     else if ( _hypType == LOCAL_LENGTH )
00619     {
00620       // Local Length hypothesis
00621       double nbseg = ceil(theLength / _value[ BEG_LENGTH_IND ]); // integer sup
00622 
00623       // NPAL17873:
00624       bool isFound = false;
00625       if (theConsiderPropagation && !_mainEdge.IsNull()) // propagated from some other edge
00626       {
00627         // Advanced processing to assure equal number of segments in case of Propagation
00628         SMESH_subMesh* sm = theMesh.GetSubMeshContaining(_mainEdge);
00629         if (sm) {
00630           bool computed = sm->IsMeshComputed();
00631           if (!computed) {
00632             if (sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) {
00633               _gen->Compute( theMesh, _mainEdge, /*anUpward=*/true);
00634               computed = sm->IsMeshComputed();
00635             }
00636           }
00637           if (computed) {
00638             SMESHDS_SubMesh* smds = sm->GetSubMeshDS();
00639             int nb_segments = smds->NbElements();
00640             if (nbseg - 1 <= nb_segments && nb_segments <= nbseg + 1) {
00641               isFound = true;
00642               nbseg = nb_segments;
00643             }
00644           }
00645         }
00646       }
00647       if (!isFound) // not found by meshed edge in the propagation chain, use precision
00648       {
00649         double aPrecision = _value[ PRECISION_IND ];
00650         double nbseg_prec = ceil((theLength / _value[ BEG_LENGTH_IND ]) - aPrecision);
00651         if (nbseg_prec == (nbseg - 1)) nbseg--;
00652       }
00653 
00654       if (nbseg <= 0)
00655         nbseg = 1;                        // degenerated edge
00656       eltSize = theLength / nbseg;
00657     }
00658     else
00659     {
00660       // Number Of Segments hypothesis
00661       int NbSegm = _ivalue[ NB_SEGMENTS_IND ];
00662       if ( NbSegm < 1 )  return false;
00663       if ( NbSegm == 1 ) return true;
00664 
00665       switch (_ivalue[ DISTR_TYPE_IND ])
00666       {
00667       case StdMeshers_NumberOfSegments::DT_Scale:
00668         {
00669           double scale = _value[ SCALE_FACTOR_IND ];
00670 
00671           if (fabs(scale - 1.0) < Precision::Confusion()) {
00672             // special case to avoid division by zero
00673             for (int i = 1; i < NbSegm; i++) {
00674               double param = f + (l - f) * i / NbSegm;
00675               theParams.push_back( param );
00676             }
00677           } else {
00678             // general case of scale distribution
00679             if ( theReverse )
00680               scale = 1.0 / scale;
00681 
00682             double alpha = pow(scale, 1.0 / (NbSegm - 1));
00683             double factor = (l - f) / (1.0 - pow(alpha, NbSegm));
00684 
00685             for (int i = 1; i < NbSegm; i++) {
00686               double param = f + factor * (1.0 - pow(alpha, i));
00687               theParams.push_back( param );
00688             }
00689           }
00690           return true;
00691         }
00692         break;
00693       case StdMeshers_NumberOfSegments::DT_TabFunc:
00694         {
00695           FunctionTable func(_vvalue[ TAB_FUNC_IND ], _ivalue[ CONV_MODE_IND ]);
00696           return computeParamByFunc(theC3d, f, l, theLength, theReverse,
00697                                     _ivalue[ NB_SEGMENTS_IND ], func,
00698                                     theParams);
00699         }
00700         break;
00701       case StdMeshers_NumberOfSegments::DT_ExprFunc:
00702         {
00703           FunctionExpr func(_svalue[ EXPR_FUNC_IND ].c_str(), _ivalue[ CONV_MODE_IND ]);
00704           return computeParamByFunc(theC3d, f, l, theLength, theReverse,
00705                                     _ivalue[ NB_SEGMENTS_IND ], func,
00706                                     theParams);
00707         }
00708         break;
00709       case StdMeshers_NumberOfSegments::DT_Regular:
00710         eltSize = theLength / _ivalue[ NB_SEGMENTS_IND ];
00711         break;
00712       default:
00713         return false;
00714       }
00715     }
00716     GCPnts_UniformAbscissa Discret(theC3d, eltSize, f, l);
00717     if ( !Discret.IsDone() )
00718       return error( "GCPnts_UniformAbscissa failed");
00719 
00720     int NbPoints = Discret.NbPoints();
00721     for ( int i = 2; i < NbPoints; i++ )
00722     {
00723       double param = Discret.Parameter(i);
00724       theParams.push_back( param );
00725     }
00726     compensateError( eltSize, eltSize, f, l, theLength, theC3d, theParams ); // for PAL9899
00727     return true;
00728   }
00729 
00730   case BEG_END_LENGTH: {
00731 
00732     // geometric progression: SUM(n) = ( a1 - an * q ) / ( 1 - q ) = theLength
00733 
00734     double a1 = _value[ BEG_LENGTH_IND ];
00735     double an = _value[ END_LENGTH_IND ];
00736     double q  = ( theLength - a1 ) / ( theLength - an );
00737     if ( q < theLength/1e6 || 1.01*theLength < a1 + an)
00738       return error ( SMESH_Comment("Invalid segment lengths (")<<a1<<" and "<<an<<") "<<
00739                      "for an edge of length "<<theLength);
00740 
00741     double U1 = theReverse ? l : f;
00742     double Un = theReverse ? f : l;
00743     double param = U1;
00744     double eltSize = theReverse ? -a1 : a1;
00745     while ( 1 ) {
00746       // computes a point on a curve <theC3d> at the distance <eltSize>
00747       // from the point of parameter <param>.
00748       GCPnts_AbscissaPoint Discret( theC3d, eltSize, param );
00749       if ( !Discret.IsDone() ) break;
00750       param = Discret.Parameter();
00751       if ( f < param && param < l )
00752         theParams.push_back( param );
00753       else
00754         break;
00755       eltSize *= q;
00756     }
00757     compensateError( a1, an, U1, Un, theLength, theC3d, theParams );
00758     if (theReverse) theParams.reverse(); // NPAL18025
00759     return true;
00760   }
00761 
00762   case ARITHMETIC_1D: {
00763 
00764     // arithmetic progression: SUM(n) = ( an - a1 + q ) * ( a1 + an ) / ( 2 * q ) = theLength
00765 
00766     double a1 = _value[ BEG_LENGTH_IND ];
00767     double an = _value[ END_LENGTH_IND ];
00768     if ( 1.01*theLength < a1 + an)
00769       return error ( SMESH_Comment("Invalid segment lengths (")<<a1<<" and "<<an<<") "<<
00770                      "for an edge of length "<<theLength);
00771 
00772     double  q = ( an - a1 ) / ( 2 *theLength/( a1 + an ) - 1 );
00773     int n = int(fabs(q) > numeric_limits<double>::min() ? ( 1+( an-a1 )/q ) : ( 1+theLength/a1 ));
00774 
00775     double U1 = theReverse ? l : f;
00776     double Un = theReverse ? f : l;
00777     double param = U1;
00778     double eltSize = a1;
00779     if ( theReverse ) {
00780       eltSize = -eltSize;
00781       q = -q;
00782     }
00783     while ( n-- > 0 && eltSize * ( Un - U1 ) > 0 ) {
00784       // computes a point on a curve <theC3d> at the distance <eltSize>
00785       // from the point of parameter <param>.
00786       GCPnts_AbscissaPoint Discret( theC3d, eltSize, param );
00787       if ( !Discret.IsDone() ) break;
00788       param = Discret.Parameter();
00789       if ( param > f && param < l )
00790         theParams.push_back( param );
00791       else
00792         break;
00793       eltSize += q;
00794     }
00795     compensateError( a1, an, U1, Un, theLength, theC3d, theParams );
00796     if (theReverse) theParams.reverse(); // NPAL18025
00797 
00798     return true;
00799   }
00800 
00801   case FIXED_POINTS_1D: {
00802     const std::vector<double>& aPnts = _fpHyp->GetPoints();
00803     const std::vector<int>& nbsegs = _fpHyp->GetNbSegments();
00804     int i = 0;
00805     TColStd_SequenceOfReal Params;
00806     for(; i<aPnts.size(); i++) {
00807       if( aPnts[i]<0.0001 || aPnts[i]>0.9999 ) continue;
00808       int j=1;
00809       bool IsExist = false;
00810       for(; j<=Params.Length(); j++) {
00811         if( fabs(aPnts[i]-Params.Value(j)) < 1e-4 ) {
00812           IsExist = true;
00813           break;
00814         }
00815         if( aPnts[i]<Params.Value(j) ) break;
00816       }
00817       if(!IsExist) Params.InsertBefore(j,aPnts[i]);
00818     }
00819     double par2, par1, lp;
00820     par1 = f;
00821     lp = l;
00822     double sign = 1.0;
00823     if(theReverse) {
00824       par1 = l;
00825       lp = f;
00826       sign = -1.0;
00827     }
00828     double eltSize, segmentSize = 0.;
00829     double currAbscissa = 0;
00830     for(i=0; i<Params.Length(); i++) {
00831       int nbseg = ( i > nbsegs.size()-1 ) ? nbsegs[0] : nbsegs[i];
00832       segmentSize = Params.Value(i+1)*theLength - currAbscissa;
00833       currAbscissa += segmentSize;
00834       GCPnts_AbscissaPoint APnt(theC3d, sign*segmentSize, par1);
00835       if( !APnt.IsDone() )
00836         return error( "GCPnts_AbscissaPoint failed");
00837       par2 = APnt.Parameter();
00838       eltSize = segmentSize/nbseg;
00839       GCPnts_UniformAbscissa Discret(theC3d, eltSize, par1, par2);
00840       if(theReverse)
00841         Discret.Initialize(theC3d, eltSize, par2, par1);
00842       else
00843         Discret.Initialize(theC3d, eltSize, par1, par2);
00844       if ( !Discret.IsDone() )
00845         return error( "GCPnts_UniformAbscissa failed");
00846       int NbPoints = Discret.NbPoints();
00847       list<double> tmpParams;
00848       for(int i=2; i<NbPoints; i++) {
00849         double param = Discret.Parameter(i);
00850         tmpParams.push_back( param );
00851       }
00852       if (theReverse) {
00853         compensateError( eltSize, eltSize, par2, par1, segmentSize, theC3d, tmpParams );
00854         tmpParams.reverse();
00855       }
00856       else {
00857         compensateError( eltSize, eltSize, par1, par2, segmentSize, theC3d, tmpParams );
00858       }
00859       list<double>::iterator itP = tmpParams.begin();
00860       for(; itP != tmpParams.end(); itP++) {
00861         theParams.push_back( *(itP) );
00862       }
00863       theParams.push_back( par2 );
00864 
00865       par1 = par2;
00866     }
00867     // add for last
00868     int nbseg = ( nbsegs.size() > Params.Length() ) ? nbsegs[Params.Length()] : nbsegs[0];
00869     segmentSize = theLength - currAbscissa;
00870     eltSize = segmentSize/nbseg;
00871     GCPnts_UniformAbscissa Discret;
00872     if(theReverse)
00873       Discret.Initialize(theC3d, eltSize, par1, lp);
00874     else
00875       Discret.Initialize(theC3d, eltSize, lp, par1);
00876     if ( !Discret.IsDone() )
00877       return error( "GCPnts_UniformAbscissa failed");
00878     int NbPoints = Discret.NbPoints();
00879     list<double> tmpParams;
00880     for(int i=2; i<NbPoints; i++) {
00881       double param = Discret.Parameter(i);
00882       tmpParams.push_back( param );
00883     }
00884     if (theReverse) {
00885       compensateError( eltSize, eltSize, lp, par1, segmentSize, theC3d, tmpParams );
00886       tmpParams.reverse();
00887     }
00888     else {
00889       compensateError( eltSize, eltSize, par1, lp, segmentSize, theC3d, tmpParams );
00890     }
00891     list<double>::iterator itP = tmpParams.begin();
00892     for(; itP != tmpParams.end(); itP++) {
00893       theParams.push_back( *(itP) );
00894     }
00895 
00896     if (theReverse) {
00897       theParams.reverse(); // NPAL18025
00898     }
00899     return true;
00900   }
00901 
00902   case DEFLECTION: {
00903 
00904     GCPnts_UniformDeflection Discret(theC3d, _value[ DEFLECTION_IND ], f, l, true);
00905     if ( !Discret.IsDone() )
00906       return false;
00907 
00908     int NbPoints = Discret.NbPoints();
00909     for ( int i = 2; i < NbPoints; i++ )
00910     {
00911       double param = Discret.Parameter(i);
00912       theParams.push_back( param );
00913     }
00914     return true;
00915   }
00916 
00917   default:;
00918   }
00919 
00920   return false;
00921 }
00922 
00923 //=============================================================================
00927 //=============================================================================
00928 
00929 bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape)
00930 {
00931   if ( _hypType == NONE )
00932     return false;
00933 
00934   SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
00935 
00936   const TopoDS_Edge & EE = TopoDS::Edge(theShape);
00937   TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
00938   int shapeID = meshDS->ShapeToIndex( E );
00939 
00940   double f, l;
00941   Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, f, l);
00942 
00943   TopoDS_Vertex VFirst, VLast;
00944   TopExp::Vertices(E, VFirst, VLast);   // Vfirst corresponds to f and Vlast to l
00945 
00946   ASSERT(!VFirst.IsNull());
00947   ASSERT(!VLast.IsNull());
00948   const SMDS_MeshNode * idFirst = SMESH_Algo::VertexNode( VFirst, meshDS );
00949   const SMDS_MeshNode * idLast = SMESH_Algo::VertexNode( VLast, meshDS );
00950   if (!idFirst || !idLast)
00951     return error( COMPERR_BAD_INPUT_MESH, "No node on vertex");
00952 
00953   // remove elements created by e.g. patern mapping (PAL21999)
00954   // CLEAN event is incorrectly ptopagated seemingly due to Propagation hyp
00955   // so TEMPORARY solution is to clean the submesh manually
00956   //theMesh.GetSubMesh(theShape)->ComputeStateEngine( SMESH_subMesh::CLEAN );
00957   if (SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(theShape))
00958   {
00959     SMDS_ElemIteratorPtr ite = subMeshDS->GetElements();
00960     while (ite->more())
00961       meshDS->RemoveFreeElement(ite->next(), subMeshDS);
00962     SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes();
00963     while (itn->more()) {
00964       const SMDS_MeshNode * node = itn->next();
00965       if ( node->NbInverseElements() == 0 )
00966         meshDS->RemoveFreeNode(node, subMeshDS);
00967       else
00968         meshDS->RemoveNode(node);
00969     }
00970   }
00971 
00972   if (!Curve.IsNull())
00973   {
00974     list< double > params;
00975     bool reversed = false;
00976     if ( theMesh.GetShapeToMesh().ShapeType() >= TopAbs_WIRE ) {
00977       // if the shape to mesh is WIRE or EDGE
00978       reversed = ( EE.Orientation() == TopAbs_REVERSED );
00979     }
00980     if ( !_mainEdge.IsNull() ) {
00981       // take into account reversing the edge the hypothesis is propagated from
00982       reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED );
00983       int mainID = meshDS->ShapeToIndex(_mainEdge);
00984       if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), mainID) != _revEdgesIDs.end())
00985         reversed = !reversed;
00986     }
00987     // take into account this edge reversing
00988     if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), shapeID) != _revEdgesIDs.end())
00989       reversed = !reversed;
00990 
00991     BRepAdaptor_Curve C3d( E );
00992     double length = EdgeLength( E );
00993     if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, reversed, true )) {
00994       return false;
00995     }
00996     redistributeNearVertices( theMesh, C3d, length, params, VFirst, VLast );
00997 
00998     // edge extrema (indexes : 1 & NbPoints) already in SMDS (TopoDS_Vertex)
00999     // only internal nodes receive an edge position with param on curve
01000 
01001     const SMDS_MeshNode * idPrev = idFirst;
01002     double parPrev = f;
01003     double parLast = l;
01004 
01005     /* NPAL18025
01006     if (reversed) {
01007       idPrev = idLast;
01008       idLast = idFirst;
01009       idFirst = idPrev;
01010       parPrev = l;
01011       parLast = f;
01012     }
01013     */
01014     for (list<double>::iterator itU = params.begin(); itU != params.end(); itU++) {
01015       double param = *itU;
01016       gp_Pnt P = Curve->Value(param);
01017 
01018       //Add the Node in the DataStructure
01019       SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
01020       meshDS->SetNodeOnEdge(node, shapeID, param);
01021 
01022       if(_quadraticMesh) {
01023         // create medium node
01024         double prm = ( parPrev + param )/2;
01025         gp_Pnt PM = Curve->Value(prm);
01026         SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z());
01027         meshDS->SetNodeOnEdge(NM, shapeID, prm);
01028         SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM);
01029         meshDS->SetMeshElementOnShape(edge, shapeID);
01030       }
01031       else {
01032         SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
01033         meshDS->SetMeshElementOnShape(edge, shapeID);
01034       }
01035 
01036       idPrev = node;
01037       parPrev = param;
01038     }
01039     if(_quadraticMesh) {
01040       double prm = ( parPrev + parLast )/2;
01041       gp_Pnt PM = Curve->Value(prm);
01042       SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z());
01043       meshDS->SetNodeOnEdge(NM, shapeID, prm);
01044       SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM);
01045       meshDS->SetMeshElementOnShape(edge, shapeID);
01046     }
01047     else {
01048       SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast);
01049       meshDS->SetMeshElementOnShape(edge, shapeID);
01050     }
01051   }
01052   else
01053   {
01054     //MESSAGE("************* Degenerated edge! *****************");
01055 
01056     // Edge is a degenerated Edge : We put n = 5 points on the edge.
01057     const int NbPoints = 5;
01058     BRep_Tool::Range( E, f, l ); // PAL15185
01059     double du = (l - f) / (NbPoints - 1);
01060 
01061     gp_Pnt P = BRep_Tool::Pnt(VFirst);
01062 
01063     const SMDS_MeshNode * idPrev = idFirst;
01064     for (int i = 2; i < NbPoints; i++) {
01065       double param = f + (i - 1) * du;
01066       SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
01067       if(_quadraticMesh) {
01068         // create medium node
01069         double prm = param - du/2.;
01070         SMDS_MeshNode * NM = meshDS->AddNode(P.X(), P.Y(), P.Z());
01071         meshDS->SetNodeOnEdge(NM, shapeID, prm);
01072         SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM);
01073         meshDS->SetMeshElementOnShape(edge, shapeID);
01074       }
01075       else {
01076         SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
01077         meshDS->SetMeshElementOnShape(edge, shapeID);
01078       }
01079       meshDS->SetNodeOnEdge(node, shapeID, param);
01080       idPrev = node;
01081     }
01082     if(_quadraticMesh) {
01083       // create medium node
01084       double prm = l - du/2.;
01085       SMDS_MeshNode * NM = meshDS->AddNode(P.X(), P.Y(), P.Z());
01086       meshDS->SetNodeOnEdge(NM, shapeID, prm);
01087       SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM);
01088       meshDS->SetMeshElementOnShape(edge, shapeID);
01089     }
01090     else {
01091       SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast);
01092       meshDS->SetMeshElementOnShape(edge, shapeID);
01093     }
01094   }
01095   return true;
01096 }
01097 
01098 
01099 //=============================================================================
01103 //=============================================================================
01104 
01105 bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh,
01106                                      const TopoDS_Shape & theShape,
01107                                      MapShapeNbElems& aResMap)
01108 {
01109   if ( _hypType == NONE )
01110     return false;
01111 
01112   //SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
01113 
01114   const TopoDS_Edge & EE = TopoDS::Edge(theShape);
01115   TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
01116   //  int shapeID = meshDS->ShapeToIndex( E );
01117 
01118   double f, l;
01119   Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, f, l);
01120 
01121   TopoDS_Vertex VFirst, VLast;
01122   TopExp::Vertices(E, VFirst, VLast);   // Vfirst corresponds to f and Vlast to l
01123 
01124   ASSERT(!VFirst.IsNull());
01125   ASSERT(!VLast.IsNull());
01126 
01127   std::vector<int> aVec(SMDSEntity_Last,0);
01128 
01129   if (!Curve.IsNull()) {
01130     list< double > params;
01131 
01132     BRepAdaptor_Curve C3d( E );
01133     double length = EdgeLength( E );
01134     if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, false, true )) {
01135       SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
01136       aResMap.insert(std::make_pair(sm,aVec));
01137       SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
01138       smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
01139       return false;
01140     }
01141     redistributeNearVertices( theMesh, C3d, length, params, VFirst, VLast );
01142 
01143     if(_quadraticMesh) {
01144       aVec[SMDSEntity_Node] = 2*params.size() + 1;
01145       aVec[SMDSEntity_Quad_Edge] = params.size() + 1;
01146     }
01147     else {
01148       aVec[SMDSEntity_Node] = params.size();
01149       aVec[SMDSEntity_Edge] = params.size() + 1;
01150     }
01151     
01152   }
01153   else {
01154     //MESSAGE("************* Degenerated edge! *****************");
01155     // Edge is a degenerated Edge : We put n = 5 points on the edge.
01156     if(_quadraticMesh) {
01157       aVec[SMDSEntity_Node] = 11;
01158       aVec[SMDSEntity_Quad_Edge] = 6;
01159     }
01160     else {
01161       aVec[SMDSEntity_Node] = 5;
01162       aVec[SMDSEntity_Edge] = 6;
01163     }
01164   }
01165 
01166   SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
01167   aResMap.insert(std::make_pair(sm,aVec));
01168 
01169   return true;
01170 }
01171 
01172 
01173 //=============================================================================
01177 //=============================================================================
01178 
01179 const list <const SMESHDS_Hypothesis *> &
01180 StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh &         aMesh,
01181                                          const TopoDS_Shape & aShape,
01182                                          const bool           ignoreAuxiliary)
01183 {
01184   _usedHypList.clear();
01185   _mainEdge.Nullify();
01186 
01187   SMESH_HypoFilter auxiliaryFilter, compatibleFilter;
01188   auxiliaryFilter.Init( SMESH_HypoFilter::IsAuxiliary() );
01189   InitCompatibleHypoFilter( compatibleFilter, /*ignoreAux=*/true );
01190 
01191   // get non-auxiliary assigned directly to aShape
01192   int nbHyp = aMesh.GetHypotheses( aShape, compatibleFilter, _usedHypList, false );
01193 
01194   if (nbHyp == 0 && aShape.ShapeType() == TopAbs_EDGE)
01195   {
01196     // Check, if propagated from some other edge
01197     _mainEdge = StdMeshers_Propagation::GetPropagationSource( aMesh, aShape );
01198     if ( !_mainEdge.IsNull() )
01199     {
01200       // Propagation of 1D hypothesis from <aMainEdge> on this edge;
01201       // get non-auxiliary assigned to _mainEdge
01202       nbHyp = aMesh.GetHypotheses( _mainEdge, compatibleFilter, _usedHypList, true );
01203     }
01204   }
01205 
01206   if (nbHyp == 0) // nothing propagated nor assigned to aShape
01207   {
01208     SMESH_Algo::GetUsedHypothesis( aMesh, aShape, ignoreAuxiliary );
01209     nbHyp = _usedHypList.size();
01210   }
01211   else
01212   {
01213     // get auxiliary hyps from aShape
01214     aMesh.GetHypotheses( aShape, auxiliaryFilter, _usedHypList, true );
01215   }
01216   if ( nbHyp > 1 && ignoreAuxiliary )
01217     _usedHypList.clear(); //only one compatible non-auxiliary hypothesis allowed
01218 
01219   return _usedHypList;
01220 }
Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS