Beispiel #1
0
/*===========================================================================*/
void ExtractEdges::calculate_uniform_coords( const kvs::StructuredVolumeObject* volume )
{
    kvs::ValueArray<kvs::Real32> coords( 3 * volume->numberOfNodes() );
    kvs::Real32* coord = coords.data();

    const kvs::Vector3ui resolution( volume->resolution() );
    const kvs::Vector3f  volume_size( volume->maxObjectCoord() - volume->minObjectCoord() );
    const kvs::Vector3ui ngrids( resolution - kvs::Vector3ui( 1, 1, 1 ) );
    const kvs::Vector3f  grid_size(
        volume_size.x() / static_cast<float>( ngrids.x() ),
        volume_size.y() / static_cast<float>( ngrids.y() ),
        volume_size.z() / static_cast<float>( ngrids.z() ) );

    for ( size_t k = 0; k < resolution.z(); ++k )
    {
        const float z =
            grid_size.z() * static_cast<float>( k );
        for ( size_t j = 0; j < resolution.y(); ++j )
        {
            const float y =
                grid_size.y() * static_cast<float>( j );
            for ( size_t i = 0; i < resolution.x(); ++i )
            {
                const float x =
                    grid_size.x() * static_cast<float>( i );

                *( coord++ ) = x;
                *( coord++ ) = y;
                *( coord++ ) = z;
            }
        }
    }

    SuperClass::setCoords( coords );
}
/*===========================================================================*/
void StochasticUniformGridRenderer::Engine::create_bounding_cube_buffer( const kvs::StructuredVolumeObject* volume )
{
    /* Index number of the bounding cube.
     *
     *       4 ------------ 5
     *     / |            / |
     *    /  |           /  |
     *   7--------------6   |
     *   |   |          |   |
     *   |   0 ---------|-- 1
     *   |  /           |  /
     *   | /            | /
     *   3 ------------ 2
     *
     */
    const kvs::Vector3ui min( 0, 0, 0 );
    const kvs::Vector3ui max( volume->resolution() - kvs::Vector3ui( 1, 1, 1 ) );
    const size_t nelements = 72; // = 4 vertices x 3 dimensions x 6 faces

    const float minx = static_cast<float>( min.x() );
    const float miny = static_cast<float>( min.y() );
    const float minz = static_cast<float>( min.z() );
    const float maxx = static_cast<float>( max.x() );
    const float maxy = static_cast<float>( max.y() );
    const float maxz = static_cast<float>( max.z() );

    const float coords[ nelements ] = {
        minx, miny, minz, // 0
        maxx, miny, minz, // 1
        maxx, miny, maxz, // 2
        minx, miny, maxz, // 3

        minx, maxy, maxz, // 7
        maxx, maxy, maxz, // 6
        maxx, maxy, minz, // 5
        minx, maxy, minz, // 4

        minx, maxy, minz, // 4
        maxx, maxy, minz, // 5
        maxx, miny, minz, // 1
        minx, miny, minz, // 0

        maxx, maxy, minz, // 5
        maxx, maxy, maxz, // 6
        maxx, miny, maxz, // 2
        maxx, miny, minz, // 1

        maxx, maxy, maxz, // 6
        minx, maxy, maxz, // 7
        minx, miny, maxz, // 3
        maxx, miny, maxz, // 2

        minx, miny, minz, // 0
        minx, miny, maxz, // 3
        minx, maxy, maxz, // 7
        minx, maxy, minz  // 4
    };

    const size_t byte_size = sizeof(float) * nelements;
    m_bounding_cube_buffer.create( byte_size, coords );
}
/*===========================================================================*/
void StochasticUniformGridRenderer::Engine::create_shader_program( const kvs::StructuredVolumeObject* volume )
{
    // Build bounding cube shader.
    {
        kvs::ShaderSource vert("RC_bounding_cube.vert");
        kvs::ShaderSource frag("RC_bounding_cube.frag");
        m_bounding_cube_shader.build( vert, frag );
    }

    // Build ray caster.
    {
        kvs::ShaderSource vert("SR_uniform_grid.vert");
        kvs::ShaderSource frag("SR_uniform_grid.frag");
        if ( isEnabledShading() )
        {
            switch ( shader().type() )
            {
            case kvs::Shader::LambertShading: frag.define("ENABLE_LAMBERT_SHADING"); break;
            case kvs::Shader::PhongShading: frag.define("ENABLE_PHONG_SHADING"); break;
            case kvs::Shader::BlinnPhongShading: frag.define("ENABLE_BLINN_PHONG_SHADING"); break;
            default: /* NO SHADING */ break;
            }
        }
        m_ray_casting_shader.build( vert, frag );
    }

    // Set uniform variables.
    const kvs::Vector3ui r = volume->resolution();
    const kvs::Real32 max_ngrids = static_cast<kvs::Real32>( kvs::Math::Max( r.x(), r.y(), r.z() ) );
    const kvs::Vector3f resolution( static_cast<float>(r.x()), static_cast<float>(r.y()), static_cast<float>(r.z()) );
    const kvs::Vector3f ratio( r.x() / max_ngrids, r.y() / max_ngrids, r.z() / max_ngrids );
    const kvs::Vector3f reciprocal( 1.0f / r.x(), 1.0f / r.y(), 1.0f / r.z() );
    kvs::Real32 min_range = 0.0f;
    kvs::Real32 max_range = 0.0f;
    kvs::Real32 min_value = m_transfer_function.colorMap().minValue();
    kvs::Real32 max_value = m_transfer_function.colorMap().maxValue();
    const std::type_info& type = volume->values().typeInfo()->type();
    if ( type == typeid( kvs::UInt8 ) )
    {
        min_range = 0.0f;
        max_range = 255.0f;
        if ( !m_transfer_function.hasRange() )
        {
            min_value = 0.0f;
            max_value = 255.0f;
        }
    }
    else if ( type == typeid( kvs::Int8 ) )
    {
        min_range = static_cast<kvs::Real32>( kvs::Value<kvs::UInt8>::Min() );
        max_range = static_cast<kvs::Real32>( kvs::Value<kvs::UInt8>::Max() );
        if ( !m_transfer_function.hasRange() )
        {
            min_value = -128.0f;
            max_value = 127.0f;
        }
    }
    else if ( type == typeid( kvs::UInt16 ) )
    {
        min_range = static_cast<kvs::Real32>( kvs::Value<kvs::UInt16>::Min() );
        max_range = static_cast<kvs::Real32>( kvs::Value<kvs::UInt16>::Max() );
        if ( !m_transfer_function.hasRange() )
        {
            min_value = static_cast<kvs::Real32>( volume->minValue() );
            max_value = static_cast<kvs::Real32>( volume->maxValue() );
        }
    }
    else if ( type == typeid( kvs::Int16 ) )
    {
        min_range = static_cast<kvs::Real32>( kvs::Value<kvs::Int16>::Min() );
        max_range = static_cast<kvs::Real32>( kvs::Value<kvs::Int16>::Max() );
        if ( !m_transfer_function.hasRange() )
        {
            min_value = static_cast<kvs::Real32>( volume->minValue() );
            max_value = static_cast<kvs::Real32>( volume->maxValue() );
        }
    }
    else if ( type == typeid( kvs::UInt32 ) || type == typeid( kvs::Int32  ) || type == typeid( kvs::Real32 ) )
    {
        min_range = 0.0f;
        max_range = 1.0f;
        min_value = 0.0f;
        max_value = 1.0f;
    }
    else
    {
        kvsMessageError( "Not supported data type '%s'.", volume->values().typeInfo()->typeName() );
    }

    m_ray_casting_shader.bind();
    m_ray_casting_shader.setUniform( "volume.resolution", resolution );
    m_ray_casting_shader.setUniform( "volume.resolution_ratio", ratio );
    m_ray_casting_shader.setUniform( "volume.resolution_reciprocal", reciprocal );
    m_ray_casting_shader.setUniform( "volume.min_range", min_range );
    m_ray_casting_shader.setUniform( "volume.max_range", max_range );
    m_ray_casting_shader.setUniform( "transfer_function.min_value", min_value );
    m_ray_casting_shader.setUniform( "transfer_function.max_value", max_value );
    m_ray_casting_shader.setUniform( "dt", m_step );
    m_ray_casting_shader.setUniform( "shading.Ka", shader().Ka );
    m_ray_casting_shader.setUniform( "shading.Kd", shader().Kd );
    m_ray_casting_shader.setUniform( "shading.Ks", shader().Ks );
    m_ray_casting_shader.setUniform( "shading.S",  shader().S );
    m_ray_casting_shader.unbind();
}
Beispiel #4
0
kvs::ObjectBase* BlockLoader::exec( const kvs::ObjectBase* object )
{
    
//    std::cout << volume->values().typeInfo()->typeName() <<std::endl;
    const size_t ndivisions = 24;
    const kvs::Vector3ui ncells = kvs::Vector3ui( nx - 1, ny - 1, nz - 1 );
    
    const int remainder_x = ncells.x() % block_size;
    const int remainder_y = ncells.y() % block_size;
    const int remainder_z = ncells.z() % block_size;
    
    const size_t block_x = ncells.x() / block_size + (bool)( remainder_x );  std::cout << "block_x: " << block_x <<std::endl;
    const size_t block_y = ncells.y() / block_size + (bool)( remainder_y );  std::cout << "block_y: " << block_y <<std::endl;
    const size_t block_z = ncells.z() / block_size + (bool)( remainder_z );  std::cout << "block_z: " << block_z <<std::endl;
    
    const size_t ncubes = block_x * block_y * block_z;
    const size_t nvertices = ( block_x + 1 ) * ( block_y + 1 ) * ( block_z + 1);
    std::cout << "nvertices: " << nvertices << std::endl;
    const size_t nnodes = nvertices + block_x * block_y * ( block_z + 1 ) + block_y * block_z * ( block_x + 1 ) + block_z * block_x * ( block_y + 1 ) + ncubes;
    std::cout << "nnodes: " << nnodes << std::endl;

    const size_t ntets = ncubes * ndivisions;
    std::cout << "ntets: " << ntets << std::endl;

    const kvs::UInt32 line_size = block_x + 1;
    std::cout<< "nnodesPerLine: " << line_size << std::endl;
    const kvs::UInt32 slice_size = ( block_x + 1 ) * ( block_y + 1 );
    std::cout<< "nnodesPerSlice: " << slice_size << std::endl;
        
    //Calculate the value and coord of every vertex
    kvs::AnyValueArray values;
    float* pvalues = static_cast<float*>( values.allocate<float>( nnodes ) );
    for( size_t i = 0; i < nnodes; i++ ) pvalues[i] = ori_values[i]; 
    
    kvs::ValueArray<kvs::Real32> coords( nnodes * 3 );
    kvs::Real32* pcoords = coords.pointer();
    float coord_x = 0.0;
    float coord_y = 0.0;
    float coord_z = 0.0;
    size_t count = 0;

    for ( size_t k = 0; k < ( block_z + 1 ); k++ )
    {
        if ( k == block_z )
        {
            coord_z = static_cast<float>( ncells.z() );
        }
        for ( size_t j = 0; j < ( block_y + 1 ); j++ )
        {
            if ( j == block_y )
            {
                coord_y = static_cast<float>( ncells.y() );
            }
            for ( size_t i = 0; i < ( block_x + 1 ); i++ )
            {
                if ( i == block_x )
                {
                    coord_x = static_cast<float>( ncells.x() );
                }
                
                count++;
                //coords
                *(pcoords++) = coord_x;   
                *(pcoords++) = coord_y;   
                *(pcoords++) = coord_z;
                coord_x += static_cast<float>( block_size );
            }            
            coord_x = 0.0;
            coord_y += static_cast<float>( block_size );
        }
        coord_y = 0.0;
        coord_z += static_cast<float>( block_size );
    }
    size_t index_x = count;

    float* p = new float[3];
    int initial_index = (int)block_size/2;
    float initial_coord = (float)block_size/2.0;
    
    int edge_index_x = remainder_x ? (int)( remainder_x )/2 : initial_index;
    int edge_index_y = remainder_y ? (int)( remainder_y )/2 : initial_index;
    int edge_index_z = remainder_z ? (int)( remainder_z )/2 : initial_index;
    float edge_coord_x = remainder_x ? (float)( remainder_x )/2.0 : initial_coord;
    float edge_coord_y = remainder_y ? (float)( remainder_y )/2.0 : initial_coord;
    float edge_coord_z = remainder_z ? (float)( remainder_z )/2.0 : initial_coord;
    
    int temp_index_x = 0;
    int temp_index_y = 0;
    int temp_index_z = 0;
    float temp_coord_x = 0.0;
    float temp_coord_y = 0.0;
    float temp_coord_z = 0.0;
    
    //Calculate the center of the face z = 0, 1, 2 ....    
    for ( size_t k = 0; k < ( block_z + 1 ); k++ )
    {
        temp_index_z = 0;
        temp_coord_z = 0.0;
        
        if ( k == block_z )
        {
            temp_index_z = remainder_z ? ( remainder_z - (int)block_size ) : 0; std::cout << "temp_index_z: " << temp_index_z << std::endl;
            temp_coord_z = remainder_z ? (float)( remainder_z - (int)block_size ) : 0.0;  std::cout << "temp_coord_z: " << temp_coord_z << std::endl;
        }
        for ( size_t j = 0; j < ( block_y ); j++ )
        {
            temp_index_y = initial_index;
            temp_coord_y = initial_coord;

            if ( j == block_y - 1 )
            {
                temp_index_y = edge_index_y;
                temp_coord_y = edge_coord_y;
            }
            for ( size_t i = 0; i < ( block_x ); i++ )
            { 
                temp_index_x = initial_index;
                temp_coord_x = initial_coord;

                if ( i == block_x - 1 )
                {
                    temp_index_x = edge_index_x;
                    temp_coord_x = edge_coord_x;
                }
                
                count++;
                p[0] = temp_coord_x + (float)(i * block_size);
                p[1] = temp_coord_y + (float)(j * block_size);
                p[2] = temp_coord_z + (float)(k * block_size);
                *(pcoords++) = p[0];
                *(pcoords++) = p[1];
                *(pcoords++) = p[2];
            }
        }
    }
    size_t index_y = count;
    std::cout<< "x_c: " << count <<std::endl;
    
    //Calculate the center of the face x = 0, 1, 2 ....    
    for ( size_t k = 0; k < ( block_z ); k++ )
    {
        temp_index_z = initial_index;
        temp_coord_z = initial_coord;
        
        if ( k == block_z - 1 )
        {
            temp_index_z = edge_index_z;
            temp_coord_z = edge_coord_z;
        }
        for ( size_t j = 0; j < ( block_y ); j++ )
        {
            temp_index_y = initial_index;
            temp_coord_y = initial_coord;

            if ( j == block_y - 1 )
            {
                temp_index_y = edge_index_y;
                temp_coord_y = edge_coord_y;
            }
            for ( size_t i = 0; i < ( block_x + 1 ); i++ )
            {
                temp_index_x = 0;
                temp_coord_x = 0.0;

                if ( i == block_x )
                {
                    temp_index_x = remainder_x ? ( remainder_x - (int)block_size ) : 0;
                    temp_coord_x = remainder_x ? (float)( remainder_x - (int)block_size ) : 0.0;
                }
                
                count++;
                
                p[0] = temp_coord_x + (float)(i * block_size);
                p[1] = temp_coord_y + (float)(j * block_size);
                p[2] = temp_coord_z + (float)(k * block_size);
                *(pcoords++) = p[0];
                *(pcoords++) = p[1];
                *(pcoords++) = p[2];
            }
        }
    }
    size_t index_z = count;
    std::cout<< "y_c: " << count <<std::endl;
    
    //Calculate the center of the face y = 0, 1, 2 ....    
    for ( size_t k = 0; k < ( block_z ); k++ )
    {
        temp_index_z = initial_index;
        temp_coord_z = initial_coord;
        
        if ( k == block_z - 1 )
        {
            temp_index_z = edge_index_z;
            temp_coord_z = edge_coord_z;
        }
        for ( size_t j = 0; j < ( block_y + 1 ); j++ )
        {
            temp_index_y = 0;
            temp_coord_y = 0.0;
            
            if ( j == block_y )
            {
                temp_index_y = remainder_y ? ( remainder_y - (int)block_size ) : 0;
                temp_coord_y = remainder_y ? (float)( remainder_y - (int)block_size ) : 0.0;
            }
            for ( size_t i = 0; i < ( block_x ); i++ )
            {
                temp_index_x = initial_index;
                temp_coord_x = initial_coord;
                
                if ( i == block_x - 1 )
                {
                    temp_index_x = edge_index_x;
                    temp_coord_x = edge_coord_x;
                }
                
                count++;
                
                p[0] = temp_coord_x + (float)(i * block_size);
                p[1] = temp_coord_y + (float)(j * block_size);
                p[2] = temp_coord_z + (float)(k * block_size);
                *(pcoords++) = p[0];
                *(pcoords++) = p[1];
                *(pcoords++) = p[2];
            }
        }
    }
    size_t index_gravity = count;
    std::cout<< "z_c: " << count <<std::endl;
    
    //Calculate the gravity center of every cell
    temp_index_x = initial_index;
    temp_index_y = initial_index;
    temp_index_z = initial_index;
    temp_coord_x = initial_coord;
    temp_coord_y = initial_coord;
    temp_coord_z = initial_coord;
    
    for ( size_t k = 0; k < ( block_z ); k++ )
    {
        if ( k == block_z - 1 )
        {
            temp_index_z = edge_index_z;
            temp_coord_z = edge_coord_z;
        }
        for ( size_t j = 0; j < ( block_y ); j++ )
        {
            if ( j == block_y - 1 )
            {
                temp_index_y = edge_index_y;
                temp_coord_y = edge_coord_y;
            }
            for ( size_t i = 0; i < ( block_x  ); i++ )
            {
                if ( i == block_x - 1 )
                {
                    temp_index_x = edge_index_x;
                    temp_coord_x = edge_coord_x;
                }
                p[0] = temp_coord_x + (float)(i * block_size);
                p[1] = temp_coord_y + (float)(j * block_size);
                p[2] = temp_coord_z + (float)(k * block_size);
                *(pcoords++) = p[0];
                *(pcoords++) = p[1];
                *(pcoords++) = p[2];
            }
            temp_index_x = initial_index;
            temp_coord_x = initial_coord;
        }
        temp_index_y = initial_coord;
        temp_coord_y = initial_coord;
    }

    //Calculate the new connection
    kvs::ValueArray<kvs::UInt32> connections( ntets * 4 );
    kvs::UInt32* pconnections = connections.pointer();
    
    for ( size_t k = 0; k < block_z; k++ )
    {
        for ( size_t j = 0; j < block_y; j++ )
        {
            for ( size_t i = 0; i < block_x; i++ )
            {
                const size_t index = i + j * line_size + k * slice_size;
                const kvs::UInt32 id0 = index;
                const kvs::UInt32 id1 = id0 + 1;
                const kvs::UInt32 id2 = id0 + line_size;
                const kvs::UInt32 id3 = id1 + line_size;
                const kvs::UInt32 id4 = id0 + slice_size;
                const kvs::UInt32 id5 = id1 + slice_size;
                const kvs::UInt32 id6 = id2 + slice_size;
                const kvs::UInt32 id7 = id3 + slice_size;
                
                const size_t index_center = i + j * block_x + k * block_x * block_y;
                const kvs::UInt32 id8 = index_x + index_center;
                const kvs::UInt32 id10 = id8 + (block_x * block_y);
                const kvs::UInt32 id11 = index_y + index_center;
                const kvs::UInt32 id9 = id11 + 1;
                const kvs::UInt32 id12 = index_z + index_center;
                const kvs::UInt32 id13 = id12 + block_x;
                const kvs::UInt32 id14 = index_gravity + index_center;

                //tet0
                *(pconnections++) = id14;
                *(pconnections++) = id8;
                *(pconnections++) = id0;
                *(pconnections++) = id1;
                
                //tet1
                *(pconnections++) = id14;
                *(pconnections++) = id8;
                *(pconnections++) = id1;
                *(pconnections++) = id3;
                
                //tet2
                *(pconnections++) = id14;
                *(pconnections++) = id8;
                *(pconnections++) = id3;
                *(pconnections++) = id2;
                
                //tet3
                *(pconnections++) = id14;
                *(pconnections++) = id8;
                *(pconnections++) = id2;
                *(pconnections++) = id0;
                
                //tet4
                *(pconnections++) = id14;
                *(pconnections++) = id9;
                *(pconnections++) = id1;
                *(pconnections++) = id5;
                
                //tet5
                *(pconnections++) = id14;
                *(pconnections++) = id9;
                *(pconnections++) = id5;
                *(pconnections++) = id7;
                
                //tet6
                *(pconnections++) = id14;
                *(pconnections++) = id9;
                *(pconnections++) = id7;
                *(pconnections++) = id3;
                
                //tet7
                *(pconnections++) = id14;
                *(pconnections++) = id9;
                *(pconnections++) = id3;
                *(pconnections++) = id1;
                
                //tet8
                *(pconnections++) = id14;
                *(pconnections++) = id10;
                *(pconnections++) = id5;
                *(pconnections++) = id4;
                
                //tet9
                *(pconnections++) = id14;
                *(pconnections++) = id10;
                *(pconnections++) = id4;
                *(pconnections++) = id6;
                
                //tet10
                *(pconnections++) = id14;
                *(pconnections++) = id10;
                *(pconnections++) = id6;
                *(pconnections++) = id7;
                
                //tet11
                *(pconnections++) = id14;
                *(pconnections++) = id10;
                *(pconnections++) = id7;
                *(pconnections++) = id5;
                
                //tet12
                *(pconnections++) = id14;
                *(pconnections++) = id11;
                *(pconnections++) = id4;
                *(pconnections++) = id0;
                
                //tet13
                *(pconnections++) = id14;
                *(pconnections++) = id11;
                *(pconnections++) = id0;
                *(pconnections++) = id2;
                
                //tet14
                *(pconnections++) = id14;
                *(pconnections++) = id11;
                *(pconnections++) = id2;
                *(pconnections++) = id6;
                
                //tet15
                *(pconnections++) = id14;
                *(pconnections++) = id11;
                *(pconnections++) = id6;
                *(pconnections++) = id4;
                
                //tet16
                *(pconnections++) = id14;
                *(pconnections++) = id12;
                *(pconnections++) = id1;
                *(pconnections++) = id0;
                
                //tet17
                *(pconnections++) = id14;
                *(pconnections++) = id12;
                *(pconnections++) = id0;
                *(pconnections++) = id4;
                
                //tet18
                *(pconnections++) = id14;
                *(pconnections++) = id12;
                *(pconnections++) = id4;
                *(pconnections++) = id5;
                
                //tet19
                *(pconnections++) = id14;
                *(pconnections++) = id12;
                *(pconnections++) = id5;
                *(pconnections++) = id1;
                
                //tet20
                *(pconnections++) = id14;
                *(pconnections++) = id13;
                *(pconnections++) = id2;
                *(pconnections++) = id3;
                
                //tet21
                *(pconnections++) = id14;
                *(pconnections++) = id13;
                *(pconnections++) = id3;
                *(pconnections++) = id7;
                
                //tet22
                *(pconnections++) = id14;
                *(pconnections++) = id13;
                *(pconnections++) = id7;
                *(pconnections++) = id6;
                
                //tet23
                *(pconnections++) = id14;
                *(pconnections++) = id13;
                *(pconnections++) = id6;
                *(pconnections++) = id2;

            }
            index_y ++;
        }
        index_z += block_x;
    }    

    SuperClass::setVeclen( 1 );
    SuperClass::setNNodes( nnodes );
    SuperClass::setNCells( ntets );
    SuperClass::setCellType( kvs::UnstructuredVolumeObject::Tetrahedra );
    SuperClass::setCoords( coords );
    SuperClass::setConnections( connections );
    SuperClass::setValues( values );
    SuperClass::updateMinMaxCoords();
    SuperClass::updateMinMaxValues();

    return this;
}
kvs::ObjectBase* CubeToTetrahedraLinear::exec( const kvs::ObjectBase* object )
{
    const kvs::StructuredVolumeObject* volume = kvs::StructuredVolumeObject::DownCast( object );

//    std::cout << volume->values().typeInfo()->typeName() <<std::endl;
    const size_t ndivisions = 24;
    const kvs::Vector3ui ncells = volume->resolution() - kvs::Vector3ui( 1, 1, 1 );
    
    const int remainder_x = ncells.x() % block_size;
    const int remainder_y = ncells.y() % block_size;
    const int remainder_z = ncells.z() % block_size;
    
    const size_t block_x = ncells.x() / block_size + (bool)( remainder_x );  std::cout << "block_x: " << block_x <<std::endl;
    const size_t block_y = ncells.y() / block_size + (bool)( remainder_y );  std::cout << "block_y: " << block_y <<std::endl;
    const size_t block_z = ncells.z() / block_size + (bool)( remainder_z );  std::cout << "block_z: " << block_z <<std::endl;
    
    const size_t ncubes = block_x * block_y * block_z;
    const size_t nvertices = ( block_x + 1 ) * ( block_y + 1 ) * ( block_z + 1);
    std::cout << "nvertices: " << nvertices << std::endl;
    const size_t nnodes = nvertices + block_x * block_y * ( block_z + 1 ) + block_y * block_z * ( block_x + 1 ) + block_z * block_x * ( block_y + 1 ) + ncubes;
    std::cout << "nnodes: " << nnodes << std::endl;

    const size_t ntets = ncubes * ndivisions;
    std::cout << "ntets: " << ntets << std::endl;

    const kvs::UInt32 line_size = block_x + 1;
    std::cout<< "nnodesPerLine: " << line_size << std::endl;
    const kvs::UInt32 slice_size = ( block_x + 1 ) * ( block_y + 1 );
    std::cout<< "nnodesPerSlice: " << slice_size << std::endl;
    
    //Calculate the new value array
    float* ori_values = ( float* )volume->values().pointer();
    const size_t nx = volume->resolution().x();
    const size_t ny = volume->resolution().y();
//    const size_t nz = volume->resolution().z();
    
    //Calculate the value and coord of every vertex
    kvs::AnyValueArray values;
    float* pvalues = static_cast<float*>( values.allocate<float>( nnodes ) );
    kvs::ValueArray<kvs::Real32> coords( nnodes * 3 );
    kvs::Real32* pcoords = coords.pointer();
    size_t count_x = 0;
    size_t count_y = 0;
    size_t count_z = 0;
    float coord_x = 0.0;
    float coord_y = 0.0;
    float coord_z = 0.0;
    size_t count = 0;

    for ( size_t k = 0; k < ( block_z + 1 ); k++ )
    {
        if ( k == block_z )
        {
            count_z = nx * ny * ncells.z();
            coord_z = static_cast<float>( ncells.z() );
        }
        for ( size_t j = 0; j < ( block_y + 1 ); j++ )
        {
            if ( j == block_y )
            {
                count_y = nx * ncells.y();
                coord_y = static_cast<float>( ncells.y() );
            }
            for ( size_t i = 0; i < ( block_x + 1 ); i++ )
            {
                if ( i == block_x )
                {
                    count_x = ncells.x();
                    coord_x = static_cast<float>( ncells.x() );
                }
                //values
                *(pvalues + (count++)) = *(ori_values + count_x + count_y + count_z );
                count_x += block_size;
                
                //coords
                *(pcoords++) = coord_x;   
                *(pcoords++) = coord_y;   
                *(pcoords++) = coord_z;
                coord_x += static_cast<float>( block_size );
            }
            count_x = 0;
            count_y += ( volume->resolution().x() ) * block_size;
            
            coord_x = 0.0;
            coord_y += static_cast<float>( block_size );
        }
        count_y = 0;
        count_z += ( volume->nnodesPerSlice() ) * block_size;
        
        coord_y = 0.0;
        coord_z += static_cast<float>( block_size );
    }
    size_t index_x = count;
    
    //Evalute the value of the divided point with Linear
    bool parity = (bool)block_size % 2;
    float* p = new float[3];
        
    int initial_index = (int)block_size/2;
    float initial_coord = (float)block_size/2.0;
    
    int edge_index_x = remainder_x ? (int)( remainder_x )/2 : initial_index;
    int edge_index_y = remainder_y ? (int)( remainder_y )/2 : initial_index;
    int edge_index_z = remainder_z ? (int)( remainder_z )/2 : initial_index;
    float edge_coord_x = remainder_x ? (float)( remainder_x )/2.0 : initial_coord;
    float edge_coord_y = remainder_y ? (float)( remainder_y )/2.0 : initial_coord;
    float edge_coord_z = remainder_z ? (float)( remainder_z )/2.0 : initial_coord;
    
    int temp_index_x = 0;
    int temp_index_y = 0;
    int temp_index_z = 0;
    float temp_coord_x = 0.0;
    float temp_coord_y = 0.0;
    float temp_coord_z = 0.0;
    
    //Calculate the center of the face z = 0, 1, 2 ....    
    for ( size_t k = 0; k < ( block_z + 1 ); k++ )
    {
        temp_index_z = 0;
        temp_coord_z = 0.0;
        
        if ( k == block_z )
        {
            temp_index_z = remainder_z ? ( remainder_z - (int)block_size ) : 0; 
            temp_coord_z = remainder_z ? (float)( remainder_z - (int)block_size ) : 0.0;
        }
        for ( size_t j = 0; j < ( block_y ); j++ )
        {
            temp_index_y = initial_index;
            temp_coord_y = initial_coord;

            if ( j == block_y - 1 )
            {
                temp_index_y = edge_index_y;
                temp_coord_y = edge_coord_y;
            }
            for ( size_t i = 0; i < ( block_x ); i++ )
            { 
                temp_index_x = initial_index;
                temp_coord_x = initial_coord;

                if ( i == block_x - 1 )
                {
                    temp_index_x = edge_index_x;
                    temp_coord_x = edge_coord_x;
                }

                    int u = temp_index_x + (i * block_size);
                    int v = temp_index_y + (j * block_size);
                    int w = temp_index_z + (k * block_size);
                    p[0] = temp_coord_x + (float)(i * block_size);
                    p[1] = temp_coord_y + (float)(j * block_size);
                    p[2] = temp_coord_z + (float)(k * block_size);
                    *(pcoords++) = p[0];
                    *(pcoords++) = p[1];
                    *(pcoords++) = p[2];
                
                const size_t index = u + v * nx + w * nx * ny; 
                if( parity )
                    *(pvalues + (count++)) = (ori_values[index] + ori_values[index + 1] + ori_values[index + nx] + ori_values[index + 1 + nx])/4.0;
                else
                    *(pvalues + (count++)) = ori_values[index];
            }
        }
    }
    size_t index_y = count;
    std::cout<< "x_c: " << count <<std::endl;
    
    //Calculate the center of the face x = 0, 1, 2 ....
    for ( size_t k = 0; k < ( block_z ); k++ )
    {
        temp_index_z = initial_index;
        temp_coord_z = initial_coord;
        
        if ( k == block_z - 1 )
        {
            temp_index_z = edge_index_z;
            temp_coord_z = edge_coord_z;
        }
        for ( size_t j = 0; j < ( block_y ); j++ )
        {
            temp_index_y = initial_index;
            temp_coord_y = initial_coord;

            if ( j == block_y - 1 )
            {
                temp_index_y = edge_index_y;
                temp_coord_y = edge_coord_y;
            }
            for ( size_t i = 0; i < ( block_x + 1 ); i++ )
            {
                temp_index_x = 0;
                temp_coord_x = 0.0;

                if ( i == block_x )
                {
                    temp_index_x = remainder_x ? ( remainder_x - (int)block_size ) : 0;
                    temp_coord_x = remainder_x ? (float)( remainder_x - (int)block_size ) : 0.0;
                }
                
                int u = temp_index_x + (i * block_size);
                int v = temp_index_y + (j * block_size);
                int w = temp_index_z + (k * block_size);
                p[0] = temp_coord_x + (float)(i * block_size);
                p[1] = temp_coord_y + (float)(j * block_size);
                p[2] = temp_coord_z + (float)(k * block_size);
                *(pcoords++) = p[0];
                *(pcoords++) = p[1];
                *(pcoords++) = p[2];
                
                const size_t index = u + v * nx + w * nx * ny; 
                if( parity )
                    *(pvalues + (count++)) = (ori_values[index] + ori_values[index + nx] + ori_values[index + nx * ny] + ori_values[index + nx + nx * ny])/4.0;
                else
                    *(pvalues + (count++)) = ori_values[index]; 
            }
        }
    }
    size_t index_z = count;
    std::cout<< "y_c: " << count <<std::endl;
    
    //Calculate the center of the face y = 0, 1, 2 ....    
    for ( size_t k = 0; k < ( block_z ); k++ )
    {
        temp_index_z = initial_index;
        temp_coord_z = initial_coord;
        
        if ( k == block_z - 1 )
        {
            temp_index_z = edge_index_z;
            temp_coord_z = edge_coord_z;
        }
        for ( size_t j = 0; j < ( block_y + 1 ); j++ )
        {
            temp_index_y = 0;
            temp_coord_y = 0.0;
            
            if ( j == block_y )
            {
                temp_index_y = remainder_y ? ( remainder_y - (int)block_size ) : 0;
                temp_coord_y = remainder_y ? (float)( remainder_y - (int)block_size ) : 0.0;
            }
            for ( size_t i = 0; i < ( block_x ); i++ )
            {
                temp_index_x = initial_index;
                temp_coord_x = initial_coord;
                
                if ( i == block_x - 1 )
                {
                    temp_index_x = edge_index_x;
                    temp_coord_x = edge_coord_x;
                }
                
                int u = temp_index_x + (i * block_size);
                int v = temp_index_y + (j * block_size);
                int w = temp_index_z + (k * block_size);
                p[0] = temp_coord_x + (float)(i * block_size);
                p[1] = temp_coord_y + (float)(j * block_size);
                p[2] = temp_coord_z + (float)(k * block_size);
                *(pcoords++) = p[0];
                *(pcoords++) = p[1];
                *(pcoords++) = p[2];
                
                const size_t index = u + v * nx + w * nx * ny; 
                if( parity )
                    *(pvalues + (count++)) = (ori_values[index] + ori_values[index + 1] + ori_values[index + nx * ny] + ori_values[index + 1 + nx * ny])/4.0;
                else
                    *(pvalues + (count++)) = ori_values[index];
                
            }
        }
    }
    size_t index_gravity = count;
    std::cout<< "z_c: " << count <<std::endl;
    
    //Calculate the gravity center of every cell
    temp_index_x = initial_index;
    temp_index_y = initial_index;
    temp_index_z = initial_index;
    temp_coord_x = initial_coord;
    temp_coord_y = initial_coord;
    temp_coord_z = initial_coord;
    
    for ( size_t k = 0; k < ( block_z ); k++ )
    {
        if ( k == block_z - 1 )
        {
            temp_index_z = edge_index_z;
            temp_coord_z = edge_coord_z;
        }
        for ( size_t j = 0; j < ( block_y ); j++ )
        {
            if ( j == block_y - 1 )
            {
                temp_index_y = edge_index_y;
                temp_coord_y = edge_coord_y;
            }
            for ( size_t i = 0; i < ( block_x  ); i++ )
            {
                if ( i == block_x - 1 )
                {
                    temp_index_x = edge_index_x;
                    temp_coord_x = edge_coord_x;
                }
                
                int u = temp_index_x + (i * block_size);
                int v = temp_index_y + (j * block_size);
                int w = temp_index_z + (k * block_size);
                p[0] = temp_coord_x + (float)(i * block_size);
                p[1] = temp_coord_y + (float)(j * block_size);
                p[2] = temp_coord_z + (float)(k * block_size);
                *(pcoords++) = p[0];
                *(pcoords++) = p[1];
                *(pcoords++) = p[2];
                
                const size_t index = u + v * nx + w * nx * ny; 
                if( parity )
                    *(pvalues + (count++)) = (ori_values[index] + ori_values[index + 1] + ori_values[index + nx] + ori_values[index + nx + 1] + ori_values[index + nx * ny] + ori_values[index + 1 + nx * ny] + ori_values[index + nx + nx * ny] + ori_values[index + nx + 1 + nx * ny])/8.0;
                else
                    *(pvalues + (count++)) = ori_values[index];

                
            }
            temp_index_x = initial_index;
            temp_coord_x = initial_coord;
        }
        temp_index_y = initial_coord;
        temp_coord_y = initial_coord;
    }

    //Calculate the new connection
    kvs::ValueArray<kvs::UInt32> connections( ntets * 4 );
    kvs::UInt32* pconnections = connections.pointer();
    
    for ( size_t k = 0; k < block_z; k++ )
    {
        for ( size_t j = 0; j < block_y; j++ )
        {
            for ( size_t i = 0; i < block_x; i++ )
            {
                const size_t index = i + j * line_size + k * slice_size;
                const kvs::UInt32 id0 = index;
                const kvs::UInt32 id1 = id0 + 1;
                const kvs::UInt32 id2 = id0 + line_size;
                const kvs::UInt32 id3 = id1 + line_size;
                const kvs::UInt32 id4 = id0 + slice_size;
                const kvs::UInt32 id5 = id1 + slice_size;
                const kvs::UInt32 id6 = id2 + slice_size;
                const kvs::UInt32 id7 = id3 + slice_size;
                
                const size_t index_center = i + j * block_x + k * block_x * block_y;
                const kvs::UInt32 id8 = index_x + index_center;
                const kvs::UInt32 id10 = id8 + (block_x * block_y);
                const kvs::UInt32 id11 = index_y + index_center;
                const kvs::UInt32 id9 = id11 + 1;
                const kvs::UInt32 id12 = index_z + index_center;
                const kvs::UInt32 id13 = id12 + block_x;
                const kvs::UInt32 id14 = index_gravity + index_center;

                //tet0
                *(pconnections++) = id14;
                *(pconnections++) = id8;
                *(pconnections++) = id0;
                *(pconnections++) = id1;
                
                //tet1
                *(pconnections++) = id14;
                *(pconnections++) = id8;
                *(pconnections++) = id1;
                *(pconnections++) = id3;
                
                //tet2
                *(pconnections++) = id14;
                *(pconnections++) = id8;
                *(pconnections++) = id3;
                *(pconnections++) = id2;
                
                //tet3
                *(pconnections++) = id14;
                *(pconnections++) = id8;
                *(pconnections++) = id2;
                *(pconnections++) = id0;
                
                //tet4
                *(pconnections++) = id14;
                *(pconnections++) = id9;
                *(pconnections++) = id1;
                *(pconnections++) = id5;
                
                //tet5
                *(pconnections++) = id14;
                *(pconnections++) = id9;
                *(pconnections++) = id5;
                *(pconnections++) = id7;
                
                //tet6
                *(pconnections++) = id14;
                *(pconnections++) = id9;
                *(pconnections++) = id7;
                *(pconnections++) = id3;
                
                //tet7
                *(pconnections++) = id14;
                *(pconnections++) = id9;
                *(pconnections++) = id3;
                *(pconnections++) = id1;
                
                //tet8
                *(pconnections++) = id14;
                *(pconnections++) = id10;
                *(pconnections++) = id5;
                *(pconnections++) = id4;
                
                //tet9
                *(pconnections++) = id14;
                *(pconnections++) = id10;
                *(pconnections++) = id4;
                *(pconnections++) = id6;
                
                //tet10
                *(pconnections++) = id14;
                *(pconnections++) = id10;
                *(pconnections++) = id6;
                *(pconnections++) = id7;
                
                //tet11
                *(pconnections++) = id14;
                *(pconnections++) = id10;
                *(pconnections++) = id7;
                *(pconnections++) = id5;
                
                //tet12
                *(pconnections++) = id14;
                *(pconnections++) = id11;
                *(pconnections++) = id4;
                *(pconnections++) = id0;
                
                //tet13
                *(pconnections++) = id14;
                *(pconnections++) = id11;
                *(pconnections++) = id0;
                *(pconnections++) = id2;
                
                //tet14
                *(pconnections++) = id14;
                *(pconnections++) = id11;
                *(pconnections++) = id2;
                *(pconnections++) = id6;
                
                //tet15
                *(pconnections++) = id14;
                *(pconnections++) = id11;
                *(pconnections++) = id6;
                *(pconnections++) = id4;
                
                //tet16
                *(pconnections++) = id14;
                *(pconnections++) = id12;
                *(pconnections++) = id1;
                *(pconnections++) = id0;
                
                //tet17
                *(pconnections++) = id14;
                *(pconnections++) = id12;
                *(pconnections++) = id0;
                *(pconnections++) = id4;
                
                //tet18
                *(pconnections++) = id14;
                *(pconnections++) = id12;
                *(pconnections++) = id4;
                *(pconnections++) = id5;
                
                //tet19
                *(pconnections++) = id14;
                *(pconnections++) = id12;
                *(pconnections++) = id5;
                *(pconnections++) = id1;
                
                //tet20
                *(pconnections++) = id14;
                *(pconnections++) = id13;
                *(pconnections++) = id2;
                *(pconnections++) = id3;
                
                //tet21
                *(pconnections++) = id14;
                *(pconnections++) = id13;
                *(pconnections++) = id3;
                *(pconnections++) = id7;
                
                //tet22
                *(pconnections++) = id14;
                *(pconnections++) = id13;
                *(pconnections++) = id7;
                *(pconnections++) = id6;
                
                //tet23
                *(pconnections++) = id14;
                *(pconnections++) = id13;
                *(pconnections++) = id6;
                *(pconnections++) = id2;

            }
            index_y ++;
        }
        index_z += block_x;
    }    

    if ( volume->hasMinMaxExternalCoords() )
    {
        const kvs::Vector3f min_coord( volume->minExternalCoord() );
        const kvs::Vector3f max_coord( volume->maxExternalCoord() );
        SuperClass::setMinMaxExternalCoords( min_coord, max_coord );
    }

    if ( volume->hasMinMaxObjectCoords() )
    {
        const kvs::Vector3f min_coord( volume->minObjectCoord() );
        const kvs::Vector3f max_coord( volume->maxObjectCoord() );
        SuperClass::setMinMaxObjectCoords( min_coord, max_coord );
    }

    if ( volume->hasMinMaxValues() )
    {
        const kvs::Real64 min_value( volume->minValue() );
        const kvs::Real64 max_value( volume->maxValue() );
        SuperClass::setMinMaxValues( min_value, max_value );
    }

    SuperClass::setVeclen( volume->veclen() );
    SuperClass::setNNodes( nnodes );
    SuperClass::setNCells( ntets );
    SuperClass::setCellType( kvs::UnstructuredVolumeObject::Tetrahedra );
    SuperClass::setCoords( coords );
    SuperClass::setConnections( connections );
    SuperClass::setValues( values );
    SuperClass::updateMinMaxCoords();
    SuperClass::updateMinMaxValues();

    return this;
}
/*===========================================================================*/
bool KVSMLObjectStructuredVolume::read( const std::string& filename )
{
    BaseClass::setFilename( filename );
    BaseClass::setSuccess( false );

    // XML document
    kvs::XMLDocument document;
    if ( !document.read( filename ) )
    {
        kvsMessageError( "%s", document.ErrorDesc().c_str() );
        return false;
    }

    // <KVSML>
    m_kvsml_tag.read( &document );

    // <Object>
    if ( !m_object_tag.read( m_kvsml_tag.node() ) )
    {
        kvsMessageError( "Cannot read <%s>.", m_object_tag.name().c_str() );
        return false;
    }

    // <StructuredVolumeObject>
    kvs::kvsml::StructuredVolumeObjectTag volume_tag;
    if ( !volume_tag.read( m_object_tag.node() ) )
    {
        kvsMessageError( "Cannot read <%s>.", volume_tag.name().c_str() );
        return false;
    }

    if ( !volume_tag.hasResolution() )
    {
        kvsMessageError( "'resolution' is not specified in <%s>.", volume_tag.name().c_str() );
        return false;
    }
    m_resolution = volume_tag.resolution();

    if ( !volume_tag.hasGridType() )
    {
        kvsMessageError( "'grid_type' is not specified in <%s>.", volume_tag.name().c_str() );
        return false;
    }
    m_grid_type = volume_tag.gridType();

    // <Node>
    kvs::kvsml::NodeTag node_tag;
    if ( !node_tag.read( volume_tag.node() ) )
    {
        kvsMessageError( "Cannot read <%s>.", node_tag.name().c_str() );
        return false;
    }

    // <Value>
    kvs::kvsml::ValueTag value_tag;
    if ( !value_tag.read( node_tag.node() ) )
    {
        kvsMessageError( "Cannot read <%s>.", value_tag.name().c_str() );
        return false;
    }

    m_has_label = value_tag.hasLabel();
    if ( m_has_label ) { m_label = value_tag.label(); }

    m_has_unit = value_tag.hasUnit();
    if ( m_has_unit ) { m_unit = value_tag.unit(); }

    if ( !value_tag.hasVeclen() )
    {
        kvsMessageError( "'veclen' is not specified in <%s>.", value_tag.name().c_str() );
        return false;
    }
    m_veclen = value_tag.veclen();

    m_has_min_value = value_tag.hasMinValue();
    if ( m_has_min_value ) { m_min_value = value_tag.minValue(); }

    m_has_max_value = value_tag.hasMaxValue();
    if ( m_has_max_value ) { m_max_value = value_tag.maxValue(); }

    // <DataArray>
    const kvs::Vector3ui resolution = volume_tag.resolution();
    const size_t nnodes = resolution.x() * resolution.y() * resolution.z();
    const size_t veclen = value_tag.veclen();
    const size_t nelements = nnodes * veclen;
    kvs::kvsml::DataArrayTag values;
    if ( !values.read( value_tag.node(), nelements, &m_values ) )
    {
        kvsMessageError( "Cannot read <%s> for <%s>.",
                         values.name().c_str(),
                         value_tag.name().c_str() );
        return false;
    }

    // <Coord>
    if ( m_grid_type == "rectilinear" )
    {
        kvs::kvsml::CoordTag coord_tag;
        if ( !coord_tag.read( node_tag.node() ) )
        {
            kvsMessageError( "Cannot read <%s>.", coord_tag.name().c_str() );
            return false;
        }

        // <DataArray>
        kvs::kvsml::DataArrayTag coords;
        const size_t dimension = 3;
        size_t coord_nelements = 0;
        for ( size_t i = 0; i < dimension; i++ ) coord_nelements += resolution[i];
        if ( !coords.read( coord_tag.node(), coord_nelements, &m_coords ) )
        {
            kvsMessageError( "Cannot read <%s> for <%s>.",
                             coords.name().c_str(),
                             coord_tag.name().c_str() );
            return false;
        }
    }
    else if ( m_grid_type == "curvilinear" )
    {
        kvs::kvsml::CoordTag coord_tag;
        if ( !coord_tag.read( node_tag.node() ) )
        {
            kvsMessageError( "Cannot read <%s>.", coord_tag.name().c_str() );
            return false;
        }

        // <DataArray>
        kvs::kvsml::DataArrayTag coords;
        const size_t dimension = 3;
        const size_t coord_nelements = nnodes * dimension;
        if ( !coords.read( coord_tag.node(), coord_nelements, &m_coords ) )
        {
            kvsMessageError( "Cannot read <%s> for <%s>.",
                             coords.name().c_str(),
                             coord_tag.name().c_str() );
            return false;
        }
    }

    BaseClass::setSuccess( true );
    return true;
}
Beispiel #7
0
void HitAndMissSampling::generate_particles( const kvs::StructuredVolumeObject* volume  )
{
    // Set the geometry arrays.
    const size_t max_nparticles = volume->numberOfNodes();
    std::vector<kvs::Real32> coords;  coords.reserve( max_nparticles * 3 );
    std::vector<kvs::UInt8>  colors;  colors.reserve( max_nparticles * 3 );
    std::vector<kvs::Real32> normals; normals.reserve( max_nparticles * 3 );

    // Aliases.
    const kvs::Vector3ui resolution = volume->resolution();
    const size_t line_size  = volume->numberOfNodesPerLine();
    const size_t slice_size = volume->numberOfNodesPerSlice();
    const T* values = reinterpret_cast<const T*>( volume->values().data() );

    kvs::MersenneTwister R; // Random number generator
    size_t index = 0;     // index of voxel
    for ( size_t k = 0; k < resolution.z(); k++ )
    {
        for ( size_t j = 0; j < resolution.y(); j++ )
        {
            for ( size_t i = 0; i < resolution.x(); i++, index++ )
            {
                // Rejection.
                const size_t voxel_value = values[ index ];
                if( R() < BaseClass::opacityMap()[ voxel_value ] )
                {
                    // Set coordinate value.
                    coords.push_back( static_cast<kvs::Real32>(i) );
                    coords.push_back( static_cast<kvs::Real32>(j) );
                    coords.push_back( static_cast<kvs::Real32>(k) );

                    // Set color value.
                    colors.push_back( BaseClass::colorMap()[ voxel_value ].r() );
                    colors.push_back( BaseClass::colorMap()[ voxel_value ].g() );
                    colors.push_back( BaseClass::colorMap()[ voxel_value ].b() );

                    // Calculate a normal vector at the node(i,j,k).
                    kvs::Vector3ui front( index, index, index ); // front index
                    kvs::Vector3ui back( index, index, index );  // back index

                    if(      i == 0                  ) front.x() += 1;
                    else if( i == resolution.x() - 1 ) back.x()  -= 1;
                    else{ front.x() += 1; back.x() -= 1; }

                    if(      j == 0                  ) front.y() += line_size;
                    else if( j == resolution.y() - 1 ) back.y()  -= line_size;
                    else{ front.y() += line_size; back.y() -= line_size; }

                    if(      k == 0                  ) front.z() += slice_size;
                    else if( k == resolution.z() - 1 ) back.z()  -= slice_size;
                    else{ front.z() += slice_size; back.z() -= slice_size; }

                    // Set normal vector.
                    normals.push_back( static_cast<kvs::Real32>( values[ front.x() ] - values[ back.x() ] ) );
                    normals.push_back( static_cast<kvs::Real32>( values[ front.y() ] - values[ back.y() ] ) );
                    normals.push_back( static_cast<kvs::Real32>( values[ front.z() ] - values[ back.z() ] ) );
                }
            } // end of i-loop
        } // end of j-loop
    } // end of k-loop

    SuperClass::setCoords( kvs::ValueArray<kvs::Real32>( coords ) );
    SuperClass::setColors( kvs::ValueArray<kvs::UInt8>( colors ) );
    SuperClass::setNormals( kvs::ValueArray<kvs::Real32>( normals ) );
    SuperClass::setSize( 1.0f );
}