RealVector AccpmGenMatrix::getColumn(int i) const { LaIndex colIndex(i,i); LaIndex rowIndex = index(0); AccpmVector col = RealMatrix::operator()(rowIndex, colIndex); return col; }
void AccpmGenMatrix::scaleColumn(int i, const AccpmVector &d) { assert(size(0) == d.size()); #if (defined(WIN32)) for (int ix = 0; ix < size(0); ++ix) { (*this)(ix, i) *= d(ix); } #else LaIndex colIndex(i,i); LaIndex rowIndex = index(0); AccpmVector col(RealMatrix::operator()(rowIndex, colIndex)); col.times(d); #endif }
bool StdMeshers_HexaFromSkin_3D::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper) { _Skin skin; int nbBlocks = skin.findBlocks(aMesh); if ( nbBlocks == 0 ) return error( skin.error()); vector< vector< const SMDS_MeshNode* > > columns; int x, xSize, y, ySize, z, zSize; _Indexer colIndex; for ( int i = 0; i < nbBlocks; ++i ) { const _Block& block = skin.getBlock( i ); // ------------------------------------------ // Fill columns of nodes with existing nodes // ------------------------------------------ xSize = block.getSide(B_BOTTOM).getHoriSize(); ySize = block.getSide(B_BOTTOM).getVertSize(); zSize = block.getSide(B_FRONT ).getVertSize(); int X = xSize - 1, Y = ySize - 1, Z = zSize - 1; colIndex = _Indexer( xSize, ySize ); columns.resize( colIndex.size() ); // fill node columns by front and back box sides for ( x = 0; x < xSize; ++x ) { vector< const SMDS_MeshNode* >& column0 = columns[ colIndex( x, 0 )]; vector< const SMDS_MeshNode* >& column1 = columns[ colIndex( x, Y )]; column0.resize( zSize ); column1.resize( zSize ); for ( z = 0; z < zSize; ++z ) { column0[ z ] = block.getSide(B_FRONT).node( x, z ); column1[ z ] = block.getSide(B_BACK) .node( x, z ); } } // fill node columns by left and right box sides for ( y = 1; y < ySize-1; ++y ) { vector< const SMDS_MeshNode* >& column0 = columns[ colIndex( 0, y )]; vector< const SMDS_MeshNode* >& column1 = columns[ colIndex( X, y )]; column0.resize( zSize ); column1.resize( zSize ); for ( z = 0; z < zSize; ++z ) { column0[ z ] = block.getSide(B_LEFT) .node( y, z ); column1[ z ] = block.getSide(B_RIGHT).node( y, z ); } } // get nodes from top and bottom box sides for ( x = 1; x < xSize-1; ++x ) { for ( y = 1; y < ySize-1; ++y ) { vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )]; column.resize( zSize ); column.front() = block.getSide(B_BOTTOM).node( x, y ); column.back() = block.getSide(B_TOP) .node( x, y ); } } // ---------------------------- // Add internal nodes of a box // ---------------------------- // projection points of internal nodes on box sub-shapes by which // coordinates of internal nodes are computed vector<gp_XYZ> pointOnShape( SMESH_Block::ID_Shell ); // projections on vertices are constant pointOnShape[ SMESH_Block::ID_V000 ] = block.getSide(B_BOTTOM).xyz( 0, 0 ); pointOnShape[ SMESH_Block::ID_V100 ] = block.getSide(B_BOTTOM).xyz( X, 0 ); pointOnShape[ SMESH_Block::ID_V010 ] = block.getSide(B_BOTTOM).xyz( 0, Y ); pointOnShape[ SMESH_Block::ID_V110 ] = block.getSide(B_BOTTOM).xyz( X, Y ); pointOnShape[ SMESH_Block::ID_V001 ] = block.getSide(B_TOP).xyz( 0, 0 ); pointOnShape[ SMESH_Block::ID_V101 ] = block.getSide(B_TOP).xyz( X, 0 ); pointOnShape[ SMESH_Block::ID_V011 ] = block.getSide(B_TOP).xyz( 0, Y ); pointOnShape[ SMESH_Block::ID_V111 ] = block.getSide(B_TOP).xyz( X, Y ); for ( x = 1; x < xSize-1; ++x ) { gp_XYZ params; // normalized parameters of internal node within a unit box params.SetCoord( 1, x / double(X) ); for ( y = 1; y < ySize-1; ++y ) { params.SetCoord( 2, y / double(Y) ); // column to fill during z loop vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )]; // projections on horizontal edges pointOnShape[ SMESH_Block::ID_Ex00 ] = block.getSide(B_BOTTOM).xyz( x, 0 ); pointOnShape[ SMESH_Block::ID_Ex10 ] = block.getSide(B_BOTTOM).xyz( x, Y ); pointOnShape[ SMESH_Block::ID_E0y0 ] = block.getSide(B_BOTTOM).xyz( 0, y ); pointOnShape[ SMESH_Block::ID_E1y0 ] = block.getSide(B_BOTTOM).xyz( X, y ); pointOnShape[ SMESH_Block::ID_Ex01 ] = block.getSide(B_TOP).xyz( x, 0 ); pointOnShape[ SMESH_Block::ID_Ex11 ] = block.getSide(B_TOP).xyz( x, Y ); pointOnShape[ SMESH_Block::ID_E0y1 ] = block.getSide(B_TOP).xyz( 0, y ); pointOnShape[ SMESH_Block::ID_E1y1 ] = block.getSide(B_TOP).xyz( X, y ); // projections on horizontal sides pointOnShape[ SMESH_Block::ID_Fxy0 ] = block.getSide(B_BOTTOM).xyz( x, y ); pointOnShape[ SMESH_Block::ID_Fxy1 ] = block.getSide(B_TOP) .xyz( x, y ); for ( z = 1; z < zSize-1; ++z ) // z loop { params.SetCoord( 3, z / double(Z) ); // projections on vertical edges pointOnShape[ SMESH_Block::ID_E00z ] = block.getSide(B_FRONT).xyz( 0, z ); pointOnShape[ SMESH_Block::ID_E10z ] = block.getSide(B_FRONT).xyz( X, z ); pointOnShape[ SMESH_Block::ID_E01z ] = block.getSide(B_BACK).xyz( 0, z ); pointOnShape[ SMESH_Block::ID_E11z ] = block.getSide(B_BACK).xyz( X, z ); // projections on vertical sides pointOnShape[ SMESH_Block::ID_Fx0z ] = block.getSide(B_FRONT).xyz( x, z ); pointOnShape[ SMESH_Block::ID_Fx1z ] = block.getSide(B_BACK) .xyz( x, z ); pointOnShape[ SMESH_Block::ID_F0yz ] = block.getSide(B_LEFT) .xyz( y, z ); pointOnShape[ SMESH_Block::ID_F1yz ] = block.getSide(B_RIGHT).xyz( y, z ); // compute internal node coordinates gp_XYZ coords; SMESH_Block::ShellPoint( params, pointOnShape, coords ); column[ z ] = aHelper->AddNode( coords.X(), coords.Y(), coords.Z() ); #ifdef DEB_GRID // debug //cout << "----------------------------------------------------------------------"<<endl; //for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id) //{ // gp_XYZ p = pointOnShape[ id ]; // SMESH_Block::DumpShapeID( id,cout)<<" ( "<<p.X()<<", "<<p.Y()<<", "<<p.Z()<<" )"<<endl; //} //cout << "Params: ( "<< params.X()<<", "<<params.Y()<<", "<<params.Z()<<" )"<<endl; //cout << "coords: ( "<< coords.X()<<", "<<coords.Y()<<", "<<coords.Z()<<" )"<<endl; #endif } } } // ---------------- // Add hexahedrons // ---------------- // find out orientation by a least distorted hexahedron (issue 0020855); // the last is defined by evaluating sum of face normals of 8 corner hexahedrons double badness = numeric_limits<double>::max(); bool isForw = true; for ( int xMax = 0; xMax < 2; ++xMax ) for ( int yMax = 0; yMax < 2; ++yMax ) for ( int zMax = 0; zMax < 2; ++zMax ) { x = xMax ? xSize-1 : 1; y = yMax ? ySize-1 : 1; z = zMax ? zSize-1 : 1; vector< const SMDS_MeshNode* >& col00 = columns[ colIndex( x-1, y-1 )]; vector< const SMDS_MeshNode* >& col10 = columns[ colIndex( x , y-1 )]; vector< const SMDS_MeshNode* >& col01 = columns[ colIndex( x-1, y )]; vector< const SMDS_MeshNode* >& col11 = columns[ colIndex( x , y )]; const SMDS_MeshNode* n000 = col00[z-1]; const SMDS_MeshNode* n100 = col10[z-1]; const SMDS_MeshNode* n010 = col01[z-1]; const SMDS_MeshNode* n110 = col11[z-1]; const SMDS_MeshNode* n001 = col00[z]; const SMDS_MeshNode* n101 = col10[z]; const SMDS_MeshNode* n011 = col01[z]; const SMDS_MeshNode* n111 = col11[z]; SMDS_VolumeOfNodes probeVolume (n000,n010,n110,n100, n001,n011,n111,n101); SMDS_VolumeTool volTool( &probeVolume ); double Nx=0.,Ny=0.,Nz=0.; for ( int iFace = 0; iFace < volTool.NbFaces(); ++iFace ) { double nx,ny,nz; volTool.GetFaceNormal( iFace, nx,ny,nz ); Nx += nx; Ny += ny; Nz += nz; } double quality = Nx*Nx + Ny*Ny + Nz*Nz; if ( quality < badness ) { badness = quality; isForw = volTool.IsForward(); } } // add elements for ( x = 0; x < xSize-1; ++x ) { for ( y = 0; y < ySize-1; ++y ) { vector< const SMDS_MeshNode* >& col00 = columns[ colIndex( x, y )]; vector< const SMDS_MeshNode* >& col10 = columns[ colIndex( x+1, y )]; vector< const SMDS_MeshNode* >& col01 = columns[ colIndex( x, y+1 )]; vector< const SMDS_MeshNode* >& col11 = columns[ colIndex( x+1, y+1 )]; // bottom face normal of a hexa mush point outside the volume if ( isForw ) for ( z = 0; z < zSize-1; ++z ) aHelper->AddVolume(col00[z], col01[z], col11[z], col10[z], col00[z+1], col01[z+1], col11[z+1], col10[z+1]); else for ( z = 0; z < zSize-1; ++z ) aHelper->AddVolume(col00[z], col10[z], col11[z], col01[z], col00[z+1], col10[z+1], col11[z+1], col01[z+1]); } } } // loop on blocks return true; }