/*===========================================================================*/ 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(); }
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; }
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 ); }