X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FControls%2FSMESH_Controls.cxx;h=3dd59cf5dadbdf63cc4afdab916c7009b4387666;hb=59f97a60c591ba0125c2e0590767e6aadd3160ee;hp=a0dd64e13ae626726bd21a96ff33e58a4c82cf7b;hpb=e4737e85f0da6d3f90fd08f6be1c2825195fe16f;p=modules%2Fsmesh.git diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index a0dd64e13..3dd59cf5d 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -17,7 +17,7 @@ // // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org -#include "SMESH_Controls.hxx" +#include "SMESH_ControlsDef.hxx" #include @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -46,80 +45,82 @@ #include "SMDS_Iterator.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" - +#include "SMDS_VolumeTool.hxx" /* AUXILIARY METHODS */ -static inline double getAngle( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) -{ - gp_Vec v1( P1 - P2 ), v2( P3 - P2 ); - - return v1.Magnitude() < gp::Resolution() || - v2.Magnitude() < gp::Resolution() ? 0 : v1.Angle( v2 ); -} - -static inline double getArea( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) -{ - gp_Vec aVec1( P2 - P1 ); - gp_Vec aVec2( P3 - P1 ); - return ( aVec1 ^ aVec2 ).Magnitude() * 0.5; -} - -static inline double getArea( const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3 ) -{ - return getArea( P1.XYZ(), P2.XYZ(), P3.XYZ() ); -} +namespace{ + inline double getAngle( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) + { + gp_Vec v1( P1 - P2 ), v2( P3 - P2 ); + + return v1.Magnitude() < gp::Resolution() || + v2.Magnitude() < gp::Resolution() ? 0 : v1.Angle( v2 ); + } -static inline double getDistance( const gp_XYZ& P1, const gp_XYZ& P2 ) -{ - double aDist = gp_Pnt( P1 ).Distance( gp_Pnt( P2 ) ); - return aDist; -} + inline double getArea( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) + { + gp_Vec aVec1( P2 - P1 ); + gp_Vec aVec2( P3 - P1 ); + return ( aVec1 ^ aVec2 ).Magnitude() * 0.5; + } -static int getNbMultiConnection( SMDS_Mesh* theMesh, const int theId ) -{ - if ( theMesh == 0 ) - return 0; + inline double getArea( const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3 ) + { + return getArea( P1.XYZ(), P2.XYZ(), P3.XYZ() ); + } - const SMDS_MeshElement* anEdge = theMesh->FindElement( theId ); - if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge || anEdge->NbNodes() != 2 ) - return 0; - TColStd_MapOfInteger aMap; - int aResult = 0; - SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator(); - if ( anIter != 0 ) + inline double getDistance( const gp_XYZ& P1, const gp_XYZ& P2 ) { - while( anIter->more() ) - { - const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); - if ( aNode == 0 ) - return 0; - SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); - while( anElemIter->more() ) - { - const SMDS_MeshElement* anElem = anElemIter->next(); - if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) - { - int anId = anElem->GetID(); + double aDist = gp_Pnt( P1 ).Distance( gp_Pnt( P2 ) ); + return aDist; + } - if ( anIter->more() ) // i.e. first node - aMap.Add( anId ); - else if ( aMap.Contains( anId ) ) - aResult++; - } + int getNbMultiConnection( const SMDS_Mesh* theMesh, const int theId ) + { + if ( theMesh == 0 ) + return 0; + + const SMDS_MeshElement* anEdge = theMesh->FindElement( theId ); + if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge || anEdge->NbNodes() != 2 ) + return 0; + + TColStd_MapOfInteger aMap; + + int aResult = 0; + SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator(); + if ( anIter != 0 ) { + while( anIter->more() ) { + const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); + if ( aNode == 0 ) + return 0; + SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); + while( anElemIter->more() ) { + const SMDS_MeshElement* anElem = anElemIter->next(); + if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) { + int anId = anElem->GetID(); + + if ( anIter->more() ) // i.e. first node + aMap.Add( anId ); + else if ( aMap.Contains( anId ) ) + aResult++; + } + } } } + + return aResult; } - return aResult; } + using namespace SMESH::Controls; /* @@ -136,15 +137,15 @@ NumericalFunctor::NumericalFunctor(): myPrecision = -1; } -void NumericalFunctor::SetMesh( SMDS_Mesh* theMesh ) +void NumericalFunctor::SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; } -bool NumericalFunctor::GetPoints(const int theId, - TColgp_SequenceOfXYZ& theRes ) const +bool NumericalFunctor::GetPoints(const int theId, + TSequenceOfXYZ& theRes ) const { - theRes.Clear(); + theRes.clear(); if ( myMesh == 0 ) return false; @@ -153,9 +154,9 @@ bool NumericalFunctor::GetPoints(const int theId, } bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem, - TColgp_SequenceOfXYZ& theRes ) + TSequenceOfXYZ& theRes ) { - theRes.Clear(); + theRes.clear(); if ( anElem == 0) return false; @@ -167,8 +168,9 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem, while( anIter->more() ) { const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); - if ( aNode != 0 ) - theRes.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) ); + if ( aNode != 0 ){ + theRes.push_back( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) ); + } } } @@ -187,7 +189,7 @@ void NumericalFunctor::SetPrecision( const long thePrecision ) double NumericalFunctor::GetValue( long theId ) { - TColgp_SequenceOfXYZ P; + TSequenceOfXYZ P; if ( GetPoints( theId, P )) { double aVal = GetValue( P ); @@ -196,7 +198,6 @@ double NumericalFunctor::GetValue( long theId ) double prec = pow( 10., (double)( myPrecision ) ); aVal = floor( aVal * prec + 0.5 ) / prec; } - return aVal; } @@ -208,30 +209,21 @@ double NumericalFunctor::GetValue( long theId ) Description : Functor for calculation of minimum angle */ -double MinimumAngle::GetValue( const TColgp_SequenceOfXYZ& P ) +double MinimumAngle::GetValue( const TSequenceOfXYZ& P ) { double aMin; - if ( P.Length() == 3 ) - { - double A0 = getAngle( P( 3 ), P( 1 ), P( 2 ) ); - double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) ); - double A2 = getAngle( P( 2 ), P( 3 ), P( 1 ) ); - - aMin = Min( A0, Min( A1, A2 ) ); - } - else if ( P.Length() == 4 ) - { - double A0 = getAngle( P( 4 ), P( 1 ), P( 2 ) ); - double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) ); - double A2 = getAngle( P( 2 ), P( 3 ), P( 4 ) ); - double A3 = getAngle( P( 3 ), P( 4 ), P( 1 ) ); - - aMin = Min( Min( A0, A1 ), Min( A2, A3 ) ); - } - else + if (P.size() <3) return 0.; + + aMin = getAngle(P( P.size() ), P( 1 ), P( 2 )); + aMin = Min(aMin,getAngle(P( P.size()-1 ), P( P.size() ), P( 1 ))); + for (int i=2; i 3) + aArea = getArea( P( 1 ), P( 2 ), P( 3 ) ); else return 0; + + for (int i=4; i<=P.size(); i++) + aArea += getArea(P(1),P(i-1),P(i)); + return aArea; } double Area::GetBadRate( double Value, int /*nbNodes*/ ) const @@ -587,9 +790,9 @@ SMDSAbs_ElementType Area::GetType() const Class : Length Description : Functor for calculating length off edge */ -double Length::GetValue( const TColgp_SequenceOfXYZ& P ) +double Length::GetValue( const TSequenceOfXYZ& P ) { - return ( P.Length() == 2 ? getDistance( P( 1 ), P( 2 ) ) : 0 ); + return ( P.size() == 2 ? getDistance( P( 1 ), P( 2 ) ) : 0 ); } double Length::GetBadRate( double Value, int /*nbNodes*/ ) const @@ -602,12 +805,198 @@ SMDSAbs_ElementType Length::GetType() const return SMDSAbs_Edge; } +/* + Class : Length2D + Description : Functor for calculating length of edge +*/ + +double Length2D::GetValue( long theElementId) +{ + TSequenceOfXYZ P; + + if (GetPoints(theElementId,P)){ + + double aVal;// = GetValue( P ); + const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId ); + SMDSAbs_ElementType aType = aElem->GetType(); + + int len = P.size(); + + switch (aType){ + case SMDSAbs_All: + case SMDSAbs_Node: + case SMDSAbs_Edge: + if (len == 2){ + aVal = getDistance( P( 1 ), P( 2 ) ); + break; + } + case SMDSAbs_Face: + if (len == 3){ // triangles + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + aVal = Max(L1,Max(L2,L3)); + break; + } + else if (len == 4){ // quadrangles + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 1 )); + aVal = Max(Max(L1,L2),Max(L3,L4)); + break; + } + case SMDSAbs_Volume: + if (len == 4){ // tetraidrs + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + double L4 = getDistance(P( 1 ),P( 4 )); + double L5 = getDistance(P( 2 ),P( 4 )); + double L6 = getDistance(P( 3 ),P( 4 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); + break; + } + else if (len == 5){ // piramids + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + double L4 = getDistance(P( 4 ),P( 1 )); + double L5 = getDistance(P( 1 ),P( 5 )); + double L6 = getDistance(P( 2 ),P( 5 )); + double L7 = getDistance(P( 3 ),P( 5 )); + double L8 = getDistance(P( 4 ),P( 5 )); + + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); + aVal = Max(aVal,Max(L7,L8)); + break; + } + else if (len == 6){ // pentaidres + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + double L4 = getDistance(P( 4 ),P( 5 )); + double L5 = getDistance(P( 5 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 4 )); + double L7 = getDistance(P( 1 ),P( 4 )); + double L8 = getDistance(P( 2 ),P( 5 )); + double L9 = getDistance(P( 3 ),P( 6 )); + + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); + aVal = Max(aVal,Max(Max(L7,L8),L9)); + break; + } + else if (len == 8){ // hexaider + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 1 )); + double L5 = getDistance(P( 5 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 7 )); + double L7 = getDistance(P( 7 ),P( 8 )); + double L8 = getDistance(P( 8 ),P( 5 )); + double L9 = getDistance(P( 1 ),P( 5 )); + double L10= getDistance(P( 2 ),P( 6 )); + double L11= getDistance(P( 3 ),P( 7 )); + double L12= getDistance(P( 4 ),P( 8 )); + + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); + aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10))); + aVal = Max(aVal,Max(L11,L12)); + break; + + } + + default: aVal=-1; + } + + if (aVal <0){ + return 0.; + } + + if ( myPrecision >= 0 ) + { + double prec = pow( 10., (double)( myPrecision ) ); + aVal = floor( aVal * prec + 0.5 ) / prec; + } + + return aVal; + + } + return 0.; +} + +double Length2D::GetBadRate( double Value, int /*nbNodes*/ ) const +{ + return Value; +} + +SMDSAbs_ElementType Length2D::GetType() const +{ + return SMDSAbs_Face; +} + +Length2D::Value::Value(double theLength,long thePntId1, long thePntId2): + myLength(theLength) +{ + myPntId[0] = thePntId1; myPntId[1] = thePntId2; + if(thePntId1 > thePntId2){ + myPntId[1] = thePntId1; myPntId[0] = thePntId2; + } +} + +bool Length2D::Value::operator<(const Length2D::Value& x) const{ + if(myPntId[0] < x.myPntId[0]) return true; + if(myPntId[0] == x.myPntId[0]) + if(myPntId[1] < x.myPntId[1]) return true; + return false; +} + +void Length2D::GetValues(TValues& theValues){ + TValues aValues; + SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); + for(; anIter->more(); ){ + const SMDS_MeshFace* anElem = anIter->next(); + SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator(); + long aNodeId[2]; + gp_Pnt P[3]; + + double aLength; + const SMDS_MeshElement* aNode; + if(aNodesIter->more()){ + aNode = aNodesIter->next(); + const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode; + P[0] = P[1] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z()); + aNodeId[0] = aNodeId[1] = aNode->GetID(); + aLength = 0; + } + for(; aNodesIter->more(); ){ + aNode = aNodesIter->next(); + const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode; + long anId = aNode->GetID(); + + P[2] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z()); + + aLength = P[1].Distance(P[2]); + + Value aValue(aLength,aNodeId[1],anId); + aNodeId[1] = anId; + P[1] = P[2]; + theValues.insert(aValue); + } + + aLength = P[0].Distance(P[1]); + + Value aValue(aLength,aNodeId[0],aNodeId[1]); + theValues.insert(aValue); + } +} /* Class : MultiConnection Description : Functor for calculating number of faces conneted to the edge */ -double MultiConnection::GetValue( const TColgp_SequenceOfXYZ& P ) +double MultiConnection::GetValue( const TSequenceOfXYZ& P ) { return 0; } @@ -626,11 +1015,182 @@ 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; +} + +double MultiConnection2D::GetValue( long theElementId ) +{ + TSequenceOfXYZ P; + int aResult = 0; + + if (GetPoints(theElementId,P)){ + const SMDS_MeshElement* anFaceElem = myMesh->FindElement( theElementId ); + SMDSAbs_ElementType aType = anFaceElem->GetType(); + + int len = P.size(); + + TColStd_MapOfInteger aMap; + int aResult = 0; + + switch (aType){ + case SMDSAbs_All: + case SMDSAbs_Node: + case SMDSAbs_Edge: + case SMDSAbs_Face: + if (len == 3){ // triangles + int Nb[3] = {0,0,0}; + + int i=0; + SMDS_ElemIteratorPtr anIter = anFaceElem->nodesIterator(); + if ( anIter != 0 ) { + while( anIter->more() ) { + const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); + if ( aNode == 0 ){ + break; + } + SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); + while( anElemIter->more() ) { + const SMDS_MeshElement* anElem = anElemIter->next(); + if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) { + int anId = anElem->GetID(); + + if ( anIter->more() ) // i.e. first node + aMap.Add( anId ); + else if ( aMap.Contains( anId ) ){ + Nb[i]++; + } + } + else if ( anElem != 0 && anElem->GetType() == SMDSAbs_Edge ) i++; + } + } + } + + aResult = Max(Max(Nb[0],Nb[1]),Nb[2]); + } + break; + case SMDSAbs_Volume: + default: aResult=0; + } + + } + return aResult;//getNbMultiConnection( myMesh, theId ); +} + +double MultiConnection2D::GetBadRate( double Value, int /*nbNodes*/ ) const +{ + return Value; +} + +SMDSAbs_ElementType MultiConnection2D::GetType() const +{ + return SMDSAbs_Face; +} + +MultiConnection2D::Value::Value(long thePntId1, long thePntId2) +{ + myPntId[0] = thePntId1; myPntId[1] = thePntId2; + if(thePntId1 > thePntId2){ + myPntId[1] = thePntId1; myPntId[0] = thePntId2; + } +} + +bool MultiConnection2D::Value::operator<(const MultiConnection2D::Value& x) const{ + if(myPntId[0] < x.myPntId[0]) return true; + if(myPntId[0] == x.myPntId[0]) + if(myPntId[1] < x.myPntId[1]) return true; + return false; +} + +void MultiConnection2D::GetValues(MValues& theValues){ + SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); + for(; anIter->more(); ){ + const SMDS_MeshFace* anElem = anIter->next(); + SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator(); + long aNodeId[3]; + + //int aNbConnects=0; + const SMDS_MeshNode* aNode0; + const SMDS_MeshNode* aNode1; + const SMDS_MeshNode* aNode2; + if(aNodesIter->more()){ + aNode0 = (SMDS_MeshNode*) aNodesIter->next(); + aNode1 = aNode0; + const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode1; + aNodeId[0] = aNodeId[1] = aNodes->GetID(); + } + for(; aNodesIter->more(); ){ + aNode2 = (SMDS_MeshNode*) aNodesIter->next(); + long anId = aNode2->GetID(); + aNodeId[2] = anId; + + Value aValue(aNodeId[1],aNodeId[2]); + MValues::iterator aItr = theValues.find(aValue); + if (aItr != theValues.end()){ + aItr->second += 1; + //aNbConnects = nb; + } else { + theValues[aValue] = 1; + //aNbConnects = 1; + } + //cout << "NodeIds: "<