- bool GetCorrectSequenceOfId( std::vector<SMESH_TNodeXYZ>& theVector )
- {
- std::list<gp_Pnt2d> 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<TNodeOfAngleAndDist> aListIdOfAngleAndDist;
- TNodeOfAngleAndDist aCurIdOfAngleAndDist;
- FindNbLowestPoint( aListProjection, aCurPoint);
- std::list<gp_Pnt2d>::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<TNodeOfAngleAndDist>::iterator anIter = aListIdOfAngleAndDist.begin();
- std::list<TNodeOfAngleAndDist> 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<TNodeOfAngleAndDist>::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<SMESH_TNodeXYZ>& thePlane1, std::vector<SMESH_TNodeXYZ>& thePlane2, std::list<int>& theResultListId )
- {
- int anIndex1, anIndex2, aShift = 0;
- double aCurSum;
- std::pair<int, double> 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<int> anIndexPlane1( anArr1, anArr1 + 3 );
- std::vector<int> anIndexPlane2( anArr2, anArr2 + aSize - 3);
- std::vector<int> anIndexCorrectPlane;
- std::vector<SMESH_TNodeXYZ> theNewPlane;
- std::vector<SMESH_TNodeXYZ> theCorrectPlane;
-
- GetCorrectSequenceOfId ( thePlane1 );
-
- while( true ) {
- anIndexCorrectPlane.clear();
- std::vector<SMESH_TNodeXYZ> 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<double> 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<int, double> 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<SMESH_TNodeXYZ>& theVectorOfNode, std::list<int>& theResultListId )
- {
- GetCorrectSequenceOfId ( theVectorOfNode );
- for (int i = 0; i < theVectorOfNode.size(); i++) {
- theResultListId.push_back( theVectorOfNode[i]._node->GetID() );
- }
- }
-
- void GetSortedNodesOnPrism( std::vector<SMESH_TNodeXYZ>& theVectorOfNode, std::list<int>& theResultListId )
- {
- int aSize = (int)theVectorOfNode.size();
- if ( aSize < 6 && aSize % 2 == 0)
- return;
- std::vector<SMESH_TNodeXYZ> aPlane1, aPlane2;
- if ( Get2BasePlane( theVectorOfNode, aPlane1, aPlane2 ) ) {
- GetCorrectSequenceTwoPlaneOfId( aPlane1, aPlane2, theResultListId);
- }
- }
-
- void GetSortedNodesOnPyramid( std::vector<SMESH_TNodeXYZ>& theVectorOfNode, std::list<int>& 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<SMESH_TNodeXYZ> 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<SMESH_TNodeXYZ> aVectorBaseOfPoint;
- std::list<TNodeOfDistToPlaneAndDist> 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<TNodeOfDistToPlaneAndDist>::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<TNodeOfDist> 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<TNodeOfDist>::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;
- }
- }
- }