Example #1
0
RealVector
AccpmGenMatrix::getColumn(int i) const
{ 
  
  LaIndex colIndex(i,i);
  LaIndex rowIndex = index(0);
  AccpmVector col = RealMatrix::operator()(rowIndex, colIndex);
  return col;
}
Example #2
0
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;
}