[just quick reply atm]
Ah, as i said, you can expect some funny words from me
I mean the callbacks + CAs.
What i imagine, in case i made such tool, is more like scheme editor/dashboard that not leave trails after it assistance.
I know is better to explain my idea/vision a bit more and clear, and i promise to do that as soon as i can.
Well, to be honest,
i’m after a tool with very different functionality,
and can’t waste your time about this one.
Also not ask for any code modifications in your outline,
its a complete and very well written tool.
The idea with nested layers is interesting to me though
and probably i’ll play with this some day.
I only wonder whether i can achieve something closer, not exact,
but without storing any data inside the scene,
especially without persistent callbacks.
Maybe this is very expensive question, not sure,
or probably no one thought about this yet,
but nothing bad to me to find this out by myself.
Thanks for your kindness!
Regards,
Panayot
So I’ve been thinking a bit about how to tackle this based on the suggestion from Denis to store the layer hierarchy as names. I think that will work to solve the merging problem, but using that alone is a little inconvenient in ‘normal’ operation.
So I came up with a combination of using the layer handles pointing to the parent of each layer, and storing the full names hierarchy when the scene is saved.
Here’s some pseudo-code to illustrate the idea:
attributes nestedLayers
parentHandle type:#integer
layerHierarchy type:#stringTab
on postLoad
for each layerName in layerHierarchy
if
(not layer exists) do
create layer
set layerHierarchy
set parentHandle
od
else do
set parentHandle
verify layerHierarchy up to the top
if it differs from that being set, change it down to every child
od
fi
end
end
end
persistent FilePreSave callback
for each layer
layerData = getCA layer
layerHierachy = #()
while (layerData != undefined AND layerData.parentHandle != -1) do
parentLayer = getAnimByHandle layerData.parentHandle
append layerHierarchy parentLayer.name
layerData = getCA parentLayer
od
layerData.layerHierarchy = layerHierarchy
end
end
function getParentLayer layer
layerData = getCA layer
getAnimByHandle layerData.parentHandle;
end
function setParentLayer layer parentLayer
layerData = getOrAddCA layer
layerData.parentHandle (getHandleByAnim parentLayer)
end
i also have been thinking and went the opposite way. i looked at my old code that i didn’t touch for many years and changed CA from names to layer objects.
now i have only one CA parameter for every layer object – #parent
the CA definition has methods:
setParent (checks dependency loop before set a parent),
getParent (checks if layer object still has valid layer),
getOwner (gets owner layer object),
getChildren (collects dependent Base_Layers)
i tested this new system and in works for merge, xref object, and xref scene … no crashes.
Yeah if that works, it is by far the most practical.
Could you have a look at this issue report and see if that works for your implementation?
http://code.google.com/p/outliner/issues/detail?id=25&colspec=ID%20Type%20Status%20Priority%20Summary
Or alternatively, create a nested layer setup, and add a few objects to the layer at the end of a branch. Then merge the objects into a new scene one by one. First one works, second one crashes in the Outliner’s case.
it works fine in my case. the system merges all objects correct.
as i have a time i will try to make a snippet, but the CA definition is:
global NestedLayerCA = attributes NestedLayerCA attribID:#(0x1967, 0x1333de47) version:1
(
local owner
parameters main
(
parent type:#maxObject
on parent set val do
(
print "parent changed"
)
)
fn getOwnerObject = (custAttributes.getOwner this)
fn isValidLayerObject obj = (iskindof obj Base_Layer and LayerManager.getLayerFromName obj.name != undefined)
fn getParentObject = if isValidLayerObject parent do parent
fn setParentObject obj = if isValidLayerObject obj and not (refs.DependencyLoopTest obj (owner = getOwnerObject())) do this.parent = obj
fn getChildrenObjects =
(
owner = getOwnerObject()
for d in (refs.dependents owner) where isValidLayerObject d collect d
)
)
/*
for k=1 to LayerManager.count-1 do
(
layer = (LayerManager.getLayer k).layerAsRefTarg
format "name:% result:%
" layer.name (custAttributes.add layer NestedLayerCA)
)
*/
I remembered now why i didn’t do it before… My tool handles layers and selection sets the same way. So it had nested selection sets as well. Because the selection set is not a max object i can’t add CA to it, and use it as max object. So I added another CA to scene root object.
I wanted to use same methods for both layers and selection sets, so I used name (string) parameter for layer CA and scene root CA.
It does crash max (2010) for me actually. I build a scene like this:
layer1 = (LayerManager.newLayer()).layerAsRefTarg;
layer2 = (LayerManager.newLayer()).layerAsRefTarg;
custAttributes.add layer2 NestedLayerCA;
layer2.setParentObject layer1;
layer2.current = true;
sphere()
sphere()
Then in a new scene, first merge sphere01. That’s fine, works a treat. When trying to then merge sphere02 into it, max crashes.
That’s crazy…! There are no callbacks other than default ones from max (not the outliner’s either).
And the crash occurs both with using your snippet of code as well as with the Outliner’s, which are in essence the same.
i’ve got a crash… when i do the sames steps manually – it works. when i put everything in script it crashes.
layer1 = (LayerManager.newLayer()).layerAsRefTarg
layer2 = (LayerManager.newLayer()).layerAsRefTarg
custAttributes.add layer2 NestedLayerCA
layer2.setParentObject layer1
layer2.current = true
sphere()
sphere()
savemaxfile (getdir #temp + "\crashtest.max")
resetmaxfile #noPrompt
mergemaxfile (getdir #temp + "\crashtest.max") #(#Sphere01) quiet:on
mergemaxfile (getdir #temp + "\crashtest.max") #(#Sphere02) quiet:on
so … it means the system needs some notification after a nested layer was merged.
Hmm interesting. So if you did the part from saveMaxFile onwards manually, it didn’t crash for you?
I get this result when doing the merging with maxscript too:
ReferenceTarget:BaseLayer
ReferenceTarget:BaseLayer
"parent changed"
true
"parent changed"
ReferenceTarget:BaseLayer
true
$Sphere:Sphere01 @ [0.000000,0.000000,0.000000]
$Sphere:Sphere02 @ [0.000000,0.000000,0.000000]
false
OK
"parent changed"
"parent changed"
true
** system exception **
i have the same result as you. but when i use max UI to merge the nodes it works fine