Skip to content

Commit

Permalink
Merge pull request #37 from favreau/master
Browse files Browse the repository at this point in the history
Added support for sequence of volumes
  • Loading branch information
favreau committed Oct 25, 2016
2 parents 6c96b58 + 17c9045 commit 50e84db
Show file tree
Hide file tree
Showing 25 changed files with 527 additions and 246 deletions.
7 changes: 4 additions & 3 deletions brayns/Brayns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ struct Brayns::Impl

// Build geometry
loadData();
scene->commitVolumeData();
scene->buildEnvironment( );
scene->buildGeometry( );

Expand Down Expand Up @@ -140,13 +141,13 @@ struct Brayns::Impl

if(!volumeParameters.getFilename().empty() || !volumeParameters.getFolder().empty())
{
scene->getVolumeHandler()->setTimestamp( 0.f );
const Vector3ui& volumeDimensions = scene->getVolumeHandler()->getDimensions();
const Vector3f& volumeScale = volumeParameters.getScale();
const Vector3f& volumeElementSpacing = volumeParameters.getElementSpacing();
Boxf& worldBounds = scene->getWorldBounds();
worldBounds.merge( Vector3f( 0.f, 0.f, 0.f ));
worldBounds.merge( Vector3f( volumeDimensions ) * volumeScale );
worldBounds.merge( Vector3f( volumeDimensions ) * volumeElementSpacing );
}
scene->commitVolumeData();

if( scene->isEmpty() && !scene->getVolumeHandler() )
scene->buildDefault();
Expand Down
36 changes: 19 additions & 17 deletions brayns/common/scene/Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include <servus/uri.h>

#include <boost/filesystem.hpp>
#include <algorithm>

