📄 ref.h
字号:
maker = hmaker;
}
};
class CoreExport RefList {
public:
RefListItem* first;
RefList() { first = NULL;}
RefListItem* FirstItem() { return first; }
RefResult DeleteItem(RefMakerHandle hmaker, int eval);
RefResult AddItem(RefMakerHandle hmaker );
void Cleanup(); // remove null entries
};
class DeleteRefRestore;
class MakeRefRestore;
class ParamBlock;
class ISave;
class ILoad;
class DependentIterator;
// Possible return values for DependentEnumProc::proc()
#define DEP_ENUM_CONTINUE 0
#define DEP_ENUM_HALT 1
#define DEP_ENUM_SKIP 2 // this is the new value
class DependentEnumProc {
public:
virtual int proc(ReferenceMaker *rmaker)=0;
};
class SaveEnumProc {
public:
virtual void proc(ReferenceMaker *rmaker)=0;
virtual int terminate(ReferenceMaker *rmaker)=0;
};
CoreExport RemapDir& NoRemap();
// Here's a pointer to a RemapDir: you must delete it when done.
CoreExport RemapDir* NewRemapDir();
/* Everything can be a reference maker. We might want to keep this
* class separate from Animatable just for clarity.
*/
class ReferenceMaker : public Animatable {
friend class DeleteRefRestore;
friend class MakeRefRestore;
friend class ReferenceTarget;
friend class ParamBlock;
friend class RootNode;
friend class BaseNode;
public:
// Constructor:
ReferenceMaker() { ClearAFlag(A_EVALUATING); }
// Destructor:
CoreExport ~ReferenceMaker();
// This routine is used when cloning reference makers, to delete old
// reference and make a new one.
CoreExport RefResult ReplaceReference(int which, RefTargetHandle newtarg, BOOL delOld=TRUE);
// new format
CoreExport RefResult MakeRefByID(Interval refInterval,int which,RefTargetHandle htarget);
// Deletes all references from this RefMaker.
CoreExport RefResult DeleteAllRefsFromMe();
// Deletes all refs to this RefMaker/RefTarget.
// also sends REFMSG_TARGET_DELETED to all dependents.
virtual RefResult DeleteAllRefsToMe() { return REF_SUCCEED; }
// Deletes all references to AND from this guy.
CoreExport RefResult DeleteAllRefs();
// This deletes all reference to and from, sends REFMSG_TARGET_DELETED
// messages, handles UNDO, and deletes the object.
CoreExport void DeleteMe();
// Enumerator to search back in the dependency network.
CoreExport virtual int EnumDependents(DependentEnumProc* dep);
CoreExport virtual IOResult Save(ISave *isave);
CoreExport virtual IOResult Load(ILoad *iload);
// Access of refs. -- These functions must be implemented
// by ALL classes that make refs.
CoreExport virtual int NumRefs();
CoreExport virtual RefTargetHandle GetReference(int i);
CoreExport virtual void SetReference(int i, RefTargetHandle rtarg);
// A maker can choose not to let TransferReferences() affect it. Note that plug-ins probably should not use this
// it is used by certain system objects that have references.
virtual BOOL CanTransferReference(int i) {return TRUE;}
//-- default Save enumeration.
CoreExport virtual void SaveEnum(SaveEnumProc& sep, BOOL isNodeCall=0);
CoreExport virtual RefResult
NotifyDependents(Interval changeInt, PartID partID,
RefMessage message, SClass_ID sclass=NOTIFY_ALL,
BOOL propagate=TRUE, RefTargetHandle hTarg=NULL );
// Enumerate auxiliary files (e.g. bitmaps)
// The default implementation just calls itself on all references.
// Entities which actually need to load aux files must implement this,
// possibly calling ReferenceMaker::EnumAuxFiles also to recurse.
CoreExport virtual void EnumAuxFiles(NameEnumCallback& nameEnum, DWORD flags);
CoreExport RefResult DeleteReference( int i);
CoreExport int FindRef(RefTargetHandle rtarg);
// When a reference target's last "real" reference is deleted
// the target is deleted. Any leftover "non-real" reference makers
// will receive a REFMSG_TARGET_DELETED notification.
virtual BOOL IsRealDependency(ReferenceTarget *rtarg) {return TRUE;}
// Implement this if you have added or deleted references and are loading
// an old file that needs to have its references remapped.
virtual int RemapRefOnLoad(int iref) { return iref; }
// This function differentiates things subclassed from ReferenceMaker from
// subclasses of ReferenceTarget.
virtual BOOL IsRefTarget() { return FALSE; }
// Rescale size of all world units in reference hierarchy.
// Must call ClearAFlagInHierarchy(rm, A_WORK1) before doing this
// on a reference hierarchy.
CoreExport virtual void RescaleWorldUnits(float f);
protected:
void BlockEval() { SetAFlag(A_EVALUATING); }
void UnblockEval() { ClearAFlag(A_EVALUATING); }
int Evaluating() { return TestAFlag(A_EVALUATING); }
CoreExport RefResult StdNotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
PartID partID, RefMessage message, BOOL propagate=TRUE);
private:
// StdNotifyRefChanged calls this, which can change the partID to new value
// If it doesnt depend on the particular message& partID, it should return
// REF_DONTCARE
virtual RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
PartID& partID, RefMessage message)=0;
};
/* Not everything is a reference target...
*/
class ReferenceTarget : public ReferenceMaker {
friend class DependentIterator;
friend class DeleteRefRestore;
friend class MakeRefRestore;
//friend class Remap;
public:
ReferenceTarget() { ClearAFlag(A_LOCK_TARGET); }
// old format: will go away
CoreExport RefResult MakeReference(Interval refInterval,RefMakerHandle hmaker,int whichRef=-1);
CoreExport RefResult TestForLoop( Interval refInterval, RefMakerHandle hmaker);
CoreExport BOOL HasDependents();
CoreExport BOOL HasRealDependents(); // not counting tree view
// Deletes all references to this refTarget.
CoreExport RefResult DeleteAllRefsToMe();
RefList& GetRefList() { return refs; }
// This function is called when a targets last ref is deleted
// Most subclasses will not need to override this. If you don't want to be
// deleted when the last ref is deleted, plug in a noop.
CoreExport virtual RefResult AutoDelete();
// This is called after deleting a reference to a ref target,
// in the case that the target was not deleted. If target needs
// to know, it should override this method.
virtual void RefDeleted() {}
virtual void RefDeletedUndoRedo() {} // Called when reference is deleted because of and undo or a redo
// This is called after making a reference-- If the
// target needs to know it can override it.
virtual void RefAdded(RefMakerHandle rm) {}
virtual void RefAddedUndoRedo(RefMakerHandle rm) {} // Called when reference is added because of and undo or a redo
// Transfer all the references from oldTarget to this
CoreExport RefResult TransferReferences(RefTargetHandle oldTarget, BOOL delOld=FALSE);
// Enumerator to search back in the dependency network.
CoreExport virtual int EnumDependents(DependentEnumProc* dep);
CoreExport virtual RefTargetHandle Clone(RemapDir &remap = NoRemap());
// Checks if there are no references, and if object is deletable, deletes it.
CoreExport RefResult MaybeAutoDelete();
// This sends the REFMSG_FLAGDEPENDENTS message up the pipeline.
// There are two reasons to flag dependents:
// 1) To put the node in the FG plane. (PART_PUT_IN_FG)
// 2) To set the node's mesh color to green to indicate it is a
// dependent. (PART_SHOW_DEPENDENCIES)
// If the PART_SHOWDEP_ON bit is set, the dependency display is
// turned on, otherwise it is turned off.
void FlagDependents( TimeValue t, PartID which=PART_PUT_IN_FG )
{
NotifyDependents(
Interval(t,t),
which,
REFMSG_FLAGDEPENDENTS );
}
// This method is called to flag dependents into the FG.
// (Note that the above method is obsolete)
// The default implementation just sends out the notification.
// In particular, a slave controller could override this method
// and call its masters version of this method.
virtual void NotifyForeground(TimeValue t)
{NotifyDependents(Interval(t,t),PART_PUT_IN_FG,REFMSG_FLAGDEPENDENTS);}
// To see if this reference target depends on something:
// first call BeginDependencyTest()
// then call NotifyDependents() on the thing with the REFMSG_TEST_DEPENDENCY
// if EndDependencyTest() returns TRUE this target is dependent on the thing.
void BeginDependencyTest() {ClearAFlag(A_DEPENDENCY_TEST);}
BOOL EndDependencyTest() {return TestAFlag(A_DEPENDENCY_TEST);}
// Notify all dependent RefMakers concerened with the message
CoreExport virtual RefResult
NotifyDependents(Interval changeInt, PartID partID,
RefMessage message, SClass_ID sclass=NOTIFY_ALL,
BOOL propagate=TRUE, RefTargetHandle hTarg=NULL);
// This function differentiates things subclassed from ReferenceMaker from
// subclasses of ReferenceTarget.
virtual BOOL IsRefTarget() { return TRUE; }
private:
// This is the list of active references that refer to us.
RefList refs;
};
class DependentIterator {
ReferenceTarget *rt;
RefListItem *next;
public:
DependentIterator(ReferenceTarget *rtarg) { rt = rtarg; next = rt->refs.first; }
CoreExport ReferenceMaker *Next();
void Reset() { next = rt->refs.first; }
};
class DeletedRestore: public RestoreObj {
RefMakerHandle anim, svanim;
public:
CoreExport DeletedRestore();
CoreExport DeletedRestore(RefMakerHandle an);
CoreExport ~DeletedRestore();
CoreExport void Restore(int isUndo);
CoreExport void Redo();
CoreExport TSTR Description();
};
class RefEnumProc {
public:
virtual void proc(ReferenceMaker *rm)=0;
};
CoreExport void EnumRefHierarchy(ReferenceMaker *rm, RefEnumProc &proc);
CoreExport ReferenceTarget *CloneRefHierarchy(ReferenceTarget *rm);
// This class lets you tap in to ALL reference messages in the entire
// system. Once registered, the NotifyRefChanged() method will be called
// once for every time NotifyRefChanged() is called on a regular
// ReferenceTarget effectively allowing you to wire tap the entire
// reference network.
//
// WARNING: This should be used with extreme care. NotifyRefChange()
// will be called MANY MANY times so it is important to do very little
// processing within this method. This most that should probably be
// done is to set a dirty bit.
//
class GlobalReferenceMaker {
public:
virtual RefResult NotifyRefChanged(
Interval iv, RefTargetHandle hTarg,
PartID& partID, RefMessage msg)=0;
};
CoreExport void RegisterGlobalReference(GlobalReferenceMaker *maker);
CoreExport void UnRegisterGlobalReference(GlobalReferenceMaker *maker);
CoreExport void ClearAFlagInHierarchy(ReferenceMaker *rm, int flag);
// DependsOn -- returns true if there is a path of references from mkr to targ;
// (note: this returns TRUE if mkr==targ)
CoreExport BOOL DependsOn(RefMakerHandle mkr, RefMakerHandle targ);
// Function to find out if we are saving an old version .MAX file.
// If this returns 0, then either (a) we are not in a save or
// we are saving the current version. If it returns non-zero, it is
// the max release number being saved, multiplied by 1000. Thus,
// when saving MAX R2 files, it will return 2000. This function can
// be used in NumRefs() and GetRef() to make an objects references
// appear as they did in the old Max version.
CoreExport DWORD GetSavingVersion();
// Function used internally to maintain the SavingVersion number, which should not be
// called by plugins.
CoreExport DWORD SetSavingVersion(DWORD version);
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -