X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FControls%2FSMESH_Controls.cxx;h=9ce464a887743d3930d92698b862a75325f1293e;hb=7242eaf55b5e6e26433e1128e47cbceeceac12e9;hp=1adabb5c6f0dba5560eacd473848fa413d1affaf;hpb=db83efeef8e138c5871f1a3ca8d5d4a64653b663;p=modules%2Fsmesh.git diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 1adabb5c6..9ce464a88 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -2469,16 +2469,22 @@ bool BareBorderFace::IsSatisfy(long theElementId ) bool OverConstrainedVolume::IsSatisfy(long theElementId ) { - // An element is over-constrained if it has N-1 free borders where - // N is the number of edges/faces for a 2D/3D element. - SMDS_VolumeTool myTool; - if ( myTool.Set( myMesh->FindElement(theElementId))) + // An element is over-constrained if all its nodes are on the boundary. + // A node is on the boundary if it is connected to one or more faces. + SMDS_VolumeTool myTool; + if (myTool.Set(myMesh->FindElement(theElementId))) { - int nbSharedFaces = 0; - for ( int iF = 0; iF < myTool.NbFaces(); ++iF ) - if ( !myTool.IsFreeFace( iF ) && ++nbSharedFaces > 1 ) - break; - return ( nbSharedFaces == 1 ); + auto nodes = myTool.GetNodes(); + + for (int i = 0; i < myTool.NbNodes(); ++i) + { + auto node = nodes[i]; + if (node->NbInverseElements(SMDSAbs_Face) == 0) + { + return false; + } + } + return true; } return false; } @@ -2491,29 +2497,19 @@ bool OverConstrainedVolume::IsSatisfy(long theElementId ) bool OverConstrainedFace::IsSatisfy(long theElementId ) { - // An element is over-constrained if it has N-1 free borders where - // N is the number of edges/faces for a 2D/3D element. - if ( const SMDS_MeshElement* face = myMesh->FindElement(theElementId)) - if ( face->GetType() == SMDSAbs_Face ) + // An element is over-constrained if all its nodes are on the boundary. + // A node is on the boundary if it is connected to one or more faces. + if (const SMDS_MeshElement *face = myMesh->FindElement(theElementId)) + if (face->GetType() == SMDSAbs_Face) { - int nbSharedBorders = 0; int nbN = face->NbCornerNodes(); - for ( int i = 0; i < nbN; ++i ) + for (int i = 0; i < nbN; ++i) { - // check if a link is shared by another face - const SMDS_MeshNode* n1 = face->GetNode( i ); - const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbN ); - SMDS_ElemIteratorPtr fIt = n1->GetInverseElementIterator( SMDSAbs_Face ); - bool isShared = false; - while ( !isShared && fIt->more() ) - { - const SMDS_MeshElement* f = fIt->next(); - isShared = ( f != face && f->GetNodeIndex(n2) != -1 ); - } - if ( isShared && ++nbSharedBorders > 1 ) - break; + const SMDS_MeshNode *n1 = face->GetNode(i); + if (n1->NbInverseElements(SMDSAbs_Edge) == 0) + return false; } - return ( nbSharedBorders == 1 ); + return true; } return false; } @@ -4347,7 +4343,7 @@ namespace { struct ElementsOnShape::Classifier { - Classifier() { mySolidClfr = 0; myFlags = 0; } + Classifier(): mySolidClfr(0), myProjFace(0), myProjEdge(0), myFlags(0) { myU = myV = 1e100; } ~Classifier(); void Init(const TopoDS_Shape& s, double tol, const Bnd_B3d* box = 0 ); bool IsOut(const gp_Pnt& p) { return SetChecked( true ), (this->*myIsOutFun)( p ); } @@ -4360,6 +4356,7 @@ struct ElementsOnShape::Classifier void SetChecked( bool is ) { is ? SetFlag( theIsCheckedFlag ) : UnsetFlag( theIsCheckedFlag ); } void SetFlag ( int flag ) { myFlags |= flag; } void UnsetFlag( int flag ) { myFlags &= ~flag; } + void GetParams( double & u, double & v ) const { u = myU; v = myV; } private: bool isOutOfSolid (const gp_Pnt& p); @@ -4373,13 +4370,14 @@ private: TopoDS_Shape prepareSolid( const TopoDS_Shape& theSolid ); bool (Classifier::* myIsOutFun)(const gp_Pnt& p); - BRepClass3d_SolidClassifier* mySolidClfr; // ptr because of a run-time forbidden copy-constructor + BRepClass3d_SolidClassifier* mySolidClfr; Bnd_B3d myBox; - GeomAPI_ProjectPointOnSurf myProjFace; - GeomAPI_ProjectPointOnCurve myProjEdge; + GeomAPI_ProjectPointOnSurf* myProjFace; + GeomAPI_ProjectPointOnCurve* myProjEdge; gp_Pnt myVertexXYZ; TopoDS_Shape myShape; double myTol; + double myU, myV; // result of isOutOfFace() and isOutOfEdge() int myFlags; }; @@ -4457,9 +4455,12 @@ SMDSAbs_ElementType ElementsOnShape::GetType() const void ElementsOnShape::SetTolerance (const double theToler) { - if (myToler != theToler) { + if (myToler != theToler) + { myToler = theToler; - SetShape(myShape, myType); + TopoDS_Shape s = myShape; + myShape.Nullify(); + SetShape( s, myType ); } } @@ -4687,6 +4688,7 @@ bool ElementsOnShape::IsSatisfy (const SMDS_MeshNode* node, isNodeOut = false; if ( okShape ) *okShape = myWorkClassifiers[i]->Shape(); + myWorkClassifiers[i]->GetParams( myU, myV ); break; } } @@ -4698,6 +4700,7 @@ bool ElementsOnShape::IsSatisfy (const SMDS_MeshNode* node, isNodeOut = false; if ( okShape ) *okShape = myClassifiers[i].Shape(); + myClassifiers[i].GetParams( myU, myV ); break; } } @@ -4740,7 +4743,8 @@ void ElementsOnShape::Classifier::Init( const TopoDS_Shape& theShape, else { surf->Bounds( u1,u2,v1,v2 ); - myProjFace.Init(surf, u1,u2, v1,v2, myTol ); + myProjFace = new GeomAPI_ProjectPointOnSurf; + myProjFace->Init( surf, u1,u2, v1,v2, myTol ); myIsOutFun = & ElementsOnShape::Classifier::isOutOfFace; } break; @@ -4753,7 +4757,8 @@ void ElementsOnShape::Classifier::Init( const TopoDS_Shape& theShape, myIsOutFun = & ElementsOnShape::Classifier::isOutOfNone; else { - myProjEdge.Init(curve, u1, u2); + myProjEdge = new GeomAPI_ProjectPointOnCurve; + myProjEdge->Init( curve, u1, u2 ); myIsOutFun = & ElementsOnShape::Classifier::isOutOfEdge; } break; @@ -4803,6 +4808,8 @@ void ElementsOnShape::Classifier::Init( const TopoDS_Shape& theShape, ElementsOnShape::Classifier::~Classifier() { delete mySolidClfr; mySolidClfr = 0; + delete myProjFace; myProjFace = 0; + delete myProjEdge; myProjEdge = 0; } TopoDS_Shape ElementsOnShape::Classifier::prepareSolid( const TopoDS_Shape& theSolid ) @@ -4839,13 +4846,12 @@ bool ElementsOnShape::Classifier::isOutOfBox( const gp_Pnt& p ) bool ElementsOnShape::Classifier::isOutOfFace( const gp_Pnt& p ) { if ( isOutOfBox( p )) return true; - myProjFace.Perform( p ); - if ( myProjFace.IsDone() && myProjFace.LowerDistance() <= myTol ) + myProjFace->Perform( p ); + if ( myProjFace->IsDone() && myProjFace->LowerDistance() <= myTol ) { // check relatively to the face - Standard_Real u, v; - myProjFace.LowerDistanceParameters(u, v); - gp_Pnt2d aProjPnt (u, v); + myProjFace->LowerDistanceParameters( myU, myV ); + gp_Pnt2d aProjPnt( myU, myV ); BRepClass_FaceClassifier aClsf ( TopoDS::Face( myShape ), aProjPnt, myTol ); if ( aClsf.State() == TopAbs_IN || aClsf.State() == TopAbs_ON ) return false; @@ -4856,8 +4862,11 @@ bool ElementsOnShape::Classifier::isOutOfFace( const gp_Pnt& p ) bool ElementsOnShape::Classifier::isOutOfEdge( const gp_Pnt& p ) { if ( isOutOfBox( p )) return true; - myProjEdge.Perform( p ); - return ! ( myProjEdge.NbPoints() > 0 && myProjEdge.LowerDistance() <= myTol ); + myProjEdge->Perform( p ); + bool isOn = ( myProjEdge->NbPoints() > 0 && myProjEdge->LowerDistance() <= myTol ); + if ( isOn ) + myU = myProjEdge->LowerDistanceParameter(); + return !isOn; } bool ElementsOnShape::Classifier::isOutOfVertex( const gp_Pnt& p )