X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FControls%2FSMESH_Controls.cxx;h=ecd12a0b5d493ef48d1f6c28a1cc4a912620bc73;hb=6ca4db2d7c49474a93e30c02bef83f05b354e540;hp=2a1e274fd530f72d4f5c50243c87b622421cbff7;hpb=074862c21362ffeb5556c4f16c843aacda569121;p=modules%2Fsmesh.git diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 2a1e274fd..ecd12a0b5 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.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 // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -233,7 +233,7 @@ bool NumericalFunctor::GetPoints(const int theId, return false; const SMDS_MeshElement* anElem = myMesh->FindElement( theId ); - if ( !anElem || anElem->GetType() != this->GetType() ) + if ( !IsApplicable( anElem )) return false; return GetPoints( anElem, theRes ); @@ -292,6 +292,24 @@ double NumericalFunctor::Round( const double & aVal ) return ( myPrecision >= 0 ) ? floor( aVal * myPrecisionValue + 0.5 ) / myPrecisionValue : aVal; } +//================================================================================ +/*! + * \brief Return true if a value can be computed for a given element. + * Some NumericalFunctor's are meaningful for elements of a certain + * geometry only. + */ +//================================================================================ + +bool NumericalFunctor::IsApplicable( const SMDS_MeshElement* element ) const +{ + return element && element->GetType() == this->GetType(); +} + +bool NumericalFunctor::IsApplicable( long theElementId ) const +{ + return IsApplicable( myMesh->FindElement( theElementId )); +} + //================================================================================ /*! * \brief Return histogram of functor values @@ -901,6 +919,11 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) return 0; } +bool AspectRatio::IsApplicable( const SMDS_MeshElement* element ) const +{ + return ( NumericalFunctor::IsApplicable( element ) && !element->IsPoly() ); +} + double AspectRatio::GetBadRate( double Value, int /*nbNodes*/ ) const { // the aspect ratio is in the range [1.0,infinity] @@ -1007,6 +1030,11 @@ double AspectRatio3D::GetValue( long theId ) return aVal; } +bool AspectRatio3D::IsApplicable( const SMDS_MeshElement* element ) const +{ + return ( NumericalFunctor::IsApplicable( element ) && !element->IsPoly() ); +} + double AspectRatio3D::GetValue( const TSequenceOfXYZ& P ) { double aQuality = 0.0; @@ -1015,11 +1043,11 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P ) int nbNodes = P.size(); if( myCurrElement->IsQuadratic() ) { - if(nbNodes==10) nbNodes=4; // quadratic tetrahedron + if (nbNodes==10) nbNodes=4; // quadratic tetrahedron else if(nbNodes==13) nbNodes=5; // quadratic pyramid else if(nbNodes==15) nbNodes=6; // quadratic pentahedron else if(nbNodes==20) nbNodes=8; // quadratic hexahedron - else if(nbNodes==27) nbNodes=8; // quadratic hexahedron + else if(nbNodes==27) nbNodes=8; // tri-quadratic hexahedron else return aQuality; } @@ -1296,6 +1324,11 @@ SMDSAbs_ElementType AspectRatio3D::GetType() const */ //================================================================================ +bool Warping::IsApplicable( const SMDS_MeshElement* element ) const +{ + return NumericalFunctor::IsApplicable( element ) && element->NbNodes() == 4; +} + double Warping::GetValue( const TSequenceOfXYZ& P ) { if ( P.size() != 4 ) @@ -1360,6 +1393,11 @@ SMDSAbs_ElementType Warping::GetType() const */ //================================================================================ +bool Taper::IsApplicable( const SMDS_MeshElement* element ) const +{ + return ( NumericalFunctor::IsApplicable( element ) && element->NbNodes() == 4 ); +} + double Taper::GetValue( const TSequenceOfXYZ& P ) { if ( P.size() != 4 ) @@ -1418,6 +1456,11 @@ static inline double skewAngle( const gp_XYZ& p1, const gp_XYZ& p2, const gp_XYZ return v1.Magnitude() < gp::Resolution() || v2.Magnitude() < gp::Resolution() ? 0. : v1.Angle( v2 ); } +bool Skew::IsApplicable( const SMDS_MeshElement* element ) const +{ + return ( NumericalFunctor::IsApplicable( element ) && element->NbNodes() <= 4 ); +} + double Skew::GetValue( const TSequenceOfXYZ& P ) { if ( P.size() != 3 && P.size() != 4 ) @@ -1532,13 +1575,36 @@ SMDSAbs_ElementType Length::GetType() const return SMDSAbs_Edge; } +//================================================================================ +/* + Class : Length3D + Description : Functor for calculating minimal length of element edge +*/ +//================================================================================ + +Length3D::Length3D(): + Length2D ( SMDSAbs_Volume ) +{ +} + //================================================================================ /* Class : Length2D - Description : Functor for calculating minimal length of edge + Description : Functor for calculating minimal length of element edge */ //================================================================================ +Length2D::Length2D( SMDSAbs_ElementType type ): + myType ( type ) +{ +} + +bool Length2D::IsApplicable( const SMDS_MeshElement* element ) const +{ + return ( NumericalFunctor::IsApplicable( element ) && + element->GetEntityType() != SMDSEntity_Polyhedra ); +} + double Length2D::GetValue( const TSequenceOfXYZ& P ) { double aVal = 0; @@ -1783,7 +1849,7 @@ double Length2D::GetBadRate( double Value, int /*nbNodes*/ ) const SMDSAbs_ElementType Length2D::GetType() const { - return SMDSAbs_Face; + return myType; } Length2D::Value::Value(double theLength,long thePntId1, long thePntId2): @@ -1805,90 +1871,96 @@ bool Length2D::Value::operator<(const Length2D::Value& x) const void Length2D::GetValues(TValues& theValues) { - TValues aValues; - for ( SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); anIter->more(); ) + if ( myType == SMDSAbs_Face ) { - const SMDS_MeshFace* anElem = anIter->next(); - if ( anElem->IsQuadratic() ) + for ( SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); anIter->more(); ) { - // use special nodes iterator - SMDS_NodeIteratorPtr anIter = anElem->interlacedNodesIterator(); - long aNodeId[4] = { 0,0,0,0 }; - gp_Pnt P[4]; - - double aLength = 0; - if ( anIter->more() ) - { - const SMDS_MeshNode* aNode = anIter->next(); - P[0] = P[1] = SMESH_NodeXYZ( aNode ); - aNodeId[0] = aNodeId[1] = aNode->GetID(); - aLength = 0; - } - for ( ; anIter->more(); ) + const SMDS_MeshFace* anElem = anIter->next(); + if ( anElem->IsQuadratic() ) { - const SMDS_MeshNode* N1 = anIter->next(); - P[2] = SMESH_NodeXYZ( N1 ); - aNodeId[2] = N1->GetID(); - aLength = P[1].Distance(P[2]); - if(!anIter->more()) break; - const SMDS_MeshNode* N2 = anIter->next(); - P[3] = SMESH_NodeXYZ( N2 ); - aNodeId[3] = N2->GetID(); - aLength += P[2].Distance(P[3]); + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = anElem->interlacedNodesIterator(); + long aNodeId[4] = { 0,0,0,0 }; + gp_Pnt P[4]; + + double aLength = 0; + if ( anIter->more() ) + { + const SMDS_MeshNode* aNode = anIter->next(); + P[0] = P[1] = SMESH_NodeXYZ( aNode ); + aNodeId[0] = aNodeId[1] = aNode->GetID(); + aLength = 0; + } + for ( ; anIter->more(); ) + { + const SMDS_MeshNode* N1 = anIter->next(); + P[2] = SMESH_NodeXYZ( N1 ); + aNodeId[2] = N1->GetID(); + aLength = P[1].Distance(P[2]); + if(!anIter->more()) break; + const SMDS_MeshNode* N2 = anIter->next(); + P[3] = SMESH_NodeXYZ( N2 ); + aNodeId[3] = N2->GetID(); + aLength += P[2].Distance(P[3]); + Value aValue1(aLength,aNodeId[1],aNodeId[2]); + Value aValue2(aLength,aNodeId[2],aNodeId[3]); + P[1] = P[3]; + aNodeId[1] = aNodeId[3]; + theValues.insert(aValue1); + theValues.insert(aValue2); + } + aLength += P[2].Distance(P[0]); Value aValue1(aLength,aNodeId[1],aNodeId[2]); - Value aValue2(aLength,aNodeId[2],aNodeId[3]); - P[1] = P[3]; - aNodeId[1] = aNodeId[3]; + Value aValue2(aLength,aNodeId[2],aNodeId[0]); theValues.insert(aValue1); theValues.insert(aValue2); } - aLength += P[2].Distance(P[0]); - Value aValue1(aLength,aNodeId[1],aNodeId[2]); - Value aValue2(aLength,aNodeId[2],aNodeId[0]); - theValues.insert(aValue1); - theValues.insert(aValue2); - } - else { - SMDS_NodeIteratorPtr aNodesIter = anElem->nodeIterator(); - long aNodeId[2] = {0,0}; - gp_Pnt P[3]; + else { + SMDS_NodeIteratorPtr aNodesIter = anElem->nodeIterator(); + long aNodeId[2] = {0,0}; + gp_Pnt P[3]; + + double aLength; + const SMDS_MeshElement* aNode; + if ( aNodesIter->more()) + { + aNode = aNodesIter->next(); + P[0] = P[1] = SMESH_NodeXYZ( aNode ); + aNodeId[0] = aNodeId[1] = aNode->GetID(); + aLength = 0; + } + for( ; aNodesIter->more(); ) + { + aNode = aNodesIter->next(); + long anId = aNode->GetID(); - double aLength; - const SMDS_MeshElement* aNode; - if ( aNodesIter->more()) - { - aNode = aNodesIter->next(); - P[0] = P[1] = SMESH_NodeXYZ( aNode ); - aNodeId[0] = aNodeId[1] = aNode->GetID(); - aLength = 0; - } - for( ; aNodesIter->more(); ) - { - aNode = aNodesIter->next(); - long anId = aNode->GetID(); + P[2] = SMESH_NodeXYZ( aNode ); - P[2] = SMESH_NodeXYZ( aNode ); + aLength = P[1].Distance(P[2]); - aLength = P[1].Distance(P[2]); + Value aValue(aLength,aNodeId[1],anId); + aNodeId[1] = anId; + P[1] = P[2]; + theValues.insert(aValue); + } - Value aValue(aLength,aNodeId[1],anId); - aNodeId[1] = anId; - P[1] = P[2]; + aLength = P[0].Distance(P[1]); + + Value aValue(aLength,aNodeId[0],aNodeId[1]); theValues.insert(aValue); } - - aLength = P[0].Distance(P[1]); - - Value aValue(aLength,aNodeId[0],aNodeId[1]); - theValues.insert(aValue); } } + else + { + // not implemented + } } //================================================================================ /* Class : Deflection2D - Description : Functor for calculating number of faces conneted to the edge + Description : computes distance between a face center and an underlying surface */ //================================================================================ @@ -3043,7 +3115,7 @@ bool ConnectedElements::IsSatisfy( long theElementId ) { // keep elements of myType const SMDS_MeshElement* element = eIt->next(); - if ( element->GetType() == myType ) + if ( myType == SMDSAbs_All || element->GetType() == myType ) myOkIDs.insert( myOkIDs.end(), element->GetID() ); // enqueue nodes of the element @@ -3589,9 +3661,10 @@ void Filter::SetPredicate( PredicatePtr thePredicate ) myPredicate = thePredicate; } -void Filter::GetElementsId( const SMDS_Mesh* theMesh, - PredicatePtr thePredicate, - TIdSequence& theSequence ) +void Filter::GetElementsId( const SMDS_Mesh* theMesh, + PredicatePtr thePredicate, + TIdSequence& theSequence, + SMDS_ElemIteratorPtr theElements ) { theSequence.clear(); @@ -3600,21 +3673,28 @@ void Filter::GetElementsId( const SMDS_Mesh* theMesh, thePredicate->SetMesh( theMesh ); - SMDS_ElemIteratorPtr elemIt = theMesh->elementsIterator( thePredicate->GetType() ); - if ( elemIt ) { - while ( elemIt->more() ) { - const SMDS_MeshElement* anElem = elemIt->next(); - long anId = anElem->GetID(); - if ( thePredicate->IsSatisfy( anId ) ) - theSequence.push_back( anId ); + if ( !theElements ) + theElements = theMesh->elementsIterator( thePredicate->GetType() ); + + if ( theElements ) { + while ( theElements->more() ) { + const SMDS_MeshElement* anElem = theElements->next(); + if ( thePredicate->GetType() == SMDSAbs_All || + thePredicate->GetType() == anElem->GetType() ) + { + long anId = anElem->GetID(); + if ( thePredicate->IsSatisfy( anId ) ) + theSequence.push_back( anId ); + } } } } void Filter::GetElementsId( const SMDS_Mesh* theMesh, - Filter::TIdSequence& theSequence ) + Filter::TIdSequence& theSequence, + SMDS_ElemIteratorPtr theElements ) { - GetElementsId(theMesh,myPredicate,theSequence); + GetElementsId(theMesh,myPredicate,theSequence,theElements); } /* @@ -4042,8 +4122,10 @@ SMDSAbs_ElementType ElementsOnSurface::GetType() const void ElementsOnSurface::SetTolerance( const double theToler ) { if ( myToler != theToler ) - myIds.Clear(); - myToler = theToler; + { + myToler = theToler; + process(); + } } double ElementsOnSurface::GetTolerance() const @@ -4160,6 +4242,7 @@ struct ElementsOnShape::Classifier TopAbs_ShapeEnum ShapeType() const { return myShape.ShapeType(); } const TopoDS_Shape& Shape() const { return myShape; } const Bnd_B3d* GetBndBox() const { return & myBox; } + double Tolerance() const { return myTol; } bool IsChecked() { return myFlags & theIsCheckedFlag; } bool IsSetFlag( int flag ) const { return myFlags & flag; } void SetChecked( bool is ) { is ? SetFlag( theIsCheckedFlag ) : UnsetFlag( theIsCheckedFlag ); } @@ -4376,10 +4459,9 @@ bool ElementsOnShape::IsSatisfy (const SMDS_MeshElement* elem) myOctree = new OctreeClassifier( myWorkClassifiers ); } - SMDS_ElemIteratorPtr aNodeItr = elem->nodesIterator(); - while (aNodeItr->more() && (isSatisfy == myAllNodesFlag)) + for ( int i = 0, nb = elem->NbNodes(); i < nb && (isSatisfy == myAllNodesFlag); ++i ) { - SMESH_TNodeXYZ aPnt( aNodeItr->next() ); + SMESH_TNodeXYZ aPnt( elem->GetNode( i )); centerXYZ += aPnt; isNodeOut = true; @@ -4734,7 +4816,8 @@ void ElementsOnShape::OctreeClassifier::buildChildrenData() for ( int i = 0; i < nbChildren(); i++ ) { OctreeClassifier* child = static_cast( myChildren[ i ]); - child->myIsLeaf = ( child->myClassifiers.size() <= 5 ); + child->myIsLeaf = ( child->myClassifiers.size() <= 5 || + child->maxSize() < child->myClassifiers[0]->Tolerance() ); } } @@ -4869,7 +4952,7 @@ bool BelongToGeom::IsSatisfy (long theId) { if ( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId )) { - if ( anElem->GetType() == myType ) + if ( myType == SMDSAbs_All || anElem->GetType() == myType ) { if ( anElem->getshapeId() < 1 ) return myElementsOnShapePtr->IsSatisfy(theId); @@ -5009,7 +5092,8 @@ bool LyingOnGeom::IsSatisfy( long theId ) if ( mySubShapesIDs.Contains( elem->getshapeId() )) return true; - if ( elem->GetType() != SMDSAbs_Node && elem->GetType() == myType ) + if (( elem->GetType() != SMDSAbs_Node ) && + ( myType == SMDSAbs_All || elem->GetType() == myType )) { SMDS_ElemIteratorPtr nodeItr = elem->nodesIterator(); while ( nodeItr->more() )