X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Regular_1D.cxx;h=c6e41cbb2b48aea869f7ffb67f042a73745e6e0f;hb=456850beda350181d4af970ac59b64c55cde20e3;hp=973f113847f2f54edcf302fb3152cecf435ede20;hpb=ef3921b2afe32874a6a266ceea8a12a30cc6f17c;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 973f11384..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 @@ -29,6 +29,7 @@ #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" +#include "SMESHDS_Mesh.hxx" #include "SMESH_Comment.hxx" #include "SMESH_Gen.hxx" #include "SMESH_HypoFilter.hxx" @@ -37,8 +38,8 @@ #include "SMESH_subMeshEventListener.hxx" #include "StdMeshers_Adaptive1D.hxx" #include "StdMeshers_Arithmetic1D.hxx" -#include "StdMeshers_Geometric1D.hxx" #include "StdMeshers_AutomaticLength.hxx" +#include "StdMeshers_Geometric1D.hxx" #include "StdMeshers_Deflection1D.hxx" #include "StdMeshers_Distribution.hxx" #include "StdMeshers_FixedPoints1D.hxx" @@ -49,8 +50,8 @@ #include "StdMeshers_SegmentLengthAroundVertex.hxx" #include "StdMeshers_StartEndLength.hxx" -#include "Utils_SALOME_Exception.hxx" -#include "utilities.h" +#include +#include #include #include @@ -77,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); @@ -121,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); @@ -155,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; @@ -357,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 @@ -385,6 +393,7 @@ static bool computeParamByFunc(Adaptor3d_Curve& C3d, } if ( theReverse ) theParams.reverse(); + return true; } @@ -392,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 */ //================================================================================ @@ -495,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*) @@ -531,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*/) { } @@ -622,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; @@ -671,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 ) @@ -968,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 ) { @@ -990,7 +1001,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, case FIXED_POINTS_1D: { const std::vector& aPnts = _fpHyp->GetPoints(); - const std::vector& nbsegs = _fpHyp->GetNbSegments(); + std::vector nbsegs = _fpHyp->GetNbSegments(); // sort normalized params, taking into account theReverse TColStd_SequenceOfReal Params; @@ -1028,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; @@ -1117,15 +1138,14 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t ASSERT(!VFirst.IsNull()); ASSERT(!VLast.IsNull()); - const SMDS_MeshNode * idFirst = SMESH_Algo::VertexNode( VFirst, meshDS ); - const SMDS_MeshNode * idLast = SMESH_Algo::VertexNode( VLast, meshDS ); - if (!idFirst || !idLast) + const SMDS_MeshNode * nFirst = SMESH_Algo::VertexNode( VFirst, meshDS ); + const SMDS_MeshNode * nLast = SMESH_Algo::VertexNode( VLast, meshDS ); + 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 - //theMesh.GetSubMesh(theShape)->ComputeStateEngine( SMESH_subMesh::CLEAN ); if (SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(theShape)) { SMDS_ElemIteratorPtr ite = subMeshDS->GetElements(); @@ -1141,11 +1161,12 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t } } - if (!Curve.IsNull()) + double length = EdgeLength( E ); + if ( !Curve.IsNull() && length > 0 ) { list< double > params; bool reversed = false; - if ( theMesh.GetShapeToMesh().ShapeType() >= TopAbs_WIRE ) { + if ( theMesh.GetShapeToMesh().ShapeType() >= TopAbs_WIRE && _revEdgesIDs.empty() ) { // if the shape to mesh is WIRE or EDGE reversed = ( EE.Orientation() == TopAbs_REVERSED ); } @@ -1153,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; @@ -1164,7 +1185,6 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t reversed = !reversed; BRepAdaptor_Curve C3d( E ); - double length = EdgeLength( E ); if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, reversed, true )) { return false; } @@ -1173,19 +1193,10 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t // 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; + const SMDS_MeshNode * nPrev = nFirst; double parPrev = f; double parLast = l; - /* NPAL18025 - if (reversed) { - idPrev = idLast; - idLast = idFirst; - idFirst = idPrev; - parPrev = l; - parLast = f; - } - */ for (list::iterator itU = params.begin(); itU != params.end(); itU++) { double param = *itU; gp_Pnt P = Curve->Value(param); @@ -1197,18 +1208,18 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t if(_quadraticMesh) { // create medium node double prm = ( parPrev + param )/2; - gp_Pnt PM = Curve->Value(prm); + 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); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, node, NM); meshDS->SetMeshElementOnShape(edge, shapeID); } else { - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, node); meshDS->SetMeshElementOnShape(edge, shapeID); } - idPrev = node; + nPrev = node; parPrev = param; } if(_quadraticMesh) { @@ -1216,11 +1227,11 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t 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); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, nLast, NM); meshDS->SetMeshElementOnShape(edge, shapeID); } else { - SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); + SMDS_MeshEdge* edge = meshDS->AddEdge(nPrev, nLast); meshDS->SetMeshElementOnShape(edge, shapeID); } } @@ -1233,7 +1244,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t gp_Pnt P = BRep_Tool::Pnt(VFirst); - const SMDS_MeshNode * idPrev = idFirst; + const SMDS_MeshNode * nPrev = nFirst; for (int i = 2; i < NbPoints; i++) { double param = f + (i - 1) * du; SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); @@ -1242,26 +1253,26 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t 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); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, node, NM); meshDS->SetMeshElementOnShape(edge, shapeID); } else { - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, node); meshDS->SetMeshElementOnShape(edge, shapeID); } meshDS->SetNodeOnEdge(node, shapeID, param); - idPrev = node; + nPrev = node; } 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); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, nLast, NM); meshDS->SetMeshElementOnShape(edge, shapeID); } else { - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, nLast); meshDS->SetMeshElementOnShape(edge, shapeID); } } @@ -1275,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; @@ -1285,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,14 +1314,14 @@ bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh, std::vector aVec(SMDSEntity_Last,0); - if (!Curve.IsNull()) { + double length = EdgeLength( E ); + if ( !Curve.IsNull() && length > 0 ) + { list< double > params; - BRepAdaptor_Curve C3d( E ); - double length = EdgeLength( 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; @@ -1318,19 +1329,19 @@ 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 { aVec[SMDSEntity_Node] = params.size(); aVec[SMDSEntity_Edge] = params.size() + 1; } - + } 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 { @@ -1339,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; } @@ -1369,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 );