X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FControls%2FSMESH_Controls.cxx;h=ecd12a0b5d493ef48d1f6c28a1cc4a912620bc73;hb=6ca4db2d7c49474a93e30c02bef83f05b354e540;hp=aa1eb5eaadbb63f1bf1c4e13870256a25fd92380;hpb=05a257d4f4e64a05ba8bb953efd5a2f1846e3fe1;p=modules%2Fsmesh.git diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index aa1eb5eaa..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 @@ -28,8 +28,6 @@ #include "SMDS_Mesh.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" -#include "SMDS_QuadraticEdge.hxx" -#include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_GroupBase.hxx" #include "SMESHDS_GroupOnFilter.hxx" @@ -45,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -98,6 +97,15 @@ namespace { v2.Magnitude() < gp::Resolution() ? 0 : v1.Angle( v2 ); } + inline double getCos2( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) + { + gp_Vec v1( P1 - P2 ), v2( P3 - P2 ); + double dot = v1 * v2, len1 = v1.SquareMagnitude(), len2 = v2.SquareMagnitude(); + + return ( dot < 0 || len1 < gp::Resolution() || len2 < gp::Resolution() ? -1 : + dot * dot / len1 / len2 ); + } + inline double getArea( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) { gp_Vec aVec1( P2 - P1 ); @@ -225,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 ); @@ -243,26 +251,7 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem, theRes.setElement( anElem ); // Get nodes of the element - SMDS_ElemIteratorPtr anIter; - - if ( anElem->IsQuadratic() ) { - switch ( anElem->GetType() ) { - case SMDSAbs_Edge: - anIter = dynamic_cast - (anElem)->interlacedNodesElemIterator(); - break; - case SMDSAbs_Face: - anIter = dynamic_cast - (anElem)->interlacedNodesElemIterator(); - break; - default: - anIter = anElem->nodesIterator(); - } - } - else { - anIter = anElem->nodesIterator(); - } - + SMDS_NodeIteratorPtr anIter= anElem->interlacedNodesIterator(); if ( anIter ) { SMESH_NodeXYZ p; while( anIter->more() ) { @@ -303,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 @@ -713,21 +720,25 @@ SMDSAbs_ElementType MaxElementLength3D::GetType() const double MinimumAngle::GetValue( const TSequenceOfXYZ& P ) { - double aMin; - - if (P.size() <3) + 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 ))); + double aMaxCos2; + + aMaxCos2 = getCos2( P( P.size() ), P( 1 ), P( 2 )); + aMaxCos2 = Max( aMaxCos2, getCos2( P( P.size()-1 ), P( P.size() ), P( 1 ))); for ( size_t i = 2; i < P.size(); i++ ) { - double A0 = getAngle( P( i-1 ), P( i ), P( i+1 ) ); - aMin = Min(aMin,A0); + double A0 = getCos2( P( i-1 ), P( i ), P( i+1 ) ); + aMaxCos2 = Max( aMaxCos2, A0 ); } + if ( aMaxCos2 < 0 ) + return 0; // all nodes coincide - return aMin * 180.0 / M_PI; + double cos = sqrt( aMaxCos2 ); + if ( cos >= 1 ) return 0; + return acos( cos ) * 180.0 / M_PI; } double MinimumAngle::GetBadRate( double Value, int nbNodes ) const @@ -757,8 +768,8 @@ double AspectRatio::GetValue( long theId ) if ( myCurrElement && myCurrElement->GetVtkType() == VTK_QUAD ) { // issue 21723 - vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myCurrElement->getMeshId()]->getGrid(); - if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->getVtkId() )) + vtkUnstructuredGrid* grid = const_cast( myMesh )->GetGrid(); + if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->GetVtkID() )) aVal = Round( vtkMeshQuality::QuadAspectRatio( avtkCell )); } else @@ -786,58 +797,51 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) if ( nbNodes == 3 ) { // Compute lengths of the sides - std::vector< double > aLen (nbNodes); - for ( int i = 0; i < nbNodes - 1; i++ ) - aLen[ i ] = getDistance( P( i + 1 ), P( i + 2 ) ); - aLen[ nbNodes - 1 ] = getDistance( P( 1 ), P( nbNodes ) ); + double aLen1 = getDistance( P( 1 ), P( 2 )); + double aLen2 = getDistance( P( 2 ), P( 3 )); + double aLen3 = getDistance( P( 3 ), P( 1 )); // Q = alfa * h * p / S, where // // alfa = sqrt( 3 ) / 6 // h - length of the longest edge // p - half perimeter // S - triangle surface - const double alfa = sqrt( 3. ) / 6.; - double maxLen = Max( aLen[ 0 ], Max( aLen[ 1 ], aLen[ 2 ] ) ); - double half_perimeter = ( aLen[0] + aLen[1] + aLen[2] ) / 2.; - double anArea = getArea( P( 1 ), P( 2 ), P( 3 ) ); + const double alfa = sqrt( 3. ) / 6.; + double maxLen = Max( aLen1, Max( aLen2, aLen3 )); + double half_perimeter = ( aLen1 + aLen2 + aLen3 ) / 2.; + double anArea = getArea( P( 1 ), P( 2 ), P( 3 )); if ( anArea <= theEps ) return theInf; return alfa * maxLen * half_perimeter / anArea; } else if ( nbNodes == 6 ) { // quadratic triangles // Compute lengths of the sides - std::vector< double > aLen (3); - aLen[0] = getDistance( P(1), P(3) ); - aLen[1] = getDistance( P(3), P(5) ); - aLen[2] = getDistance( P(5), P(1) ); - // Q = alfa * h * p / S, where - // - // alfa = sqrt( 3 ) / 6 - // h - length of the longest edge - // p - half perimeter - // S - triangle surface - const double alfa = sqrt( 3. ) / 6.; - double maxLen = Max( aLen[ 0 ], Max( aLen[ 1 ], aLen[ 2 ] ) ); - double half_perimeter = ( aLen[0] + aLen[1] + aLen[2] ) / 2.; - double anArea = getArea( P(1), P(3), P(5) ); + double aLen1 = getDistance( P( 1 ), P( 3 )); + double aLen2 = getDistance( P( 3 ), P( 5 )); + double aLen3 = getDistance( P( 5 ), P( 1 )); + // algo same as for the linear triangle + const double alfa = sqrt( 3. ) / 6.; + double maxLen = Max( aLen1, Max( aLen2, aLen3 )); + double half_perimeter = ( aLen1 + aLen2 + aLen3 ) / 2.; + double anArea = getArea( P( 1 ), P( 3 ), P( 5 )); if ( anArea <= theEps ) return theInf; return alfa * maxLen * half_perimeter / anArea; } else if( nbNodes == 4 ) { // quadrangle // Compute lengths of the sides - std::vector< double > aLen (4); + double aLen[4]; aLen[0] = getDistance( P(1), P(2) ); aLen[1] = getDistance( P(2), P(3) ); aLen[2] = getDistance( P(3), P(4) ); aLen[3] = getDistance( P(4), P(1) ); // Compute lengths of the diagonals - std::vector< double > aDia (2); + double aDia[2]; aDia[0] = getDistance( P(1), P(3) ); aDia[1] = getDistance( P(2), P(4) ); // Compute areas of all triangles which can be built // taking three nodes of the quadrangle - std::vector< double > anArea (4); + double anArea[4]; anArea[0] = getArea( P(1), P(2), P(3) ); anArea[1] = getArea( P(1), P(2), P(4) ); anArea[2] = getArea( P(1), P(3), P(4) ); @@ -853,35 +857,35 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) // Si - areas of the triangles const double alpha = sqrt( 1 / 32. ); double L = Max( aLen[ 0 ], - Max( aLen[ 1 ], - Max( aLen[ 2 ], - Max( aLen[ 3 ], - Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) ); + Max( aLen[ 1 ], + Max( aLen[ 2 ], + Max( aLen[ 3 ], + Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) ); double C1 = sqrt( ( aLen[0] * aLen[0] + aLen[1] * aLen[1] + aLen[2] * aLen[2] + aLen[3] * aLen[3] ) / 4. ); double C2 = Min( anArea[ 0 ], - Min( anArea[ 1 ], - Min( anArea[ 2 ], anArea[ 3 ] ) ) ); + Min( anArea[ 1 ], + Min( anArea[ 2 ], anArea[ 3 ] ) ) ); if ( C2 <= theEps ) return theInf; return alpha * L * C1 / C2; } else if( nbNodes == 8 || nbNodes == 9 ) { // nbNodes==8 - quadratic quadrangle // Compute lengths of the sides - std::vector< double > aLen (4); + double aLen[4]; aLen[0] = getDistance( P(1), P(3) ); aLen[1] = getDistance( P(3), P(5) ); aLen[2] = getDistance( P(5), P(7) ); aLen[3] = getDistance( P(7), P(1) ); // Compute lengths of the diagonals - std::vector< double > aDia (2); + double aDia[2]; aDia[0] = getDistance( P(1), P(5) ); aDia[1] = getDistance( P(3), P(7) ); // Compute areas of all triangles which can be built // taking three nodes of the quadrangle - std::vector< double > anArea (4); + double anArea[4]; anArea[0] = getArea( P(1), P(3), P(5) ); anArea[1] = getArea( P(1), P(3), P(7) ); anArea[2] = getArea( P(1), P(5), P(7) ); @@ -915,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] @@ -1008,8 +1017,8 @@ double AspectRatio3D::GetValue( long theId ) // Action from CoTech | ACTION 31.3: // EURIWARE BO: Homogenize the formulas used to calculate the Controls in SMESH to fit with // those of ParaView. The library used by ParaView for those calculations can be reused in SMESH. - vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myCurrElement->getMeshId()]->getGrid(); - if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->getVtkId() )) + vtkUnstructuredGrid* grid = const_cast( myMesh )->GetGrid(); + if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->GetVtkID() )) aVal = Round( vtkMeshQuality::TetAspectRatio( avtkCell )); } else @@ -1021,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; @@ -1028,12 +1042,12 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P ) int nbNodes = P.size(); - if(myCurrElement->IsQuadratic()) { - if(nbNodes==10) nbNodes=4; // quadratic tetrahedron + if( myCurrElement->IsQuadratic() ) { + 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; } @@ -1272,7 +1286,7 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P ) } // switch(nbNodes) if ( nbNodes > 4 ) { - // avaluate aspect ratio of quadranle faces + // evaluate aspect ratio of quadrangle faces AspectRatio aspect2D; SMDS_VolumeTool::VolumeType type = SMDS_VolumeTool::GetType( nbNodes ); int nbFaces = SMDS_VolumeTool::NbFaces( type ); @@ -1281,7 +1295,7 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P ) if ( SMDS_VolumeTool::NbFaceNodes( type, i ) != 4 ) continue; const int* pInd = SMDS_VolumeTool::GetFaceNodesIndices( type, i, true ); - for ( int p = 0; p < 4; ++p ) // loop on nodes of a quadranle face + for ( int p = 0; p < 4; ++p ) // loop on nodes of a quadrangle face points( p + 1 ) = P( pInd[ p ] + 1 ); aQuality = std::max( aQuality, aspect2D.GetValue( points )); } @@ -1310,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 ) @@ -1374,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 ) @@ -1432,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 ) @@ -1546,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; @@ -1797,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): @@ -1819,92 +1871,96 @@ bool Length2D::Value::operator<(const Length2D::Value& x) const void Length2D::GetValues(TValues& theValues) { - TValues aValues; - SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); - for(; anIter->more(); ){ - const SMDS_MeshFace* anElem = anIter->next(); + if ( myType == SMDSAbs_Face ) + { + for ( SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); anIter->more(); ) + { + const SMDS_MeshFace* anElem = anIter->next(); + if ( anElem->IsQuadratic() ) + { + // use special nodes iterator + SMDS_NodeIteratorPtr anIter = anElem->interlacedNodesIterator(); + long aNodeId[4] = { 0,0,0,0 }; + gp_Pnt P[4]; - if(anElem->IsQuadratic()) { - const SMDS_VtkFace* F = - dynamic_cast(anElem); - // use special nodes iterator - SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); - long aNodeId[4] = { 0,0,0,0 }; - gp_Pnt P[4]; - - double aLength = 0; - const SMDS_MeshElement* aNode; - if(anIter->more()){ - aNode = anIter->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(; anIter->more(); ){ - const SMDS_MeshNode* N1 = static_cast (anIter->next()); - P[2] = gp_Pnt(N1->X(),N1->Y(),N1->Z()); - aNodeId[2] = N1->GetID(); - aLength = P[1].Distance(P[2]); - if(!anIter->more()) break; - const SMDS_MeshNode* N2 = static_cast (anIter->next()); - P[3] = gp_Pnt(N2->X(),N2->Y(),N2->Z()); - aNodeId[3] = N2->GetID(); - aLength += P[2].Distance(P[3]); + 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_ElemIteratorPtr aNodesIter = anElem->nodesIterator(); - long aNodeId[2] = {0,0}; - 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); - } + 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(); + + P[2] = SMESH_NodeXYZ( aNode ); - aLength = P[0].Distance(P[1]); + aLength = P[1].Distance(P[2]); - Value aValue(aLength,aNodeId[0],aNodeId[1]); - theValues.insert(aValue); + 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); + } } } + 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 */ //================================================================================ @@ -1922,6 +1978,12 @@ double Deflection2D::GetValue( const TSequenceOfXYZ& P ) if ( !S.IsNull() && S.ShapeType() == TopAbs_FACE ) { mySurface = new ShapeAnalysis_Surface( BRep_Tool::Surface( TopoDS::Face( S ))); + + GeomLib_IsPlanarSurface isPlaneCheck( mySurface->Surface() ); + if ( isPlaneCheck.IsPlanar() ) + myPlane.reset( new gp_Pln( isPlaneCheck.Plan() )); + else + myPlane.reset(); } } // project gravity center to the surface @@ -1934,8 +1996,7 @@ double Deflection2D::GetValue( const TSequenceOfXYZ& P ) { gc += P(i+1); - if ( const SMDS_FacePosition* fPos = dynamic_cast - ( P.getElement()->GetNode( i )->GetPosition() )) + if ( SMDS_FacePositionPtr fPos = P.getElement()->GetNode( i )->GetPosition() ) { uv.ChangeCoord(1) += fPos->GetUParameter(); uv.ChangeCoord(2) += fPos->GetVParameter(); @@ -1947,12 +2008,22 @@ double Deflection2D::GetValue( const TSequenceOfXYZ& P ) double maxLen = MaxElementLength2D().GetValue( P ); double tol = 1e-3 * maxLen; - if ( uv.X() != 0 && uv.Y() != 0 ) // faster way - mySurface->NextValueOfUV( uv, gc, tol, 0.5 * maxLen ); + double dist; + if ( myPlane ) + { + dist = myPlane->Distance( gc ); + if ( dist < tol ) + dist = 0; + } else - mySurface->ValueOfUV( gc, tol ); - - return Round( mySurface->Gap() ); + { + if ( uv.X() != 0 && uv.Y() != 0 ) // faster way + mySurface->NextValueOfUV( uv, gc, tol, 0.5 * maxLen ); + else + mySurface->ValueOfUV( gc, tol ); + dist = mySurface->Gap(); + } + return Round( dist ); } } return 0; @@ -1962,6 +2033,7 @@ void Deflection2D::SetMesh( const SMDS_Mesh* theMesh ) { NumericalFunctor::SetMesh( dynamic_cast( theMesh )); myShapeIndex = -100; + myPlane.reset(); } SMDSAbs_ElementType Deflection2D::GetType() const @@ -2100,59 +2172,24 @@ bool MultiConnection2D::Value::operator<(const MultiConnection2D::Value& x) cons void MultiConnection2D::GetValues(MValues& theValues) { if ( !myMesh ) return; - SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); - for(; anIter->more(); ){ - const SMDS_MeshFace* anElem = anIter->next(); - SMDS_ElemIteratorPtr aNodesIter; - if ( anElem->IsQuadratic() ) - aNodesIter = dynamic_cast - (anElem)->interlacedNodesElemIterator(); - else - aNodesIter = anElem->nodesIterator(); - long aNodeId[3] = {0,0,0}; + for ( SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); anIter->more(); ) + { + const SMDS_MeshFace* anElem = anIter->next(); + SMDS_NodeIteratorPtr aNodesIter = anElem->interlacedNodesIterator(); - //int aNbConnects=0; - const SMDS_MeshNode* aNode0; - const SMDS_MeshNode* aNode1; + const SMDS_MeshNode* aNode1 = anElem->GetNode( anElem->NbNodes() - 1 ); 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: "<