X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=inline;f=src%2FStdMeshers%2FStdMeshers_RadialQuadrangle_1D2D.cxx;h=8c5869107d5e0cc5859628bd117bbc22ae3b71bf;hb=d2248790d7e9f3862ac49798c4c55eeff28df18a;hp=4f2329d5932db1ad5f770be021cdb6c6a5a6898f;hpb=1cea00918546e5ab79c0d74d49d7820d431f3c85;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx index 4f2329d59..8c5869107 100644 --- a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -74,9 +74,8 @@ using namespace std; //======================================================================= StdMeshers_RadialQuadrangle_1D2D::StdMeshers_RadialQuadrangle_1D2D(int hypId, - int studyId, SMESH_Gen* gen) - :StdMeshers_Quadrangle_2D( hypId, studyId, gen ) + :StdMeshers_Quadrangle_2D( hypId, gen ) { _name = "RadialQuadrangle_1D2D"; _shapeType = (1 << TopAbs_FACE); // 1 bit per shape type @@ -164,38 +163,45 @@ namespace static TEdgeMarker theEdgeMarker; return &theEdgeMarker; } - //! Clear face sumbesh if something happens on edges + //! Clear edge sumbesh if something happens on face void ProcessEvent(const int event, const int eventType, - SMESH_subMesh* edgeSubMesh, - EventListenerData* data, + SMESH_subMesh* faceSubMesh, + EventListenerData* edgesHolder, const SMESH_Hypothesis* /*hyp*/) { - if ( data && !data->mySubMeshes.empty() && eventType == SMESH_subMesh::ALGO_EVENT) + if ( edgesHolder && eventType == SMESH_subMesh::ALGO_EVENT) { - ASSERT( data->mySubMeshes.front() != edgeSubMesh ); - SMESH_subMesh* faceSubMesh = data->mySubMeshes.front(); - faceSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN ); + std::list::iterator smIt = edgesHolder->mySubMeshes.begin(); + for ( ; smIt != edgesHolder->mySubMeshes.end(); ++smIt ) + { + SMESH_subMesh* edgeSM = *smIt; + edgeSM->ComputeStateEngine( SMESH_subMesh::CLEAN ); + } } } - }; - - //================================================================================ - /*! - * \brief Mark an edge as computed by StdMeshers_RadialQuadrangle_1D2D - */ - //================================================================================ - - void markEdgeAsComputedByMe(const TopoDS_Edge& edge, SMESH_subMesh* faceSubMesh) - { - if ( SMESH_subMesh* edgeSM = faceSubMesh->GetFather()->GetSubMeshContaining( edge )) + //! Store edge SMESH_subMesh'es computed by the algo + static void markEdge( const TopoDS_Edge& edge, SMESH_subMesh* faceSM ) { - if ( !edgeSM->GetEventListenerData( TEdgeMarker::getListener() )) - faceSubMesh->SetEventListener( TEdgeMarker::getListener(), - SMESH_subMeshEventListenerData::MakeData(faceSubMesh), - edgeSM); + if ( SMESH_subMesh* edgeSM = faceSM->GetFather()->GetSubMeshContaining( edge )) + { + EventListenerData* edgesHolder = faceSM->GetEventListenerData( getListener() ); + if ( edgesHolder ) + { + std::list::iterator smIt = std::find( edgesHolder->mySubMeshes.begin(), + edgesHolder->mySubMeshes.end(), + edgeSM ); + if ( smIt == edgesHolder->mySubMeshes.end() ) + edgesHolder->mySubMeshes.push_back( edgeSM ); + } + else + { + edgesHolder = SMESH_subMeshEventListenerData::MakeData( edgeSM ); + faceSM->SetEventListener( TEdgeMarker::getListener(), edgesHolder, faceSM ); + } + } } - } + }; //================================================================================ /*! @@ -208,7 +214,8 @@ namespace SMESH_Mesh* aMesh, StdMeshers_FaceSidePtr& aCircSide, StdMeshers_FaceSidePtr& aLinSide1, - StdMeshers_FaceSidePtr& aLinSide2) + StdMeshers_FaceSidePtr& aLinSide2, + SMESH_MesherHelper* helper) { const TopoDS_Face& face = TopoDS::Face( aShape ); aCircSide.reset(); aLinSide1.reset(); aLinSide2.reset(); @@ -259,7 +266,7 @@ namespace StdMeshers_FaceSidePtr side; if ( aMesh ) side = StdMeshers_FaceSide::New( face, sideEdges, aMesh, - /*isFwd=*/true, /*skipMedium=*/ true ); + /*isFwd=*/true, /*skipMedium=*/ true, helper ); sides.push_back( side ); } @@ -306,6 +313,24 @@ namespace } deviation2sideInd.insert( make_pair( devia, iS )); } + double maxDevi = deviation2sideInd.rbegin()->first; + if ( maxDevi < 1e-7 && sides.size() == 3 ) + { + // a triangle FACE; use a side with the most outstanding length as an elliptic one + deviation2sideInd.clear(); + multimap< double, int > len2sideInd; + for ( size_t iS = 0; iS < sides.size(); ++iS ) + len2sideInd.insert( make_pair( sides[iS]->Length(), iS )); + + multimap< double, int >::iterator l2i = len2sideInd.begin(); + double len0 = l2i->first; + double len1 = (++l2i)->first; + double len2 = (++l2i)->first; + if ( len1 - len0 > len2 - len1 ) + deviation2sideInd.insert( make_pair( 0., len2sideInd.begin()->second )); + else + deviation2sideInd.insert( make_pair( 0., len2sideInd.rbegin()->second )); + } int iCirc = deviation2sideInd.rbegin()->second; aCircSide = sides[ iCirc ]; @@ -339,7 +364,7 @@ namespace edges.push_back( aCircSide->Edge( iE % aCircSide->NbEdges() )); aCircSide = StdMeshers_FaceSide::New( face, edges, aMesh, - /*isFwd=*/true, /*skipMedium=*/ true ); + /*isFwd=*/true, /*skipMedium=*/ true, helper ); } } @@ -582,7 +607,7 @@ namespace { if ( meshDS->FindEdge( nodes[i].node, nodes[i-1].node )) continue; - const SMDS_MeshElement* seg = meshDS->AddEdge( nodes[i].node, nodes[i-1].node ); + const SMDS_MeshElement* seg = helper->AddEdge( nodes[i].node, nodes[i-1].node ); double normParam = 0.5 * ( nodes[i].normParam + nodes[i-1].normParam ); edgeID = linSide->EdgeID( linSide->EdgeIndex( normParam )); @@ -612,7 +637,7 @@ public: const int myID = -1001; TNodeDistributor* myHyp = dynamic_cast( aMesh.GetHypothesis( myID )); if ( !myHyp ) - myHyp = new TNodeDistributor( myID, 0, aMesh.GetGen() ); + myHyp = new TNodeDistributor( myID, aMesh.GetGen() ); return myHyp; } // ----------------------------------------------------------------------------- @@ -650,7 +675,7 @@ public: return true; } // ----------------------------------------------------------------------------- - //! Make mesh on an adge using assigned 1d hyp or defaut nb of segments + //! Make mesh on an edge using assigned 1d hyp or default nb of segments bool ComputeCircularEdge( SMESH_Mesh& aMesh, const StdMeshers_FaceSidePtr& aSide ) { @@ -678,7 +703,7 @@ public: return ok; } // ----------------------------------------------------------------------------- - //! Make mesh on an adge using assigned 1d hyp or defaut nb of segments + //! Make mesh on an edge using assigned 1d hyp or default nb of segments bool EvaluateCircularEdge(SMESH_Mesh& aMesh, const StdMeshers_FaceSidePtr aSide, MapShapeNbElems& aResMap) @@ -707,8 +732,8 @@ public: } protected: // ----------------------------------------------------------------------------- - TNodeDistributor( int hypId, int studyId, SMESH_Gen* gen) - : StdMeshers_Regular_1D( hypId, studyId, gen) + TNodeDistributor( int hypId, SMESH_Gen* gen) + : StdMeshers_Regular_1D( hypId, gen) { } // ----------------------------------------------------------------------------- @@ -726,19 +751,19 @@ protected: * \brief Allow algo to do something after persistent restoration * \param subMesh - restored submesh * - * call markEdgeAsComputedByMe() + * call TEdgeMarker::markEdge() */ //======================================================================= void StdMeshers_RadialQuadrangle_1D2D::SubmeshRestored(SMESH_subMesh* faceSubMesh) { - // if ( !faceSubMesh->IsEmpty() ) - // { - // for ( TopExp_Explorer e( faceSubMesh->GetSubShape(), TopAbs_EDGE ); e.More(); e.Next() ) - // { - // markEdgeAsComputedByMe( TopoDS::Edge( e.Current() ), faceSubMesh ); - // } - // } + if ( !faceSubMesh->IsEmpty() ) + { + for ( TopExp_Explorer e( faceSubMesh->GetSubShape(), TopAbs_EDGE ); e.More(); e.Next() ) + { + TEdgeMarker::markEdge( TopoDS::Edge( e.Current() ), faceSubMesh ); + } + } } //======================================================================= @@ -755,19 +780,22 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, StdMeshers_Quadrangle_2D::myCheckOri = false; StdMeshers_Quadrangle_2D::myQuadList.clear(); + myHelper->SetSubShape( aShape ); + myHelper->SetElementsOnShape( true ); + StdMeshers_FaceSidePtr circSide, linSide1, linSide2; - int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2 ); + int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2, myHelper ); if( nbSides > 3 || nbSides < 1 ) return error("The face must be a full ellipse or a part of ellipse (i.e. the number " "of edges is less or equal to 3 and one of them is an ellipse curve)"); // get not yet computed EDGEs - // list< TopoDS_Edge > emptyEdges; - // for ( TopExp_Explorer e( aShape, TopAbs_EDGE ); e.More(); e.Next() ) - // { - // if ( aMesh.GetSubMesh( e.Current() )->IsEmpty() ) - // emptyEdges.push_back( TopoDS::Edge( e.Current() )); - // } + list< TopoDS_Edge > emptyEdges; + for ( TopExp_Explorer e( aShape, TopAbs_EDGE ); e.More(); e.Next() ) + { + if ( aMesh.GetSubMesh( e.Current() )->IsEmpty() ) + emptyEdges.push_back( TopoDS::Edge( e.Current() )); + } TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh); @@ -779,7 +807,6 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, Handle(Geom_Surface) S = BRep_Tool::Surface(F); myHelper->IsQuadraticSubMesh( aShape ); - myHelper->SetElementsOnShape( true ); vector< double > layerPositions; // [0,1] @@ -793,7 +820,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, TopoDS_Edge linEdge = makeEdgeToCenter( circSide, F, circNode ); StdMeshers_FaceSidePtr tmpSide = - StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true ); + StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true, myHelper ); if ( !computeLayerPositions( tmpSide, layerPositions )) return false; @@ -837,7 +864,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, isVIn0Shared = vIn0.IsSame( circSide->FirstVertex( iE )); linSide1 = StdMeshers_FaceSide::New( F, edges, &aMesh, - /*isFrw=*/isVIn0Shared, /*skipMedium=*/true ); + /*isFrw=*/isVIn0Shared, /*skipMedium=*/true, myHelper ); int nbMeshedEdges; if ( !computeLayerPositions( linSide1, layerPositions, &nbMeshedEdges )) @@ -941,9 +968,9 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, centerUV = nodes2.back().UV(); } - // list< TopoDS_Edge >::iterator ee = emptyEdges.begin(); - // for ( ; ee != emptyEdges.end(); ++ee ) - // markEdgeAsComputedByMe( *ee, aMesh.GetSubMesh( F )); + list< TopoDS_Edge >::iterator ee = emptyEdges.begin(); + for ( ; ee != emptyEdges.end(); ++ee ) + TEdgeMarker::markEdge( *ee, aMesh.GetSubMesh( F )); circSide->GetUVPtStruct(); // let sides take into account just computed nodes linSide1->GetUVPtStruct(); @@ -1087,7 +1114,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh, TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh); StdMeshers_FaceSidePtr circSide, linSide1, linSide2; - int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2 ); + int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2, myHelper ); if( nbSides > 3 || nbSides < 1 ) return false; @@ -1105,7 +1132,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh, TopoDS_Edge linEdge = makeEdgeToCenter( circSide, F, circNode ); StdMeshers_FaceSidePtr tmpSide = - StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true ); + StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true, myHelper ); if ( !computeLayerPositions( tmpSide, layerPositions )) return false; @@ -1202,7 +1229,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::IsApplicable( const TopoDS_Shape & aShape for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces ) { StdMeshers_FaceSidePtr circSide, linSide1, linSide2; - int nbSides = analyseFace( aShape, NULL, circSide, linSide1, linSide2 ); + int nbSides = analyseFace( exp.Current(), NULL, circSide, linSide1, linSide2, NULL ); bool ok = ( 0 < nbSides && nbSides <= 3 && isCornerInsideCircle( circSide, linSide1, linSide2 )); if( toCheckAll && !ok ) return false;