-if ( i1 == i2 )
-return;
-int tmp = idNodes[ i1 ];
-idNodes[ i1 ] = idNodes[ i2 ];
-idNodes[ i2 ] = tmp;
-gp_Pnt Ptmp = P[ i1 ];
-P[ i1 ] = P[ i2 ];
-P[ i2 ] = Ptmp;
-DUMPSO( i1 << "(" << idNodes[ i2 ] << ") <-> " << i2 << "(" << idNodes[ i1 ] << ")");
-}
-
-//=======================================================================
-//function : SortQuadNodes
-//purpose : Set 4 nodes of a quadrangle face in a good order.
-// Swap 1<->2 or 2<->3 nodes and correspondingly return
-// 1 or 2 else 0.
-//=======================================================================
-
-int SMESH_MeshEditor::SortQuadNodes (const SMDS_Mesh * theMesh,
-int idNodes[] )
-{
- gp_Pnt P[4];
- int i;
- for ( i = 0; i < 4; i++ ) {
- const SMDS_MeshNode *n = theMesh->FindNode( idNodes[i] );
- if ( !n ) return 0;
- P[ i ].SetCoord( n->X(), n->Y(), n->Z() );
- }
-
- gp_Vec V1(P[0], P[1]);
- gp_Vec V2(P[0], P[2]);
- gp_Vec V3(P[0], P[3]);
-
- gp_Vec Cross1 = V1 ^ V2;
- gp_Vec Cross2 = V2 ^ V3;
-
- i = 0;
- if (Cross1.Dot(Cross2) < 0)
- {
- Cross1 = V2 ^ V1;
- Cross2 = V1 ^ V3;
-
- if (Cross1.Dot(Cross2) < 0)
- i = 2;
- else
- i = 1;
- swap ( i, i + 1, idNodes, P );
-
- // for ( int ii = 0; ii < 4; ii++ ) {
- // const SMDS_MeshNode *n = theMesh->FindNode( idNodes[ii] );
- // DUMPSO( ii << "(" << idNodes[ii] <<") : "<<n->X()<<" "<<n->Y()<<" "<<n->Z());
- // }
- }
- return i;
-}
-
-//=======================================================================
-//function : SortHexaNodes
-//purpose : Set 8 nodes of a hexahedron in a good order.
-// Return success status
-//=======================================================================
-
-bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh,
- int idNodes[] )
-{
- gp_Pnt P[8];
- int i;
- DUMPSO( "INPUT: ========================================");
- for ( i = 0; i < 8; i++ ) {
- const SMDS_MeshNode *n = theMesh->FindNode( idNodes[i] );
- if ( !n ) return false;
- P[ i ].SetCoord( n->X(), n->Y(), n->Z() );
- DUMPSO( i << "(" << idNodes[i] <<") : "<<n->X()<<" "<<n->Y()<<" "<<n->Z());
- }
- DUMPSO( "========================================");
-
-
- set<int> faceNodes; // ids of bottom face nodes, to be found
- set<int> checkedId1; // ids of tried 2-nd nodes
- Standard_Real leastDist = DBL_MAX; // dist of the 4-th node from 123 plane
- const Standard_Real tol = 1.e-6; // tolerance to find nodes in plane
- int iMin, iLoop1 = 0;
-
- // Loop to try the 2-nd nodes
-
- while ( leastDist > DBL_MIN && ++iLoop1 < 8 )
- {
- // Find not checked 2-nd node
- for ( i = 1; i < 8; i++ )
- if ( checkedId1.find( idNodes[i] ) == checkedId1.end() ) {
- int id1 = idNodes[i];
- swap ( 1, i, idNodes, P );
- checkedId1.insert ( id1 );
- break;
- }
-
- // Find the 3-d node so that 1-2-3 triangle to be on a hexa face,
- // ie that all but meybe one (id3 which is on the same face) nodes
- // lay on the same side from the triangle plane.
-
- bool manyInPlane = false; // more than 4 nodes lay in plane
- int iLoop2 = 0;
- while ( ++iLoop2 < 6 ) {
-
- // get 1-2-3 plane coeffs
- Standard_Real A, B, C, D;
- gp_Vec N = gp_Vec (P[0], P[1]).Crossed( gp_Vec (P[0], P[2]) );
- if ( N.SquareMagnitude() > gp::Resolution() )
- {
- gp_Pln pln ( P[0], N );
- pln.Coefficients( A, B, C, D );
-
- // find the node (iMin) closest to pln
- Standard_Real dist[ 8 ], minDist = DBL_MAX;
- set<int> idInPln;
- for ( i = 3; i < 8; i++ ) {
- dist[i] = A * P[i].X() + B * P[i].Y() + C * P[i].Z() + D;
- if ( fabs( dist[i] ) < minDist ) {
- minDist = fabs( dist[i] );
- iMin = i;
- }
- if ( fabs( dist[i] ) <= tol )
- idInPln.insert( idNodes[i] );
- }
-
- // there should not be more than 4 nodes in bottom plane
- if ( idInPln.size() > 1 )
- {
- DUMPSO( "### idInPln.size() = " << idInPln.size());
- // idInPlane does not contain the first 3 nodes
- if ( manyInPlane || idInPln.size() == 5)
- return false; // all nodes in one plane
- manyInPlane = true;
-
- // set the 1-st node to be not in plane
- for ( i = 3; i < 8; i++ ) {
- if ( idInPln.find( idNodes[ i ] ) == idInPln.end() ) {
- DUMPSO( "### Reset 0-th node");
- swap( 0, i, idNodes, P );
- break;
- }
- }
-
- // reset to re-check second nodes
- leastDist = DBL_MAX;
- faceNodes.clear();
- checkedId1.clear();
- iLoop1 = 0;
- break; // from iLoop2;
- }
-
- // check that the other 4 nodes are on the same side
- bool sameSide = true;
- bool isNeg = dist[ iMin == 3 ? 4 : 3 ] <= 0.;
- for ( i = 3; sameSide && i < 8; i++ ) {
- if ( i != iMin )
- sameSide = ( isNeg == dist[i] <= 0.);
- }
-
- // keep best solution
- if ( sameSide && minDist < leastDist ) {
- leastDist = minDist;
- faceNodes.clear();
- faceNodes.insert( idNodes[ 1 ] );
- faceNodes.insert( idNodes[ 2 ] );
- faceNodes.insert( idNodes[ iMin ] );
- DUMPSO( "loop " << iLoop2 << " id2 " << idNodes[ 1 ] << " id3 " << idNodes[ 2 ]
- << " leastDist = " << leastDist);
- if ( leastDist <= DBL_MIN )
- break;
- }
- }
-
- // set next 3-d node to check
- int iNext = 2 + iLoop2;
- if ( iNext < 8 ) {
- DUMPSO( "Try 2-nd");
- swap ( 2, iNext, idNodes, P );
- }
- } // while ( iLoop2 < 6 )
- } // iLoop1
-
- if ( faceNodes.empty() ) return false;
-
- // Put the faceNodes in proper places
- for ( i = 4; i < 8; i++ ) {
- if ( faceNodes.find( idNodes[ i ] ) != faceNodes.end() ) {
- // find a place to put
- int iTo = 1;
- while ( faceNodes.find( idNodes[ iTo ] ) != faceNodes.end() )
- iTo++;
- DUMPSO( "Set faceNodes");
- swap ( iTo, i, idNodes, P );
- }
- }
-
-
- // Set nodes of the found bottom face in good order
- DUMPSO( " Found bottom face: ");
- i = SortQuadNodes( theMesh, idNodes );
- if ( i ) {
- gp_Pnt Ptmp = P[ i ];
- P[ i ] = P[ i+1 ];
- P[ i+1 ] = Ptmp;
- }
- // else
- // for ( int ii = 0; ii < 4; ii++ ) {
- // const SMDS_MeshNode *n = theMesh->FindNode( idNodes[ii] );
- // DUMPSO( ii << "(" << idNodes[ii] <<") : "<<n->X()<<" "<<n->Y()<<" "<<n->Z());
- // }
-
- // Gravity center of the top and bottom faces
- gp_Pnt aGCb = ( P[0].XYZ() + P[1].XYZ() + P[2].XYZ() + P[3].XYZ() ) / 4.;
- gp_Pnt aGCt = ( P[4].XYZ() + P[5].XYZ() + P[6].XYZ() + P[7].XYZ() ) / 4.;
-
- // Get direction from the bottom to the top face
- gp_Vec upDir ( aGCb, aGCt );
- Standard_Real upDirSize = upDir.Magnitude();
- if ( upDirSize <= gp::Resolution() ) return false;
- upDir / upDirSize;
-
- // Assure that the bottom face normal points up
- gp_Vec Nb = gp_Vec (P[0], P[1]).Crossed( gp_Vec (P[0], P[2]) );
- Nb += gp_Vec (P[0], P[2]).Crossed( gp_Vec (P[0], P[3]) );
- if ( Nb.Dot( upDir ) < 0 ) {
- DUMPSO( "Reverse bottom face");
- swap( 1, 3, idNodes, P );
- }
-
- // Find 5-th node - the one closest to the 1-st among the last 4 nodes.
- Standard_Real minDist = DBL_MAX;
- for ( i = 4; i < 8; i++ ) {
- // projection of P[i] to the plane defined by P[0] and upDir
- gp_Pnt Pp = P[i].Translated( upDir * ( upDir.Dot( gp_Vec( P[i], P[0] ))));
- Standard_Real sqDist = P[0].SquareDistance( Pp );
- if ( sqDist < minDist ) {
- minDist = sqDist;
- iMin = i;
- }
- }
- DUMPSO( "Set 4-th");
- swap ( 4, iMin, idNodes, P );
-
- // Set nodes of the top face in good order
- DUMPSO( "Sort top face");
- i = SortQuadNodes( theMesh, &idNodes[4] );
- if ( i ) {
- i += 4;
- gp_Pnt Ptmp = P[ i ];
- P[ i ] = P[ i+1 ];
- P[ i+1 ] = Ptmp;
- }
-
- // Assure that direction of the top face normal is from the bottom face
- gp_Vec Nt = gp_Vec (P[4], P[5]).Crossed( gp_Vec (P[4], P[6]) );
- Nt += gp_Vec (P[4], P[6]).Crossed( gp_Vec (P[4], P[7]) );
- if ( Nt.Dot( upDir ) < 0 ) {
- DUMPSO( "Reverse top face");
- swap( 5, 7, idNodes, P );
- }
-
- // DUMPSO( "OUTPUT: ========================================");
- // for ( i = 0; i < 8; i++ ) {
- // float *p = ugrid->GetPoint(idNodes[i]);
- // DUMPSO( i << "(" << idNodes[i] << ") : " << p[0] << " " << p[1] << " " << p[2]);
- // }
-
- return true;
-}*/
-
-//================================================================================
-/*!
- * \brief Return nodes linked to the given one
- * \param theNode - the node
- * \param linkedNodes - the found nodes
- * \param type - the type of elements to check
- *
- * Medium nodes are ignored
- */
-//================================================================================
-
-void SMESH_MeshEditor::GetLinkedNodes( const SMDS_MeshNode* theNode,
- TIDSortedElemSet & linkedNodes,
- SMDSAbs_ElementType type )
-{
- SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator(type);
- while ( elemIt->more() )
- {
- const SMDS_MeshElement* elem = elemIt->next();
- if(elem->GetType() == SMDSAbs_0DElement)
- continue;