X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FControls%2FSMESH_Controls.cxx;h=7686e655db6ba1215f01d19318b80dcf844a738a;hp=239aa41e4be9f406af25451bce4fb401b16db0d8;hb=cbfe948334a884ec727eaac7acf123846fcbf0ce;hpb=9a54694a0ab1e5cbc558a35c4606ceea4f7af2ef diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 239aa41e4..7686e655d 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 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 @@ -18,6 +18,7 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include "SMESH_ControlsDef.hxx" @@ -32,6 +33,7 @@ #include "SMESHDS_GroupBase.hxx" #include "SMESHDS_Mesh.hxx" #include "SMESH_OctreeNode.hxx" +#include "SMESH_MeshAlgos.hxx" #include #include @@ -64,6 +66,7 @@ #include #include +#include /* AUXILIARY METHODS @@ -210,10 +213,13 @@ using namespace SMESH::Controls; * FUNCTORS */ +//================================================================================ /* Class : NumericalFunctor Description : Base class for numerical functors */ +//================================================================================ + NumericalFunctor::NumericalFunctor(): myMesh(NULL) { @@ -321,6 +327,7 @@ double NumericalFunctor::Round( const double & aVal ) * \param minmax - boundaries of diapason of values to divide into intervals */ //================================================================================ + void NumericalFunctor::GetHistogram(int nbIntervals, std::vector& nbEvents, std::vector& funValues, @@ -403,9 +410,11 @@ void NumericalFunctor::GetHistogram(int nbIntervals, } //======================================================================= -//function : GetValue -//purpose : -//======================================================================= +/* + Class : Volume + Description : Functor calculating volume of a 3D element +*/ +//================================================================================ double Volume::GetValue( long theElementId ) { @@ -417,21 +426,11 @@ double Volume::GetValue( long theElementId ) return 0; } -//======================================================================= -//function : GetBadRate -//purpose : meaningless as it is not quality control functor -//======================================================================= - double Volume::GetBadRate( double Value, int /*nbNodes*/ ) const { return Value; } -//======================================================================= -//function : GetType -//purpose : -//======================================================================= - SMDSAbs_ElementType Volume::GetType() const { return SMDSAbs_Volume; @@ -442,6 +441,8 @@ SMDSAbs_ElementType Volume::GetType() const Class : MaxElementLength2D Description : Functor calculating maximum length of 2D element */ +//================================================================================ + double MaxElementLength2D::GetValue( const TSequenceOfXYZ& P ) { if(P.size() == 0) @@ -508,6 +509,7 @@ SMDSAbs_ElementType MaxElementLength2D::GetType() const Class : MaxElementLength3D Description : Functor calculating maximum length of 3D element */ +//================================================================================ double MaxElementLength3D::GetValue( long theElementId ) { @@ -683,6 +685,7 @@ SMDSAbs_ElementType MaxElementLength3D::GetType() const Class : MinimumAngle Description : Functor for calculation of minimum angle */ +//================================================================================ double MinimumAngle::GetValue( const TSequenceOfXYZ& P ) { @@ -715,10 +718,13 @@ SMDSAbs_ElementType MinimumAngle::GetType() const } +//================================================================================ /* Class : AspectRatio Description : Functor for calculating aspect ratio */ +//================================================================================ + double AspectRatio::GetValue( long theId ) { double aVal = 0; @@ -899,10 +905,13 @@ SMDSAbs_ElementType AspectRatio::GetType() const } +//================================================================================ /* Class : AspectRatio3D Description : Functor for calculating aspect ratio */ +//================================================================================ + namespace{ inline double getHalfPerimeter(double theTria[3]){ @@ -1269,10 +1278,13 @@ SMDSAbs_ElementType AspectRatio3D::GetType() const } +//================================================================================ /* Class : Warping Description : Functor for calculating warping */ +//================================================================================ + double Warping::GetValue( const TSequenceOfXYZ& P ) { if ( P.size() != 4 ) @@ -1285,7 +1297,11 @@ double Warping::GetValue( const TSequenceOfXYZ& P ) double A3 = ComputeA( P( 3 ), P( 4 ), P( 1 ), G ); double A4 = ComputeA( P( 4 ), P( 1 ), P( 2 ), G ); - return Max( Max( A1, A2 ), Max( A3, A4 ) ); + double val = Max( Max( A1, A2 ), Max( A3, A4 ) ); + + const double eps = 0.1; // val is in degrees + + return val < eps ? 0. : val; } double Warping::ComputeA( const gp_XYZ& thePnt1, @@ -1326,10 +1342,13 @@ SMDSAbs_ElementType Warping::GetType() const } +//================================================================================ /* Class : Taper Description : Functor for calculating taper */ +//================================================================================ + double Taper::GetValue( const TSequenceOfXYZ& P ) { if ( P.size() != 4 ) @@ -1350,7 +1369,11 @@ double Taper::GetValue( const TSequenceOfXYZ& P ) double T3 = fabs( ( J3 - JA ) / JA ); double T4 = fabs( ( J4 - JA ) / JA ); - return Max( Max( T1, T2 ), Max( T3, T4 ) ); + double val = Max( Max( T1, T2 ), Max( T3, T4 ) ); + + const double eps = 0.01; + + return val < eps ? 0. : val; } double Taper::GetBadRate( double Value, int /*nbNodes*/ ) const @@ -1366,11 +1389,13 @@ SMDSAbs_ElementType Taper::GetType() const return SMDSAbs_Face; } - +//================================================================================ /* Class : Skew Description : Functor for calculating skew in degrees */ +//================================================================================ + static inline double skewAngle( const gp_XYZ& p1, const gp_XYZ& p2, const gp_XYZ& p3 ) { gp_XYZ p12 = ( p2 + p1 ) / 2.; @@ -1388,7 +1413,7 @@ double Skew::GetValue( const TSequenceOfXYZ& P ) return 0.; // Compute skew - static double PI2 = M_PI / 2.; + const double PI2 = M_PI / 2.; if ( P.size() == 3 ) { double A0 = fabs( PI2 - skewAngle( P( 3 ), P( 1 ), P( 2 ) ) ); @@ -1408,11 +1433,11 @@ double Skew::GetValue( const TSequenceOfXYZ& P ) double A = v1.Magnitude() <= gp::Resolution() || v2.Magnitude() <= gp::Resolution() ? 0. : fabs( PI2 - v1.Angle( v2 ) ); - //BUG SWP12743 - if ( A < theEps ) - return theInf; + double val = A * 180. / M_PI; - return A * 180. / M_PI; + const double eps = 0.1; // val is in degrees + + return val < eps ? 0. : val; } } @@ -1430,10 +1455,13 @@ SMDSAbs_ElementType Skew::GetType() const } +//================================================================================ /* Class : Area Description : Functor for calculating area */ +//================================================================================ + double Area::GetValue( const TSequenceOfXYZ& P ) { double val = 0.0; @@ -1463,11 +1491,13 @@ SMDSAbs_ElementType Area::GetType() const return SMDSAbs_Face; } - +//================================================================================ /* Class : Length Description : Functor for calculating length of edge */ +//================================================================================ + double Length::GetValue( const TSequenceOfXYZ& P ) { switch ( P.size() ) { @@ -1488,10 +1518,12 @@ SMDSAbs_ElementType Length::GetType() const return SMDSAbs_Edge; } +//================================================================================ /* Class : Length2D Description : Functor for calculating length of edge */ +//================================================================================ double Length2D::GetValue( long theElementId) { @@ -1799,10 +1831,13 @@ void Length2D::GetValues(TValues& theValues){ } } +//================================================================================ /* Class : MultiConnection Description : Functor for calculating number of faces conneted to the edge */ +//================================================================================ + double MultiConnection::GetValue( const TSequenceOfXYZ& P ) { return 0; @@ -1823,10 +1858,13 @@ SMDSAbs_ElementType MultiConnection::GetType() const return SMDSAbs_Edge; } +//================================================================================ /* Class : MultiConnection2D Description : Functor for calculating number of faces conneted to the edge */ +//================================================================================ + double MultiConnection2D::GetValue( const TSequenceOfXYZ& P ) { return 0; @@ -1970,10 +2008,13 @@ void MultiConnection2D::GetValues(MValues& theValues){ } +//================================================================================ /* Class : BallDiameter Description : Functor returning diameter of a ball element */ +//================================================================================ + double BallDiameter::GetValue( long theId ) { double diameter = 0; @@ -2002,10 +2043,12 @@ SMDSAbs_ElementType BallDiameter::GetType() const PREDICATES */ +//================================================================================ /* Class : BadOrientedVolume Description : Predicate bad oriented volumes */ +//================================================================================ BadOrientedVolume::BadOrientedVolume() { @@ -2052,9 +2095,11 @@ bool BareBorderVolume::IsSatisfy(long theElementId ) return false; } +//================================================================================ /* Class : BareBorderFace */ +//================================================================================ bool BareBorderFace::IsSatisfy(long theElementId ) { @@ -2092,9 +2137,11 @@ bool BareBorderFace::IsSatisfy(long theElementId ) return ok; } +//================================================================================ /* Class : OverConstrainedVolume */ +//================================================================================ bool OverConstrainedVolume::IsSatisfy(long theElementId ) { @@ -2112,9 +2159,11 @@ bool OverConstrainedVolume::IsSatisfy(long theElementId ) return false; } +//================================================================================ /* Class : OverConstrainedFace */ +//================================================================================ bool OverConstrainedFace::IsSatisfy(long theElementId ) { @@ -2145,10 +2194,12 @@ bool OverConstrainedFace::IsSatisfy(long theElementId ) return false; } +//================================================================================ /* Class : CoincidentNodes Description : Predicate of Coincident nodes */ +//================================================================================ CoincidentNodes::CoincidentNodes() { @@ -2190,11 +2241,13 @@ void CoincidentNodes::SetMesh( const SMDS_Mesh* theMesh ) } } +//================================================================================ /* Class : CoincidentElements Description : Predicate of Coincident Elements Note : This class is suitable only for visualization of Coincident Elements */ +//================================================================================ CoincidentElements::CoincidentElements() { @@ -2245,10 +2298,12 @@ SMDSAbs_ElementType CoincidentElements3D::GetType() const } +//================================================================================ /* Class : FreeBorders Description : Predicate for free borders */ +//================================================================================ FreeBorders::FreeBorders() { @@ -2271,10 +2326,13 @@ SMDSAbs_ElementType FreeBorders::GetType() const } +//================================================================================ /* Class : FreeEdges Description : Predicate for free Edges */ +//================================================================================ + FreeEdges::FreeEdges() { myMesh = 0; @@ -2406,11 +2464,12 @@ void FreeEdges::GetBoreders(TBorders& theBorders) } } - +//================================================================================ /* Class : FreeNodes Description : Predicate for free nodes */ +//================================================================================ FreeNodes::FreeNodes() { @@ -2437,10 +2496,12 @@ SMDSAbs_ElementType FreeNodes::GetType() const } +//================================================================================ /* Class : FreeFaces Description : Predicate for free faces */ +//================================================================================ FreeFaces::FreeFaces() { @@ -2493,10 +2554,12 @@ SMDSAbs_ElementType FreeFaces::GetType() const return SMDSAbs_Face; } +//================================================================================ /* Class : LinearOrQuadratic Description : Predicate to verify whether a mesh element is linear */ +//================================================================================ LinearOrQuadratic::LinearOrQuadratic() { @@ -2527,10 +2590,12 @@ SMDSAbs_ElementType LinearOrQuadratic::GetType() const return myType; } +//================================================================================ /* Class : GroupColor Description : Functor for check color of group to whic mesh element belongs to */ +//================================================================================ GroupColor::GroupColor() { @@ -2599,6 +2664,7 @@ void GroupColor::SetMesh( const SMDS_Mesh* theMesh ) void GroupColor::SetColorStr( const TCollection_AsciiString& theStr ) { + Kernel_Utils::Localizer loc; TCollection_AsciiString aStr = theStr; aStr.RemoveAll( ' ' ); aStr.RemoveAll( '\t' ); @@ -2619,6 +2685,7 @@ void GroupColor::SetColorStr( const TCollection_AsciiString& theStr ) // Purpose : Get range as a string. // Example: "1,2,3,50-60,63,67,70-" //======================================================================= + void GroupColor::GetColorStr( TCollection_AsciiString& theResStr ) const { theResStr.Clear(); @@ -2627,10 +2694,12 @@ void GroupColor::GetColorStr( TCollection_AsciiString& theResStr ) const theResStr += TCollection_AsciiString( ";" ) + TCollection_AsciiString( myColor.Blue() ); } +//================================================================================ /* Class : ElemGeomType Description : Predicate to check element geometry type */ +//================================================================================ ElemGeomType::ElemGeomType() { @@ -2677,6 +2746,197 @@ SMDSAbs_GeometryType ElemGeomType::GetGeomType() const return myGeomType; } +//================================================================================ +/* + Class : ElemEntityType + Description : Predicate to check element entity type +*/ +//================================================================================ + +ElemEntityType::ElemEntityType(): + myMesh( 0 ), + myType( SMDSAbs_All ), + myEntityType( SMDSEntity_0D ) +{ +} + +void ElemEntityType::SetMesh( const SMDS_Mesh* theMesh ) +{ + myMesh = theMesh; +} + +bool ElemEntityType::IsSatisfy( long theId ) +{ + if ( !myMesh ) return false; + if ( myType == SMDSAbs_Node ) + return myMesh->FindNode( theId ); + const SMDS_MeshElement* anElem = myMesh->FindElement( theId ); + return ( anElem && + myEntityType == anElem->GetEntityType() ); +} + +void ElemEntityType::SetType( SMDSAbs_ElementType theType ) +{ + myType = theType; +} + +SMDSAbs_ElementType ElemEntityType::GetType() const +{ + return myType; +} + +void ElemEntityType::SetElemEntityType( SMDSAbs_EntityType theEntityType ) +{ + myEntityType = theEntityType; +} + +SMDSAbs_EntityType ElemEntityType::GetElemEntityType() const +{ + return myEntityType; +} + +//================================================================================ +/*! + * \brief Class ConnectedElements + */ +//================================================================================ + +ConnectedElements::ConnectedElements(): + myNodeID(0), myType( SMDSAbs_All ), myOkIDsReady( false ) {} + +SMDSAbs_ElementType ConnectedElements::GetType() const +{ return myType; } + +int ConnectedElements::GetNode() const +{ return myXYZ.empty() ? myNodeID : 0; } // myNodeID can be found by myXYZ + +std::vector ConnectedElements::GetPoint() const +{ return myXYZ; } + +void ConnectedElements::clearOkIDs() +{ myOkIDsReady = false; myOkIDs.clear(); } + +void ConnectedElements::SetType( SMDSAbs_ElementType theType ) +{ + if ( myType != theType || myMeshModifTracer.IsMeshModified() ) + clearOkIDs(); + myType = theType; +} + +void ConnectedElements::SetMesh( const SMDS_Mesh* theMesh ) +{ + myMeshModifTracer.SetMesh( theMesh ); + if ( myMeshModifTracer.IsMeshModified() ) + { + clearOkIDs(); + if ( !myXYZ.empty() ) + SetPoint( myXYZ[0], myXYZ[1], myXYZ[2] ); // find a node near myXYZ it in a new mesh + } +} + +void ConnectedElements::SetNode( int nodeID ) +{ + myNodeID = nodeID; + myXYZ.clear(); + + bool isSameDomain = false; + if ( myOkIDsReady && myMeshModifTracer.GetMesh() && !myMeshModifTracer.IsMeshModified() ) + if ( const SMDS_MeshNode* n = myMeshModifTracer.GetMesh()->FindNode( myNodeID )) + { + SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator( myType ); + while ( !isSameDomain && eIt->more() ) + isSameDomain = IsSatisfy( eIt->next()->GetID() ); + } + if ( !isSameDomain ) + clearOkIDs(); +} + +void ConnectedElements::SetPoint( double x, double y, double z ) +{ + myXYZ.resize(3); + myXYZ[0] = x; + myXYZ[1] = y; + myXYZ[2] = z; + myNodeID = 0; + + bool isSameDomain = false; + + // find myNodeID by myXYZ if possible + if ( myMeshModifTracer.GetMesh() ) + { + auto_ptr searcher + ( SMESH_MeshAlgos::GetElementSearcher( (SMDS_Mesh&) *myMeshModifTracer.GetMesh() )); + + vector< const SMDS_MeshElement* > foundElems; + searcher->FindElementsByPoint( gp_Pnt(x,y,z), SMDSAbs_All, foundElems ); + + if ( !foundElems.empty() ) + { + myNodeID = foundElems[0]->GetNode(0)->GetID(); + if ( myOkIDsReady && !myMeshModifTracer.IsMeshModified() ) + isSameDomain = IsSatisfy( foundElems[0]->GetID() ); + } + } + if ( !isSameDomain ) + clearOkIDs(); +} + +bool ConnectedElements::IsSatisfy( long theElementId ) +{ + // Here we do NOT check if the mesh has changed, we do it in Set...() only!!! + + if ( !myOkIDsReady ) + { + if ( !myMeshModifTracer.GetMesh() ) + return false; + const SMDS_MeshNode* node0 = myMeshModifTracer.GetMesh()->FindNode( myNodeID ); + if ( !node0 ) + return false; + + list< const SMDS_MeshNode* > nodeQueue( 1, node0 ); + std::set< int > checkedNodeIDs; + // algo: + // foreach node in nodeQueue: + // foreach element sharing a node: + // add ID of an element of myType to myOkIDs; + // push all element nodes absent from checkedNodeIDs to nodeQueue; + while ( !nodeQueue.empty() ) + { + const SMDS_MeshNode* node = nodeQueue.front(); + nodeQueue.pop_front(); + + // loop on elements sharing the node + SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(); + while ( eIt->more() ) + { + // keep elements of myType + const SMDS_MeshElement* element = eIt->next(); + if ( element->GetType() == myType ) + myOkIDs.insert( myOkIDs.end(), element->GetID() ); + + // enqueue nodes of the element + SMDS_ElemIteratorPtr nIt = element->nodesIterator(); + while ( nIt->more() ) + { + const SMDS_MeshNode* n = static_cast< const SMDS_MeshNode* >( nIt->next() ); + if ( checkedNodeIDs.insert( n->GetID() ).second ) + nodeQueue.push_back( n ); + } + } + } + if ( myType == SMDSAbs_Node ) + std::swap( myOkIDs, checkedNodeIDs ); + + size_t totalNbElems = myMeshModifTracer.GetMesh()->GetMeshInfo().NbElements( myType ); + if ( myOkIDs.size() == totalNbElems ) + myOkIDs.clear(); + + myOkIDsReady = true; + } + + return myOkIDs.empty() ? true : myOkIDs.count( theElementId ); +} + //================================================================================ /*! * \brief Class CoplanarFaces