X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_RadialQuadrangle_1D2D.cxx;h=b861f3701c87d909fc01924f1445e02bc75b9e38;hb=a695ce3aeecb27a023e248ccb9433d62916308cd;hp=3aeee6062afbbcd9380a9e6d52b016dc91d0f519;hpb=f5016d85b7b4b88623723027a1585c6414c4dc66;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx index 3aeee6062..b861f3701 100644 --- a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2015 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 // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -75,10 +75,12 @@ StdMeshers_RadialQuadrangle_1D2D::StdMeshers_RadialQuadrangle_1D2D(int hypId, _compatibleHypothesis.push_back("LayerDistribution2D"); _compatibleHypothesis.push_back("NumberOfLayers2D"); - myNbLayerHypo = 0; - myDistributionHypo = 0; _requireDiscreteBoundary = false; _supportSubmeshes = true; + _neededLowerHyps[ 1 ] = true; // suppress warning on hiding a global 1D algo + + myNbLayerHypo = 0; + myDistributionHypo = 0; } @@ -278,6 +280,38 @@ namespace } return nbe; } + //================================================================================ + /*! + * \brief Checks if the common vertex between LinEdge's lies inside the circle + * and not outside + * \param [in] CircEdge - + * \param [in] LinEdge1 - + * \param [in] LinEdge2 - + * \return bool - false if there are 3 EDGEs and the corner is outside + */ + //================================================================================ + + bool isCornerInsideCircle(const TopoDS_Edge& CircEdge, + const TopoDS_Edge& LinEdge1, + const TopoDS_Edge& LinEdge2) + { + if ( !CircEdge.IsNull() && + !LinEdge1.IsNull() && + !LinEdge2.IsNull() ) + { + Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge )); + TopoDS_Vertex aCommonV; + if ( !aCirc.IsNull() && + TopExp::CommonVertex( LinEdge1, LinEdge2, aCommonV )) + { + gp_Pnt aCommonP = BRep_Tool::Pnt( aCommonV ); + gp_Pnt aCenter = aCirc->Location(); + double dist = aCenter.Distance( aCommonP ); + return dist < 0.1 * aCirc->Radius(); + } + } + return true; + } //================================================================================ //================================================================================ @@ -295,12 +329,11 @@ public: // ----------------------------------------------------------------------------- static TNodeDistributor* GetDistributor(SMESH_Mesh& aMesh) { - const int myID = -1000; - map < int, SMESH_1D_Algo * > & algoMap = aMesh.GetGen()->_map1D_Algo; - map < int, SMESH_1D_Algo * >::iterator id_algo = algoMap.find( myID ); - if ( id_algo == algoMap.end() ) - return new TNodeDistributor( myID, 0, aMesh.GetGen() ); - return static_cast< TNodeDistributor* >( id_algo->second ); + const int myID = -1001; + TNodeDistributor* myHyp = dynamic_cast( aMesh.GetHypothesis( myID )); + if ( !myHyp ) + myHyp = new TNodeDistributor( myID, 0, aMesh.GetGen() ); + return myHyp; } // ----------------------------------------------------------------------------- //! Computes distribution of nodes on a straight line ending at pIn and pOut @@ -420,7 +453,7 @@ void StdMeshers_RadialQuadrangle_1D2D::SubmeshRestored(SMESH_subMesh* faceSubMes //======================================================================= //function : Compute -//purpose : +//purpose : //======================================================================= bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, @@ -429,18 +462,18 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); myHelper = new SMESH_MesherHelper( aMesh ); - myHelper->IsQuadraticSubMesh( aShape ); // to delete helper at exit from Compute() - auto_ptr helperDeleter( myHelper ); + SMESHUtils::Deleter helperDeleter( myHelper ); TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh); TopoDS_Edge CircEdge, LinEdge1, LinEdge2; int nbe = analyseFace( aShape, CircEdge, LinEdge1, LinEdge2 ); Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge )); - if( nbe>3 || nbe < 1 || aCirc.IsNull() ) - return error("The face must be a full circle or a part of circle (i.e. the number of edges is less or equal to 3 and one of them is a circle curve)"); - + if( nbe > 3 || nbe < 1 || aCirc.IsNull() ) + return error("The face must be a full circle or a part of circle (i.e. the number " + "of edges is less or equal to 3 and one of them is a circle curve)"); + gp_Pnt P0, P1; // points for rotation TColgp_SequenceOfPnt Points; @@ -467,6 +500,8 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, if ( !GetSortedNodesOnEdge(aMesh.GetMeshDS(),CircEdge,true,theNodes)) return error("Circular edge is incorrectly meshed"); + myHelper->IsQuadraticSubMesh( aShape ); + CNodes.clear(); map< double, const SMDS_MeshNode* >::iterator itn = theNodes.begin(); const SMDS_MeshNode* NF = (*itn).second; @@ -502,8 +537,8 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, gp_Vec2d aVec2d(PC,p2dV); Nodes1.resize( myLayerPositions.size()+1 ); Nodes2.resize( myLayerPositions.size()+1 ); - int i = 0; - for(; iIsQuadraticSubMesh( aShape ); + map< double, const SMDS_MeshNode* >::iterator itn = theNodes.begin(); CNodes.clear(); CNodes.push_back( itn->second ); @@ -611,7 +648,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, meshDS->SetNodeOnEdge(NC, edgeID, cp); Nodes1.resize( myLayerPositions.size()+1 ); Nodes2.resize( myLayerPositions.size()+1 ); - int i = 0; + size_t i = 0; for(; iComputeCircularEdge( aMesh, CircEdge )) return error( algo1d->GetComputeError() ); map< double, const SMDS_MeshNode* > theNodes; - if ( !GetSortedNodesOnEdge(aMesh.GetMeshDS(),CircEdge,true,theNodes)) + if ( !GetSortedNodesOnEdge( aMesh.GetMeshDS(), CircEdge, true, theNodes )) return error("Circular edge is incorrectly meshed"); + myHelper->IsQuadraticSubMesh( aShape ); + const SMDS_MeshNode* NF = theNodes.begin()->second; const SMDS_MeshNode* NL = theNodes.rbegin()->second; CNodes.clear(); @@ -733,8 +774,8 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, bool nodesFromP0ToP1 = ( theNodes.rbegin()->second == NF ); NC = const_cast ( nodesFromP0ToP1 ? theNodes.begin()->second : theNodes.rbegin()->second ); - int i = 0, ir = Nodes1.size()-1; - int * pi = nodesFromP0ToP1 ? &i : &ir; + size_t i = 0, ir = Nodes1.size()-1; + size_t * pi = nodesFromP0ToP1 ? &i : &ir; itn = theNodes.begin(); if ( nodesFromP0ToP1 ) ++itn; for ( ; i < Nodes1.size(); ++i, --ir, ++itn ) @@ -776,8 +817,8 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, meshDS->SetNodeOnVertex(NC, vertID); } double dp = lp-fp; - int i = 0; - for(; iAddNode(P.X(), P.Y(), P.Z()); Nodes1[i] = node; double param; - if(!ori) + if ( !ori ) param = fp + dp*(1-myLayerPositions[i]); else param = fp + dp*myLayerPositions[i]; @@ -799,11 +840,11 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, // create 1D elements on edge SMDS_MeshEdge* ME = myHelper->AddEdge( NC, Nodes1[0] ); if(ME) meshDS->SetMeshElementOnShape(ME, edgeID); - for(i=1; iAddEdge( Nodes1[i-1], Nodes1[i] ); if(ME) meshDS->SetMeshElementOnShape(ME, edgeID); } - if (nbe==2 && LinEdge1.Orientation() == TopAbs_INTERNAL ) + if ( nbe == 2 && LinEdge1.Orientation() == TopAbs_INTERNAL ) Nodes2 = Nodes1; } markEdgeAsComputedByMe( LinEdge1, aMesh.GetSubMesh( F )); @@ -815,8 +856,8 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, return error("Invalid mesh on a straight edge"); bool nodesFromP0ToP2 = ( theNodes.rbegin()->second == NL ); - int i = 0, ir = Nodes1.size()-1; - int * pi = nodesFromP0ToP2 ? &i : &ir; + size_t i = 0, ir = Nodes1.size()-1; + size_t * pi = nodesFromP0ToP2 ? &i : &ir; itn = theNodes.begin(); if ( nodesFromP0ToP2 ) ++itn; for ( ; i < Nodes2.size(); ++i, --ir, ++itn ) @@ -845,7 +886,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, PC = PL; } double dp = lp-fp; - for(int i=0; iAddEdge( NC, Nodes2[0] ); - if(ME) meshDS->SetMeshElementOnShape(ME, edgeID); - for(int i=1; iSetMeshElementOnShape(ME, edgeID); + for ( size_t i = 1; i < Nodes2.size(); i++ ) { ME = myHelper->AddEdge( Nodes2[i-1], Nodes2[i] ); if(ME) meshDS->SetMeshElementOnShape(ME, edgeID); } @@ -890,7 +931,6 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, //cout<<"Nodes1.size() = "<& aVec = aResMap[ aMesh.GetSubMesh(LinEdge1) ]; - ok = ( aVec[SMDSEntity_Node] == myLayerPositions.size() ); + ok = ( aVec[SMDSEntity_Node] == (int) myLayerPositions.size() ); } if(ok) { ok = algo1d->EvaluateCircularEdge( aMesh, CircEdge, aResMap ); @@ -1203,7 +1243,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh, // other curve not line return error(COMPERR_BAD_SHAPE); } - int nbLayers = myLayerPositions.size(); + size_t nbLayers = myLayerPositions.size(); computeLayerPositions( P0, P1, LinEdge2 ); if ( nbLayers != myLayerPositions.size() ) return error("Different hypotheses apply to radial edges"); @@ -1214,7 +1254,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh, ok = true; // override other 1d hyps else { const vector& aVec = aResMap[ aMesh.GetSubMesh(LinEdge1) ]; - ok = ( aVec[SMDSEntity_Node] == myLayerPositions.size() ); + ok = ( aVec[SMDSEntity_Node] == (int) myLayerPositions.size() ); } } if( ok && aResMap.count( aMesh.GetSubMesh(LinEdge2) )) { @@ -1222,7 +1262,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh, ok = true; // override other 1d hyps else { const vector& aVec = aResMap[ aMesh.GetSubMesh(LinEdge2) ]; - ok = ( aVec[SMDSEntity_Node] == myLayerPositions.size() ); + ok = ( aVec[SMDSEntity_Node] == (int) myLayerPositions.size() ); } } if(ok) { @@ -1282,3 +1322,26 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh, return false; } + +//================================================================================ +/*! + * \brief Return true if the algorithm can compute mesh on this shape + */ +//================================================================================ + +bool StdMeshers_RadialQuadrangle_1D2D::IsApplicable( const TopoDS_Shape & aShape, bool toCheckAll ) +{ + int nbFoundFaces = 0; + for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces ) + { + TopoDS_Edge CircEdge, LinEdge1, LinEdge2; + int nbe = analyseFace( exp.Current(), CircEdge, LinEdge1, LinEdge2 ); + Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge )); + bool ok = ( nbe <= 3 && nbe >= 1 && !aCirc.IsNull() && + isCornerInsideCircle( CircEdge, LinEdge1, LinEdge2 )); + if( toCheckAll && !ok ) return false; + if( !toCheckAll && ok ) return true; + } + if( toCheckAll && nbFoundFaces != 0 ) return true; + return false; +};