void PrimitiveReader::readGeomParam( const T ¶m, const Alembic::Abc::ISampleSelector &sampleSelector, IECoreScene::Primitive *primitive ) const { typedef typename T::prop_type::sample_ptr_type SamplePtr; typedef typename IGeomParamTraits<T>::DataType DataType; typedef typename T::sample_type GeomParamSample; if( param.getArrayExtent() > 1 ) { IECore::msg( IECore::Msg::Warning, "FromAlembicGeomBaseConverter::convertArbGeomParam", boost::format( "Param \"%s\" has unsupported array extent" ) % param.getHeader().getName() ); return; } SamplePtr sample; Abc::UInt32ArraySamplePtr indices; if( param.isIndexed() ) { GeomParamSample geomParamSample = param.getIndexedValue( sampleSelector ); sample = geomParamSample.getVals(); indices = geomParamSample.getIndices(); } else { sample = param.getExpandedValue( sampleSelector ).getVals(); } typename DataType::Ptr data = new DataType(); data->writable().resize( sample->size() ); std::copy( sample->get(), sample->get() + sample->size(), data->writable().begin() ); ApplyGeometricInterpretation<DataType, T>::apply( data.get() ); PrimitiveVariable pv; pv.interpolation = interpolation( param.getScope() ); pv.data = data; if( param.isIndexed() ) { IntVectorDataPtr indexData = new IntVectorData(); indexData->writable().resize( indices->size() ); std::copy( indices->get(), indices->get() + indices->size(), indexData->writable().begin() ); pv.indices = indexData; } primitive->variables[param.getHeader().getName()] = pv; }
DataPtr EXRImageReader::readTypedChannel( const std::string &name, const Imath::Box2i &dataWindow, const Imf::Channel *channel ) { assert( channel ); Imath::V2i pixelDimensions = dataWindow.size() + Imath::V2i( 1 ); unsigned numPixels = pixelDimensions.x * pixelDimensions.y; typedef TypedData<vector<T> > DataType; typename DataType::Ptr data = new DataType; data->writable().resize( numPixels ); Imath::Box2i fullDataWindow = this->dataWindow(); if( fullDataWindow.min.x==dataWindow.min.x && fullDataWindow.max.x==dataWindow.max.x ) { // the width we want to read matches the width in the file, so we can read straight // into the result buffer FrameBuffer frameBuffer; T *buffer00 = data->baseWritable() - dataWindow.min.y * pixelDimensions.x - fullDataWindow.min.x; Slice slice( channel->type, (char *)buffer00, sizeof(T), sizeof(T) * pixelDimensions.x ); frameBuffer.insert( name.c_str(), slice ); m_inputFile->setFrameBuffer( frameBuffer ); // exr library will choose the best order to read scanlines automatically (increasing or decreasing) try { m_inputFile->readPixels( dataWindow.min.y, dataWindow.max.y ); } catch( Iex::InputExc &e ) { // so we can read incomplete files msg( Msg::Warning, "EXRImageReader::readChannel", e.what() ); return data; } } else { // widths don't match, we need to read into a temporary buffer and then transfer just // the bits we need into the result buffer. int numTmpPixels = fullDataWindow.size().x + 1; vector<T> tmpBuffer( numTmpPixels ); T *tmpBufferTransferStart = &(tmpBuffer[0]) + dataWindow.min.x - fullDataWindow.min.x; size_t tmpBufferTransferLength = pixelDimensions.x * sizeof( T ); T *transferDestination = &(data->writable()[0]); // slice has yStride of 0 so each successive scanline just overwrites the previous one Slice slice( channel->type, (char *)(&(tmpBuffer[0]) - fullDataWindow.min.x), sizeof(T), 0 ); FrameBuffer frameBuffer; frameBuffer.insert( name.c_str(), slice ); m_inputFile->setFrameBuffer( frameBuffer ); int yStart = dataWindow.min.y; int yEnd = dataWindow.max.y; int yStep = 1; try { for( int y=yStart; y!=(yEnd+yStep); y+=yStep ) { m_inputFile->readPixels( y ); memcpy( (char *)transferDestination, (const char *)tmpBufferTransferStart, tmpBufferTransferLength ); transferDestination += pixelDimensions.x; } } catch( Iex::InputExc &e ) { // so we can read incomplete files msg( Msg::Warning, "EXRImageReader::readChannel", e.what() ); return data; } } #ifndef NDEBUG for ( typename DataType::ValueType::const_iterator it = data->readable().begin(); it != data->readable().end(); ++it ) { assert( *it == *it ); // Will fail iff NaN } #endif return data; }