Notifications
Clear all

[Closed] Merging linked layer references in custom attributes conundrum

What do you mean by “background wire” ?

1 Reply
(@panayot)
Joined: 11 months ago

Posts: 0

[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
1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

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.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

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.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

it doesn’t crash for me. i don’t know what to say. maybe anyone else can test it ?

maybe you have some callback that causes the crash?

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 **
1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

i have the same result as you. but when i use max UI to merge the nodes it works fine

Page 2 / 4