I’m making progress on removing
smtk::model::Tessellation in favor of a class that will provide VTK (and/or VTK-m) data on demand. I would like some feedback before I go too much further.
The replacement class is named GeometryProvider and here are its relevant features:
- Instead of each
Tessellationobject, now each
Resourcemay (if the
Resourcehas any renderable geometry) supply a non-null
GeometryProvider. You can ask the provider about the
Component. In particular you can ask for:
a. the geometry’s serial number - like a generation number that is incremented each time the geometry changes. This must be a fast query.
b. the object’s bounds – as a 6-tuple; this is assumed to be fast.
c. the geometry’s role – which specifies how the object is to be treated by the renderer (as normal tessellation, as instance placements, as image/volume data, possibly with labels to be volume rendered). The role lets us decide which blocks inside the
vtkResourceMultiBlockSource's output to place the provided data:
d. data (as a
vtkDataObject*) – specifying the object’s geometry. This operation is assumed to be slow and may copy data (but may be fast using zero-copy).
GeometryProvidermust also provide a
visit()method to traverse all objects that have geometry (whether they have been converted to a
vtkDataObjectyet or not). Traversing would not cause conversion, just report objects. This may be implemented by simply mirroring the resource’s component-visitor but some providers might be wish to be more intelligent.
smtk::common::Generator<ResourceSubclass, GeometryProviderPtr>, it is possible for
Resourceclasses in the smtkCore to construct geometry providers present in other libraries (as long as the application is linked to them or SMTK has loaded a plugin containing them). Note that this means if smtkCore is loaded with no other libraries, classes like
smtk::mesh::Resourcewill report no renderable geometry. Operations that run on resources using their native modeling kernel should work fine, but any that assume the resource’s components have a
Tessellationwill not work. I have not found any existing operations which do this, but it will mean some unit tests need a rewrite.
- Because all resources may provide geometry, we can eliminate the subclasses of
vtkResourceMultiBlockSourcewill just ask the resource for its geometry provider and visit all objects with geometry, only calling
GeometryProvider::data()on objects with stale or non-existent cache entries.
@tj.corona I’m not really familiar with
smtk::mesh::Resourceand have a question: will a
MeshSet's elements ever change? If so, can I tell when? It seems like this is possible if someone (a) modifies point coordinates or (b) adds/removes handles from the
MeshSet. But I do not know how to detect this so that I can increment the relevant
MeshSets’ (and only the relevant
MeshSets') serial numbers. It feels like we should avoid forcing operations to query for a
GeometryProviderin order to mark entries in its cache of
vtkDataObjectsdirty. Should the
operation::Managers? That seems restrictive and then I’m not sure how the provider could discover the managers on its own… the application would need to configure every relevant geometry provider. Bleh! This means Python scripts, too. Double-bleh! Maybe I am changing my mind about forcing operations to do some of the work. Opinions? Or am I an ignoramus who doesn’t know how mesh can track changes?
- Is requiring geometry providers to implement
- There are some special cases with roles I’m not sure exactly how to handle. Even if I don’t implement anything to cover these cases immediately, I’d like to make sure we’re not making it impossible to deal with them:
a. Some components may share geometry but use it differently.
i. Example: If we ever deal with model face-uses instead of model faces, the uses may share geometry but want to specify whether they apply to the front-face or the back-face.
ii. Example: For medical applications, geometry is usually a volumetric image. Multiple tissues/organs (each of which will be an SMTK model entity) may exist on the same image as either (a) distinct integer values in a single scalar field or (b) a separate scalar field for each tissue type.
b. Some components might serve multiple roles. For example, when a model entity has its own geometry but also serves as the prototype for some instanced geometry. I plan to deal with this particular example by asking anything that reports its Role as an instance for its prototype’s geometry. But are there other cases?
- One of the reasons I’m working on this now is a medical application that needs volume rendering, slice rendering, and widgets for editing segmentation label-maps. I plan to extend
vtkResourceMultiBlockSourcewith a new top-level block holding vtkImageData objects and then make the
vtkSMTKResourceRepresentationcreate separate actors for each image (during
I want to avoid separate representations (because that would be really messy to manage) but also want end users to have control over each image’s visual style (render as slice, volume render, etc.). Is this a bad design? It feels un-ParaView-like although it could be addressed to some degree with a self-generating source proxy. On the other hand, if I make separate representations for images inside a resource, how will things like close-resource, selection (incl. highlight-on-hover), and visibility-editing in descriptive phrase views all work? That feels un-SMTK-like.