X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Regular_1D.cxx;h=d3d92f9ea20d8a66a327c83c04ee3208f5623fbc;hb=da425c6a4aa2f29deb92e1ebbebbd0855f373b16;hp=aa069ff8c89c4ef63f1caa11d43280485b1dffe4;hpb=c3bf92bd87b770fd81631a3853f7f5bb1ac6a4e8;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index aa069ff8c..d3d92f9ea 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -30,27 +30,46 @@ 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 #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 "Utils_SALOME_Exception.hxx" #include "utilities.h" +#include #include #include +#include #include -#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include //============================================================================= /*! @@ -63,15 +82,14 @@ StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId, { MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D"); _name = "Regular_1D"; - // _shapeType = TopAbs_EDGE; _shapeType = (1 << TopAbs_EDGE); + _compatibleHypothesis.push_back("LocalLength"); _compatibleHypothesis.push_back("NumberOfSegments"); - - _localLength = 0; - _numberOfSegments = 0; - _hypLocalLength = NULL; - _hypNumberOfSegments = NULL; + _compatibleHypothesis.push_back("StartEndLength"); + _compatibleHypothesis.push_back("Deflection1D"); + _compatibleHypothesis.push_back("Arithmetic1D"); + _compatibleHypothesis.push_back("AutomaticLength"); } //============================================================================= @@ -95,56 +113,383 @@ bool StdMeshers_Regular_1D::CheckHypothesis const TopoDS_Shape& aShape, SMESH_Hypothesis::Hypothesis_Status& aStatus) { - //MESSAGE("StdMeshers_Regular_1D::CheckHypothesis"); + _hypType = NONE; + + const list &hyps = GetUsedHypothesis(aMesh, aShape); + if (hyps.size() == 0) + { + 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") + { + const StdMeshers_LocalLength * hyp = + dynamic_cast (theHyp); + ASSERT(hyp); + _value[ BEG_LENGTH_IND ] = _value[ END_LENGTH_IND ] = hyp->GetLength(); + ASSERT( _value[ BEG_LENGTH_IND ] > 0 ); + _hypType = LOCAL_LENGTH; + aStatus = SMESH_Hypothesis::HYP_OK; + } + + else if (hypName == "NumberOfSegments") + { + const StdMeshers_NumberOfSegments * hyp = + dynamic_cast (theHyp); + ASSERT(hyp); + _ivalue[ NB_SEGMENTS_IND ] = hyp->GetNumberOfSegments(); + ASSERT( _ivalue[ NB_SEGMENTS_IND ] > 0 ); + _ivalue[ DISTR_TYPE_IND ] = (int) hyp->GetDistrType(); + switch (_ivalue[ DISTR_TYPE_IND ]) + { + case StdMeshers_NumberOfSegments::DT_Scale: + _value[ SCALE_FACTOR_IND ] = hyp->GetScaleFactor(); + break; + case StdMeshers_NumberOfSegments::DT_TabFunc: + _vvalue[ TAB_FUNC_IND ] = hyp->GetTableFunction(); + break; + case StdMeshers_NumberOfSegments::DT_ExprFunc: + _svalue[ EXPR_FUNC_IND ] = hyp->GetExpressionFunction(); + break; + case StdMeshers_NumberOfSegments::DT_Regular: + break; + default: + ASSERT(0); + break; + } + if (_ivalue[ DISTR_TYPE_IND ] == StdMeshers_NumberOfSegments::DT_TabFunc || + _ivalue[ DISTR_TYPE_IND ] == StdMeshers_NumberOfSegments::DT_ExprFunc) + _ivalue[ CONV_MODE_IND ] = hyp->ConversionMode(); + _hypType = NB_SEGMENTS; + aStatus = SMESH_Hypothesis::HYP_OK; + } + + else if (hypName == "Arithmetic1D") + { + const StdMeshers_Arithmetic1D * hyp = + dynamic_cast (theHyp); + ASSERT(hyp); + _value[ BEG_LENGTH_IND ] = hyp->GetLength( true ); + _value[ END_LENGTH_IND ] = hyp->GetLength( false ); + ASSERT( _value[ BEG_LENGTH_IND ] > 0 && _value[ END_LENGTH_IND ] > 0 ); + _hypType = ARITHMETIC_1D; + aStatus = SMESH_Hypothesis::HYP_OK; + } + + else if (hypName == "StartEndLength") + { + const StdMeshers_StartEndLength * hyp = + dynamic_cast (theHyp); + ASSERT(hyp); + _value[ BEG_LENGTH_IND ] = hyp->GetLength( true ); + _value[ END_LENGTH_IND ] = hyp->GetLength( false ); + ASSERT( _value[ BEG_LENGTH_IND ] > 0 && _value[ END_LENGTH_IND ] > 0 ); + _hypType = BEG_END_LENGTH; + aStatus = SMESH_Hypothesis::HYP_OK; + } + + else if (hypName == "Deflection1D") + { + const StdMeshers_Deflection1D * hyp = + dynamic_cast (theHyp); + ASSERT(hyp); + _value[ DEFLECTION_IND ] = hyp->GetDeflection(); + ASSERT( _value[ DEFLECTION_IND ] > 0 ); + _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; + + return ( _hypType != NONE ); +} + +//======================================================================= +//function : compensateError +//purpose : adjust theParams so that the last segment length == an +//======================================================================= + +static void compensateError(double a1, double an, + double U1, double Un, + double length, + GeomAdaptor_Curve& C3d, + list & theParams) +{ + int i, nPar = theParams.size(); + if ( a1 + an < length && nPar > 1 ) + { + list::reverse_iterator itU = theParams.rbegin(); + double Ul = *itU++; + // dist from the last point to the edge end , it should be equal + double Ln = GCPnts_AbscissaPoint::Length( C3d, Ul, Un ); + double dLn = an - Ln; // error of + if ( Abs( dLn ) <= Precision::Confusion() ) + return; + double dU = Abs( Ul - *itU ); // parametric length of the last but one segment + double dUn = dLn * Abs( Un - U1 ) / length; // parametric error of + if ( dUn < 0.5 * dU ) { // last segment is a bit shorter than it should + dUn = -dUn; // move the last parameter to the edge beginning + } + else { // last segment is much shorter than it should -> remove the last param and + theParams.pop_back(); nPar--; // move the rest points toward the edge end + Ln = GCPnts_AbscissaPoint::Length( C3d, theParams.back(), Un ); + dUn = ( an - Ln ) * Abs( Un - U1 ) / length; + if ( dUn < 0.5 * dU ) + dUn = -dUn; + } + if ( U1 > Un ) + dUn = -dUn; + double q = dUn / ( nPar - 1 ); + for ( itU = theParams.rbegin(), i = 1; i < nPar; itU++, i++ ) { + (*itU) += dUn; + dUn -= q; + } + } +} - list ::const_iterator itl; - const SMESHDS_Hypothesis *theHyp; +static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last, + double length, bool theReverse, + int nbSeg, Function& func, + list& theParams) +{ + OSD::SetSignal( true ); + + if( nbSeg<=0 ) + return false; + + MESSAGE( "computeParamByFunc" ); + + int nbPnt = 1 + nbSeg; + vector x(nbPnt, 0.); + + if( !buildDistribution( func, 0.0, 1.0, nbSeg, x, 1E-4 ) ) + return false; + + MESSAGE( "Points:\n" ); + char buf[1024]; + for( int i=0; i<=nbSeg; i++ ) + { + sprintf( buf, "%f\n", float(x[i] ) ); + MESSAGE( buf ); + } + + + + // apply parameters in range [0,1] to the space of the curve + double prevU = first; + double sign = 1.; + if (theReverse) + { + prevU = last; + sign = -1.; + } + for( int i = 1; i < nbSeg; i++ ) + { + double curvLength = length * (x[i] - x[i-1]) * sign; + GCPnts_AbscissaPoint Discret( C3d, curvLength, prevU ); + if ( !Discret.IsDone() ) + return false; + double U = Discret.Parameter(); + if ( U > first && U < last ) + theParams.push_back( U ); + else + return false; + prevU = U; + } + return true; +} - const list &hyps = GetUsedHypothesis(aMesh, aShape); - int nbHyp = hyps.size(); - if (!nbHyp) +//============================================================================= +/*! + * + */ +//============================================================================= +bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge, + list & theParams, + const bool theReverse) const +{ + theParams.clear(); + + double f, l; + Handle(Geom_Curve) Curve = BRep_Tool::Curve(theEdge, f, l); + GeomAdaptor_Curve C3d(Curve); + + double length = EdgeLength(theEdge); + + switch( _hypType ) + { + case LOCAL_LENGTH: + case NB_SEGMENTS: { + + double eltSize = 1; + if ( _hypType == LOCAL_LENGTH ) + { + // Local Length hypothesis + double nbseg = ceil(length / _value[ BEG_LENGTH_IND ]); // integer sup + if (nbseg <= 0) + nbseg = 1; // degenerated edge + eltSize = length / nbseg; + } + else + { + // Number Of Segments hypothesis + switch (_ivalue[ DISTR_TYPE_IND ]) + { + case StdMeshers_NumberOfSegments::DT_Scale: { - aStatus = SMESH_Hypothesis::HYP_MISSING; - return false; // can't work with no hypothesis + 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 ); + } + return true; } - - itl = hyps.begin(); - theHyp = (*itl); // use only the first hypothesis - - string hypName = theHyp->GetName(); - int hypId = theHyp->GetID(); - //SCRUTE(hypName); - - bool isOk = false; - - if (hypName == "LocalLength") - { - _hypLocalLength = dynamic_cast (theHyp); - ASSERT(_hypLocalLength); - _localLength = _hypLocalLength->GetLength(); - _numberOfSegments = 0; - isOk = true; - aStatus = SMESH_Hypothesis::HYP_OK; - } - - else if (hypName == "NumberOfSegments") - { - _hypNumberOfSegments = - dynamic_cast (theHyp); - ASSERT(_hypNumberOfSegments); - _numberOfSegments = _hypNumberOfSegments->GetNumberOfSegments(); - _scaleFactor = _hypNumberOfSegments->GetScaleFactor(); - _localLength = 0; - isOk = true; - aStatus = SMESH_Hypothesis::HYP_OK; - } - else - aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; - - //SCRUTE(_localLength); - //SCRUTE(_numberOfSegments); - - return isOk; + break; + case StdMeshers_NumberOfSegments::DT_TabFunc: + { + FunctionTable func(_vvalue[ TAB_FUNC_IND ], _ivalue[ CONV_MODE_IND ]); + return computeParamByFunc(C3d, f, l, length, theReverse, + _ivalue[ NB_SEGMENTS_IND ], func, + theParams); + } + break; + case StdMeshers_NumberOfSegments::DT_ExprFunc: + { + 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); + } + break; + case StdMeshers_NumberOfSegments::DT_Regular: + eltSize = length / _ivalue[ NB_SEGMENTS_IND ]; + break; + default: + return false; + } + } + + GCPnts_UniformAbscissa Discret(C3d, eltSize, f, l); + if ( !Discret.IsDone() ) + return false; + + int NbPoints = Discret.NbPoints(); + for ( int i = 2; i < NbPoints; i++ ) + { + double param = Discret.Parameter(i); + theParams.push_back( param ); + } + compensateError( eltSize, eltSize, f, l, length, C3d, theParams ); // for PAL9899 + return true; + } + + case BEG_END_LENGTH: { + + // geometric progression: SUM(n) = ( a1 - an * q ) / ( 1 - q ) = length + + double a1 = _value[ BEG_LENGTH_IND ]; + double an = _value[ END_LENGTH_IND ]; + double q = ( length - a1 ) / ( length - an ); + + double U1 = theReverse ? l : f; + double Un = theReverse ? f : l; + double param = U1; + double eltSize = theReverse ? -a1 : a1; + while ( 1 ) { + // computes a point on a curve at the distance + // from the point of parameter . + GCPnts_AbscissaPoint Discret( C3d, eltSize, param ); + if ( !Discret.IsDone() ) break; + param = Discret.Parameter(); + if ( param > f && param < l ) + theParams.push_back( param ); + else + break; + eltSize *= q; + } + compensateError( a1, an, U1, Un, length, C3d, theParams ); + return true; + } + + case ARITHMETIC_1D: { + + // arithmetic progression: SUM(n) = ( an - a1 + q ) * ( a1 + an ) / ( 2 * q ) = length + + double a1 = _value[ BEG_LENGTH_IND ]; + double an = _value[ END_LENGTH_IND ]; + + double q = ( an - a1 ) / ( 2 *length/( a1 + an ) - 1 ); + int n = int( 1 + ( an - a1 ) / q ); + + double U1 = theReverse ? l : f; + double Un = theReverse ? f : l; + double param = U1; + double eltSize = a1; + if ( theReverse ) { + eltSize = -eltSize; + q = -q; + } + while ( n-- > 0 && eltSize * ( Un - U1 ) > 0 ) { + // computes a point on a curve at the distance + // from the point of parameter . + GCPnts_AbscissaPoint Discret( C3d, eltSize, param ); + if ( !Discret.IsDone() ) break; + param = Discret.Parameter(); + if ( param > f && param < l ) + theParams.push_back( param ); + else + break; + eltSize += q; + } + compensateError( a1, an, U1, Un, length, C3d, theParams ); + + return true; + } + + case DEFLECTION: { + + GCPnts_UniformDeflection Discret(C3d, _value[ DEFLECTION_IND ], true); + if ( !Discret.IsDone() ) + return false; + + int NbPoints = Discret.NbPoints(); + for ( int i = 2; i < NbPoints; i++ ) + { + double param = Discret.Parameter(i); + theParams.push_back( param ); + } + return true; + + } + + default:; + } + + return false; } //============================================================================= @@ -155,135 +500,151 @@ bool StdMeshers_Regular_1D::CheckHypothesis bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) { - MESSAGE("StdMeshers_Regular_1D::Compute"); - - SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); - SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); - - const TopoDS_Edge & EE = TopoDS::Edge(aShape); - TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD)); - - double f, l; - Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, f, l); - - TopoDS_Vertex VFirst, VLast; - TopExp::Vertices(E, VFirst, VLast); // Vfirst corresponds to f and Vlast to l - - double length = EdgeLength(E); - //SCRUTE(length); - - double eltSize = 1; -// if (_localLength > 0) eltSize = _localLength; - if (_localLength > 0) - { - double nbseg = ceil(length / _localLength); // integer sup - if (nbseg <= 0) - nbseg = 1; // degenerated edge - eltSize = length / nbseg; - } - else - { - ASSERT(_numberOfSegments > 0); - eltSize = length / _numberOfSegments; - } - - ASSERT(!VFirst.IsNull()); - SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes(); - const SMDS_MeshNode * idFirst = lid->next(); - - ASSERT(!VLast.IsNull()); - lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes(); - const SMDS_MeshNode * idLast = lid->next(); - - if (!Curve.IsNull()) - { - GeomAdaptor_Curve C3d(Curve); - GCPnts_UniformAbscissa Discret(C3d, eltSize, f, l); - int NbPoints = Discret.NbPoints(); - //MESSAGE("nb points on edge : "< 1) - { - double epsilon = 0.001; - if (fabs(_scaleFactor - 1.0) > epsilon) - { - double alpha = - pow(_scaleFactor, 1.0 / (_numberOfSegments - 1)); - double d = - length * (1 - pow(alpha, i - 1)) / (1 - pow(alpha, - _numberOfSegments)); - param = d; - } - } - - gp_Pnt P = Curve->Value(param); - - //Add the Node in the DataStructure - //MESSAGE("point "<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); - - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); - meshDS->SetMeshElementOnShape(edge, E); - idPrev = node; - } - SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); - meshDS->SetMeshElementOnShape(edge, E); - } - else - { -// MESSAGE ("Edge Degeneree non traitee --- arret"); -// ASSERT(0); - if (BRep_Tool::Degenerated(E)) - { - // Edge is a degenerated Edge : We put n = 5 points on the edge. - int NbPoints = 5; - BRep_Tool::Range(E, f, l); - double du = (l - f) / (NbPoints - 1); - MESSAGE("************* Degenerated edge! *****************"); - - TopoDS_Vertex V1, V2; - TopExp::Vertices(E, V1, V2); - gp_Pnt P = BRep_Tool::Pnt(V1); - - const SMDS_MeshNode * idPrev = idFirst; - 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); - -// Handle (SMDS_EdgePosition) epos -// = new SMDS_EdgePosition(theSubMesh->GetId(),param); -// node->SetPosition(epos); - SMDS_EdgePosition* epos = - dynamic_cast(node->GetPosition().get()); - epos->SetUParameter(param); - - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); - meshDS->SetMeshElementOnShape(edge, E); - idPrev = node; - } - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast); - meshDS->SetMeshElementOnShape(edge, E); - } - else - ASSERT(0); - } - return true; + MESSAGE("StdMeshers_Regular_1D::Compute"); + + if ( _hypType == NONE ) + return false; + + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + aMesh.GetSubMesh(aShape); + + // quardatic mesh required? + SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "QuadraticMesh" )); + bool isQuadraticMesh = aMesh->GetHypothesis( aShape, filter, true ); + + 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); + + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // Vfirst corresponds to f and Vlast to l + + ASSERT(!VFirst.IsNull()); + SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes(); + if (!lid->more()) + { + MESSAGE (" NO NODE BUILT ON VERTEX "); + return false; + } + const SMDS_MeshNode * idFirst = lid->next(); + + ASSERT(!VLast.IsNull()); + lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes(); + if (!lid->more()) + { + MESSAGE (" NO NODE BUILT ON VERTEX "); + return false; + } + const SMDS_MeshNode * idLast = lid->next(); + + if (!Curve.IsNull()) + { + list< double > params; + bool reversed = false; + if ( !_mainEdge.IsNull() ) + reversed = aMesh.IsReversedInChain( EE, _mainEdge ); + try { + if ( ! computeInternalParameters( E, params, reversed )) + return false; + } + catch ( Standard_Failure ) { + return false; + } + + // edge extrema (indexes : 1 & NbPoints) already in SMDS (TopoDS_Vertex) + // only internal nodes receive an edge position with param on curve + + const SMDS_MeshNode * idPrev = idFirst; + + 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, shapeID, param); + + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + meshDS->SetMeshElementOnShape(edge, shapeID); + idPrev = node; + } + SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + else + { + // Edge is a degenerated Edge : We put n = 5 points on the edge. + int NbPoints = 5; + BRep_Tool::Range(E, f, l); + double du = (l - f) / (NbPoints - 1); + //MESSAGE("************* Degenerated edge! *****************"); + + TopoDS_Vertex V1, V2; + TopExp::Vertices(E, V1, V2); + gp_Pnt P = BRep_Tool::Pnt(V1); + + const SMDS_MeshNode * idPrev = idFirst; + 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, shapeID, param); + + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + meshDS->SetMeshElementOnShape(edge, shapeID); + idPrev = node; + } + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast); + meshDS->SetMeshElementOnShape(edge, shapeID); + } + return true; +} + +//============================================================================= +/*! + * See comments in SMESH_Algo.cxx + */ +//============================================================================= + +const list & StdMeshers_Regular_1D::GetUsedHypothesis( + SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +{ + _usedHypList.clear(); + _usedHypList = GetAppliedHypothesis(aMesh, aShape); // copy + int nbHyp = _usedHypList.size(); + _mainEdge.Nullify(); + 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(); + } + } + if (nbHyp == 0) + { + 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; + } + } + if (nbHyp > 1) + _usedHypList.clear(); //only one compatible hypothesis allowed + return _usedHypList; } //=============================================================================