Validity Intervals

A validity intervals describes a range of time over which the modification preformed by the modifier is accurate. Many things in 3ds Max can be animated and thus change over time. Validity intervals allow 3ds Max to minimize redundant evaluations of modifications.

For example, consider the case above of the procedural sphere and the volume select modifier applied to select a set of vertices. A 3ds Max user might animate the number of segments in the sphere as an animated camera gets closer to it -- this keeps the silhouette of the sphere from appearing faceted. The volume select modifier applied to the sphere needs to select all the vertices in the region defined by its gizmo which represents its volume. Since the segment count in the sphere is changing, the number of vertices in the region defined by the modifier's gizmo is changing. Therefore the selection done at one frame may not be valid at the next frame. In order to tell 3ds Max how long the modification is valid, what's called a validity interval is computed and returned. This describes the range of time over which the modification is accurate and up to date.

There are two methods that a modifier needs to call or implement. These are Object::UpdateValidity() and Modifier::LocalValidity() (or SimpleMod::GetValidity())

When a modifier is finished altering an object it needs to include its interval in the validity interval of the object. This way if an object was static, but had an animated modifier applied to it, 3ds Max would know that the modifier would need to be re-evaluated if the user moves to a new time. To do this, the modifier calls the UpdateValidity() method on the object, specifying the channel and the modifier's interval. Modifiers that only affect the geometry channel would specify GEOM_CHAN_NUM. Modifiers that affect other channels would have to call this method once for each channel modified. The interval that is passed in to this method is then intersected with the interval that the object keeps for each channel. So as the object travels through the pipeline, its validity intervals are potentially getting smaller as (possibly) animated modifiers are applied to it.

Here are the calls to UpdateValidity() that the Volume Select Modifier makes to the object it modifies. These calls are made inside the modifier's ModifyObject() method.

 obj->UpdateValidity(SUBSEL_TYPE_CHAN_NUM,FOREVER);
 obj->UpdateValidity(SELECT_CHAN_NUM,valid);
 obj->UpdateValidity(GEOM_CHAN_NUM,valid);
 obj->UpdateValidity(TOPO_CHAN_NUM,valid);

The modifier must also implement a method to return to 3ds Max its own validity, independent of the object it is modifying. This method is Modifier::LocalValidity(). This value is computed by starting an interval off at FOREVER, and intersecting the validity intervals of all the animated parameters of the modifier. In the case of the Volume Select Modifer, it has a single animated parameter -- its gizmo which represents the actual extents of the volume it selects. Below is the implementation of this method by Volume Select.

Interval SelMod::LocalValidity(TimeValue t)
{ 
   Interval valid = FOREVER;
   if (tmControl) {
     Matrix3 tm(1);
     tmControl->GetValue(t,&tm,valid,CTRL_RELATIVE);
   }
   return valid;
}

Note the interval is started as FOREVER. Then the gizmo's transform controller's GetValue() method is called passing it this initial interval of FOREVER. The controller's GetValue() method will update this interval to reflect the validity of the gizmo. This interval is then returned. Note that if the volume has not been animated yet, and thus there is not a controller assigned to the gizmo yet, FOREVER is returned. This means the modifier is valid at all times.

Some modifiers are sub-classed from SimpleMod and not Modifier. To return the validity interval of the modifier to SimpleMod, the developer must implement a method named GetValidity(). SimpleMod then provides the implementation of LocalValidity() itself but calls GetValidity() on the SimpleModifier.