Custom Attributes Version Number Handling

Handling of version numbers when loading scripted custom attributes from scene files was added in 3ds Max 2012.

Technical Overview

The definition of scripted custom attributes is stored in the scene file in the "ScriptedCustAttribDefs" stream, which is read in ILoadImp::LoadDllDir. This is called early in the file load process, immediately before reading in the list of used classes, since the used classes will include the scripted custom attribute classes.

In 3ds Max versions prior to 3ds Max 2012, when reading the scripted custom attributes definitions, if a scripted custom attributes definition did not exactly match an existing definition, the loaded definition was evaluated, which converted any existing instances of that scripted custom attribute to the loaded definition.

We now want to evaluate the loaded definition only if it does not exactly match an existing definition and the loaded definition has a higher version number than the existing version number.

Since earlier versions of 3ds Max were always updating the scripted custom attributes definitions to the loaded definitions, they never had to migrate the instances created while loading the scene file to the existing definition, but starting with 3ds Max 2012, this has to be done.

NOTE:

Note that the internal logic for migrating was already present, since the same process is performed for scripted plugins.

However, to do this migration requires data loaded from the "Config" stream, which hasn't been read yet.

Loading order in versions prior to 3ds Max 2012: Loading order since 3ds Max 2012:
  1. Load ScriptedCustAttribDefs, updating current instances to loaded defs
  2. Load reference hierarchy
  3. Run postload callbacks
  4. Load config data, which includes the maxscript data containing the pb2 definitions for scripted plugins
  5. Run postload callbacks, which will migrate scripted plugin paramblocks to the current scripted plugin definitions

Note that in some cases, scene evaluations can occur at step 3. If those evaluations include the evaluation of the scripted plugin, errors could occur because at that point their param blocks may not correspond to the scripted plugin definitions.

  1. Load ScriptedCustAttribDefs, updating current instances to loaded defs if loaded def are newer version.
  2. Load reference hierarchy
  3. Load part of the config data - the MAXScript data containing the pb2 definitions for scripted plugins
  4. Run postload callbacks, which will migrate scripted plugin paramblocks to the current scripted plugin definitions
  5. Load remaining config data - excludes the MAXScript data containing the pb2 definitions for scripted plugins
  6. Run postload callbacks.

Note that if you evaluate a scripted custom attribute definition (or a scripted plugin definition), the evaluated definition is always used regardless of the version number of a previously existing definition.