1#include <IO/VolumesLoader/VolumeLoader.hpp>
3#include <IO/VolumesLoader/pvmutils.hpp>
5#include <Core/Asset/FileData.hpp>
6#include <Core/Geometry/Volume.hpp>
7#include <Core/Utils/Log.hpp>
17using namespace Ra::Core::Utils;
22VolumeLoader::VolumeLoader() =
default;
23VolumeLoader::~VolumeLoader() =
default;
26 return { {
"*." + volFileExtension }, {
"*." + pvmFileExtension } };
29bool VolumeLoader::handleFileExtension(
const std::string& extension )
const {
30 return ( extension.
compare( volFileExtension ) == 0 ) ||
31 ( extension.
compare( pvmFileExtension ) == 0 );
37 input >> name >> beg >> r >> g >> b >> end;
43 if ( expected != found ) {
44 LOG( logWARNING ) <<
"\tVolumeLoader : unexpected volume attribute " << found <<
" : "
45 << expected <<
" was expected";
51Ra::Core::Asset::FileData* VolumeLoader::loadVolFile(
const std::string& filename ) {
52 LOG( logINFO ) <<
"VolumeLoader : loading vol (pbrt based) file " << filename;
55 auto fileData =
new Ra::Core::Asset::FileData( filename );
57 auto sigma_a = readColor( input, attribname );
58 if ( !checkExpected(
"sigma_a", attribname ) ) {
return nullptr; }
59 auto sigma_s = readColor( input, attribname );
60 if ( !checkExpected(
"sigma_s", attribname ) ) {
return nullptr; }
65 input >> attribname >> beg >> sx >> sy >> sz >> end;
66 if ( !checkExpected(
"size", attribname ) ) {
return nullptr; }
68 input >> attribname >> beg;
69 if ( !checkExpected(
"density", attribname ) ) {
return nullptr; }
71 LOG( logWARNING ) <<
"\tVolumeLoader : unexpected start of density gri delimiter "
75 LOG( logINFO ) <<
"\tVolumeLoader : reading a volume of size " << sx <<
"x" << sy <<
"x"
78 Ra::Core::Vector3 voxelSize { 1_ra, 1_ra, 1_ra };
80 density->setSize( Vector3i( sx, sy, sz ) );
81 density->setBinSize( voxelSize );
82 std::generate( density->data().begin(), density->data().end(), [&input]() {
90 LOG( logWARNING ) <<
"\tVolumeLoader : unexpected end of density grid delimiter "
94 LOG( logINFO ) <<
"\tVolumeLoader : done reading";
97 volume->volume = density;
98 volume->sigma_a = sigma_a;
99 volume->sigma_s = sigma_s;
101 Ra::Core::Vector3 p0( 0, 0, 0 );
102 Ra::Core::Vector3 p1( sx, sy, sz );
103 volume->boundingBox = Aabb( p0, p1 );
104 volume->densityToModel = Transform::Identity();
105 volume->modelToWorld = Eigen::Scaling( 1_ra / maxDim );
109 LOG( logWARNING ) <<
"VolumeLoader : unable to open file " << filename;
113Ra::Core::Asset::FileData* VolumeLoader::loadPvmFile(
const std::string& filename ) {
114 using namespace PVMVolume;
116 unsigned int width, height, depth, bytePerVoxel;
117 float scalex, scaley, scalez;
118 unsigned char *description, *courtesy, *parameter, *comment;
120 auto volumeData = readPVMvolume( filename.
c_str(),
134 unsigned char empty[1] {
'\0' };
135 LOG( logINFO ) <<
"VolumeLoader : \n\tpvm (The Volume Library) file " << filename
136 <<
" \n\twidth = " << width <<
" \n\theight = " << height
137 <<
" \n\tdepth = " << depth <<
" \n\tbyte per voxel = " << bytePerVoxel
138 <<
" \n\tscalex = " << scalex <<
" \n\tscaley = " << scaley
139 <<
" \n\tscalez = " << scalez
140 <<
" \n\tdescription = " << ( description ? description : empty )
141 <<
" \n\tcourtesy = " << ( courtesy ? courtesy : empty )
142 <<
" \n\tparameter = " << ( parameter ? parameter : empty )
143 <<
" \n\tcomment = " << ( comment ? comment : empty ) <<
'\n';
145 auto fillRadiumVolume = [](
auto container,
auto densityData ) {
146 std::generate( container->data().begin(), container->data().end(), [&densityData]() {
147 auto d = *densityData++;
148 return Scalar( d ) / Scalar( std::numeric_limits<decltype( d )>::max() );
151 Ra::Core::Vector3 binSize { Scalar( scalex ), Scalar( scaley ), Scalar( scalez ) };
152 Ra::Core::Vector3i gridSize { int( width ), int( height ), int( depth ) };
154 density->setSize( gridSize );
155 density->setBinSize( binSize );
157 switch ( bytePerVoxel ) {
159 fillRadiumVolume( density, volumeData );
163 fillRadiumVolume( density, (uint16_t*)( volumeData ) );
167 fillRadiumVolume( density, (uint*)( volumeData ) );
171 LOG( logERROR ) <<
"VolumeLoader : unsupported number of componenets : "
176 LOG( logINFO ) <<
"\tVolumeLoader : done reading";
179 volume->volume = density;
181 Ra::Core::Vector3 p0 = Vector3::Zero();
182 Ra::Core::Vector3 p1 = gridSize.cast<Scalar>().cwiseProduct( binSize );
183 volume->boundingBox = Aabb( p0, p1 );
184 volume->densityToModel = Eigen::Scaling( binSize );
185 volume->modelToWorld = Eigen::Scaling( 1_ra / maxDim ) * Translation( p1 * -0.5 );
187 auto fileData =
new Ra::Core::Asset::FileData( filename );
191 LOG( logWARNING ) <<
"VolumeLoader : unable to open file " << filename;
195Ra::Core::Asset::FileData* VolumeLoader::loadFile(
const std::string& filename ) {
197 if ( extension.
compare( volFileExtension ) == 0 ) {
return loadVolFile( filename ); }
198 else if ( extension.
compare( pvmFileExtension ) == 0 ) {
return loadPvmFile( filename ); }
199 LOG( logWARNING ) <<
"VolumeLoader : unsupported file format : " << filename;
204 return "VolumeLoader (pbrt experimental, pvm)";
Discrete volume data storing values in a regular grid.
T find_last_of(T... args)
This namespace contains everything "low level", related to data, datastuctures, and computation.
hepler function to manage enum as underlying types in VariableSet