void execute(const FutureMap& input, PromiseMap& output) const { const UniqueFutureMap uniqueInputs(input.getFutures()); const auto& frustum = uniqueInputs.get<Frustum>("Frustum"); const auto& frame = uniqueInputs.get<uint32_t>("Frame"); const auto& range = uniqueInputs.get<Range>("DataRange"); const auto& params = uniqueInputs.get<VolumeRendererParameters>("Params"); const auto& vp = uniqueInputs.get<PixelViewport>("Viewport"); const auto& clipPlanes = uniqueInputs.get<ClipPlanes>("ClipPlanes"); const uint32_t windowHeight = vp[3]; const float sse = params.getScreenSpaceError(); const uint32_t minLOD = params.getMinLod(); const uint32_t maxLOD = std::min(params.getMaxLod(), _dataSource.getVolumeInfo().rootNode.getDepth() - 1); SelectVisibles visitor(frustum, windowHeight, sse, minLOD, maxLOD, range, clipPlanes); DFSTraversal traverser(_dataSource); traverser.traverse(visitor, frame); output.set("VisibleNodes", visitor.getVisibles()); output.set("Params", params); }
void execute(const FutureMap& input, PromiseMap& output) const { const auto& frustums = input.get<Frustum>("Frustum"); const auto& viewports = input.get<Viewport>("RelativeViewport"); auto dataSourceRange = input.get<Vector2f>("DataSourceRange").front(); const auto& frustum = frustums.front(); const auto& viewport = viewports.front(); Histogram histogramAccumulated; for (const auto& cacheObjects : input.getFutures("CacheObjects")) for (const auto& cacheObject : cacheObjects.get<ConstCacheObjects>()) { const CacheId& cacheId = cacheObject->getId(); // Hist cache object expands the data source range if data has // larger values ConstHistogramObjectPtr histCacheObject = _histogramCache.load<HistogramObject>(cacheId, _dataCache, _dataSource, dataSourceRange); if (!histCacheObject) continue; const Vector2f& currentRange = histCacheObject->getHistogram().getRange(); if (currentRange[0] < dataSourceRange[0]) dataSourceRange[0] = currentRange[0]; histogramAccumulated.setMin(dataSourceRange[0]); if (currentRange[1] > dataSourceRange[1]) dataSourceRange[1] = currentRange[1]; histogramAccumulated.setMax(dataSourceRange[1]); const size_t currentBinCount = histCacheObject->getHistogram().getBins().size(); if (histogramAccumulated.getBins().empty()) histogramAccumulated.resize(currentBinCount); // When a frame is rendered in multi-channel, multi-node, etc // config, some nodes are rendered twice in sort-first // renderings // To avoid counting nodes twice, we check if the center of the // node is in // this frustum (because it can only be in one tile at a time). // For viewports // on the border of the absolute viewport, the frustum is // virtually extended // to infinity on the boundary. try { const LODNode& lodNode = _dataSource.getNode(NodeId(cacheId)); if (isCenterInViewport(frustum, lodNode.getWorldBox(), viewport)) histogramAccumulated += histCacheObject->getHistogram(); } catch (const std::runtime_error&) { // Only compatible histograms can be added.( i.e same data // range and number of // bins.) Until data range converges to the full data range // combined from other // rendering clients, the cache objects are purged from the // cache. _histogramCache.purge(cacheId); } } output.set("Histogram", histogramAccumulated); }