bool GusdUSD_StageProxy::MultiAccessor::_GetPrims( const UT_Array<SdfPath>& primPaths, UT_Array<UsdPrim>& prims, GusdUT_ErrorContext* err) { if(!_Load(primPaths)) return false; prims.setSize(primPaths.size()); std::atomic_bool workerInterrupt(false); UTparallelFor(UT_BlockedRange<size_t>(0, primPaths.size()), _GetPrimsFn(*this, primPaths, prims, err, workerInterrupt)); return !UTgetInterrupt()->opInterrupt() && !workerInterrupt; }
void RainData::shiftPositions( GU_Detail* gdp, const GA_Range &range ) { UTparallelFor(GA_SplittableRange(range), ParallelShift( this, gdp ), 2, 1); }
bool GusdUSD_StageProxy::MultiAccessor::_Load(const UT_Array<SdfPath>& paths) { if(paths.isEmpty()) return true; UT_ASSERT_P(paths.size() == _size); typedef tbb::concurrent_unordered_set< SdfPath,SdfPath::Hash> ConcurrentPathSet; struct _ComputeUnloadedPrimsFn { _ComputeUnloadedPrimsFn(const UT_Array<SdfPath>& paths, const UT_Array<exint>& indexMap, const UT_Array<_PrimLoader*>& loaders, UT_Array<ConcurrentPathSet*>& pathSets) : _paths(paths), _indexMap(indexMap), _loaders(loaders), _pathSets(pathSets) {} void operator()(const UT_BlockedRange<size_t>& r) const { auto* boss = UTgetInterrupt(); char bcnt = 0; for(size_t i = r.begin(); i < r.end(); ++i) { if(BOOST_UNLIKELY(!++bcnt && boss->opInterrupt())) return; exint idx = _indexMap(i); if(idx >= 0) { if(auto* loader = _loaders(idx)) { const SdfPath& path = _paths(i); if(!path.IsEmpty() && !loader->IsLoaded(path)) _pathSets(idx)->insert(path); } } } } private: const UT_Array<SdfPath>& _paths; const UT_Array<exint>& _indexMap; const UT_Array<_PrimLoader*>& _loaders; UT_Array<ConcurrentPathSet*> _pathSets; }; /* Compute sets of unloaded prims. This constitutes the bulk of binding time, so do this parallel.*/ UT_Array<_PrimLoader*> loaders(_numAccessors, _numAccessors); UT_Array<ConcurrentPathSet*> pathSets(_numAccessors, _numAccessors); for(exint i = 0; i < _numAccessors; ++i) { if ( _accessors[i] ) { auto* loader = _accessors[i].GetProxy()->_primLoader; if(loader) { loaders(i) = loader; pathSets(i) = new ConcurrentPathSet; } } } UTparallelFor(UT_BlockedRange<size_t>(0, _size), _ComputeUnloadedPrimsFn(paths, _indexMap, loaders, pathSets)); if(UTgetInterrupt()->opInterrupt()) return false; /* Load the actual prims. This could be done in parallel, but is probably not worth it since there's only work to perform the first time a prim load is requested.*/ for(exint i = 0; i < _numAccessors; ++i) { if(auto* pathSet = pathSets(i)) { SdfPathSet pathsToLoad(pathSet->begin(), pathSet->end()); _accessors[i]._Load(pathsToLoad); delete pathSet; } } return true; }