X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESHGUI%2FSMESHGUI_VTKUtils.cxx;h=a6755381339772b94d273354e213133579846cb7;hp=6b67d5e9cc8cb3ffb6a1d399c1b562bee2dc679f;hb=ea8a0289f14641c23d515de68aa4fdc24a6208ba;hpb=bcfa36bbd041d724ff56560fb606261235d5f9e1 diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx index 6b67d5e9c..a67553813 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx @@ -76,6 +76,14 @@ // OCCT includes #include #include +#include +#include +#include +#include +#include +#include +#include +#include namespace SMESH { @@ -1112,6 +1120,135 @@ namespace SMESH //---------------------------------------------------------------------------- + int GetNameOfSelectedSortedNodes( SMDSAbs_EntityType theElementType, + SVTK_Selector* theSelector, + SMESH_Actor* theActor, + int theShift, + QString& theName) + { + theName = ""; + TColStd_IndexedMapOfInteger aMapIndex; + Handle(SALOME_InteractiveObject) anIO = theActor->getIO(); + theSelector->GetIndex(anIO, aMapIndex); + + SMDS_Mesh* aMesh = 0; + if (theActor) + aMesh = theActor->GetObject()->GetMesh(); + + std::vector aVectorOfNode; + std::list aListOfId; + int aSize = aMapIndex.Extent(); + for( int i = 1 ; i <= aSize; i++) { + SMESH_TNodeXYZ aCurNode = aMesh->FindNode( aMapIndex(i) ); + aVectorOfNode.push_back( aCurNode ); + aListOfId.push_back( aCurNode._node->GetID() ); + } + SMESH_TNodeXYZ aFirstNode; + if ( aSize > 0 ) + aFirstNode = aVectorOfNode[0]; + int myNbNodes = 0; + std::list aResultListId; + switch ( theElementType ) { + case SMDSEntity_0D: + myNbNodes = 1; + break; + case SMDSEntity_Ball: + myNbNodes = 1; + break; + case SMDSEntity_Edge: + case SMDSEntity_Quad_Edge: + myNbNodes = 2; + break; + case SMDSEntity_Triangle: + case SMDSEntity_Quad_Triangle: + case SMDSEntity_BiQuad_Triangle: + myNbNodes = 3; + break; + case SMDSEntity_Quadrangle: + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + myNbNodes = 4; + if ( myNbNodes <= aSize ) { + aVectorOfNode.resize( myNbNodes ); + aVectorOfNode[0] = aVectorOfNode[theShift % myNbNodes]; + aVectorOfNode[theShift % myNbNodes] = aFirstNode; + GetSortedNodesOnPolygon( aVectorOfNode, aResultListId ); + } + break; + case SMDSEntity_Polygon: + myNbNodes = 0; + if ( aSize > 0 ) { + aVectorOfNode[0] = aVectorOfNode[theShift % aVectorOfNode.size()]; + aVectorOfNode[theShift % aVectorOfNode.size()] = aFirstNode; + } + GetSortedNodesOnPolygon( aVectorOfNode, aResultListId ); + break; + case SMDSEntity_Tetra: + case SMDSEntity_Quad_Tetra: + myNbNodes = 4; + break; + case SMDSEntity_Pyramid: + case SMDSEntity_Quad_Pyramid: + myNbNodes = 5; + if ( myNbNodes <= aSize ) { + aVectorOfNode.resize( myNbNodes ); + aVectorOfNode[0] = aVectorOfNode[theShift % myNbNodes]; + aVectorOfNode[theShift % myNbNodes] = aFirstNode; + GetSortedNodesOnPyramid( aVectorOfNode, aResultListId ); + } + break; + case SMDSEntity_Hexa: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + myNbNodes = 8; + if ( myNbNodes <= aSize ) { + aVectorOfNode.resize( myNbNodes ); + aVectorOfNode[0] = aVectorOfNode[theShift % myNbNodes]; + aVectorOfNode[theShift % myNbNodes] = aFirstNode; + GetSortedNodesOnPrism( aVectorOfNode, aResultListId ); + } + break; + case SMDSEntity_Penta: + case SMDSEntity_Quad_Penta: + myNbNodes = 6; + if ( myNbNodes <= aSize ) { + aVectorOfNode.resize( myNbNodes ); + aVectorOfNode[0] = aVectorOfNode[theShift % myNbNodes]; + aVectorOfNode[theShift % myNbNodes] = aFirstNode; + GetSortedNodesOnPrism( aVectorOfNode, aResultListId ); + } + break; + case SMDSEntity_Hexagonal_Prism: + myNbNodes = 12; + if ( myNbNodes <= aSize ) { + aVectorOfNode.resize( myNbNodes ); + aVectorOfNode[0] = aVectorOfNode[theShift % myNbNodes]; + aVectorOfNode[theShift % myNbNodes] = aFirstNode; + GetSortedNodesOnPrism( aVectorOfNode, aResultListId ); + } + break; + default: + myNbNodes = 2; + } + if( myNbNodes > 0 ) { + if ( myNbNodes <= 3 || myNbNodes > aSize || theElementType == SMDSEntity_Tetra ) + aResultListId = aListOfId; + if ( myNbNodes < aSize ) { + if ( aResultListId.size() == 0 ) + return 0; + aVectorOfNode.resize( myNbNodes ); + aResultListId.resize( myNbNodes ); + } + } + std::list::iterator anIter = aResultListId.begin(); + + for( ; anIter != aResultListId.end(); anIter++ ) { + theName += QString(" %1").arg( *anIter ); + } + if ( myNbNodes <= 3 || myNbNodes > aSize || theElementType == SMDSEntity_Tetra ) + return aSize; + return aVectorOfNode.size(); + } int GetNameOfSelectedNodes(SVTK_Selector* theSelector, const Handle(SALOME_InteractiveObject)& theIO, QString& theName) @@ -1407,9 +1544,590 @@ namespace SMESH DistanceToPosition( theBounds, theNormal, theDist, theOrigin ); return true; } + bool CreatePlaneOnThreePoints( const gp_Pnt& thePoint1, + const gp_Pnt& thePoint2, + const gp_Pnt& thePoint3, + gp_Pln& thePlane ) + { + gp_Vec aVec1, aVec2; + aVec1 = gp_Vec( thePoint1, thePoint2 ); + aVec2 = gp_Vec( thePoint1, thePoint3 ); + double anAngle = aVec1.Angle( aVec2 ); + bool isOnStraight = ( anAngle != 0 && anAngle != M_PI ); + if ( isOnStraight ) { + gce_MakePln aMakePln (thePoint1, thePoint2, thePoint3); + if ( aMakePln.IsDone() ) { + thePlane = aMakePln.Value(); + } + } + return isOnStraight; + } + + void FindNbLowestPoint( std::list theList, gp_Pnt2d& theNode ) + { + std::list::iterator anIter = theList.begin(); + gp_Pnt2d aNode = gp_Pnt2d ( (*anIter).X(), (*anIter).Y()); + for( ; anIter != theList.end(); anIter++ ) { + if ( (*anIter).Y() < aNode.Y() || ( (*anIter).Y() == aNode.Y() && (*anIter).X() < aNode.X() ) ) + aNode = *anIter; + } + theNode = aNode; + } + static bool CompareNodeOfAngleAndDist (const TNodeOfAngleAndDist& first, const TNodeOfAngleAndDist& second ) + { + if ( first.second.second == 0 ) + return true; + if ( second.second.second == 0 ) + return false; + if ( first.second.first == 0 && second.second.first == 0 ) + if ( first.second.second > second.second.second ) + return false; + else + return true; + if ( first.second.first < second.second.first || + ( first.second.first == second.second.first && first.second.second >= second.second.second ) ) + return true; + return false; + } + + static bool CompareNodeOfDist (const TNodeOfAngleAndDist& first, const TNodeOfAngleAndDist& second ) + { + if ( first.second.second < second.second.second ) + return true; + return false; + } + + static bool CompareDistOfPlane ( const TNodeOfDistToPlaneAndDist& first, const TNodeOfDistToPlaneAndDist& second ) + { + if ( first.second.first == 0 && second.second.first != 0 ) + return true; + if ( first.second.first != 0 && second.second.first == 0 ) + return false; + if ( first.second.first < second.second.first || + ( first.second.first != 0 && second.second.first != 0 && + first.second.first == second.second.first && first.second.second > second.second.second ) ) + return true; + return false; + } + + static bool CompareDistOfPlaneById ( const TIdOfDistToPlaneAndDist& first, const TIdOfDistToPlaneAndDist& second ) + { + if ( first.second.first == 0 && second.second.first != 0 ) + return true; + if ( first.second.first != 0 && second.second.first == 0 ) + return false; + if ( first.second.first < second.second.first || + ( first.second.first != 0 && second.second.first != 0 && + first.second.first == second.second.first && first.second.second > second.second.second ) ) + return true; + return false; + } + + static bool CompareDistForCorrectPlane ( const TNodeOfDist& first, const TNodeOfDist& second ) + { + if ( first.second < second.second ) return true; + return false; + } + + bool IsNotPlaneIntersection( std::vector& theVector, const gp_Pln& thePlane ) + { + double A, B, C, D, aCur; + thePlane.Coefficients(A, B, C, D); + int aPlus = -1; + for ( int i = 0 ; i < (int)theVector.size(); ++i ) { + aCur = A * theVector[i]._xyz[0] + B * theVector[i]._xyz[1] + C * theVector[i]._xyz[2] + D; + if ( aCur == 0 ) + continue; + if ( aPlus == -1 && aCur != 0 ) + aPlus = ( aCur < 0 ) ? 0 : 1; + if ( aPlus > -1 && aPlus != ( aCur < 0 ) ? 0 : 1 ) + return false; + } + return true; + } + + bool GetNextCombination ( std::vector& theVector1, std::vector& theVector2, int theNbPoint ) + { + int aSize = (int)theVector1.size(); + for ( int i = aSize - 1; i >= 0; --i ) { + if ( theVector1[i] < theNbPoint - aSize + i ) { + ++theVector1[i]; + for ( int j = i + 1; j < aSize; ++j ) + theVector1[j] = theVector1[j-1] + 1; + int it = 0; + int it2 = 0; + bool isVec; + for ( int k = 0; k < theNbPoint; ++k ) { + isVec = false; + if( it < aSize ) { + if( k == theVector1[it] ) { + isVec = true; + ++it; + } + } + if ( isVec ) + continue; + theVector2[it2] = k; + it2++; + if ( it2 == (int)theVector2.size() ) + break; + } + return true; + } + } + return false; + } + + bool Get2BasePlane( std::vector& theVector, + std::vector& thePlane1, + std::vector& thePlane2 ) + { + int aSize = (int)theVector.size() / 2; + if ( aSize < 3 || (int)theVector.size() % 2 != 0 ) + return false; + int anArr1[3]; + int anArr2[2 * aSize - 3]; + for (int i = 0; i < 3 ; i++) { + anArr1[i] = i; + } + for (int i = 0; i < 2 * aSize - 3 ; i++) { + anArr2[i] = i + 3; + } + int aNbSwapFirstPoint = 0; + while ( thePlane1.empty() && thePlane2.empty() && aNbSwapFirstPoint < aSize * 2 ) { + std::vector anIndexPlane1( anArr1, anArr1 + 3 ); + std::vector anIndexPlane2( anArr2, anArr2 + 2 * aSize - 3); + int aNbCombination = 0; + double aMax = 0; + double aSumMin = -1; + int aMaxCombination = 0; + thePlane1.clear(); + thePlane2.clear(); + for (int i = 1; i < 2 * aSize - 1; i++ ) { + aMaxCombination += i; + } + while ( aNbCombination < aMaxCombination ) { + gp_Pln aPlane; + double aSumMinDist1 = 0; + double aSumMinDist2 = 0; + std::vector aVectorOfPoint; + for(int i = 0; i < 2 * aSize - 3; i++) { + aVectorOfPoint.push_back(theVector[anIndexPlane2[i]]); + } + bool isCorrectPlane = false; + bool isCreatePlane = CreatePlaneOnThreePoints( gp_Pnt(theVector[anIndexPlane1[0]]._xyz[0], theVector[anIndexPlane1[0]]._xyz[1], theVector[anIndexPlane1[0]]._xyz[2]), + gp_Pnt(theVector[anIndexPlane1[1]]._xyz[0], theVector[anIndexPlane1[1]]._xyz[1], theVector[anIndexPlane1[1]]._xyz[2]), + gp_Pnt(theVector[anIndexPlane1[2]]._xyz[0], theVector[anIndexPlane1[2]]._xyz[1], theVector[anIndexPlane1[2]]._xyz[2]), + aPlane ); + if ( isCreatePlane ) { + isCorrectPlane = IsNotPlaneIntersection( aVectorOfPoint, aPlane ); + } + if ( !isCorrectPlane ) { + GetNextCombination( anIndexPlane1, anIndexPlane2, 2*aSize ); + aNbCombination++; + continue; + } + std::vector anIndexCorrectPlane1; + std::vector anIndexCorrectPlane2; + if ( aSize == 3 ) { + for (int i = 0; i < aSize ; i++) { + anIndexCorrectPlane1.push_back( anIndexPlane1[i] ); + anIndexCorrectPlane2.push_back( anIndexPlane2[i] ); + } + } + if ( aSize >= 4 ) { + std::list aListBaseOfPoint; + TIdOfDistToPlaneAndDist aCurDistOfPlane; + for (int i = 0; i < 2 * aSize - 3; i++ ) { + aCurDistOfPlane.second.first = aPlane.Distance( gp_Pnt( theVector[anIndexPlane2[i]]._xyz[0], theVector[anIndexPlane2[i]]._xyz[1], theVector[anIndexPlane2[i]]._xyz[2] )); + if ( aCurDistOfPlane.second.first == 0 ) + aCurDistOfPlane.second.second = 0; + else { + double aCurDist = 0; + for (int j = 0; j < 3; j++) { + aCurDist += pow( theVector[anIndexPlane1[j]]._xyz[0] - theVector[anIndexPlane2[i]]._xyz[0], 2.0 ) + + pow( theVector[anIndexPlane1[j]]._xyz[1] - theVector[anIndexPlane2[i]]._xyz[1], 2.0 ) + + pow( theVector[anIndexPlane1[j]]._xyz[2] - theVector[anIndexPlane2[i]]._xyz[2], 2.0 ); + } + aCurDistOfPlane.second.second = aCurDist; + } + aCurDistOfPlane.first = anIndexPlane2[i]; + aListBaseOfPoint.push_back( aCurDistOfPlane ); + } + aListBaseOfPoint.sort( CompareDistOfPlaneById ); + std::list::iterator anIterDist = aListBaseOfPoint.begin(); + for (int i = 0; i < 3; i++) { + anIndexCorrectPlane1.push_back( anIndexPlane1[i] ); + } + for (int i = 0; i < aSize - 3; i++, anIterDist++) { + anIndexCorrectPlane1.push_back((*anIterDist).first); + } + for (int i = 0; i < 2 * aSize - 3 ; i++) { + anIterDist = aListBaseOfPoint.begin(); + bool isFinded = false; + for (int j = 0; j < aSize - 3; j++, anIterDist++) { + if ( anIndexPlane2[i] == (*anIterDist).first ) { + isFinded = true; + break; + } + } + if ( !isFinded ) + anIndexCorrectPlane2.push_back( anIndexPlane2[i] ); + } + } + double aCurDist1, aCurDist2, aMinDist1, aMinDist2, aSumDist1, aSumDist2, aSumDistBase1, aSumDistBase2; + bool isCorrect2Base = true; + aSumDist1 = aSumDistBase1 = aSumDist2 = aSumDistBase2 = 0; + for( int i = 0 ; i < aSize ; i++ ) { + aMinDist1 = 0; + aMinDist2 = 0; + for(int j = 0 ; j < aSize ; j++ ) { + aCurDist1 = pow( theVector[anIndexCorrectPlane1[i]]._xyz[0] - theVector[anIndexCorrectPlane2[j]]._xyz[0], 2.0 ) + + pow( theVector[anIndexCorrectPlane1[i]]._xyz[1] - theVector[anIndexCorrectPlane2[j]]._xyz[1], 2.0 ) + + pow( theVector[anIndexCorrectPlane1[i]]._xyz[2] - theVector[anIndexCorrectPlane2[j]]._xyz[2], 2.0 ); + aCurDist2 = pow( theVector[anIndexCorrectPlane1[j]]._xyz[0] - theVector[anIndexCorrectPlane2[i]]._xyz[0], 2.0 ) + + pow( theVector[anIndexCorrectPlane1[j]]._xyz[1] - theVector[anIndexCorrectPlane2[i]]._xyz[1], 2.0 ) + + pow( theVector[anIndexCorrectPlane1[j]]._xyz[2] - theVector[anIndexCorrectPlane2[i]]._xyz[2], 2.0 ); + aSumDistBase1 += pow( theVector[anIndexCorrectPlane1[i]]._xyz[0] - theVector[anIndexCorrectPlane1[j]]._xyz[0], 2.0 ) + + pow( theVector[anIndexCorrectPlane1[i]]._xyz[1] - theVector[anIndexCorrectPlane1[j]]._xyz[1], 2.0 ) + + pow( theVector[anIndexCorrectPlane1[i]]._xyz[2] - theVector[anIndexCorrectPlane1[j]]._xyz[2], 2.0 ); + aSumDistBase2 += pow( theVector[anIndexCorrectPlane2[i]]._xyz[0] - theVector[anIndexCorrectPlane2[j]]._xyz[0], 2.0 ) + + pow( theVector[anIndexCorrectPlane2[i]]._xyz[1] - theVector[anIndexCorrectPlane2[j]]._xyz[1], 2.0 ) + + pow( theVector[anIndexCorrectPlane2[i]]._xyz[2] - theVector[anIndexCorrectPlane2[j]]._xyz[2], 2.0 ); + if ( aCurDist1 < aMinDist1 || aMinDist1 == 0) + aMinDist1 = aCurDist1; + if ( aCurDist2 < aMinDist2 || aMinDist2 == 0) + aMinDist2 = aCurDist2; + aSumDist1 += aCurDist1; + aSumDist2 += aCurDist2; + } + aSumMinDist1 += aMinDist1; + aSumDist1 -= aMinDist1; + aSumMinDist2 += aMinDist2; + aSumDist2 -= aMinDist2; + } + isCorrect2Base = ( aSumDistBase1 + aSumDistBase2 <= aSumDist1 + aSumDist2 ); + if ( isCorrect2Base && ( aSumMinDist1 == aSumMinDist2 || ( aSumMinDist1 + aSumMinDist2 ) > aMax || aMax == 0 || + ( (aSumMinDist1 + aSumMinDist2 ) == aMax && ( (aSumDist1 + aSumDist2 - aSumDistBase1 - aSumDistBase2) < aSumMin || aSumMin == -1 ) ) ) ) { + aMax = aSumMinDist1 + aSumMinDist2; + aSumMin = aSumDist1 + aSumDist2 - aSumDistBase1 - aSumDistBase2; + thePlane1.clear(); + thePlane2.clear(); + for(int i = 0; i < aSize; i++) { + thePlane1.push_back(theVector[anIndexCorrectPlane1[i]]); + thePlane2.push_back(theVector[anIndexCorrectPlane2[i]]); + } + } + if ( aSumMinDist1 == aSumMinDist2 ) + break; + if ( !GetNextCombination( anIndexPlane1, anIndexPlane2, 2 * aSize) ) + break; + aNbCombination++; + } + if ( thePlane1.empty() && thePlane2.empty() ) { + aNbSwapFirstPoint++; + SMESH_TNodeXYZ aPoint; + aPoint = theVector[0]; + theVector[0] = theVector[aNbSwapFirstPoint]; + theVector[aNbSwapFirstPoint] = aPoint; + } + } + if ( thePlane1.empty() && thePlane2.empty() ) + return false; + return true; + } + + bool GetCorrectSequenceOfId( std::vector& theVector ) + { + std::list aListProjection; + gp_Pnt2d aCurPoint; + int aSize = (int)theVector.size(); + if ( aSize < 3 ) + return false; + gp_Pln aPlane; + bool isCreatePlane = false; + for (int i = 0; i < aSize - 1; i++ ) { + isCreatePlane = CreatePlaneOnThreePoints( gp_Pnt( theVector[i]._xyz[0], theVector[i]._xyz[1], theVector[i]._xyz[2] ), + gp_Pnt( theVector[i+1]._xyz[0], theVector[i+1]._xyz[1], theVector[i+1]._xyz[2] ), + gp_Pnt( theVector[i+2]._xyz[0], theVector[i+2]._xyz[1], theVector[i+2]._xyz[2] ), aPlane ); + if ( isCreatePlane) + break; + } + if ( !isCreatePlane ) + return false; + for ( int i = 0; i < aSize; i++) { + aCurPoint = ProjLib::Project( aPlane, gp_Pnt( theVector[i]._xyz[0], theVector[i]._xyz[1], theVector[i]._xyz[2] )); + aListProjection.push_back( aCurPoint ); + } + std::list aListIdOfAngleAndDist; + TNodeOfAngleAndDist aCurIdOfAngleAndDist; + FindNbLowestPoint( aListProjection, aCurPoint); + std::list::iterator anIter2d = aListProjection.begin(); + gp_Vec2d aCurVec; + gp_Vec2d aAxisVec = gp_Vec2d( 1, 0 ); + for( int i = 0 ; anIter2d != aListProjection.end(); anIter2d++, i++) { + aCurVec = gp_Vec2d( (*anIter2d).X() - aCurPoint.X(), (*anIter2d).Y() - aCurPoint.Y() ); + aCurIdOfAngleAndDist.first = theVector[i]; + if ( (*anIter2d).X() == aCurPoint.X() && (*anIter2d).Y() == aCurPoint.Y() ) + aCurIdOfAngleAndDist.second.first = 0; + else { + double anAngle = aAxisVec.Angle( aCurVec ); + double anRoundAngle = anAngle * 100000; + int anIntAngle = anRoundAngle + 0.5; + anRoundAngle = (double) anIntAngle / 100000; + aCurIdOfAngleAndDist.second.first = anRoundAngle; + } + aCurIdOfAngleAndDist.second.second = pow( (*anIter2d).X() - aCurPoint.X(), 2.0 ) + + pow( (*anIter2d).Y() - aCurPoint.Y(), 2.0 ) + + pow( aPlane.Distance( gp_Pnt( theVector[i]._xyz[0], theVector[i]._xyz[1], theVector[i]._xyz[2] )), 2.0 ); + aListIdOfAngleAndDist.push_back( aCurIdOfAngleAndDist ); + } + aListIdOfAngleAndDist.sort( CompareNodeOfAngleAndDist ); + std::list::iterator anIter = aListIdOfAngleAndDist.begin(); + std::list aListResult; + double anAngle = 0; + bool isSort = true; + for(int i = 0 ; anIter != aListIdOfAngleAndDist.end(); anIter++, i++) { + if ( anAngle == (*anIter).second.first && anAngle != 0 ) { + isSort = false; + break; + } + if ( ( anAngle > (*anIter).second.first && anAngle != 0 ) || i > 1) + break; + if ( (*anIter).second.first > 0 ) + anAngle = (*anIter).second.first; + } + if ( !isSort ) { + anIter = aListIdOfAngleAndDist.begin(); + for( ; anIter != aListIdOfAngleAndDist.end(); anIter++) { + if ( anAngle == (*anIter).second.first) + aListResult.push_back( *anIter ); + else if ( anAngle < (*anIter).second.first) + break; + } + } + else + anAngle = 0; + aListResult.sort(CompareNodeOfDist); + anIter = aListIdOfAngleAndDist.begin(); + theVector.clear(); + for( ; anIter != aListIdOfAngleAndDist.end(); anIter++) { + if ( !isSort && anAngle == (*anIter).second.first ){ + for( std::list::iterator anIter2 = aListResult.begin() ; anIter2 != aListResult.end(); anIter2++) { + theVector.push_back((*anIter2).first); + } + isSort = true; + } + if ( isSort && anAngle != 0 && anAngle == (*anIter).second.first ) + continue; + theVector.push_back((*anIter).first); + } + + return true; +} + + void GetCorrectSequenceTwoPlaneOfId( std::vector& thePlane1, std::vector& thePlane2, std::list& theResultListId ) + { + int anIndex1, anIndex2, aShift = 0; + double aCurSum; + std::pair aShiftOfDist; + int aSize = (int)thePlane1.size(); + aShiftOfDist.first = aShiftOfDist.second = 0; + int anArr1[3]; + int anArr2[aSize - 3]; + for (int i = 0; i < 3 ; i++) { + anArr1[i] = i; + } + for (int i = 0; i < aSize - 3 ; i++) { + anArr2[i] = i + 3; + } + std::vector anIndexPlane1( anArr1, anArr1 + 3 ); + std::vector anIndexPlane2( anArr2, anArr2 + aSize - 3); + std::vector anIndexCorrectPlane; + std::vector theNewPlane; + std::vector theCorrectPlane; + + GetCorrectSequenceOfId ( thePlane1 ); + + while( true ) { + anIndexCorrectPlane.clear(); + std::vector theNewPlane; + for (int i = 0; i < 3; i++) { + anIndexCorrectPlane.push_back( anIndexPlane1[i] ); + } + for (int i = 0; i < aSize - 3; i++) { + anIndexCorrectPlane.push_back( anIndexPlane2[i] ); + } + for (int i = 0; i < aSize; i++) { + theNewPlane.push_back( thePlane2[anIndexCorrectPlane[i]] ); + } + aShift = 0; + if ( GetCorrectSequenceOfId ( theNewPlane ) ) + { + std::vector aVectorSum; + while ( aShift != 2 * aSize ) { + anIndex1 = 0; + aCurSum = 0; + ( aShift < aSize ) ? anIndex2 = 0 : anIndex2 = aSize - 1; + while ( ( aShift < aSize && anIndex2 < aSize ) || ( aShift >= aSize && anIndex2 >= 0 ) ) { + aCurSum += pow( thePlane1[anIndex1]._xyz[0] - theNewPlane[ ( anIndex2 + aShift ) % aSize ]._xyz[0], 2.0 ) + + pow( thePlane1[anIndex1]._xyz[1] - theNewPlane[ ( anIndex2 + aShift ) % aSize ]._xyz[1], 2.0 ) + + pow( thePlane1[anIndex1]._xyz[2] - theNewPlane[ ( anIndex2 + aShift ) % aSize ]._xyz[2], 2.0 ); + ( aShift < aSize ) ? anIndex2++ : anIndex2--; + anIndex1++; + } + aVectorSum.push_back( aCurSum ); + aShift++; + } + double aCurSumMin = 0; + std::pair aCurShiftOfDist; + aCurShiftOfDist.first = aCurShiftOfDist.second = 0; + for ( int i = 0; i < (int)aVectorSum.size(); i++ ) { + if ( aVectorSum[i] < aCurShiftOfDist.second || aCurShiftOfDist.second == 0 ) { + aCurShiftOfDist.first = i; + aCurShiftOfDist.second = aVectorSum[i]; + } + } + if ( aCurShiftOfDist.second <= aShiftOfDist.second || aShiftOfDist.second == 0){ + aShiftOfDist = aCurShiftOfDist; + theCorrectPlane = theNewPlane; + } + } + if ( !GetNextCombination( anIndexPlane1, anIndexPlane2, aSize) ) + break; + } + thePlane2 = theCorrectPlane; + aShift = aShiftOfDist.first; + anIndex1 = 0; + theResultListId.clear(); + ( aShift < aSize ) ? anIndex2 = 0 : anIndex2 = aSize - 1; + while ( anIndex1 != aSize ) { + theResultListId.push_back(thePlane1[anIndex1]._node->GetID()); + anIndex1++; + } + while ( ( aShift < aSize && anIndex2 < aSize ) || ( aShift >= aSize && anIndex2 >= 0 ) ) { + theResultListId.push_back( thePlane2[( anIndex2 + aShift ) % aSize]._node->GetID() ); + ( aShift < aSize ) ? anIndex2++ : anIndex2--; + } + } + + void GetSortedNodesOnPolygon( std::vector& theVectorOfNode, std::list& theResultListId ) + { + GetCorrectSequenceOfId ( theVectorOfNode ); + for (int i = 0; i < theVectorOfNode.size(); i++) { + theResultListId.push_back( theVectorOfNode[i]._node->GetID() ); + } + } + + void GetSortedNodesOnPrism( std::vector& theVectorOfNode, std::list& theResultListId ) + { + int aSize = (int)theVectorOfNode.size(); + if ( aSize < 6 && aSize % 2 == 0) + return; + std::vector aPlane1, aPlane2; + if ( Get2BasePlane( theVectorOfNode, aPlane1, aPlane2 ) ) { + GetCorrectSequenceTwoPlaneOfId( aPlane1, aPlane2, theResultListId); + } + } + + void GetSortedNodesOnPyramid( std::vector& theVectorOfNode, std::list& theResultListId ) + { + int aSize = (int)theVectorOfNode.size(); + if ( aSize < 5 ) + return; + gp_Pln aPlane; + bool isCreatePlane, isCorrectPlane; + int aNumPlane = 0; + double aMax = 0; + while ( aNumPlane != aSize ) { + isCreatePlane = CreatePlaneOnThreePoints( gp_Pnt( theVectorOfNode[aNumPlane]._xyz[0], theVectorOfNode[aNumPlane]._xyz[1], theVectorOfNode[aNumPlane]._xyz[2] ), + gp_Pnt( theVectorOfNode[(aNumPlane + 1) % aSize]._xyz[0], theVectorOfNode[(aNumPlane + 1) % aSize]._xyz[1], theVectorOfNode[(aNumPlane + 1) % aSize]._xyz[2] ), + gp_Pnt( theVectorOfNode[(aNumPlane + 2) % aSize]._xyz[0], theVectorOfNode[(aNumPlane + 2) % aSize]._xyz[1], theVectorOfNode[(aNumPlane + 2) % aSize]._xyz[2] ), aPlane ); + isCorrectPlane = false; + std::vector aVectorOfPoint; + if ( isCreatePlane ) { + for(int j = 0; j < aSize - 3; j++) { + aVectorOfPoint.push_back(theVectorOfNode[(aNumPlane + j + 3) % aSize]); + } + isCorrectPlane = IsNotPlaneIntersection( aVectorOfPoint, aPlane ); + } + if ( !isCorrectPlane ) { + aNumPlane++; + continue; + } + std::vector aVectorBaseOfPoint; + std::list aListBaseOfPoint; + TNodeOfDistToPlaneAndDist aCurDistOfPlane; + aListBaseOfPoint.clear(); + for (int i = 0; i < aSize; i++ ) { + aCurDistOfPlane.second.first = aPlane.Distance( gp_Pnt( theVectorOfNode[i]._xyz[0], theVectorOfNode[i]._xyz[1], theVectorOfNode[i]._xyz[2] )); + if ( aCurDistOfPlane.second.first == 0 ) + aCurDistOfPlane.second.second = 0; + else { + double aCurDist = 0; + for (int j = 0; j < 3; j++) { + aCurDist += pow( theVectorOfNode[(aNumPlane + j) % aSize]._xyz[0] - theVectorOfNode[i]._xyz[0], 2.0 ) + + pow( theVectorOfNode[(aNumPlane + j) % aSize]._xyz[1] - theVectorOfNode[i]._xyz[1], 2.0 ) + + pow( theVectorOfNode[(aNumPlane + j) % aSize]._xyz[2] - theVectorOfNode[i]._xyz[2], 2.0 ); + } + aCurDistOfPlane.second.second = aCurDist; + } + aCurDistOfPlane.first = theVectorOfNode[i]; + aListBaseOfPoint.push_back( aCurDistOfPlane ); + } + aListBaseOfPoint.sort( CompareDistOfPlane ); + std::list::iterator anIterDist = aListBaseOfPoint.begin(); + for (; anIterDist != aListBaseOfPoint.end(); anIterDist++ ) { + aVectorBaseOfPoint.push_back((*anIterDist).first); + } + SMESH_TNodeXYZ aTopNode = aVectorBaseOfPoint.back(); + aVectorBaseOfPoint.resize( aVectorBaseOfPoint.size() - 1); + double aCur = 0; + double aSum = 0; + std::list aListBaseCorrect; + for (int i = 0; i < aSize - 1; i++) { + aCur = pow( aVectorBaseOfPoint[i]._xyz[0] - aTopNode._xyz[0], 2.0 ) + + pow( aVectorBaseOfPoint[i]._xyz[1] - aTopNode._xyz[1], 2.0 ) + + pow( aVectorBaseOfPoint[i]._xyz[2] - aTopNode._xyz[2], 2.0 ); + aListBaseCorrect.push_back(std::make_pair(aVectorBaseOfPoint[i], aCur) ); + } + bool isCorrectTop = true; + for (int i = 0; i < aSize - 1; i++) { + isCreatePlane = CreatePlaneOnThreePoints( gp_Pnt( aVectorBaseOfPoint[i]._xyz[0], aVectorBaseOfPoint[i]._xyz[1], aVectorBaseOfPoint[i]._xyz[2] ), + gp_Pnt( aVectorBaseOfPoint[(i+1) % (aSize - 1)]._xyz[0], aVectorBaseOfPoint[(i+1) % (aSize - 1)]._xyz[1], aVectorBaseOfPoint[(i+1) % (aSize - 1)]._xyz[2] ), + gp_Pnt( aVectorBaseOfPoint[(i+2) % (aSize - 1)]._xyz[0], aVectorBaseOfPoint[(i+2) % (aSize - 1)]._xyz[1], aVectorBaseOfPoint[(i+2) % (aSize - 1)]._xyz[2] ), aPlane ); + if ( isCreatePlane ) { + aCur = aPlane.Distance( gp_Pnt( aTopNode._xyz[0], aTopNode._xyz[1], aTopNode._xyz[2] )); + if ( aCur == 0 ) { + isCorrectTop = false; + continue; + } + aSum += aCur; + } + } + aNumPlane++; + if ( ( isCorrectTop || aSum == 0 ) && ( aMax == 0 || aSum > aMax ) ) { + aListBaseCorrect.sort(CompareDistForCorrectPlane); + aVectorBaseOfPoint.clear(); + std::list::iterator anIter = aListBaseCorrect.begin(); + for ( ; anIter != aListBaseCorrect.end(); anIter++) { + aVectorBaseOfPoint.push_back((*anIter).first); + } + GetCorrectSequenceOfId( aVectorBaseOfPoint ); + aMax = aSum; + theResultListId.clear(); + for (int i = 0; i < aVectorBaseOfPoint.size(); i++) { + theResultListId.push_back( aVectorBaseOfPoint[i]._node->GetID() ); + } + theResultListId.push_back( aTopNode._node->GetID() ); + if ( aSum == 0 ) + break; + } + } + } bool ComputeBounds( std::list theActorList, - double theBounds[6]) + double theBounds[6]) { bool anIsOk = false; theBounds[0] = theBounds[2] = theBounds[4] = VTK_DOUBLE_MAX;