2021-11-07 23:43:01 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
# ifdef NEW_DIRECTLINK_PLUGIN
# include "DatasmithMaxDirectLink.h"
# include "Logging/LogMacros.h"
# include "Windows/AllowWindowsPlatformTypes.h"
MAX_INCLUDES_START
# include "max.h"
# include "notify.h"
# include "ISceneEventManager.h"
MAX_INCLUDES_END
namespace DatasmithMaxDirectLink
{
// This is used to handle some of change events
class FNodeEventCallback : public INodeEventCallback
{
ISceneTracker & SceneTracker ;
public :
FNodeEventCallback ( ISceneTracker & InSceneTracker ) : SceneTracker ( InSceneTracker )
{
}
virtual BOOL VerboseDeleted ( ) { return TRUE ; }
virtual void NameChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " NameChanged " , nodes ) ;
for ( int NodeIndex = 0 ; NodeIndex < nodes . Count ( ) ; + + NodeIndex )
{
2022-04-15 13:41:06 -04:00
SceneTracker . NodeNameChanged ( nodes [ NodeIndex ] ) ;
2021-11-07 23:43:01 -05:00
}
}
2022-03-23 03:56:41 -04:00
virtual void LinkChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " LinkChanged " , nodes ) ;
for ( int NodeIndex = 0 ; NodeIndex < nodes . Count ( ) ; + + NodeIndex )
{
SceneTracker . NodeLinkChanged ( nodes [ NodeIndex ] ) ;
}
}
2022-11-11 00:45:51 -05:00
# if MAX_PRODUCT_YEAR_NUMBER < 2020 // Starting 2020 using ReferenceMaker to handle this notification
virtual void UserPropertiesChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " UserPropertiesChanged " , nodes ) ;
for ( int NodeIndex = 0 ; NodeIndex < nodes . Count ( ) ; + + NodeIndex )
{
SceneTracker . NodePropertiesChanged ( NodeEventNamespace : : GetNodeByKey ( nodes [ NodeIndex ] ) ) ;
}
}
# endif
2021-11-07 23:43:01 -05:00
// Not used:
2022-05-17 10:39:25 -04:00
virtual void LayerChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " LayerChanged " , nodes ) ;
}
virtual void HideChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " HideChanged " , nodes ) ;
}
virtual void RenderPropertiesChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " RenderPropertiesChanged " , nodes ) ;
}
virtual void GeometryChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " GeometryChanged " , nodes ) ;
}
virtual void TopologyChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " TopologyChanged " , nodes ) ;
}
virtual void MappingChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " MappingChanged " , nodes ) ;
}
// Fired when node transform changes
virtual void ControllerOtherEvent ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " ControllerOtherEvent " , nodes ) ;
}
// Tracks material assignment on node
virtual void MaterialStructured ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " MaterialStructured " , nodes ) ;
}
2022-05-24 11:17:58 -04:00
// Tracks node's material parameter change(even if it's a submaterial of multimat that is assigned)
virtual void MaterialOtherEvent ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " MaterialOtherEvent " , nodes ) ;
}
2021-11-07 23:43:01 -05:00
virtual void Added ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " Added " , nodes ) ;
}
virtual void Deleted ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " Deleted " , nodes ) ;
}
virtual void GroupChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " GroupChanged " , nodes ) ;
}
virtual void HierarchyOtherEvent ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " HierarchyOtherEvent " , nodes ) ;
}
virtual void ModelStructured ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " ModelStructured " , nodes ) ;
}
virtual void ExtentionChannelChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " ExtentionChannelChanged " , nodes ) ;
}
virtual void ModelOtherEvent ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " ModelOtherEvent " , nodes ) ;
}
virtual void ControllerStructured ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " ControllerStructured " , nodes ) ;
}
virtual void WireColorChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " WireColorChanged " , nodes ) ;
}
virtual void DisplayPropertiesChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " DisplayPropertiesChanged " , nodes ) ;
}
virtual void PropertiesOtherEvent ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " PropertiesOtherEvent " , nodes ) ;
}
virtual void SubobjectSelectionChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " SubobjectSelectionChanged " , nodes ) ;
}
virtual void SelectionChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " SelectionChanged " , nodes ) ;
}
virtual void FreezeChanged ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " FreezeChanged " , nodes ) ;
}
virtual void DisplayOtherEvent ( NodeKeyTab & nodes ) override
{
LogNodeEvent ( L " DisplayOtherEvent " , nodes ) ;
}
virtual void CallbackBegin ( ) override
{
LOG_DEBUG_HEAVY ( L " NodeEventCallback: CallbackBegin \n " ) ;
}
virtual void CallbackEnd ( ) override
{
LOG_DEBUG_HEAVY ( L " NodeEventCallback: CallbackEnd \n " ) ;
}
ISceneEventManager : : CallbackKey CallbackKey ;
} ;
2022-05-24 11:17:58 -04:00
// Watches all notifications sent to a single ReferenceTarget(INode, Mtl etc)
template < typename ItemNotificationsHandler >
class TBaseItemNotifications : public ReferenceMaker
2021-11-07 23:43:01 -05:00
{
public :
2022-05-17 10:39:25 -04:00
2022-05-24 11:17:58 -04:00
explicit TBaseItemNotifications ( ItemNotificationsHandler & InHandler ) : Handler ( InHandler )
2021-11-07 23:43:01 -05:00
{
2022-05-24 11:17:58 -04:00
LogDebug ( FString : : Printf ( TEXT ( " TBaseItemNotifications(%s - %p)::TBaseItemNotifications " ) , * GetName ( ) , Handler . GetNotificationTargetHandle ( ) ) ) ;
2022-05-17 10:39:25 -04:00
// Don't record setting reference for Undo/Redo - we control this ourselves(e.g. on ADDED_NODE event for addition)
HoldSuspend SuspendUndoRedoGuard ;
2022-05-24 11:17:58 -04:00
ReplaceReference ( 0 , Handler . GetNotificationTargetHandle ( ) ) ;
2021-11-07 23:43:01 -05:00
}
2022-05-17 10:39:25 -04:00
void Delete ( )
2021-11-07 23:43:01 -05:00
{
2022-05-24 11:17:58 -04:00
LogDebug ( FString : : Printf ( TEXT ( " TBaseItemNotifications(%p)::Delete " ) , Handler . GetNotificationTargetHandle ( ) ) ) ;
2022-05-17 10:39:25 -04:00
HoldSuspend SuspendUndoRedoGuard ;
DeleteMe ( ) ; //Instead of calling DeleteAllRefs() in destructor, calling DeleteMe under HoldSuspend to disable undo for this object
2021-11-07 23:43:01 -05:00
}
2022-05-24 11:17:58 -04:00
// Same pointer could be added to the scene - handle this in case notifier for this pointer still kept
2022-05-17 10:39:25 -04:00
void ReAdded ( )
2021-11-07 23:43:01 -05:00
{
2022-05-24 11:17:58 -04:00
ReplaceReference ( 0 , Handler . GetNotificationTargetHandle ( ) ) ;
2022-05-17 10:39:25 -04:00
}
protected :
virtual RefResult NotifyRefChanged ( const Interval & ChangeInterval , RefTargetHandle TargetHandle , PartID & PartId , RefMessage Message , BOOL propagate ) override
{
if ( ! bReferenceSet )
2022-03-23 03:56:41 -04:00
{
2022-05-24 11:17:58 -04:00
LOG_DEBUG_HEAVY ( FString : : Printf ( TEXT ( " TBaseItemNotifications(UNSET - %p)::NotifyRefChanged: Target - %p, Message - %x " ) , Handler . GetNotificationTargetHandle ( ) , TargetHandle , Message ) ) ;
2022-05-17 10:39:25 -04:00
return REF_DONTCARE ;
2022-03-23 03:56:41 -04:00
}
2022-05-17 10:39:25 -04:00
2022-05-24 11:17:58 -04:00
LOG_DEBUG_HEAVY ( FString : : Printf ( TEXT ( " TBaseItemNotifications(%s - %p)::NotifyRefChanged: Target - %p, Message - %x " ) , * GetName ( ) , Handler . GetNotificationTargetHandle ( ) , TargetHandle , Message ) ) ;
return Handler . HandleEvent ( ChangeInterval , TargetHandle , PartId , Message ) ;
}
virtual int NumRefs ( ) override
{
return 1 ;
}
FString GetName ( )
{
return Handler . GetName ( ) ;
}
virtual RefTargetHandle GetReference ( int ReferenceIndex ) override
{
if ( bReferenceSet )
{
LOG_DEBUG_HEAVY ( FString : : Printf ( TEXT ( " TBaseItemNotifications(%s - %p)::GetReference: %d " ) , * GetName ( ) , Handler . GetNotificationTargetHandle ( ) , ReferenceIndex ) ) ;
return Handler . GetNotificationTargetHandle ( ) ;
}
else
{
LOG_DEBUG_HEAVY ( FString : : Printf ( TEXT ( " TBaseItemNotifications(UNSET - %p)::GetReference: %d " ) , Handler . GetNotificationTargetHandle ( ) , ReferenceIndex ) ) ;
return nullptr ;
}
}
virtual void SetReference ( int ReferenceIndex , RefTargetHandle Handle ) override
{
LOG_DEBUG_HEAVY ( FString : : Printf ( TEXT ( " TBaseItemNotifications(%s - %p)::SetReference: %d, %p " ) , * GetName ( ) , Handler . GetNotificationTargetHandle ( ) , ReferenceIndex , Handle ) ) ;
// Either clears reference or passes the same handler
check ( ( Handle = = nullptr ) | | ( Handle = = Handler . GetNotificationTargetHandle ( ) ) ) ;
bool bReferenceSetNew = Handle ! = nullptr ;
if ( bReferenceSet & & ! bReferenceSetNew )
{
Handler . HandleDeleted ( ) ;
}
bReferenceSet = bReferenceSetNew ;
}
private :
ItemNotificationsHandler & Handler ; // Handler for specific item type
bool bReferenceSet = false ;
protected :
virtual ~ TBaseItemNotifications ( ) override { } // Should call Delete
} ;
class FMaterialNotifications : public FNoncopyable
{
public :
FMaterialNotifications ( ISceneTracker & InSceneTracker , Mtl & Material )
: SceneTracker ( InSceneTracker )
, Material ( Material )
, ItemNotifications ( new TBaseItemNotifications { * this } )
{
}
~ FMaterialNotifications ( )
{
ItemNotifications - > Delete ( ) ;
}
FString GetName ( )
{
return Material . GetName ( ) . data ( ) ;
}
RefTargetHandle GetNotificationTargetHandle ( )
{
return & Material ;
}
RefResult HandleEvent ( const Interval & ChangeInterval , RefTargetHandle TargetHandle , PartID & PartId , RefMessage Message )
{
if ( SceneTracker . IsUpdateInProgress ( ) )
{
LogDebug ( TEXT ( " Event Skipped during Update " ) ) ;
// Don't propagate ReferenceMaker events when Update is in progress - these events are result of accessing render geometry on some objects, including
// Smooth/TurboSmooth modifiers, VRay proxy and similar. Plugin retrieves render mesh from them and those objects fire geometry change events
// Plugin reverts settings back to previously set(i.e. viewport for smooth modifiers or whatever vray proxy had for display)
return REF_DONTCARE ;
}
switch ( Message )
{
case REFMSG_REF_DELETED :
//
break ;
case REFMSG_CHANGE :
LOG_DEBUG_HEAVY ( FString : : Printf ( TEXT ( " REFMSG_CHANGE.PartId: %llx " ) , PartId ) ) ;
SceneTracker . MaterialGraphModified ( & Material ) ;
break ;
case REFMSG_SUBANIM_STRUCTURE_CHANGED :
SceneTracker . MaterialGraphModified ( & Material ) ;
break ;
default :
break ;
} ;
return REF_SUCCEED ;
}
void HandleDeleted ( )
{
}
void ReAdded ( )
{
ItemNotifications - > ReAdded ( ) ;
}
private :
ISceneTracker & SceneTracker ;
Mtl & Material ;
TBaseItemNotifications < FMaterialNotifications > * ItemNotifications ;
} ;
class FMaterialObserver
{
public :
ISceneTracker & SceneTracker ;
FMaterialObserver ( ISceneTracker & InSceneTracker ) : SceneTracker ( InSceneTracker )
{
}
~ FMaterialObserver ( )
{
}
void AddItem ( Mtl * Material )
{
if ( TUniquePtr < FMaterialNotifications > * NotifierPtr = Items . Find ( Material ) )
{
( * NotifierPtr ) - > ReAdded ( ) ;
}
else
{
Items . Emplace ( Material , new FMaterialNotifications ( SceneTracker , * Material ) ) ;
}
}
void Reset ( )
{
Items . Reset ( ) ;
}
private :
TMap < Mtl * , TUniquePtr < FMaterialNotifications > > Items ;
} ;
class FNodeNotifications : public FNoncopyable
{
public :
FNodeNotifications ( ISceneTracker & InSceneTracker , INode & Node )
: SceneTracker ( InSceneTracker )
, Node ( Node )
, ItemNotifications ( new TBaseItemNotifications { * this } )
{
}
~ FNodeNotifications ( )
{
ItemNotifications - > Delete ( ) ;
}
RefResult HandleEvent ( const Interval & ChangeInterval , RefTargetHandle TargetHandle , PartID & PartId , RefMessage Message )
{
2022-05-17 10:39:25 -04:00
LogDebugNode ( TEXT ( " Node: " ) , & Node ) ;
if ( SceneTracker . IsUpdateInProgress ( ) )
2022-03-23 03:56:41 -04:00
{
2022-05-24 11:17:58 -04:00
LogDebug ( TEXT ( " Event Skipped during Update " ) ) ;
2022-05-17 10:39:25 -04:00
// Don't propagate ReferenceMaker events when Update is in progress - these events are result of accessing render geometry on some objects, including
// Smooth/TurboSmooth modifiers, VRay proxy and similar. Plugin retrieves render mesh from them and those objects fire geometry change events
// Plugin reverts settings back to previously set(i.e. viewport for smooth modifiers or whatever vray proxy had for display)
return REF_DONTCARE ;
2022-03-23 03:56:41 -04:00
}
2021-11-07 23:43:01 -05:00
2022-05-17 10:39:25 -04:00
switch ( Message )
{
case REFMSG_REF_DELETED :
//
break ;
case REFMSG_CHANGE :
LOG_DEBUG_HEAVY ( FString : : Printf ( TEXT ( " REFMSG_CHANGE.PartId: %llx " ) , PartId ) ) ;
if ( PartId & ( PART_TOPO | PART_GEOM | PART_TEXMAP ) )
{
SceneTracker . NodeGeometryChanged ( & Node ) ;
}
if ( PartId & PART_TM )
{
SceneTracker . NodeTransformChanged ( & Node ) ;
}
break ;
2022-10-17 13:01:12 -04:00
case REFMSG_BEGIN_EDIT :
// Workaround for missing events for some modifiers
// E.g. Body Cutter won't sent a CHANGE event an object is converted to it
SceneTracker . NodeGeometryChanged ( & Node ) ;
break ;
2022-05-17 10:39:25 -04:00
case REFMSG_NODE_MATERIAL_CHANGED :
SceneTracker . NodeMaterialAssignmentChanged ( & Node ) ;
break ;
case REFMSG_DISPLAY_MATERIAL_CHANGE :
SceneTracker . NodeMaterialGraphModified ( & Node ) ;
break ;
2022-08-16 02:51:36 -04:00
// Sadly, this event only sent for node when it's being hidden by using Display/Hide Byt Category. Unhiding it using that option doesn't send meaningful message per node
// At least NOTIFY_BY_CATEGORY_DISPLAY_FILTER_CHANGED is sent(handled elsewhere)
// case REFMSG_NODE_DISPLAY_PROP_CHANGED: break;
2022-05-17 10:39:25 -04:00
case REFMSG_SUBANIM_STRUCTURE_CHANGED :
if ( Node . GetMtl ( ) = = TargetHandle )
{
SceneTracker . NodeMaterialGraphModified ( & Node ) ;
}
break ;
case REFMSG_NODE_RENDERING_PROP_CHANGED :
// Handle Renderable flag change. mxs: box.setRenderable
SceneTracker . NodePropertiesChanged ( & Node ) ;
break ;
2022-11-11 00:45:51 -05:00
# if MAX_PRODUCT_YEAR_NUMBER >= 2020
case REFMSG_NODE_USER_PROPERTY_CHANGED :
SceneTracker . NodePropertiesChanged ( & Node ) ;
break ;
# endif
2022-05-17 10:39:25 -04:00
// SceneTracker.NodeGeometryChanged(nodes[NodeIndex]);
default :
break ;
} ;
2021-11-07 23:43:01 -05:00
return REF_SUCCEED ;
}
2022-05-24 11:17:58 -04:00
FString GetName ( )
2021-11-07 23:43:01 -05:00
{
2022-05-24 11:17:58 -04:00
return Node . GetName ( ) ;
2021-11-07 23:43:01 -05:00
}
2022-05-24 11:17:58 -04:00
RefTargetHandle GetNotificationTargetHandle ( )
2021-11-07 23:43:01 -05:00
{
2022-05-24 11:17:58 -04:00
return & Node ;
2021-11-07 23:43:01 -05:00
}
2022-05-17 10:39:25 -04:00
2022-05-24 11:17:58 -04:00
void HandleDeleted ( )
2022-05-17 10:39:25 -04:00
{
2022-05-24 11:17:58 -04:00
SceneTracker . NodeDeleted ( & Node ) ;
}
2022-05-17 10:39:25 -04:00
2022-05-24 11:17:58 -04:00
void ReAdded ( )
{
ItemNotifications - > ReAdded ( ) ;
2022-05-17 10:39:25 -04:00
}
2021-11-07 23:43:01 -05:00
private :
2022-05-24 11:17:58 -04:00
ISceneTracker & SceneTracker ;
2022-05-17 10:39:25 -04:00
INode & Node ;
2022-05-24 11:17:58 -04:00
TBaseItemNotifications < FNodeNotifications > * ItemNotifications ;
2022-05-17 10:39:25 -04:00
} ;
class FNodeObserver
{
public :
ISceneTracker & SceneTracker ;
FNodeObserver ( ISceneTracker & InSceneTracker ) : SceneTracker ( InSceneTracker )
{
}
~ FNodeObserver ( )
{
}
void AddItem ( INode * Node )
{
2022-05-24 11:17:58 -04:00
if ( TUniquePtr < FNodeNotifications > * NotifierPtr = Items . Find ( Node ) )
2022-05-17 10:39:25 -04:00
{
( * NotifierPtr ) - > ReAdded ( ) ;
}
else
{
2022-05-24 11:17:58 -04:00
Items . Emplace ( Node , new FNodeNotifications ( SceneTracker , * Node ) ) ;
2022-05-17 10:39:25 -04:00
}
}
void Reset ( )
{
2022-05-24 11:17:58 -04:00
Items . Reset ( ) ;
2022-05-17 10:39:25 -04:00
}
private :
2022-05-24 11:17:58 -04:00
TMap < INode * , TUniquePtr < FNodeNotifications > > Items ;
2021-11-07 23:43:01 -05:00
} ;
FNotifications : : FNotifications ( IExporter & InExporter )
: Exporter ( InExporter )
2022-05-17 10:39:25 -04:00
, NodeObserver ( MakeUnique < FNodeObserver > ( InExporter . GetSceneTracker ( ) ) )
2022-05-24 11:17:58 -04:00
, MaterialObserver ( MakeUnique < FMaterialObserver > ( InExporter . GetSceneTracker ( ) ) )
2021-12-06 14:48:33 -05:00
{
RegisterForSystemNotifications ( ) ; // Always follow system events like file reset, new, open and others. But some system notifications also track changes within scene.
}
2021-11-07 23:43:01 -05:00
FNotifications : : ~ FNotifications ( )
{
2021-12-06 14:48:33 -05:00
for ( int Code : NotificationCodesRegistered )
{
UnRegisterNotification ( On3dsMaxNotification , this , Code ) ;
}
NotificationCodesRegistered . Reset ( ) ;
StopSceneChangeTracking ( ) ;
2021-11-07 23:43:01 -05:00
}
void FNotifications : : AddNode ( INode * Node )
{
NodeObserver - > AddItem ( Node ) ;
}
2022-05-24 11:17:58 -04:00
void FNotifications : : AddMaterial ( Mtl * Node )
{
MaterialObserver - > AddItem ( Node ) ;
}
2021-12-06 14:48:33 -05:00
void FNotifications : : RegisterForSystemNotifications ( )
2021-11-07 23:43:01 -05:00
{
// Build todo: remove strings, for debug/logging
# pragma warning(push)
# pragma warning(disable:4995) // disable error on deprecated events, we just assign handlers not firing them
2024-04-09 01:09:02 -04:00
int Codes [ ] = { NOTIFY_UNITS_CHANGE , NOTIFY_TIMEUNITS_CHANGE , NOTIFY_VIEWPORT_CHANGE , NOTIFY_SPACEMODE_CHANGE , NOTIFY_SYSTEM_PRE_RESET , NOTIFY_SYSTEM_POST_RESET , NOTIFY_SYSTEM_PRE_NEW , NOTIFY_SYSTEM_POST_NEW , NOTIFY_FILE_PRE_OPEN , NOTIFY_FILE_POST_OPEN , NOTIFY_FILE_PRE_MERGE , NOTIFY_FILE_PRE_SAVE , NOTIFY_FILE_POST_SAVE , NOTIFY_FILE_OPEN_FAILED , NOTIFY_FILE_PRE_SAVE_OLD , NOTIFY_FILE_POST_SAVE_OLD , NOTIFY_SELECTIONSET_CHANGED , NOTIFY_BITMAP_CHANGED , NOTIFY_PRE_RENDER , NOTIFY_POST_RENDER , NOTIFY_PRE_RENDERFRAME , NOTIFY_POST_RENDERFRAME , NOTIFY_PRE_IMPORT , NOTIFY_POST_IMPORT , NOTIFY_IMPORT_FAILED , NOTIFY_PRE_EXPORT , NOTIFY_POST_EXPORT , NOTIFY_EXPORT_FAILED , NOTIFY_NODE_RENAMED , NOTIFY_PRE_PROGRESS , NOTIFY_POST_PROGRESS , NOTIFY_MODPANEL_SEL_CHANGED , NOTIFY_RENDPARAM_CHANGED , NOTIFY_MATLIB_PRE_OPEN , NOTIFY_MATLIB_POST_OPEN , NOTIFY_MATLIB_PRE_SAVE , NOTIFY_MATLIB_POST_SAVE , NOTIFY_MATLIB_PRE_MERGE , NOTIFY_MATLIB_POST_MERGE , NOTIFY_FILELINK_BIND_FAILED , NOTIFY_FILELINK_DETACH_FAILED , NOTIFY_FILELINK_RELOAD_FAILED , NOTIFY_FILELINK_ATTACH_FAILED , NOTIFY_FILELINK_PRE_BIND , NOTIFY_FILELINK_POST_BIND , NOTIFY_FILELINK_PRE_DETACH , NOTIFY_FILELINK_POST_DETACH , NOTIFY_FILELINK_PRE_RELOAD , NOTIFY_FILELINK_POST_RELOAD , NOTIFY_FILELINK_PRE_ATTACH , NOTIFY_FILELINK_POST_ATTACH , NOTIFY_RENDER_PREEVAL , NOTIFY_NODE_CREATED , NOTIFY_NODE_LINKED , NOTIFY_NODE_UNLINKED , NOTIFY_NODE_HIDE , NOTIFY_NODE_UNHIDE , NOTIFY_NODE_FREEZE , NOTIFY_NODE_UNFREEZE , NOTIFY_NODE_PRE_MTL , NOTIFY_NODE_POST_MTL , NOTIFY_SCENE_ADDED_NODE , NOTIFY_SCENE_PRE_DELETED_NODE , NOTIFY_SCENE_POST_DELETED_NODE , NOTIFY_SEL_NODES_PRE_DELETE , NOTIFY_SEL_NODES_POST_DELETE , NOTIFY_WM_ENABLE , NOTIFY_SYSTEM_SHUTDOWN , NOTIFY_SYSTEM_STARTUP , NOTIFY_PLUGIN_LOADED , NOTIFY_SYSTEM_SHUTDOWN2 , NOTIFY_ANIMATE_ON , NOTIFY_ANIMATE_OFF , NOTIFY_COLOR_CHANGE , NOTIFY_PRE_EDIT_OBJ_CHANGE , NOTIFY_POST_EDIT_OBJ_CHANGE , NOTIFY_RADIOSITYPROCESS_STARTED , NOTIFY_RADIOSITYPROCESS_STOPPED , NOTIFY_RADIOSITYPROCESS_RESET , NOTIFY_RADIOSITYPROCESS_DONE , NOTIFY_LIGHTING_UNIT_DISPLAY_SYSTEM_CHANGE , NOTIFY_BEGIN_RENDERING_REFLECT_REFRACT_MAP , NOTIFY_BEGIN_RENDERING_ACTUAL_FRAME , NOTIFY_BEGIN_RENDERING_TONEMAPPING_IMAGE , NOTIFY_RADIOSITY_PLUGIN_CHANGED , NOTIFY_SCENE_UNDO , NOTIFY_SCENE_REDO , NOTIFY_MANIPULATE_MODE_OFF , NOTIFY_MANIPULATE_MODE_ON , NOTIFY_SCENE_XREF_PRE_MERGE , NOTIFY_SCENE_XREF_POST_MERGE , NOTIFY_OBJECT_XREF_PRE_MERGE , NOTIFY_OBJECT_XREF_POST_MERGE , NOTIFY_PRE_MIRROR_NODES , NOTIFY_POST_MIRROR_NODES , NOTIFY_NODE_CLONED , NOTIFY_PRE_NOTIFYDEPENDENTS , NOTIFY_POST_NOTIFYDEPENDENTS , NOTIFY_MTL_REFDELETED , NOTIFY_TIMERANGE_CHANGE , NOTIFY_PRE_MODIFIER_ADDED , NOTIFY_POST_MODIFIER_ADDED , NOTIFY_PRE_MODIFIER_DELETED , NOTIFY_POST_MODIFIER_DELETED , NOTIFY_FILELINK_POST_RELOAD_PRE_PRUNE , NOTIFY_PRE_NODES_CLONED , NOTIFY_POST_NODES_CLONED , NOTIFY_SYSTEM_PRE_DIR_CHANGE , NOTIFY_SYSTEM_POST_DIR_CHANGE , NOTIFY_SV_SELECTIONSET_CHANGED , NOTIFY_SV_DOUBLECLICK_GRAPHNODE , NOTIFY_PRE_RENDERER_CHANGE , NOTIFY_POST_RENDERER_CHANGE , NOTIFY_SV_PRE_LAYOUT_CHANGE , NOTIFY_SV_POST_LAYOUT_CHANGE , NOTIFY_BY_CATEGORY_DISPLAY_FILTER_CHANGED , NOTIFY_CUSTOM_DISPLAY_FILTER_CHANGED , NOTIFY_LAYER_CREATED , NOTIFY_LAYER_DELETED , NOTIFY_NODE_LAYER_CHANGED , NOTIFY_TABBED_DIALOG_CREATED , NOTIFY_TABBED_DIALOG_DELETED , NOTIFY_NODE_NAME_SET , NOTIFY_HW_TEXTURE_CHANGED , NOTIFY_MXS_STARTUP , NOTIFY_MXS_POST_STARTUP , NOTIFY_ACTION_ITEM_HOTKEY_PRE_EXEC , NOTIFY_ACTION_ITEM_HOTKEY_POST_EXEC , NOTIFY_SCENESTATE_PRE_SAVE , NOTIFY_SCENESTATE_POST_SAVE , NOTIFY_SCENESTATE_PRE_RESTORE , NOTIFY_SCENESTATE_POST_RESTORE , NOTIFY_SCENESTATE_DELETE , NOTIFY_SCENESTATE_RENAME , NOTIFY_SCENE_PRE_UNDO , NOTIFY_SCENE_PRE_REDO , NOTIFY_SCENE_POST_UNDO , NOTIFY_SCENE_POST_REDO , NOTIFY_MXS_SHUTDOWN , NOTIFY_D3D_PRE_DEVICE_RESET , NOTIFY_D3D_POST_DEVICE_RESET , NOTIFY_TOOLPALETTE_MTL_SUSPEND , NOTIFY_TOOLPALETTE_MTL_RESUME , NOTIFY_CLASSDESC_REPLACED , NOTIFY_FILE_PRE_OPEN_PROCESS , NOTIFY_FILE_POST_OPEN_PROCESS , NOTIFY_FILE_PRE_SAVE_PROCESS , NOTIFY_FILE_POST_SAVE_PROCESS , NOTIFY_CLASSDESC_LOADED , NOTIFY_TOOLBARS_PRE_LOAD , NOTIFY_TOOLBARS_POST_LOAD , NOTIFY_ATS_PRE_REPATH_PHASE , NOTIFY_ATS_POST_REPATH_PH
2021-11-18 14:37:34 -05:00
# if MAX_PRODUCT_YEAR_NUMBER >= 2018
, NOTIFY_PRE_VIEWPORT_TOOLTIP , NOTIFY_WELCOMESCREEN_DONE , NOTIFY_PLAYBACK_START , NOTIFY_PLAYBACK_END , NOTIFY_SCENE_EXPLORER_NEEDS_UPDATE , NOTIFY_FILE_POST_OPEN_PROCESS_FINALIZED , NOTIFY_FILE_POST_MERGE_PROCESS_FINALIZED
# endif
2021-11-07 23:43:01 -05:00
# if MAX_PRODUCT_YEAR_NUMBER >= 2022
2024-04-09 01:09:02 -04:00
, NOTIFY_PRE_PROJECT_FOLDER_CHANGE , NOTIFY_POST_PROJECT_FOLDER_CHANGE , NOTIFY_PRE_MXS_STARTUP_SCRIPT_LOAD , NOTIFY_SYSTEM_SHUTDOWN_CHECK , NOTIFY_SYSTEM_SHUTDOWN_CHECK_FAILED , NOTIFY_SYSTEM_SHUTDOWN_CHECK_PASSED , NOTIFY_FILE_POST_MERGE3 , NOTIFY_ACTIVESHADE_IN_FRAMEBUFFER_TOGGLED , NOTIFY_PRE_ACTIVESHADE_IN_VIEWPORT_TOGGLED , NOTIFY_POST_ACTIVESHADE_IN_VIEWPORT_TOGGLED
2021-11-07 23:43:01 -05:00
# endif
, NOTIFY_INTERNAL_USE_START } ;
2024-04-09 01:09:02 -04:00
FString Strings [ ] = { TEXT ( " NOTIFY_UNITS_CHANGE " ) , TEXT ( " NOTIFY_TIMEUNITS_CHANGE " ) , TEXT ( " NOTIFY_VIEWPORT_CHANGE " ) , TEXT ( " NOTIFY_SPACEMODE_CHANGE " ) , TEXT ( " NOTIFY_SYSTEM_PRE_RESET " ) , TEXT ( " NOTIFY_SYSTEM_POST_RESET " ) , TEXT ( " NOTIFY_SYSTEM_PRE_NEW " ) , TEXT ( " NOTIFY_SYSTEM_POST_NEW " ) , TEXT ( " NOTIFY_FILE_PRE_OPEN " ) , TEXT ( " NOTIFY_FILE_POST_OPEN " ) , TEXT ( " NOTIFY_FILE_PRE_MERGE " ) , TEXT ( " NOTIFY_FILE_PRE_SAVE " ) , TEXT ( " NOTIFY_FILE_POST_SAVE " ) , TEXT ( " NOTIFY_FILE_OPEN_FAILED " ) , TEXT ( " NOTIFY_FILE_PRE_SAVE_OLD " ) , TEXT ( " NOTIFY_FILE_POST_SAVE_OLD " ) , TEXT ( " NOTIFY_SELECTIONSET_CHANGED " ) , TEXT ( " NOTIFY_BITMAP_CHANGED " ) , TEXT ( " NOTIFY_PRE_RENDER " ) , TEXT ( " NOTIFY_POST_RENDER " ) , TEXT ( " NOTIFY_PRE_RENDERFRAME " ) , TEXT ( " NOTIFY_POST_RENDERFRAME " ) , TEXT ( " NOTIFY_PRE_IMPORT " ) , TEXT ( " NOTIFY_POST_IMPORT " ) , TEXT ( " NOTIFY_IMPORT_FAILED " ) , TEXT ( " NOTIFY_PRE_EXPORT " ) , TEXT ( " NOTIFY_POST_EXPORT " ) , TEXT ( " NOTIFY_EXPORT_FAILED " ) , TEXT ( " NOTIFY_NODE_RENAMED " ) , TEXT ( " NOTIFY_PRE_PROGRESS " ) , TEXT ( " NOTIFY_POST_PROGRESS " ) , TEXT ( " NOTIFY_MODPANEL_SEL_CHANGED " ) , TEXT ( " NOTIFY_RENDPARAM_CHANGED " ) , TEXT ( " NOTIFY_MATLIB_PRE_OPEN " ) , TEXT ( " NOTIFY_MATLIB_POST_OPEN " ) , TEXT ( " NOTIFY_MATLIB_PRE_SAVE " ) , TEXT ( " NOTIFY_MATLIB_POST_SAVE " ) , TEXT ( " NOTIFY_MATLIB_PRE_MERGE " ) , TEXT ( " NOTIFY_MATLIB_POST_MERGE " ) , TEXT ( " NOTIFY_FILELINK_BIND_FAILED " ) , TEXT ( " NOTIFY_FILELINK_DETACH_FAILED " ) , TEXT ( " NOTIFY_FILELINK_RELOAD_FAILED " ) , TEXT ( " NOTIFY_FILELINK_ATTACH_FAILED " ) , TEXT ( " NOTIFY_FILELINK_PRE_BIND " ) , TEXT ( " NOTIFY_FILELINK_POST_BIND " ) , TEXT ( " NOTIFY_FILELINK_PRE_DETACH " ) , TEXT ( " NOTIFY_FILELINK_POST_DETACH " ) , TEXT ( " NOTIFY_FILELINK_PRE_RELOAD " ) , TEXT ( " NOTIFY_FILELINK_POST_RELOAD " ) , TEXT ( " NOTIFY_FILELINK_PRE_ATTACH " ) , TEXT ( " NOTIFY_FILELINK_POST_ATTACH " ) , TEXT ( " NOTIFY_RENDER_PREEVAL " ) , TEXT ( " NOTIFY_NODE_CREATED " ) , TEXT ( " NOTIFY_NODE_LINKED " ) , TEXT ( " NOTIFY_NODE_UNLINKED " ) , TEXT ( " NOTIFY_NODE_HIDE " ) , TEXT ( " NOTIFY_NODE_UNHIDE " ) , TEXT ( " NOTIFY_NODE_FREEZE " ) , TEXT ( " NOTIFY_NODE_UNFREEZE " ) , TEXT ( " NOTIFY_NODE_PRE_MTL " ) , TEXT ( " NOTIFY_NODE_POST_MTL " ) , TEXT ( " NOTIFY_SCENE_ADDED_NODE " ) , TEXT ( " NOTIFY_SCENE_PRE_DELETED_NODE " ) , TEXT ( " NOTIFY_SCENE_POST_DELETED_NODE " ) , TEXT ( " NOTIFY_SEL_NODES_PRE_DELETE " ) , TEXT ( " NOTIFY_SEL_NODES_POST_DELETE " ) , TEXT ( " NOTIFY_WM_ENABLE " ) , TEXT ( " NOTIFY_SYSTEM_SHUTDOWN " ) , TEXT ( " NOTIFY_SYSTEM_STARTUP " ) , TEXT ( " NOTIFY_PLUGIN_LOADED " ) , TEXT ( " NOTIFY_SYSTEM_SHUTDOWN2 " ) , TEXT ( " NOTIFY_ANIMATE_ON " ) , TEXT ( " NOTIFY_ANIMATE_OFF " ) , TEXT ( " NOTIFY_COLOR_CHANGE " ) , TEXT ( " NOTIFY_PRE_EDIT_OBJ_CHANGE " ) , TEXT ( " NOTIFY_POST_EDIT_OBJ_CHANGE " ) , TEXT ( " NOTIFY_RADIOSITYPROCESS_STARTED " ) , TEXT ( " NOTIFY_RADIOSITYPROCESS_STOPPED " ) , TEXT ( " NOTIFY_RADIOSITYPROCESS_RESET " ) , TEXT ( " NOTIFY_RADIOSITYPROCESS_DONE " ) , TEXT ( " NOTIFY_LIGHTING_UNIT_DISPLAY_SYSTEM_CHANGE " ) , TEXT ( " NOTIFY_BEGIN_RENDERING_REFLECT_REFRACT_MAP " ) , TEXT ( " NOTIFY_BEGIN_RENDERING_ACTUAL_FRAME " ) , TEXT ( " NOTIFY_BEGIN_RENDERING_TONEMAPPING_IMAGE " ) , TEXT ( " NOTIFY_RADIOSITY_PLUGIN_CHANGED " ) , TEXT ( " NOTIFY_SCENE_UNDO " ) , TEXT ( " NOTIFY_SCENE_REDO " ) , TEXT ( " NOTIFY_MANIPULATE_MODE_OFF " ) , TEXT ( " NOTIFY_MANIPULATE_MODE_ON " ) , TEXT ( " NOTIFY_SCENE_XREF_PRE_MERGE " ) , TEXT ( " NOTIFY_SCENE_XREF_POST_MERGE " ) , TEXT ( " NOTIFY_OBJECT_XREF_PRE_MERGE " ) , TEXT ( " NOTIFY_OBJECT_XREF_POST_MERGE " ) , TEXT ( " NOTIFY_PRE_MIRROR_NODES " ) , TEXT ( " NOTIFY_POST_MIRROR_NODES " ) , TEXT ( " NOTIFY_NODE_CLONED " ) , TEXT ( " NOTIFY_PRE_NOTIFYDEPENDENTS " ) , TEXT ( " NOTIFY_POST_NOTIFYDEPENDENTS " ) , TEXT ( " NOTIFY_MTL_REFDELETED " ) , TEXT ( " NOTIFY_TIMERANGE_CHANGE " ) , TEXT ( " NOTIFY_PRE_MODIFIER_ADDED " ) , TEXT ( " NOTIFY_POST_MODIFIER_ADDED " ) , TEXT ( " NOTIFY_PRE_MODIFIER_DELETED " ) , TEXT ( " NOTIFY_POST_MODIFIER_DELETED " ) , TEXT ( " NOTIFY_FILELINK_POST_RELOAD_PRE_PRUNE " ) , TEXT ( " NOTIFY_PRE_NODES_CLONED " ) , TEXT ( " NOTIFY_POST_NODES_CLONED " ) , TEXT ( " NOTIFY_SYSTEM_PRE_DIR_CHANGE " ) , TEXT ( " NOTIFY_SYSTEM_POST_DIR_CHANGE " ) , TEXT ( " NOTIFY_SV_SELECTIONSET_CHANGED " ) , TEXT ( " NOTIFY_SV_DOUBLECLICK_GRAPHNODE " ) , TEXT ( " NOTIFY_PRE_RENDERER_CHANGE " ) , TEXT ( " NOTIFY_POST_RENDERER_CHANGE " ) , TEXT ( " NOTIFY_SV_PRE_LAYOUT_CHANGE " ) , TEXT ( " NOTIFY_SV_POST_LAYOUT_CHANGE " ) , TEXT ( " NOTIFY_BY_CATEGORY_DISPLAY_FILTER_CHANGED " ) , TEXT ( " NOTIFY_CUSTOM_DISPLAY_FILTER_CHANGED " ) , TEXT ( " NOTIFY_LAYER_CREATED " ) , TEXT ( " NOTIFY_LAY
2021-11-18 14:37:34 -05:00
# if MAX_PRODUCT_YEAR_NUMBER >= 2018
, TEXT ( " NOTIFY_PRE_VIEWPORT_TOOLTIP " ) , TEXT ( " NOTIFY_WELCOMESCREEN_DONE " ) , TEXT ( " NOTIFY_PLAYBACK_START " ) , TEXT ( " NOTIFY_PLAYBACK_END " ) , TEXT ( " NOTIFY_SCENE_EXPLORER_NEEDS_UPDATE " ) , TEXT ( " NOTIFY_FILE_POST_OPEN_PROCESS_FINALIZED " ) , TEXT ( " NOTIFY_FILE_POST_MERGE_PROCESS_FINALIZED " )
# endif
2021-11-07 23:43:01 -05:00
# if MAX_PRODUCT_YEAR_NUMBER >= 2022
2024-04-09 01:09:02 -04:00
, TEXT ( " NOTIFY_PRE_PROJECT_FOLDER_CHANGE " ) , TEXT ( " NOTIFY_POST_PROJECT_FOLDER_CHANGE " ) , TEXT ( " NOTIFY_PRE_MXS_STARTUP_SCRIPT_LOAD " ) , TEXT ( " NOTIFY_SYSTEM_SHUTDOWN_CHECK " ) , TEXT ( " NOTIFY_SYSTEM_SHUTDOWN_CHECK_FAILED " ) , TEXT ( " NOTIFY_SYSTEM_SHUTDOWN_CHECK_PASSED " ) , TEXT ( " NOTIFY_FILE_POST_MERGE3 " ) , TEXT ( " NOTIFY_ACTIVESHADE_IN_FRAMEBUFFER_TOGGLED " ) , TEXT ( " NOTIFY_PRE_ACTIVESHADE_IN_VIEWPORT_TOGGLED " ) , TEXT ( " NOTIFY_POST_ACTIVESHADE_IN_VIEWPORT_TOGGLED " )
2021-11-07 23:43:01 -05:00
# endif
, TEXT ( " NOTIFY_INTERNAL_USE_START " ) } ;
# pragma warning(pop)
int i = 0 ;
for ( int Code : Codes )
{
RegisterNotification ( On3dsMaxNotification , this , Code ) ;
NotificationCodetoString . Add ( Code , Strings [ i ] ) ;
2021-11-25 12:45:05 -05:00
NotificationCodesRegistered . Add ( Code ) ;
2021-11-07 23:43:01 -05:00
+ + i ;
}
2021-12-06 14:48:33 -05:00
}
void FNotifications : : StartSceneChangeTracking ( )
{
if ( bSceneChangeTracking )
{
return ;
}
bSceneChangeTracking = true ;
2021-11-07 23:43:01 -05:00
NodeEventCallback = MakeUnique < FNodeEventCallback > ( Exporter . GetSceneTracker ( ) ) ;
// Setup Node Event System callback
// https://help.autodesk.com/view/3DSMAX/2018/ENU/?guid=__files_GUID_7C91D285_5683_4606_9F7C_B8D3A7CA508B_htm
NodeEventCallback - > CallbackKey = GetISceneEventManager ( ) - > RegisterCallback ( NodeEventCallback . Get ( ) ) ;
2021-12-06 14:48:33 -05:00
}
2021-11-25 12:45:05 -05:00
2021-12-06 14:48:33 -05:00
void FNotifications : : StopSceneChangeTracking ( )
{
if ( ! bSceneChangeTracking )
{
return ;
}
bSceneChangeTracking = false ;
GetISceneEventManager ( ) - > UnRegisterCallback ( NodeEventCallback - > CallbackKey ) ;
NodeEventCallback . Reset ( ) ;
NodeObserver - > Reset ( ) ;
MaterialObserver - > Reset ( ) ;
2021-11-07 23:43:01 -05:00
}
FString FNotifications : : ConvertNotificationCodeToString ( int code )
{
FString * Str = NotificationCodetoString . Find ( code ) ;
return Str ? * Str : TEXT ( " <unknown> " ) ;
}
2022-03-03 00:57:55 -05:00
void FNotifications : : PrepareForUpdate ( )
{
if ( NodeEventCallback )
{
GetISceneEventManager ( ) - > TriggerMessages ( NodeEventCallback - > CallbackKey ) ;
}
}
2021-11-07 23:43:01 -05:00
void FNotifications : : On3dsMaxNotification ( void * param , NotifyInfo * info )
{
2021-12-06 14:48:33 -05:00
FNotifications & NotificationsHandler = * static_cast < FNotifications * > ( param ) ;
2021-11-07 23:43:01 -05:00
IExporter * Exporter = & NotificationsHandler . Exporter ;
switch ( info - > intcode )
{
2021-12-06 14:48:33 -05:00
// Skip some events to display(spamming tests)
2021-11-07 23:43:01 -05:00
case NOTIFY_VIEWPORT_CHANGE :
case NOTIFY_PRE_RENDERER_CHANGE :
case NOTIFY_POST_RENDERER_CHANGE :
case NOTIFY_CUSTOM_ATTRIBUTES_ADDED :
case NOTIFY_CUSTOM_ATTRIBUTES_REMOVED :
case NOTIFY_MTL_REFDELETED :
break ;
2021-12-16 19:33:40 -05:00
case NOTIFY_PLUGINS_PRE_SHUTDOWN : // This one crashes when calling LogInfo
return ;
2022-04-15 13:41:06 -04:00
// case NOTIFY_NODE_LAYER_CHANGED:
// break;
case NOTIFY_NODE_UNLINKED :
case NOTIFY_NODE_CREATED :
case NOTIFY_NODE_LINKED :
{
INode * Node = reinterpret_cast < INode * > ( info - > callParam ) ;
LogDebugNode ( NotificationsHandler . ConvertNotificationCodeToString ( info - > intcode ) , Node ) ;
}
break ;
2021-11-07 23:43:01 -05:00
default :
LOG_DEBUG_HEAVY ( FString ( TEXT ( " Notify: " ) ) + NotificationsHandler . ConvertNotificationCodeToString ( info - > intcode ) ) ;
} ;
2021-12-06 14:48:33 -05:00
if ( NotificationsHandler . bSceneChangeTracking )
{
ISceneTracker & SceneTracker = Exporter - > GetSceneTracker ( ) ;
switch ( info - > intcode )
{
2022-08-16 02:51:36 -04:00
case NOTIFY_BY_CATEGORY_DISPLAY_FILTER_CHANGED :
SceneTracker . HideByCategoryChanged ( ) ;
break ;
2021-12-06 14:48:33 -05:00
case NOTIFY_NODE_POST_MTL :
// Event - node got a new material
break ;
2021-11-07 23:43:01 -05:00
2021-12-06 14:48:33 -05:00
case NOTIFY_SCENE_ADDED_NODE :
{
// note: INodeEventCallback::Added/Deleted is not used because there's a test case when it fails:
// When a box is being created(dragging corners using mouse interface) and then cancelled during creation(RMB pressed)
// INodeEventCallback::Deleted event is not fired by Max, although Added was called(along with other change events during creation)
INode * Node = reinterpret_cast < INode * > ( info - > callParam ) ;
LogDebugNode ( NotificationsHandler . ConvertNotificationCodeToString ( info - > intcode ) , Node ) ;
SceneTracker . NodeAdded ( Node ) ;
break ;
}
case NOTIFY_SCENE_PRE_DELETED_NODE :
{
// note: INodeEventCallback::Deleted is not called when object creation was cancelled in the process
INode * Node = reinterpret_cast < INode * > ( info - > callParam ) ;
LogDebugNode ( NotificationsHandler . ConvertNotificationCodeToString ( info - > intcode ) , Node ) ;
SceneTracker . NodeDeleted ( reinterpret_cast < INode * > ( info - > callParam ) ) ;
break ;
}
2022-03-03 00:57:55 -05:00
case NOTIFY_NODE_UNLINKED :
{
INode * Node = reinterpret_cast < INode * > ( info - > callParam ) ;
LogDebugNode ( NotificationsHandler . ConvertNotificationCodeToString ( info - > intcode ) , Node ) ;
break ;
}
2022-05-17 10:39:25 -04:00
case NOTIFY_NODE_HIDE :
case NOTIFY_NODE_UNHIDE :
{
INode * Node = reinterpret_cast < INode * > ( info - > callParam ) ;
SceneTracker . NodeHideChanged ( reinterpret_cast < INode * > ( info - > callParam ) ) ;
break ;
}
2022-03-03 00:57:55 -05:00
case NOTIFY_SCENE_POST_DELETED_NODE :
{
INode * Node = reinterpret_cast < INode * > ( info - > callParam ) ;
LogDebugNode ( NotificationsHandler . ConvertNotificationCodeToString ( info - > intcode ) , Node ) ;
break ;
}
case NOTIFY_SCENE_XREF_POST_MERGE :
{
INode * Node = reinterpret_cast < INode * > ( info - > callParam ) ;
LogDebugNode ( NotificationsHandler . ConvertNotificationCodeToString ( info - > intcode ) , Node ) ;
SceneTracker . NodeXRefMerged ( Node ) ;
break ;
}
2021-12-06 14:48:33 -05:00
}
}
2022-03-03 00:57:55 -05:00
// Handle events for scene load/new/reset
// Note - different UI functions which destroy current scene send different notifications
// Reset - NOTIFY_SYSTEM_PRE_RESET NOTIFY_POST_SCENE_RESET
// Open - NOTIFY_FILE_PRE_OPEN_PROCESS NOTIFY_FILE_PRE_OPEN NOTIFY_POST_SCENE_RESET NOTIFY_FILE_POST_OPEN NOTIFY_FILE_POST_OPEN_PROCESS NOTIFY_FILE_POST_OPEN_PROCESS_FINALIZED
// File>New>New All - NOTIFY_SYSTEM_PRE_NEW NOTIFY_POST_SCENE_RESET NOTIFY_SYSTEM_POST_NEW
// File>New>New From Template - NOTIFY_SYSTEM_PRE_RESET NOTIFY_POST_SCENE_RESET NOTIFY_SYSTEM_POST_RESET
2021-11-07 23:43:01 -05:00
switch ( info - > intcode )
{
2022-03-03 00:57:55 -05:00
// Handle New/Reset events sent before scene reset - stop tracking immediately when "Pre" events are received - after this point all nodes are invalid, don't wait for "Post" event
2021-11-25 12:45:05 -05:00
case NOTIFY_SYSTEM_PRE_NEW : // Sent when File>New>New All is selected
case NOTIFY_SYSTEM_PRE_RESET : // Sent when Reset OR File>New>New From Template is selected
2022-03-03 00:57:55 -05:00
case NOTIFY_FILE_PRE_OPEN : // Sent when File>Open is used
Exporter - > ResetSceneTracking ( ) ;
2021-11-07 23:43:01 -05:00
break ;
2022-03-03 00:57:55 -05:00
case NOTIFY_SYSTEM_POST_NEW :
case NOTIFY_SYSTEM_POST_RESET :
2021-11-07 23:43:01 -05:00
case NOTIFY_FILE_POST_OPEN :
2022-03-03 00:57:55 -05:00
Exporter - > InitializeDirectLinkForScene ( ) ;
2021-11-07 23:43:01 -05:00
break ;
}
}
}
# include "Windows/HideWindowsPlatformTypes.h"
# endif // NEW_DIRECTLINK_PLUGIN