Notifications
Clear all

[Closed] When object deleted, delete children. Huh?

Okay, well, I tried linking the various nodes from the tabs to each other instead of to the master, and there were no problems with undo. So can we just create a something to hold the nodeTab array without actually having anything parented to it, and tell it if the parent node is deleted to delete the rest?

Or, do you already have something in mind besides using nodeTab?

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

sure… i knew that #nodeTab can’t work. read about weak references

What about my other suggestion? Not worth looking into? x)

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

what is the other suggestion?

create a something to hold the nodeTab array without actually having anything parented to it, and tell it if the parent node is deleted to delete the rest?

In other words, have one node that is the parent to to the others, and one that holds them all in a nodeTab.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

you don’t want to read the help… well…
the idea of the using #nodeTab parameter was almost perfect, but we had a little problem… so let’s just rethink a little. let’s use #maxobjectTab and NodeTransformMonitor objects instead of nodes. capiche?

edit: deleted as doubled

what? the post is doubled. never mind. read the last one

I have no problem reading the help. Part of the reason I brought it up, though, is that I thought doing it the other way would help me more with my other goal, which is to set something up where if ANY of the objects in a collection like this are deleted, then all of the rest will ALSO be deleted.

that’s the simplest part in the our (technically yours) pipeline. the only thing we need is to receive right messages. that’s the thing that we are working on now.
PS: (probably you guess that i have already a completely working solution, but it’s so boring just post it)

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

This is very interesting topic.
Denis I really appreciate your contribution an effort for amazing explanation.
Probably this is not perfect way but works for me


