X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Regular_1D.cxx;h=c6e41cbb2b48aea869f7ffb67f042a73745e6e0f;hp=8f4a105477fd31c27c64093c0b7830158d7fedb7;hb=cb55604f37e3d2583272fd436bb6557b041948b5;hpb=145e217ae6852460e3f461e22fe34cf6bc15fc36 diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 8f4a10547..c6e41cbb2 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2020 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 @@ -50,8 +50,8 @@ #include "StdMeshers_SegmentLengthAroundVertex.hxx" #include "StdMeshers_StartEndLength.hxx" -#include "Utils_SALOME_Exception.hxx" -#include "utilities.h" +#include +#include #include #include @@ -78,9 +78,8 @@ using namespace StdMeshers; //============================================================================= StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, - int studyId, SMESH_Gen * gen) - :SMESH_1D_Algo( hypId, studyId, gen ) + :SMESH_1D_Algo( hypId, gen ) { _name = "Regular_1D"; _shapeType = (1 << TopAbs_EDGE); @@ -122,10 +121,11 @@ bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, Hypothesis_Status& aStatus ) { - _hypType = NONE; - _quadraticMesh = false; + _hypType = NONE; + _quadraticMesh = false; _onlyUnaryInput = true; + // check propagation in a redefined GetUsedHypothesis() const list & hyps = GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliaryHyps=*/false); @@ -156,13 +156,17 @@ bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh& aMesh, string hypName = theHyp->GetName(); - if ( hypName == "LocalLength" ) + if ( !_mainEdge.IsNull() && _hypType == DISTRIB_PROPAGATION ) + { + aStatus = SMESH_Hypothesis::HYP_OK; + } + else if ( hypName == "LocalLength" ) { const StdMeshers_LocalLength * hyp = dynamic_cast (theHyp); ASSERT(hyp); _value[ BEG_LENGTH_IND ] = hyp->GetLength(); - _value[ PRECISION_IND ] = hyp->GetPrecision(); + _value[ PRECISION_IND ] = hyp->GetPrecision(); ASSERT( _value[ BEG_LENGTH_IND ] > 0 ); _hypType = LOCAL_LENGTH; aStatus = SMESH_Hypothesis::HYP_OK; @@ -358,7 +362,10 @@ static bool computeParamByFunc(Adaptor3d_Curve& C3d, int nbPnt = 1 + nbSeg; vector x( nbPnt, 0. ); - if ( !buildDistribution( func, 0.0, 1.0, nbSeg, x, 1E-4 )) + + const double eps = Min( 1E-4, 1./nbSeg/100. ); + + if ( !buildDistribution( func, 0.0, 1.0, nbSeg, x, eps )) return false; // apply parameters in range [0,1] to the space of the curve @@ -386,6 +393,7 @@ static bool computeParamByFunc(Adaptor3d_Curve& C3d, } if ( theReverse ) theParams.reverse(); + return true; } @@ -393,15 +401,15 @@ static bool computeParamByFunc(Adaptor3d_Curve& C3d, //================================================================================ /*! * \brief adjust internal node parameters so that the last segment length == an - * \param a1 - the first segment length - * \param an - the last segment length - * \param U1 - the first edge parameter - * \param Un - the last edge parameter - * \param length - the edge length - * \param C3d - the edge curve - * \param theParams - internal node parameters to adjust - * \param adjustNeighbors2an - to adjust length of segments next to the last one - * and not to remove parameters + * \param a1 - the first segment length + * \param an - the last segment length + * \param U1 - the first edge parameter + * \param Un - the last edge parameter + * \param length - the edge length + * \param C3d - the edge curve + * \param theParams - internal node parameters to adjust + * \param adjustNeighbors2an - to adjust length of segments next to the last one + * and not to remove parameters */ //================================================================================ @@ -496,7 +504,7 @@ static void compensateError(double a1, double an, // * \brief Clean mesh on edges // * \param event - algo_event or compute_event itself (of SMESH_subMesh) // * \param eventType - ALGO_EVENT or COMPUTE_EVENT (of SMESH_subMesh) -// * \param subMesh - the submesh where the event occures +// * \param subMesh - the submesh where the event occurs // */ // void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh, // EventListenerData*, const SMESH_Hypothesis*) @@ -532,7 +540,7 @@ void StdMeshers_Regular_1D::SetEventListener(SMESH_subMesh* subMesh) */ //============================================================================= -void StdMeshers_Regular_1D::SubmeshRestored(SMESH_subMesh* subMesh) +void StdMeshers_Regular_1D::SubmeshRestored(SMESH_subMesh* /*subMesh*/) { } @@ -623,7 +631,7 @@ void StdMeshers_Regular_1D::redistributeNearVertices (SMESH_Mesh & theM double L = GCPnts_AbscissaPoint::Length( theC3d, *itU, l); static StdMeshers_Regular_1D* auxAlgo = 0; if ( !auxAlgo ) { - auxAlgo = new StdMeshers_Regular_1D( _gen->GetANewId(), _studyId, _gen ); + auxAlgo = new StdMeshers_Regular_1D( _gen->GetANewId(), _gen ); auxAlgo->_hypType = BEG_END_LENGTH; } auxAlgo->_value[ BEG_LENGTH_IND ] = Lm; @@ -672,10 +680,10 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, // Propagation Of Distribution // - if ( !_mainEdge.IsNull() && _isPropagOfDistribution ) + if ( !_mainEdge.IsNull() && _hypType == DISTRIB_PROPAGATION ) { TopoDS_Edge mainEdge = TopoDS::Edge( _mainEdge ); // should not be a reference! - _gen->Compute( theMesh, mainEdge, /*aShapeOnly=*/true, /*anUpward=*/true); + _gen->Compute( theMesh, mainEdge, SMESH_Gen::SHAPE_ONLY_UPWARD ); SMESHDS_SubMesh* smDS = theMesh.GetMeshDS()->MeshElements( mainEdge ); if ( !smDS ) @@ -969,6 +977,8 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, an = eltSize; eltSize *= q; ++nbParams; + if ( q < 1. && eltSize < 1e-100 ) + return error("Too small common ratio causes too many segments"); } if ( nbParams > 1 ) { @@ -992,8 +1002,6 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, { const std::vector& aPnts = _fpHyp->GetPoints(); std::vector nbsegs = _fpHyp->GetNbSegments(); - if ( theReverse ) - std::reverse( nbsegs.begin(), nbsegs.end() ); // sort normalized params, taking into account theReverse TColStd_SequenceOfReal Params; @@ -1031,6 +1039,16 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, uVec.back() = theLastU; // divide segments + if ( theReverse ) + { + if ((int) nbsegs.size() > Params.Length() + 1 ) + nbsegs.resize( Params.Length() + 1 ); + std::reverse( nbsegs.begin(), nbsegs.end() ); + } + if ( nbsegs.empty() ) + { + nbsegs.push_back( 1 ); + } Params.InsertBefore( 1, 0.0 ); Params.Append( 1.0 ); double eltSize, segmentSize, par1, par2; @@ -1125,7 +1143,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t if ( !nFirst || !nLast ) return error( COMPERR_BAD_INPUT_MESH, "No node on vertex"); - // remove elements created by e.g. patern mapping (PAL21999) + // remove elements created by e.g. pattern mapping (PAL21999) // CLEAN event is incorrectly ptopagated seemingly due to Propagation hyp // so TEMPORARY solution is to clean the submesh manually if (SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(theShape)) @@ -1156,7 +1174,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t // take into account reversing the edge the hypothesis is propagated from // (_mainEdge.Orientation() marks mutual orientation of EDGEs in propagation chain) reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED ); - if ( !_isPropagOfDistribution ) { + if ( _hypType != DISTRIB_PROPAGATION ) { int mainID = meshDS->ShapeToIndex(_mainEdge); if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), mainID) != _revEdgesIDs.end()) reversed = !reversed; @@ -1268,9 +1286,9 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t */ //============================================================================= -bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh, +bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape, - MapShapeNbElems& aResMap) + MapShapeNbElems& theResMap) { if ( _hypType == NONE ) return false; @@ -1278,7 +1296,7 @@ bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh, if ( _hypType == ADAPTIVE ) { _adaptiveHyp->GetAlgo()->InitComputeError(); - _adaptiveHyp->GetAlgo()->Evaluate( theMesh, theShape, aResMap ); + _adaptiveHyp->GetAlgo()->Evaluate( theMesh, theShape, theResMap ); return error( _adaptiveHyp->GetAlgo()->GetComputeError() ); } @@ -1303,7 +1321,7 @@ bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh, BRepAdaptor_Curve C3d( E ); if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, false, true )) { SMESH_subMesh * sm = theMesh.GetSubMesh(theShape); - aResMap.insert(std::make_pair(sm,aVec)); + theResMap.insert(std::make_pair(sm,aVec)); SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); return false; @@ -1311,7 +1329,7 @@ bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh, redistributeNearVertices( theMesh, C3d, length, params, VFirst, VLast ); if(_quadraticMesh) { - aVec[SMDSEntity_Node] = 2*params.size() + 1; + aVec[SMDSEntity_Node ] = 2*params.size() + 1; aVec[SMDSEntity_Quad_Edge] = params.size() + 1; } else { @@ -1323,7 +1341,7 @@ bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh, else { // Edge is a degenerated Edge : We put n = 5 points on the edge. if ( _quadraticMesh ) { - aVec[SMDSEntity_Node] = 11; + aVec[SMDSEntity_Node ] = 11; aVec[SMDSEntity_Quad_Edge] = 6; } else { @@ -1332,8 +1350,8 @@ bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh, } } - SMESH_subMesh * sm = theMesh.GetSubMesh(theShape); - aResMap.insert(std::make_pair(sm,aVec)); + SMESH_subMesh * sm = theMesh.GetSubMesh( theShape ); + theResMap.insert( std::make_pair( sm, aVec )); return true; } @@ -1362,10 +1380,13 @@ StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh & aMesh, if (nbHyp == 0 && aShape.ShapeType() == TopAbs_EDGE) { // Check, if propagated from some other edge + bool isPropagOfDistribution = false; _mainEdge = StdMeshers_Propagation::GetPropagationSource( aMesh, aShape, - _isPropagOfDistribution ); + isPropagOfDistribution ); if ( !_mainEdge.IsNull() ) { + if ( isPropagOfDistribution ) + _hypType = DISTRIB_PROPAGATION; // Propagation of 1D hypothesis from on this edge; // get non-auxiliary assigned to _mainEdge nbHyp = aMesh.GetHypotheses( _mainEdge, *compatibleFilter, _usedHypList, true );