Files
2025-09-29 00:52:08 +02:00

432 lines
13 KiB
Plaintext
Executable File

--
-- Object Link manager
-- @Author Gunnar Droege
-- @Description An interface to the dotnet library to manage externally defined global linking
--
global gRsLinkMgr
global useMetaLinks = false
struct sLinkState
(
name,
guid,
asset,
target,
linkState,
linkChannel = -1,
sceneState = #unresolved, -- #resolved #resolvedByName #notSerialised
fn ResolveInScene linkObj =
(
name = linkObj.name
guid = linkObj.guid.toString()
asset = linkObj.ContentNode
linkState = linkObj.StatusFlags
target = ::RsGuidTools.GetObjByGuid guid
if undefined!=target then
(
sceneState = #resolved
)
else
(
-- optional name fallback
local nameMatches = getNodeByName name all:true
if nameMatches.count>0 then
(
sceneState = #resolvedByName
target = nameMatches[1]
)
)
)
)
struct sObjChannelLinkStates
(
linkChannel = -1,
parent,
children = #()
)
struct RsObjLinkMgr
(
dotnetMgr,
---------------------------------
fn ResolveContainer obj =
(
local map = RsMapObjectGetMapContainerFor obj
if undefined==map then
map = RsMapContainer name:"none" filename:(maxfilePath+maxFileName)
return map
),
public
---------------------------------
fn SetContentTreeHelper CTreeHelper =
(
print "setting contenttreehelper"
dotnetMgr.CTreeHelper = CTreeHelper
),
fn SetLog ulog =
(
print "setting ulog"
dotnetMgr.Log = ulog
),
fn SetBranch branch =
(
print ("setting branch to "+branch.Project.name as string+"|"+branch.name as string)
dotnetMgr.Branch = branch
),
fn printBranch =
(
local branch = dotnetMgr.Branch
print ("branch "+branch.Project.name as string+"|"+branch.name as string)
),
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Reset .Net cache
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
fn FlushCache deleteSceneLinks:true =
(
if not useMetaLinks then
return true
print "Resetting link cache"
local serialisedGuids = dotnetMgr.FlushEditedNodes()
if deleteSceneLinks then
(
progressstart "Deleting links' scene representation"
local i=1
for guid in serialisedGuids while (RsMapProgress i serialisedGuids.count) do
(
local sceneObj = ::RsGuidTools.GetObjByGuid (guid.toString())
if undefined!=sceneObj then
(
RsSceneLink.RemoveContainer ::LinkType_ANY sceneObj
)
i+=1
)
progressend()
)
),
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- forget viewport links
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
fn RemoveRsSceneLinks =
(
local openContainers = RsMapGetMapContainers()
for map in openContainers do
(
editingNamespace = map.name
print ("Deleting RsScene links on map \""+editingNamespace+"\"")
progressStart ("Map \""+editingNamespace+"\" link deletion.")
local objIndex = 1
for obj in map.objects while (RsMapProgress objIndex map.objects.count) do
(
RsSceneLink.RemoveContainer ::LinkType_ANY obj
objIndex += 1
)
progressEnd()
)
),
fn GetLinkFile obj =
(
local objGuid = RsGuidMgr.GetGuid obj
if undefined!=objGuid then
(
return (dotnetClass "RSG.ObjectLinks.MetaAssetResolver").GetMetaFilePath gRsBranch (::RsObjLinkFuncs.MakeGuid objGuid) ((dotnetclass "RSG.ObjectLinks.MetaTypes").MetaTypeLinks)
)
return ""
),
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Save link from scene into meta files
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
fn SaveObjLinks obj map: =
(
if not isValidnode obj then
return false
if map==unsupplied then
map = ResolveContainer obj
-- save out legacy scene stored linking
for parentLinkType in RsSceneLink.GetNodeParentLinkTypes obj do
(
local target = RsSceneLink.GetParent parentLinkType obj
if undefined!=target then
this.SetParent parentLinkType obj target sourcemap:map
else
RsSceneLink.RemoveContainer parentLinkType obj
)
for childLinkType in RsSceneLink.GetNodeChildLinkTypes obj do
(
local children = #()
RsSceneLink.GetChildren childLinkType obj &children
for child in children do
(
if undefined!=child then
this.SetParent childLinkType child obj targetmap:map
)
)
),
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Save all scene links from scene into meta files and delete .Net cache
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
fn SaveSceneLinks =
(
-- Touching nodes
print "Saving out links"
local openContainers = RsMapGetMapContainers()
local sceneObjs = objects as array
for map in openContainers do
(
editingNamespace = map.name
progressStart ("Saving out links for map \""+editingNamespace as string+"\"")
local objIndex = 0
for obj in map.objects while (RsMapProgress objIndex map.objects.count) do
(
local kids = #()
::RsCollectChildren obj kids
for k in kids do
(
SaveObjLinks k map:map
local sceneObjIndex = findItem sceneObjs k
deleteItem sceneObjs sceneObjIndex
)
objIndex += 1
)
progressEnd()
)
-- we need to save out SOME sort of asset information. we can't resolve any objects in DCC if no assetpath is given and it's unlikely to be exported, too.
if maxFilename!="" then
(
progressStart ("Saving out mapless links")
objIndex = 0
local maplessContainer = RsMapContainer \
name:(getFilenameFile maxFilename) \
filename:(maxFilePath + maxFilename) \
objects:sceneObjs
for obj in sceneObjs where isValidNode obj while (RsMapProgress objIndex sceneObjs.count) do
(
SaveObjLinks obj map:maplessContainer
objIndex += 1
)
progressEnd()
)
-- triggerng serialiation and cache reset
FlushCache()
gRsUlog.Validate()
),
fn ResolveChannelObjStates obj channelObj =
(
local channelStates = sObjChannelLinkStates linkChannel:channelObj.Channel.value__
local linkParent = channelObj.Parent
if undefined!=linkParent then
(
channelStates.parent = sLinkState linkChannel:channelObj.Channel.value__
channelStates.parent.ResolveInScene linkParent
if channelStates.parent.sceneState != #unresolved then
(
local res = RsSceneLink.Setparent channelStates.parent.linkChannel obj channelStates.parent.target
)
)
local linkChildren = channelObj.Children
local childEnum = linkChildren.GetEnumerator()
while childEnum.MoveNext() do
(
linkChild = childEnum.Current
local linkState = sLinkState linkChannel:channelObj.Channel.value__
linkState.ResolveInScene linkChild
if linkState.sceneState != #unresolved then
(
local res = RsSceneLink.Setparent linkState.linkChannel linkState.target obj
)
append channelStates.children linkState
)
return channelStates
),
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Save scenes from scene into meta files and delete .Net cache
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
fn LoadObjLinks obj =
(
local objectChannelStates = #()
-- local now = (dotnetclass "DateTime").now
local objGuid = RsGuidMgr.GetGuid obj
if undefined==objGuid then
return objectChannelStates
-- now = (dotnetclass "DateTime").now
local linkObj = dotnetMgr.Resolve (::RsObjLinkFuncs.MakeGuid objGuid)
-- print ("Time for "+obj.name+" Container resolve: "+ ((dotnetclass "DateTime").now.subtract now).tostring())
-- now = (dotnetclass "DateTime").now
if undefined!=linkObj then
(
local chEnum = linkObj.Channels.GetEnumerator()
while chEnum.MoveNext() do
(
append objectChannelStates (ResolveChannelObjStates obj chEnum.Current)
)
)
-- print ("loading time: "+ ((dotnetclass "DateTime").now.subtract now).tostring())
objectChannelStates
),
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- load all links from meta files into scene cache
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
fn LoadSceneLinks conts:(RsMapGetMapContainers()) =
(
progressStart ("Loading links for map...")
local objIndex = 0
for obj in objects while (RsMapProgress objIndex objects.count) do
(
LoadObjLinks obj
objIndex += 1
)
progressEnd()
FlushCache deleteSceneLinks:false
gRsUlog.Validate()
),
fn SaveCallback =
(
if not useMetaLinks then
return true
if (RsQueryBoxTimeOut "Save out ALL SceneLinks to metadata? This will delete all local links in max to avoid ambiguity on next load." timeout:10 defaultBtn:2) then
(
SaveSceneLinks()
)
else
(
FlushCache()
)
),
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- accessors
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
fn SetParent linkChannel source target sourcemap: targetmap: =
(
if not isValidNode source or not isValidNode target then
(
print ("Either of the nodes is not a valid node to link: "+source as string+", "+target as string)
return false
)
if not RsSceneLink.SetParent linkChannel source target then
(
print ("Linking failed for nodes "+source as string+" and "+target as string+" for channel "+linkChannel as string)
return false
)
if sourcemap==unsupplied then
sourcemap = ResolveContainer source
if targetmap==unsupplied then
targetmap = ResolveContainer target
-- we need all f these to link:
if undefined == sourcemap or
#none == sourcemap or
undefined == sourcemap.filename or
"" == sourcemap.filename or
undefined == targetmap or
#none == targetmap or
undefined == targetmap.filename or
"" == targetmap.filename then
(
gRsUlog.LogWarning ("Didn't (re)link "+source as string+" and "+target as string+" due to missing map information.") context:#(source, target)
return false
)
local sourceGuid = (RsGuidMgr.GetGuid source)
local targetGuid = (RsGuidMgr.GetGuid target)
local sourceContentNode = (RsContentTree.getContentNode sourcemap.filename)
local targetContentNode = (RsContentTree.getContentNode targetmap.filename)
dotnetMgr.CTreeHelper = RsContentTree.ContentTreeHelper
-- print ("Linking "+target as string+" to "+source as string+" on channel "+linkChannel as string+" with map "+map as string)
dotnetMgr.Link \
linkChannel \
sourceContentNode sourceGuid (source.name) \
targetContentNode targetGuid (target.name)
),
fn Unlink linkChannel source target:unsupplied map: =
(
if map==unsupplied then
map = ResolveContainer source
local filename = map.filename
local srcGuidStr = (RsGuidMgr.GetGuid source)
RsSceneLink.RemoveContainer linkChannel source
local trgGuidStr = ""
if unsupplied!=target then
(
trgGuidStr = (RsGuidMgr.GetGuid target)
)
dotnetMgr.Unlink linkChannel srcGuidStr trgGuidStr
return false
),
fn GetChildren ch obj kids update:true =
(
if useMetaLinks and update then
LoadObjLinks obj
RsSceneLink.GetChildren ch obj kids
),
fn GetParents ch obj kids update:true =
(
if useMetaLinks and update then
LoadObjLinks obj
RsSceneLink.GetParents ch obj kids
),
fn GetParent ch obj update:true =
(
if useMetaLinks and update then
LoadObjLinks obj
RsSceneLink.GetParent ch obj
),
fn GetNodeChildLinkTypes obj update:true =
(
if useMetaLinks and update then
LoadObjLinks obj
RsSceneLink.GetNodeChildLinkTypes obj
),
fn GetNodeParentLinkTypes obj update:true =
(
if useMetaLinks and update then
LoadObjLinks obj
RsSceneLink.GetNodeParentLinkTypes obj
),
getChannelName = RsSceneLink.getChannelName
)
filein "ObjectLink_funcs.ms"