void ResourceLoadNode::evaluateResource() { void const *urlMemberData = getConstData( "url", 0 ); bool sameURL = m_fabricResourceStreamData.isURLEqualTo( urlMemberData ); bool isFirstEvalAfterLoad = m_firstEvalAfterLoad; m_firstEvalAfterLoad = false; if( sameURL && m_inProgress ) return; if( sameURL && isFirstEvalAfterLoad ) return;//[JeromeCG 20111221] The data was already set asynchronously, during setResourceData, so the work is already done. if( sameURL && (m_keepMemoryCache || m_asFile) ) { //Set from m_fabricResourceStreamData //[JeromeCG 20110727] Note: if m_asFile, the handle was created as "readOnly", so in theory the data is still valid. setResourceData( NULL, false ); return; } // [JeromeCG 20110727] Note: we use a generation because if there was a previous uncompleted request we might receive more callbacks; // we create a new one in parallel instead of waiting its completion. m_streamGeneration++; m_fabricResourceStreamData.setURL( urlMemberData ); m_fabricResourceStreamData.setMIMEType( "" ); //[JeromeCG 20120119] setDataExternalLocation: Should we care about deleting the cache file? The browser created it... can it reuse the same temp file? Maybe the user still uses it? m_fabricResourceStreamData.setDataExternalLocation( "" ); m_fabricResourceStreamData.resizeData( 0 ); m_keepMemoryCache = false; setResourceData( NULL, false ); m_keepMemoryCache = getContext()->getRTManager()->getBooleanDesc()->getValue( getConstData( "keepMemoryCache", 0 ) ); m_asFile = getContext()->getRTManager()->getBooleanDesc()->getValue( getConstData( "storeDataAsFile", 0 ) ); std::string url = m_fabricResourceStreamData.getURL(); if( !url.empty() ) { m_inProgress = true; getContext()->getIOManager()->getResourceManager()->get( url.c_str(), this, m_asFile, (void*)m_streamGeneration ); } else releaseFile(); }
void ResourceLoadNode::setResourceData( char const *errorDesc, bool notify ) { m_firstEvalAfterLoad = true; std::string url = m_fabricResourceStreamData.getURL(); std::string extension = IO::GetURLExtension( url ); size_t extensionPos = url.rfind('.'); if( extensionPos != std::string::npos ) extension = url.substr( extensionPos+1 ); else { std::string mimeType = m_fabricResourceStreamData.getMIMEType(); extensionPos = mimeType.rfind('/'); if( extensionPos != std::string::npos ) extension = mimeType.substr( extensionPos+1 ); } m_fabricResourceStreamData.setExtension( extension ); void const *prevResourceData = getConstData( "resource", 0 ); if( !m_fabricResourceStreamData.isDataEqualTo( prevResourceData ) || !m_fabricResourceStreamData.isDataExternalLocationEqualTo( prevResourceData ) ) { void *resourceDataMember = getMutableData( "resource", 0 ); m_fabricResourceStreamData.getDesc()->setData( m_fabricResourceStreamData.get(), resourceDataMember ); if( !m_keepMemoryCache ) m_fabricResourceStreamData.resizeData( 0 ); if( errorDesc ) { if ( getContext()->getLogCollector() ) { getContext()->getLogCollector()->add( ( "ResourceLoadNode " + getName() + ": error loading " + url + ": " + std::string( errorDesc ) ).c_str() ); } } } if( notify ) { std::vector<std::string> src; src.push_back( "DG" ); src.push_back( getName() ); if( errorDesc ) getContext()->jsonNotify( src, "resourceLoadFailure", 19 ); else getContext()->jsonNotify( src, "resourceLoadSuccess", 19 ); } }
PtexFaceData* PtexReader::getData(int faceid) { if (faceid < 0 || size_t(faceid) >= _header.nfaces) return 0; if (!_ok) return 0; FaceInfo& fi = _faceinfo[faceid]; if (fi.isConstant() || fi.res == 0) { return new ConstDataPtr(getConstData() + faceid * _pixelsize, _pixelsize); } // get level zero (full) res face AutoLockCache locker(_cache->cachelock); Level* level = getLevel(0); FaceData* face = getFace(0, level, faceid); level->unref(); return face; }
PtexFaceData* PtexReader::getData(int faceid, Res res) { if (!_ok) return 0; if (faceid < 0 || size_t(faceid) >= _header.nfaces) return 0; FaceInfo& fi = _faceinfo[faceid]; if ((fi.isConstant() && res >= 0) || res == 0) { return new ConstDataPtr(getConstData() + faceid * _pixelsize, _pixelsize); } // lock cache (can't autolock since we might need to unlock early) _cache->cachelock.lock(); // determine how many reduction levels are needed int redu = fi.res.ulog2 - res.ulog2, redv = fi.res.vlog2 - res.vlog2; if (redu == 0 && redv == 0) { // no reduction - get level zero (full) res face Level* level = getLevel(0); FaceData* face = getFace(0, level, faceid); level->unref(); _cache->cachelock.unlock(); return face; } if (redu == redv && !fi.hasEdits() && res >= 0) { // reduction is symmetric and non-negative // and face has no edits => access data from reduction level (if present) int levelid = redu; if (size_t(levelid) < _levels.size()) { Level* level = getLevel(levelid); // get reduction face id int rfaceid = _rfaceids[faceid]; // get the face data (if present) FaceData* face = 0; if (size_t(rfaceid) < level->faces.size()) face = getFace(levelid, level, rfaceid); level->unref(); if (face) { _cache->cachelock.unlock(); return face; } } } // dynamic reduction required - look in dynamic reduction cache FaceData*& face = _reductions[ReductionKey(faceid, res)]; if (face) { face->ref(); _cache->cachelock.unlock(); return face; } // not found, generate new reduction // unlock cache - getData and reduce will handle their own locking _cache->cachelock.unlock(); if (res.ulog2 < 0 || res.vlog2 < 0) { std::cerr << "PtexReader::getData - reductions below 1 pixel not supported" << std::endl; return 0; } if (redu < 0 || redv < 0) { std::cerr << "PtexReader::getData - enlargements not supported" << std::endl; return 0; } if (_header.meshtype == mt_triangle) { if (redu != redv) { std::cerr << "PtexReader::getData - anisotropic reductions not supported for triangle mesh" << std::endl; return 0; } PtexPtr<PtexFaceData> psrc ( getData(faceid, Res(res.ulog2+1, res.vlog2+1)) ); FaceData* src = dynamic_cast<FaceData*>(psrc.get()); assert(src); if (src) src->reduce(face, this, res, PtexUtils::reduceTri); return face; } // determine which direction to blend bool blendu; if (redu == redv) { // for symmetric face blends, alternate u and v blending blendu = (res.ulog2 & 1); } else blendu = redu > redv; if (blendu) { // get next-higher u-res and reduce in u PtexPtr<PtexFaceData> psrc ( getData(faceid, Res(res.ulog2+1, res.vlog2)) ); FaceData* src = dynamic_cast<FaceData*>(psrc.get()); assert(src); if (src) src->reduce(face, this, res, PtexUtils::reduceu); } else { // get next-higher v-res and reduce in v PtexPtr<PtexFaceData> psrc ( getData(faceid, Res(res.ulog2, res.vlog2+1)) ); FaceData* src = dynamic_cast<FaceData*>(psrc.get()); assert(src); if (src) src->reduce(face, this, res, PtexUtils::reducev); } return face; }