+//=======================================================================
+//function : LoadMeshBlock
+//purpose : prepare to work with theVolume
+//=======================================================================
+
+#define gpXYZ(n) gp_XYZ(n->X(),n->Y(),n->Z())
+
+bool SMESH_Block::LoadMeshBlock(const SMDS_MeshVolume* theVolume,
+ const int theNode000Index,
+ const int theNode001Index,
+ vector<const SMDS_MeshNode*>& theOrderedNodes)
+{
+ MESSAGE(" ::LoadMeshBlock()");
+
+ myNbIterations = 0;
+ mySumDist = 0;
+ myGridComputed = false;
+
+ SMDS_VolumeTool vTool;
+ if (!vTool.Set( theVolume ) || vTool.NbNodes() != 8 ||
+ !vTool.IsLinked( theNode000Index, theNode001Index )) {
+ MESSAGE(" Bad arguments ");
+ return false;
+ }
+ vTool.SetExternalNormal();
+ // In terms of indices used for access to nodes and faces in SMDS_VolumeTool:
+ int V000, V100, V010, V110, V001, V101, V011, V111; // 8 vertices
+ int Fxy0, Fxy1; // bottom and top faces
+ // vertices of faces
+ vector<int> vFxy0, vFxy1;
+
+ V000 = theNode000Index;
+ V001 = theNode001Index;
+
+ // get faces sharing V000 and V001
+ list<int> fV000, fV001;
+ int i, iF, iE, iN;
+ for ( iF = 0; iF < vTool.NbFaces(); ++iF ) {
+ const int* nid = vTool.GetFaceNodesIndices( iF );
+ for ( iN = 0; iN < 4; ++iN )
+ if ( nid[ iN ] == V000 ) {
+ fV000.push_back( iF );
+ } else if ( nid[ iN ] == V001 ) {
+ fV001.push_back( iF );
+ }
+ }
+
+ // find the bottom (Fxy0), the top (Fxy1) faces
+ list<int>::iterator fIt1, fIt2, Fxy0Pos;
+ for ( fIt1 = fV000.begin(); fIt1 != fV000.end(); fIt1++) {
+ fIt2 = std::find( fV001.begin(), fV001.end(), *fIt1 );
+ if ( fIt2 != fV001.end() ) { // *fIt1 is in the both lists
+ fV001.erase( fIt2 ); // erase Fx0z or F0yz from fV001
+ } else { // *fIt1 is in fV000 only
+ Fxy0Pos = fIt1; // points to Fxy0
+ }
+ }
+ Fxy0 = *Fxy0Pos;
+ Fxy1 = fV001.front();
+ const SMDS_MeshNode** nn = vTool.GetNodes();
+
+ // find bottom veritices, their order is that a face normal is external
+ vFxy0.resize(4);
+ const int* nid = vTool.GetFaceNodesIndices( Fxy0 );
+ for ( i = 0; i < 4; ++i )
+ if ( nid[ i ] == V000 )
+ break;
+ for ( iN = 0; iN < 4; ++iN, ++i ) {
+ if ( i == 4 ) i = 0;
+ vFxy0[ iN ] = nid[ i ];
+ }
+ // find top veritices, their order is that a face normal is external
+ vFxy1.resize(4);
+ nid = vTool.GetFaceNodesIndices( Fxy1 );
+ for ( i = 0; i < 4; ++i )
+ if ( nid[ i ] == V001 )
+ break;
+ for ( iN = 0; iN < 4; ++iN, ++i ) {
+ if ( i == 4 ) i = 0;
+ vFxy1[ iN ] = nid[ i ];
+ }
+ // find indices of the rest veritices
+ V100 = vFxy0[3];
+ V010 = vFxy0[1];
+ V110 = vFxy0[2];
+ V101 = vFxy1[1];
+ V011 = vFxy1[3];
+ V111 = vFxy1[2];
+
+ // set points coordinates
+ myPnt[ ID_V000 - 1 ] = gpXYZ( nn[ V000 ] );
+ myPnt[ ID_V100 - 1 ] = gpXYZ( nn[ V100 ] );
+ myPnt[ ID_V010 - 1 ] = gpXYZ( nn[ V010 ] );
+ myPnt[ ID_V110 - 1 ] = gpXYZ( nn[ V110 ] );
+ myPnt[ ID_V001 - 1 ] = gpXYZ( nn[ V001 ] );
+ myPnt[ ID_V101 - 1 ] = gpXYZ( nn[ V101 ] );
+ myPnt[ ID_V011 - 1 ] = gpXYZ( nn[ V011 ] );
+ myPnt[ ID_V111 - 1 ] = gpXYZ( nn[ V111 ] );
+
+ // fill theOrderedNodes
+ theOrderedNodes.resize( 8 );
+ theOrderedNodes[ 0 ] = nn[ V000 ];
+ theOrderedNodes[ 1 ] = nn[ V100 ];
+ theOrderedNodes[ 2 ] = nn[ V010 ];
+ theOrderedNodes[ 3 ] = nn[ V110 ];
+ theOrderedNodes[ 4 ] = nn[ V001 ];
+ theOrderedNodes[ 5 ] = nn[ V101 ];
+ theOrderedNodes[ 6 ] = nn[ V011 ];
+ theOrderedNodes[ 7 ] = nn[ V111 ];
+
+ // fill edges
+ myEdge[ ID_Ex00 - ID_Ex00 ].myNodes[ 0 ] = myPnt[ ID_V000 - 1 ];
+ myEdge[ ID_Ex00 - ID_Ex00 ].myNodes[ 1 ] = myPnt[ ID_V100 - 1 ];
+
+ myEdge[ ID_Ex10 - ID_Ex00 ].myNodes[ 0 ] = myPnt[ ID_V010 - 1 ];
+ myEdge[ ID_Ex10 - ID_Ex00 ].myNodes[ 1 ] = myPnt[ ID_V110 - 1 ];
+
+ myEdge[ ID_Ex01 - ID_Ex00 ].myNodes[ 0 ] = myPnt[ ID_V001 - 1 ];
+ myEdge[ ID_Ex01 - ID_Ex00 ].myNodes[ 1 ] = myPnt[ ID_V101 - 1 ];
+
+ myEdge[ ID_Ex11 - ID_Ex00 ].myNodes[ 0 ] = myPnt[ ID_V011 - 1 ];
+ myEdge[ ID_Ex11 - ID_Ex00 ].myNodes[ 1 ] = myPnt[ ID_V111 - 1 ];
+
+ myEdge[ ID_E0y0 - ID_Ex00 ].myNodes[ 0 ] = myPnt[ ID_V000 - 1 ];
+ myEdge[ ID_E0y0 - ID_Ex00 ].myNodes[ 1 ] = myPnt[ ID_V010 - 1 ];
+
+ myEdge[ ID_E1y0 - ID_Ex00 ].myNodes[ 0 ] = myPnt[ ID_V100 - 1 ];
+ myEdge[ ID_E1y0 - ID_Ex00 ].myNodes[ 1 ] = myPnt[ ID_V110 - 1 ];
+
+ myEdge[ ID_E0y1 - ID_Ex00 ].myNodes[ 0 ] = myPnt[ ID_V001 - 1 ];
+ myEdge[ ID_E0y1 - ID_Ex00 ].myNodes[ 1 ] = myPnt[ ID_V011 - 1 ];
+
+ myEdge[ ID_E1y1 - ID_Ex00 ].myNodes[ 0 ] = myPnt[ ID_V101 - 1 ];
+ myEdge[ ID_E1y1 - ID_Ex00 ].myNodes[ 1 ] = myPnt[ ID_V111 - 1 ];
+
+ myEdge[ ID_E00z - ID_Ex00 ].myNodes[ 0 ] = myPnt[ ID_V000 - 1 ];
+ myEdge[ ID_E00z - ID_Ex00 ].myNodes[ 1 ] = myPnt[ ID_V001 - 1 ];
+
+ myEdge[ ID_E10z - ID_Ex00 ].myNodes[ 0 ] = myPnt[ ID_V100 - 1 ];
+ myEdge[ ID_E10z - ID_Ex00 ].myNodes[ 1 ] = myPnt[ ID_V101 - 1 ];
+
+ myEdge[ ID_E01z - ID_Ex00 ].myNodes[ 0 ] = myPnt[ ID_V010 - 1 ];
+ myEdge[ ID_E01z - ID_Ex00 ].myNodes[ 1 ] = myPnt[ ID_V011 - 1 ];
+
+ myEdge[ ID_E11z - ID_Ex00 ].myNodes[ 0 ] = myPnt[ ID_V110 - 1 ];
+ myEdge[ ID_E11z - ID_Ex00 ].myNodes[ 1 ] = myPnt[ ID_V111 - 1 ];
+
+ for ( iE = ID_Ex00; iE <= ID_E11z; ++iE )
+ myEdge[ iE - ID_Ex00 ].myCoordInd = GetCoordIndOnEdge( iE );
+
+ // fill faces corners
+ for ( iF = ID_Fxy0; iF < ID_Shell; ++iF )
+ {
+ TFace& tFace = myFace[ iF - ID_Fxy0 ];
+ vector< int > edgeIdVec(4, -1);
+ GetFaceEdgesIDs( iF, edgeIdVec );
+ tFace.myNodes[ 0 ] = myEdge[ edgeIdVec [ 0 ] - ID_Ex00 ].myNodes[ 1 ];
+ tFace.myNodes[ 1 ] = myEdge[ edgeIdVec [ 0 ] - ID_Ex00 ].myNodes[ 0 ];
+ tFace.myNodes[ 2 ] = myEdge[ edgeIdVec [ 1 ] - ID_Ex00 ].myNodes[ 0 ];
+ tFace.myNodes[ 3 ] = myEdge[ edgeIdVec [ 1 ] - ID_Ex00 ].myNodes[ 1 ];
+ tFace.myCoordInd[ 0 ] = GetCoordIndOnEdge( edgeIdVec[ 0 ] );
+ tFace.myCoordInd[ 1 ] = GetCoordIndOnEdge( edgeIdVec[ 1 ] );
+ tFace.myCoordInd[ 2 ] = GetCoordIndOnEdge( edgeIdVec[ 2 ] );
+ tFace.myCoordInd[ 3 ] = GetCoordIndOnEdge( edgeIdVec[ 3 ] );
+ }
+
+ return true;
+}
+