global ContainerAttrib = attributes ContainerAttrib attribID:#(0x1f05aab6, 0x7a59c3a6)
(
	local handler
	fn getNode = (refs.dependentnodes (custattributes.getowner this) firstonly:on)
	fn constructNode node: = if not (theHold.Redoing() or theHold.Holding()) do
	(
		if node == unsupplied do node = getNode()
		if isvalidnode node and not isdeleted node and handler == undefined do
		(
			handler = when node deleted node do if (attr = node.baseobject.custattributes[#ContainerAttrib]) != undefined do 
			(
				if attr.handler != undefined do deleteChangeHandler attr.handler
				attr.handler = undefined
				delete (for n in attr.container where isvalidnode n.node and not isdeleted n.node collect n.node)
				attr.container = #()
			)
		)
	)
	parameters params 
	(
		container type:#maxObjectTab tabsizevariable:on
		on container set val do constructNode()
	)

	on update do constructNode()
	on load do constructNode()
)
(
	num = [1,1,10]
	for i=1 to num[1] do 
	(
		gc()
		delete objects
		for k=1 to num[2] do
		(
			y = (k-1)*20
			global b = dummy name:(uniquename "master") pos:[0,y,0]
			custattributes.add b ContainerAttrib
			b.ContainerAttrib.constructNode()
			b.container = for k = 1 to num[3] collect (nodeTransformMonitor node:(point pos:[k*20,y,0] wirecolor:orange parent:b) forwardTransformChangeMsgs:false)
		)
	)
	print "DONE!"
	ok
)

I’m sure it’s a lot more fun to watch me flail helplessly.

I promise, I am trying to learn here. Anyway, just swapping things in like this obviously doesn’t work:

global containerAttrib = attributes containerAttrib attribID:#(0x1f05aab6, 0x7a59c3a6)
(
	local handler
	fn constructNode =
	(
		--format "theHold.redoing(): %, theHold.holding(): %
" (theHold.redoing()) (theHold.holding())
		if not (theHold.redoing() or theHold.holding()) do
		(
			node = refs.dependentNodes (custAttributes.getOwner this) firstOnly:on
			if (isValidNode node) and not (isDeleted node) and (handler == undefined) do
			(
				handler =	when node deleted node do
				(
				    if (attr = nodeTransformMonitor node:node) != undefined do
					(
						if attr.handler != undefined do deleteChangeHandler attr.handler
						attr.handler = undefined
						delete (for n in attr.container where isValidNode n and not isDeleted n collect n)
						attr.container = #()
					)
				) -- end handler
			)
		)
	) -- end fn constructNode
	parameters params 
	(
		container type:#maxObjectTab tabSizeVariable:on
		on container set val do constructNode()
	)
	on update do constructNode()
	on load do constructNode()
)

And I don’t know what to do instead because there’s nothing useful in the documentation about working with node transform monitors.

I have a question: Why we need to use for loop with n=[1,1,10] and declare master dummy as global. Can we simply use this concept?


global ContainerAttrib = attributes ContainerAttrib attribID:#(0x1f05aab6, 0x7a59c3a6)
(
	local handler
	fn getNode = (refs.dependentnodes (custattributes.getowner this) firstonly:on)
	fn constructNode node: = if not (theHold.Redoing() or theHold.Holding()) do
	(
		if node == unsupplied do node = getNode()
		if isvalidnode node and not isdeleted node and handler == undefined do
		(
			handler = when node deleted node do if (attr = node.baseobject.custattributes[#ContainerAttrib]) != undefined do 
			(
				if attr.handler != undefined do deleteChangeHandler attr.handler
				attr.handler = undefined
				delete (for n in attr.container where isvalidnode n.node and not isdeleted n.node collect n.node)
				attr.container = #()
			)
		)
	)
	parameters params 
	(
		container type:#maxObjectTab tabsizevariable:on
		on container set val do constructNode()
	)

	on update do constructNode()
	on load do constructNode()
)
(
	gc() ; delete objects
	dm = dummy name:(uniquename "master") pos:[0,0,0]
	custattributes.add dm ContainerAttrib
	dm.ContainerAttrib.constructNode()
	dm.container = for k = 1 to 10 collect (nodeTransformMonitor node:(point pos:[k*20,0,0] wirecolor:orange parent:dm) forwardTransformChangeMsgs:false)
	print "DONE!" ; ok
)

2 Replies
(@denist)
Joined: 11 months ago

Posts: 0

both things are just for easier debugging.

… your code is almost correct. but… because #maxobjectTab can contain any maxobjects when you are deleting nodes you have to check that an item is a NodeTransformMonitor object.

and now the next problem. because a NodeTransformMonitor object don’t pass all messages to dependents we lost when construct mechanics for the container parameter.

(@gazybara)
Joined: 11 months ago

Posts: 0

So what do you suggest?
For now when I delete master dummy then press Undo and delete again everything works fine.
I newer used “when construct mechanic” 🙁

Edit:

Like this?

delete (for n in attr.container where isKindOf n NodeTransformMonitor and isvalidnode n.node and not isdeleted n.node collect n.node)

global ContainerAttrib = attributes ContainerAttrib attribID:#(0x1f05aab6, 0x7a59c3a6)
(
	local handler
	fn getNode = (refs.dependentnodes (custattributes.getowner this) firstonly:on)
	fn constructNode node: = if not (theHold.Redoing() or theHold.Holding()) do
	(
		if node == unsupplied do node = getNode()
		if isvalidnode node and not isdeleted node and handler == undefined do
		(
			handler = when node deleted node do if (attr = node.baseobject.custattributes[#ContainerAttrib]) != undefined do 
			(
				if attr.handler != undefined do deleteChangeHandler attr.handler
				attr.handler = undefined
				delete (for n in attr.container where isvalidnode n and not isdeleted n collect n)
				--delete (for n in attr.container where iskindof n NodeTransformMonitor and isvalidnode n.node and not isdeleted n.node collect n.node)
				attr.container = #()
			)
		)
	)
	parameters params 
	(
		container type:#nodeTab tabsizevariable:on
--		container type:#maxobjectTab tabsizevariable:on
		on container set val do constructNode()
	)

	fn constructTransform = 
	(
		when parameters container change handleAt:#redrawViews do format "params changed...
"
	)
	on create do constructTransform()

	on update do constructNode()
	on load do constructNode()
)
(
	num = [1,2,4]
	for i=1 to num[1] do 
	(
		gc()
		delete objects
		for k=1 to num[2] do
		(
			y = (k-1)*20
			global b = dummy name:(uniquename "master") pos:[0,y,0]
			custattributes.add b ContainerAttrib
			b.container = for k = 1 to num[3] collect (point pos:[k*20,y,0] wirecolor:orange)
			--in b (b.container = for k = 1 to num[3] collect NodeTransformMonitor node:(point pos:[k*20,y,0] wirecolor:orange))
		)
	)
	print "DONE!"
	ok
)

i returned the code to the nodeTab solution. as you can see any move, link, delete, etc… actions with point fires a parameter changed event (because we constructed it using when parameters container change).
now change the code to the maxobjectTab and NodeTransformMonitor solution. and you will see that our when construct stops working. that’s because NodeTransformMonitor doesn’t notify its dependents about all events.

2 Replies
(@gazybara)
Joined: 11 months ago

Posts: 0

Are you purposely forgot to parent points to dummy?
I added this line “(point pos:[k*20,y,0] wirecolor:orange parent:b)” which is works but after deleting master and back it with UNDO again max complains about “dependency loop”

(@denist)
Joined: 11 months ago

Posts: 0

i purposely didn’t link points to the dummies. because we can’t link dependents and put them as nodes to master’s nodetab.
that was a reason why we moved from nodetab to maxobjecttab solution.

Page 4 / 10