// **************************************************************************** // Method: avtDatasetOnDemandFilter::GetLoadedDomains // // Purpose: // Return a list of domains that are loaded. // // Programmer: Dave Pugmire // Creation: March 19, 2008 // // Modifications: // // Dave Pugmire, Tue Mar 10 12:41:11 EDT 2009 // Added support for time/domain. // // **************************************************************************** void avtDatasetOnDemandFilter::GetLoadedDomains(std::vector<std::vector<int> > &domains) { if (DebugStream::Level1()) { debug1<<"avtDatasetOnDemandFilter::GetLoadedDomains()\n"; } if ( ! OperatingOnDemand() ) EXCEPTION0(ImproperUseException); domains.resize(0); std::list<DomainCacheEntry>::const_iterator it; for ( it = domainQueue.begin(); it != domainQueue.end(); it++ ) { std::vector<int> dom(2); dom[0] = it->domainID; dom[1] = it->timeStep; domains.push_back(dom); } }
vtkDataSet * avtDatasetOnDemandFilter::GetDomain(int domainId, int timeStep) { if (DebugStream::Level5()) { debug5<<"avtDatasetOnDemandFilter::GetDomain("<<domainId<<", "<<timeStep<<");"<<endl; } if ( ! OperatingOnDemand() ) EXCEPTION0(ImproperUseException); if ( domainId < 0 ) return NULL; // See if it is already in the cache. If so, just return it. std::list<DomainCacheEntry>::iterator it; for ( it = domainQueue.begin(); it != domainQueue.end(); it++ ) { // Found it. Move it to the front of the list. if (it->domainID == domainId && it->timeStep == timeStep) { DomainCacheEntry entry; entry = *it; //Remove, then move to front. domainQueue.erase( it ); domainQueue.push_front( entry ); return entry.ds; } } avtSILRestriction_p silr; if (timeStep == firstContract->GetDataRequest()->GetTimestep()) { silr = firstContract->GetDataRequest()->GetRestriction(); } else if ((*lastUsedContract != NULL) && (timeStep == lastUsedContract->GetDataRequest()->GetTimestep())) { silr = lastUsedContract->GetDataRequest()->GetRestriction(); } else { // The SIL restriction associated with the contract may be for the wrong // time step. Go get the correct one. std::string db = GetInput()->GetInfo().GetAttributes().GetFullDBName(); ref_ptr<avtDatabase> dbp = avtCallback::GetDatabase(db, 0, NULL); if (*dbp == NULL) EXCEPTION1(InvalidFilesException, db.c_str()); std::string mesh = GetInput()->GetInfo().GetAttributes().GetMeshname(); avtDataObject_p dob = dbp->GetOutput(mesh.c_str(), timeStep); lastUsedContract = dob->GetOriginatingSource()->GetGeneralContract(); silr = lastUsedContract->GetDataRequest()->GetRestriction(); } avtDataRequest_p new_dr = new avtDataRequest(firstContract->GetDataRequest(), silr); avtContract_p new_contract = new avtContract(firstContract, new_dr); if (DebugStream::Level5()) { debug5<<" Update->GetDomain "<<domainId<<" time= "<<timeStep<<endl; } std::vector<int> domains; domains.push_back(domainId); new_contract->GetDataRequest()->GetRestriction()->TurnOnAll(); new_contract->GetDataRequest()->GetRestriction()->RestrictDomains(domains); new_contract->GetDataRequest()->SetTimestep(timeStep); new_contract->SetOnDemandStreaming(true); GetInput()->Update(new_contract); vtkDataSet *rv = GetInputDataTree()->GetSingleLeaf(); if (rv == NULL) { // This issue has been known to occur when: // -- the SIL is time varying // -- the domain requested doesn't exist for the initial time step // (which is the one where the SIL is created from). EXCEPTION1(VisItException, "Failure retrieving a data set while " "advecting particles. Please report this to a VisIt " "developer."); } // Add it to the cache. DomainCacheEntry entry; entry.domainID = domainId; entry.timeStep = timeStep; entry.ds = rv; rv->Register(NULL); loadDSCount++; //Update the domainLoadCount. //Turn two ints into a long. Put timeStep in upper, domain in lower. unsigned long long A = (((unsigned long long)timeStep)<<32); unsigned long long B = ((unsigned long long)domainId); unsigned long long idx = A | B; if (domainLoadCount.find(idx) == domainLoadCount.end()) { domainLoadCount[idx] = 1; } else { domainLoadCount[idx] ++; } domainQueue.push_front(entry); if ( domainQueue.size() > (size_t)maxQueueLength ) { DomainCacheEntry tmp = domainQueue.back(); PurgeDomain( tmp.domainID, tmp.timeStep ); domainQueue.pop_back(); purgeDSCount++; } return rv; }
vtkDataSet * avtDatasetOnDemandFilter::GetDataAroundPoint(double X, double Y, double Z, int timeStep) { if (DebugStream::Level1()) { debug1<<"avtDatasetOnDemandFilter::GetDataAroundPoint("<<X<<", "<<Y<<", "<<Z<<", "<<timeStep<<");"<<endl; } if ( ! OperatingOnDemand() ) { EXCEPTION0(ImproperUseException); } int domainId = 0; //Need to hash XYZ to domainId ??? // FIXME: For the moment we just use one domain ID (0) for all points. This choice will cause // the following for loop to test *all* cache entries whether they contain the point location. // This strategy is not very efficient, but better than a pipeline re-execute. if (DebugStream::Level5()) { debug5<<"Look in cache: "<<domainId<<" sz= "<<domainQueue.size()<<endl; } //See if it's in the cache. std::list<DomainCacheEntry>::iterator it; int foundPos = 0; for ( it = domainQueue.begin(); it != domainQueue.end(); it++ ) { // Found it. Move it to the front of the list. if (it->domainID == domainId && it->timeStep == timeStep) { //Do a bbox check. double bbox[6]; it->ds->GetBounds(bbox); if (DebugStream::Level5()) { debug5<<"BBOX ["<<bbox[0]<<", "<<bbox[1]<<"]["<<bbox[2]<<", "<<bbox[3]<<"]["<<bbox[4]<<", "<<bbox[5]<<"]"<<endl; } if (! (X >= bbox[0] && X <= bbox[1] && Y >= bbox[2] && Y <= bbox[3] && Z >= bbox[4] && Z <= bbox[5])) continue; bool foundIt = false; // If rectilinear, we found the domain. if (it->ds->GetDataObjectType() == VTK_RECTILINEAR_GRID) foundIt = true; else { //Do a cell check.... if (DebugStream::Level5()) { debug5<<"It's in the bbox. Check the cell.\n"; } vtkVisItCellLocator *cellLocator = it->cl; if ( cellLocator == NULL ) { cellLocator = vtkVisItCellLocator::New(); cellLocator->SetDataSet(it->ds); cellLocator->IgnoreGhostsOn(); cellLocator->BuildLocator(); it->cl = cellLocator; } double rad = 1e-6, dist=0.0; double p[3] = {X,Y,Z}, resPt[3]={0.0,0.0,0.0}; vtkIdType foundCell = -1; int subId = 0; if (cellLocator->FindClosestPointWithinRadius(p, rad, resPt, foundCell, subId, dist)) { foundIt = true; if (DebugStream::Level5()) { debug5<<"Cell locate: We found the domain!\n"; } } } if (foundIt) { if (DebugStream::Level5()) { debug5<<"Found data in cace, returning cache entry " << foundPos << std::endl; } DomainCacheEntry entry; entry = *it; //Remove, then move to front. domainQueue.erase( it ); domainQueue.push_front( entry ); return entry.ds; } } } if (DebugStream::Level5()) { debug5<<" Update->GetDataAroundPoint, time= "<<timeStep<<endl; } avtContract_p new_contract = new avtContract(firstContract); new_contract->GetDataRequest()->GetRestriction()->TurnOnAll(); avtPointSelection *ptsel = new avtPointSelection; double p[3] = { X, Y, Z }; ptsel->SetPoint(p); // data selection will be deleted by contract. new_contract->GetDataRequest()->AddDataSelection(ptsel); new_contract->GetDataRequest()->SetTimestep(timeStep); new_contract->SetOnDemandStreaming(true); GetInput()->Update(new_contract); vtkDataSet *rv = GetInputDataTree()->GetSingleLeaf(); if( rv ) { // Add it to the cache. DomainCacheEntry entry; entry.domainID = domainId; entry.timeStep = timeStep; entry.ds = rv; entry.cl = NULL; rv->Register(NULL); loadDSCount++; domainQueue.push_front(entry); if ( domainQueue.size() > (size_t)maxQueueLength ) { DomainCacheEntry tmp = domainQueue.back(); PurgeDomain( tmp.domainID, tmp.timeStep ); domainQueue.pop_back(); purgeDSCount++; } } return rv; }
vtkDataSet * avtDatasetOnDemandFilter::GetDomain(int domainId, int timeStep) { debug5<<"avtDatasetOnDemandFilter::GetDomain("<<domainId<<", "<<timeStep<<");"<<endl; if ( ! OperatingOnDemand() ) EXCEPTION0(ImproperUseException); if ( domainId < 0 ) return NULL; // See if it is already in the cache. If so, just return it. std::list<DomainCacheEntry>::iterator it; for ( it = domainQueue.begin(); it != domainQueue.end(); it++ ) // Found it. Move it to the front of the list. if (it->domainID == domainId && it->timeStep == timeStep) { DomainCacheEntry entry; entry = *it; //Remove, then move to front. domainQueue.erase( it ); domainQueue.push_front( entry ); return entry.ds; } debug5<<" Update->GetDomain "<<domainId<<" time= "<<timeStep<<endl; avtContract_p new_contract = new avtContract(firstContract); vector<int> domains; domains.push_back(domainId); new_contract->GetDataRequest()->GetRestriction()->TurnOnAll(); new_contract->GetDataRequest()->GetRestriction()->RestrictDomains(domains); if (timeStep >= 0) new_contract->GetDataRequest()->SetTimestep(timeStep); new_contract->SetOnDemandStreaming(true); GetInput()->Update(new_contract); vtkDataSet *rv = GetInputDataTree()->GetSingleLeaf(); // Add it to the cache. DomainCacheEntry entry; entry.domainID = domainId; entry.timeStep = timeStep; entry.ds = rv; rv->Register(NULL); loadDSCount++; //Update the domainLoadCount. //Turn two ints into a long. Put timeStep in upper, domain in lower. unsigned long long A = (((unsigned long long)timeStep)<<32); unsigned long long B = ((unsigned long long)domainId); unsigned long long idx = A | B; if (domainLoadCount.find(idx) == domainLoadCount.end()) domainLoadCount[idx] = 0; domainLoadCount[idx] ++; domainQueue.push_front(entry); if ( domainQueue.size() > maxQueueLength ) { domainQueue.pop_back(); purgeDSCount++; } return rv; }