Improvements to multi-block sources needed

Problem

The vtkResourceMultiBlockSource (and child classes vtk{Model,Mesh,Attribute}MultiBlockSource) are in need of some changes to prevent unnecessary regeneration of vtkPolyData objects they store in their output.

Currently, when the VTK source classes listed above are marked modified, they regenerate vtkPolyData objects for every component, whether it has been modified or not.

Currently, when model components are modified, operations are expected to update the component’s geometric bounds by calling smtk::model::Resource::setBoundingBox() or smtk::model::Resource::setTessellationAndBoundingBox(). This will cause an integer property (SMTK_TESS_GEN_PROP) to be incremented.

Proposed Changes

We should use the integer property to improve performance by caching that integer at the time we create a vtkPolyData in vtkModelMultiBlockSource. Here’s a way to do that which should make life easier down the road for all types of resources:

  1. Add methods to vtkResourceMultiBlockSource that subclasses can use to (a) provide a data object to cache as a component’s geometric representation and (b) fetch later, provided the generation number is new enough.
  2. Remove the cache objects from vtkModelMultiBlockSource and all the logic that deleted the cache each time the multiblock source was marked modified.

The following API would work nicely for caching vtkDataObject instances for components:

class vtkResourceMultiBlockSource
{
public:
  void SetCachedData(
    const smtk::common::UUID& uid,
    vtkDataObject* data,
    int serialNumber);
  int GetCachedDataSerialNumber(
    const smtk::common::UUID& uid) const;
  vtkDataObject* GetCachedDataObject(
    const smtk::common::UUID& uid);

protected:
  std::map<smtk::common::UUID,
    std::pair<int, vtkSmartPointer<vtkDataObject>>>
      m_cachedData;
};

Then, for each model entity inside vtkModelMultiBlockSource, it would be possible to determine whether to use the cache or update it like so:

  smtk::model::EntityPtr ent;
  smtk::model::ResourcePtr rsrc = ent->modelResource();
  smtk::common::UUID uid = ent->id();
  bool useCache = false;
  int serialNum = 0;
  if (rsrc->hasIntegerProperty(uid, SMTK_TESS_GEN_PROP) &&
    rsrc->integerProperty(uid, SMTK_TESS_GEN_PROP)[0] <=
    (serialNum = this->GetCachedDataSerialNumber(uid)))
  {
    useCache = true;
  }
  if (useCache)
  {
    leaf = this->GetCachedDataObject(uid);
  }
  else
  {
    // populate leaf with data using existing methods
    this->SetCachedData(uid, leaf, serialNum);
  }
  // add leaf to output multiblock in proper spot

Has this suggestion been implemented?

Nope, I’ve been booked since I wrote it.

Working on it now to hopefully speed up a demo.

See SMTK MR 1785.