X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_RadialQuadrangle_1D2D.cxx;h=204682ea9180c9a3a2c966fe5fcdc82f945cb131;hb=9493563cbc59acba2b9b036bb22fb184f5be946d;hp=83e667968052f799a550cecbd61eebd633688a86;hpb=6aea23b893abc82fbeecf5924d0939370c110271;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx index 83e667968..204682ea9 100644 --- a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 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 @@ -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; + } //================================================================================ //================================================================================ @@ -419,7 +453,7 @@ void StdMeshers_RadialQuadrangle_1D2D::SubmeshRestored(SMESH_subMesh* faceSubMes //======================================================================= //function : Compute -//purpose : +//purpose : //======================================================================= bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, @@ -428,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; @@ -466,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; @@ -540,6 +576,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 ); + map< double, const SMDS_MeshNode* >::iterator itn = theNodes.begin(); CNodes.clear(); CNodes.push_back( itn->second ); @@ -665,17 +703,21 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, // segments of line double fp, lp; Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge )); - Handle(Geom_Line) aLine1 = Handle(Geom_Line)::DownCast( getCurve( LinEdge1 )); - Handle(Geom_Line) aLine2 = Handle(Geom_Line)::DownCast( getCurve( LinEdge2 )); - if( aCirc.IsNull() || aLine1.IsNull() || aLine2.IsNull() ) + Handle(Geom_Line) aLine1 = Handle(Geom_Line )::DownCast( getCurve( LinEdge1 )); + Handle(Geom_Line) aLine2 = Handle(Geom_Line )::DownCast( getCurve( LinEdge2 )); + if ( aCirc.IsNull() || aLine1.IsNull() || aLine2.IsNull() ) + return error(COMPERR_BAD_SHAPE); + if ( !isCornerInsideCircle( CircEdge, LinEdge1, LinEdge2 )) return error(COMPERR_BAD_SHAPE); if ( !algo1d->ComputeCircularEdge( 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(); @@ -988,9 +1030,9 @@ bool StdMeshers_RadialQuadrangle_1D2D::computeLayerPositions(const gp_Pnt& if ( !edge.IsNull() ) { // find a hyp usable by TNodeDistributor - SMESH_HypoFilter hypKind; - TNodeDistributor::GetDistributor(*mesh)->InitCompatibleHypoFilter(hypKind,/*ignoreAux=*/1); - hyp1D = mesh->GetHypothesis( edge, hypKind, /*fromAncestors=*/true); + const SMESH_HypoFilter* hypKind = + TNodeDistributor::GetDistributor(*mesh)->GetCompatibleHypoFilter(/*ignoreAux=*/true); + hyp1D = mesh->GetHypothesis( edge, *hypKind, /*fromAncestors=*/true); } } if ( hyp1D ) // try to compute with hyp1D @@ -1284,19 +1326,22 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh, //================================================================================ /*! - * \brief Return true if applied compute mesh on this shape + * \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 ){ + for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces ) + { TopoDS_Edge CircEdge, LinEdge1, LinEdge2; - int nbe = analyseFace( TopoDS_Shape( exp.Current() ), CircEdge, LinEdge1, LinEdge2 ); + int nbe = analyseFace( exp.Current(), CircEdge, LinEdge1, LinEdge2 ); Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge )); - if( toCheckAll && ( nbe > 3 || nbe < 1 || aCirc.IsNull() )) return false; - if( !toCheckAll && ( nbe <= 3 && nbe >= 1 && !aCirc.IsNull() )) return true; + 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;