namespace brayns
{
Expand Down Expand Up @@ -160,6 +159,8 @@ void Scene::buildDefault( )
{
BRAYNS_INFO << "Building default Cornell Box scene" << std::endl;

const Vector3f WHITE = { 1.f, 1.f, 1.f };

const Vector3f positions[8] =
{
{ 0.f, 0.f, 0.f },
Expand Down Expand Up @@ -192,26 +193,24 @@ void Scene::buildDefault( )
{ 0.8f, 0.8f, 0.8f }
};

const Vector3f WHITE = { 1.f, 1.f, 1.f };

// Cornell box
for( size_t material = 1; material < 6; ++material )
{
_materials[material]->setColor( colors[material] );
_materials[material]->setColor( colors[ material ] );
_materials[material]->setSpecularColor( WHITE );
_materials[material]->setSpecularExponent( 10.f );
_materials[material]->setReflectionIndex( material == 4 ? 0.8f : 0.f );
_materials[material]->setOpacity( 1.f );
for( size_t i = 0; i < 6; ++i )
{
const Vector3f& position = positions[ indices[material][i] ];
const Vector3f& position = positions[ indices[ material ][ i ] ];
_trianglesMeshes[material].getVertices().push_back( position );
_bounds.merge( position );
_trianglesMeshes[material].getIndices().push_back(
Vector3i( 0, 1, 2 ));
_trianglesMeshes[material].getIndices().push_back(
Vector3i( 3, 4, 5 ));
}
_trianglesMeshes[material].getIndices().push_back(
Vector3ui( 0, 1, 2 ));
_trianglesMeshes[material].getIndices().push_back(
Vector3ui( 3, 4, 5 ));
}

size_t material = 7;
Expand Down Expand Up @@ -514,21 +513,23 @@ AbstractSimulationHandlerPtr Scene::getSimulationHandler() const

VolumeHandlerPtr Scene::getVolumeHandler()
{
const std::string& volumeFile =
_parametersManager.getVolumeParameters().getFilename();
const std::string& volumeFolder =
_parametersManager.getVolumeParameters().getFolder();
if( volumeFile.empty() && volumeFolder.empty() )
return 0;

try
{
const std::string& volumeFile =
_parametersManager.getVolumeParameters().getFilename();
const std::string& volumeFolder =
_parametersManager.getVolumeParameters().getFolder();

if( !_volumeHandler && ( !volumeFile.empty() || !volumeFolder.empty() ))
if( !_volumeHandler )
{
_volumeHandler.reset( new VolumeHandler( _parametersManager.getVolumeParameters() ));
_volumeHandler.reset( new VolumeHandler(
_parametersManager.getVolumeParameters(), TimestampMode::modulo ));
if( !volumeFile.empty() )
_volumeHandler->attachVolumeToFile( 0.f, volumeFile );
else
{
float timestamp = 0.f;
strings filenames;

boost::filesystem::directory_iterator endIter;
Expand All @@ -550,6 +551,7 @@ VolumeHandlerPtr Scene::getVolumeHandler()
}
}
std::sort(filenames.begin(), filenames.end());
float timestamp = 0.f;
for( const auto& filename: filenames )
{
_volumeHandler->attachVolumeToFile( timestamp, filename );
Expand Down
7 changes: 7 additions & 0 deletions brayns/common/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,13 @@ enum CameraType
CT_PANORAMIC
};

enum class TimestampMode
{
unchanged,
modulo,
bounded
};

}

#endif // TYPES_H
174 changes: 139 additions & 35 deletions brayns/common/volume/VolumeHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,66 +28,170 @@
#include <sys/stat.h>
#include <fcntl.h>

namespace
{
const int NO_DESCRIPTOR = -1;
}

namespace brayns
{

VolumeHandler::VolumeHandler(
const VolumeParameters& volumeParameters )
: _dimensions( volumeParameters.getDimensions() )
VolumeParameters& volumeParameters,
const TimestampMode timestampMode )
: _volumeParameters( &volumeParameters )
, _timestamp( std::numeric_limits<float>::max( ))
, _timestampRange( std::numeric_limits<float>::max(), std::numeric_limits<float>::min( ))
, _timestampMode( timestampMode )
{
}

VolumeHandler::~VolumeHandler()
{
for( auto memoryMapPtr: _memoryMapPtrs )
if( memoryMapPtr.second )
::munmap( (void *)memoryMapPtr.second, _size );

for( auto cacheFileDescriptor: _cacheFileDescriptors )
if( cacheFileDescriptor.second != -1 )
::close( cacheFileDescriptor.second );
_volumeDescriptors.clear();
}

void VolumeHandler::attachVolumeToFile( const float timestamp, const std::string& volumeFile )
{
BRAYNS_INFO << "Attaching " << volumeFile << " to timestamp " << timestamp << std::endl;
_cacheFileDescriptors[ timestamp ] = open( volumeFile.c_str(), O_RDONLY );
if( _cacheFileDescriptors[ timestamp ] == -1 )
BRAYNS_THROW( std::runtime_error( "Failed to attach " + volumeFile ));
// Add volume descriptor for specified timestamp
_volumeDescriptors[ timestamp ].reset( new VolumeDescriptor(
volumeFile,
_volumeParameters->getDimensions(),
_volumeParameters->getElementSpacing(),
_volumeParameters->getOffset()));

struct stat sb;
if( ::fstat( _cacheFileDescriptors[ timestamp ], &sb ) == -1 )
BRAYNS_THROW( std::runtime_error( "Failed to attach " + volumeFile ));
// Update timestamp range
for( const auto& volumeDescriptor: _volumeDescriptors )
{
_timestampRange.x() = std::min( _timestampRange.x(), volumeDescriptor.first );
_timestampRange.y() = std::max( _timestampRange.y(), volumeDescriptor.first );
}
BRAYNS_INFO << "Attached " << volumeFile << " to timestamp "
<< timestamp << " " << _timestampRange << std::endl;
}

_memoryMapPtrs[ timestamp ] = ::mmap(
0, sb.st_size, PROT_READ, MAP_PRIVATE, _cacheFileDescriptors[ timestamp ], 0 );
if( _memoryMapPtrs[ timestamp ] == MAP_FAILED )
void VolumeHandler::setTimestamp( const float timestamp )
{
const float ts = _getBoundedTimestamp( timestamp );
if( ts != _timestamp &&
_volumeDescriptors.find( ts ) != _volumeDescriptors.end( ))
{
_memoryMapPtrs[ timestamp ] = 0;
::close( _cacheFileDescriptors[ timestamp ] );
BRAYNS_THROW( std::runtime_error( "Failed to attach " + volumeFile ));
if( _volumeDescriptors.find( _timestamp ) != _volumeDescriptors.end( ))
_volumeDescriptors[ _timestamp ]->unmap();
_timestamp = ts;
_volumeDescriptors[ _timestamp ]->map();
}
}

_size = sb.st_size;
void* VolumeHandler::getData() const
{
return _volumeDescriptors.at( _timestamp )->getMemoryMapPtr();
}

BRAYNS_INFO << "Volume size : " << _size << " bytes ["
<< _size / 1048576 << " MB]" << std::endl;
BRAYNS_INFO << "Volume dimensions: " << _dimensions << std::endl;
BRAYNS_INFO << "Successfully attached to " << volumeFile << std::endl;
float VolumeHandler::getEpsilon(
const Vector3f& elementSpacing,
const uint16_t samplesPerRay )
{
const Vector3f diag = _volumeDescriptors.at( _timestamp )->getDimensions( ) * elementSpacing;
return diag.find_max() / float( samplesPerRay );
}

const Vector3ui VolumeHandler::getDimensions() const
{
return _volumeDescriptors.at( _timestamp )->getDimensions();
}

const Vector3f VolumeHandler::getElementSpacing() const
{
return _volumeDescriptors.at( _timestamp )->getElementSpacing();
}

void* VolumeHandler::getData( const float timestamp )
const Vector3f VolumeHandler::getOffset() const
{
size_t ts = timestamp;
ts = ts % _memoryMapPtrs.size();
BRAYNS_INFO << "Assigning volume for timestamp " << ts << std::endl;
return _memoryMapPtrs[ ts ];
return _volumeDescriptors.at( _timestamp )->getOffset();
}

float VolumeHandler::getEpsilon( const Vector3f& scale, const uint16_t samplesPerRay )
uint64_t VolumeHandler::getSize() const
{
Vector3f diag = Vector3f(_dimensions) * scale;
return std::max(diag.x(), std::max( diag.y(), diag.z())) / float( samplesPerRay );
return _volumeDescriptors.at( _timestamp )->getSize();
}

float VolumeHandler::_getBoundedTimestamp( const float timestamp ) const
{
float result;
switch( _timestampMode )
{
case TimestampMode::modulo:
result = size_t( timestamp + _timestampRange.x( )) % _volumeDescriptors.size();
break;
case TimestampMode::bounded:
result = std::max( std::min( timestamp, _timestampRange.y( )), _timestampRange.x( ));
case TimestampMode::unchanged:
default:
result = timestamp;
}
return result;
}

VolumeHandler::VolumeDescriptor::VolumeDescriptor(
const std::string& filename,
const Vector3ui& dimensions,
const Vector3f& elementSpacing,
const Vector3f& offset )
: _filename( filename )
, _memoryMapPtr( 0 )
, _cacheFileDescriptor( NO_DESCRIPTOR )
, _dimensions( dimensions )
, _elementSpacing( elementSpacing )
, _offset( offset )
{
}

VolumeHandler::VolumeDescriptor::~VolumeDescriptor()
{
unmap();
}

void VolumeHandler::VolumeDescriptor::map()
{
_cacheFileDescriptor = open( _filename.c_str(), O_RDONLY );
if( _cacheFileDescriptor == NO_DESCRIPTOR )
{
BRAYNS_ERROR << "Failed to attach " << _filename << std::endl;
return;
}

struct stat sb;
if( ::fstat( _cacheFileDescriptor, &sb ) == NO_DESCRIPTOR )
{
BRAYNS_ERROR << "Failed to attach " << _filename << std::endl;
return;
}

_size = sb.st_size;
_memoryMapPtr = ::mmap( 0, _size, PROT_READ, MAP_PRIVATE, _cacheFileDescriptor, 0 );
if( _memoryMapPtr == MAP_FAILED )
{
_memoryMapPtr = 0;
::close( _cacheFileDescriptor );
_cacheFileDescriptor = NO_DESCRIPTOR;
BRAYNS_ERROR << "Failed to attach " << _filename << std::endl;
return;
}
}

void VolumeHandler::VolumeDescriptor::unmap()
{
if( _memoryMapPtr )
{
::munmap( (void*)_memoryMapPtr, _size );
_memoryMapPtr = 0;
}
if( _cacheFileDescriptor != NO_DESCRIPTOR )
{
::close( _cacheFileDescriptor );
_cacheFileDescriptor = NO_DESCRIPTOR;
}
}

}
Loading

0 comments on commit 50e84db

Please sign in to comment.