Share

Guidelines for Changing the Reference Structure

A plug-in can save a different reference structure than it exposes to 3ds Max at run-time (e.g. ReferenceMaker::GetReference(), ReferenceMaker::NumRefs()). You need to override the virtual function ReferenceMaker::SpecifySaveReferences() and use the ReferenceSaveManager parameter to describe the differences between its actual and to-be-saved reference structure as a series of add, remove and change operations. Changes to indirect references are also supported. A plug-in can also specify another version of plug-in to be saved instead of itself. There will be strict restrictions for changing the reference structure if the plug-in does not use the ReferenceSaveManager API. This will be discussed later.

The following member functions are used to describe changes to the structure of direct references of a plug-in:

  • void ReferenceSaveManager::AddReferenceSlot(int insertAt, ReferenceTarget* theRef) ;
  • void ReferenceSaveManager::ReplaceReferenceSlot(int which, ReferenceTarget* theRef) ;
  • void ReferenceSaveManager::RemoveReferenceSlot(int which) ;
  • void ReferenceSaveManager::SetReplacementReferenceTarget(ReferenceTarget* replacementRefTarg) ;

Similar functions exist for specifying indirect reference changes. The alternate reference hierarchy is exposed via the following member functions of the class ReferenceSaveManager:

  • ReferenceTarget* ReferenceSaveManager::GetIndirectReference(int i, bool usePersistenceTests) ;
  • ReferenceTarget* ReferenceSaveManager::GetReference(int i, bool usePersistenceTests) ;
  • int ReferenceSaveManager::NumIndirectRefs() ;
  • int ReferenceSaveManager::NumRefs() ;

When an alternate reference hierarchy hasn't been defined, the ReferenceSaveManager member functions will use the reference structure currently define by the plug-in. If the plug-in defines an alternate reference hierarchy, it exists only during a file save operation. While developers are encouraged to use the ReferenceSaveManager API to change the reference structure, there is a certain case in which it is easier to do that without using that API. This is when a new reference is added as the last one to the list of references. Following is the guidelines the plug-in should follow if the ReferenceSaveManager API is not used.

  • The meaning (e.g. type) associated with a reference index must not be changed. This also means that reference indexes must not be swapped.
  • If a reference is removed from any position other than the last, the number of references returned by ReferenceMaker::NumRefs() must not be reduced and NULL must be returned for that reference index.
  • New references must only be added to the last position.

In summary for this case, the order and type of references should not change. If a reference is no longer needed, its reference number should remain valid but always return NULL. If a reference needs to change type then it should return NULL, and a new one of the desired type should be added at the end of the list. To avoid instabilities all reference positions should support NULL references.

For more information and sample code, see the documentation of ReferenceMaker::SpecifySaveReferences() member function and ReferenceSaveManager class.

Was this information helpful?