Notifications
Clear all

[Closed] GroupBoxes – in development.

here is what i have… there are many problems and probably bugs there but the idea works. check this out:


 plugin simpleManipulator GroupControl
 	name:"GroupControl"
 	classID:#(0x2feb1967, 0x111c058a)
 	--invisible:on
 category:"Manipulators"
 (
 	local updated = off
 	
 	local rd = colorMan.getColor #manipulatorsSelected
 	local ye = colorMan.getColor #manipulatorsInactive
 
 	local node
 	fn getNode = (refs.dependentnodes this)[1]
 
 	local size = [1,1,1], offset = [0,0,0]
 	fn hierarchyBBox =
 	(
 		local bmin = [1e9, 1e9, 1e9]
 		local bmax = [-1e9, -1e9, -1e9]
 		
 		children = deleteitem (join #() node) 1
 		for c in children do 
 		(
 			cmin = c.min
 			cmax = c.max
 		
 			bmin.x = amin bmin.x cmin.x
 			bmin.y = amin bmin.y cmin.y
 			bmin.z = amin bmin.z cmin.z
 
 			bmax.x = amax bmax.x cmax.x
 			bmax.y = amax bmax.y cmax.y
 			bmax.z = amax bmax.z cmax.z
 		)
 		size = bmax - bmin
 		offset = bmin
 	)
 
 	parameters mainParams 
 	( 
 		update type:#boolean animatable:on
 	)	
 	on canManipulate target return off
 
 	tool create
 	(
 		on mousePoint click do case click of
 		(
 			1: 
 			(
 				nodeTM.translation = gridPoint
 				#stop 
 			)
 		)
 	)
 	mapped fn addPoint p giz = 
 	(
 		if p == #new then giz.startNewLine() else giz.addPoint p
 	)
 	local giz
 	fn makeBoxGizmo = 
 	(
 		giz = manip.makeGizmoShape()
 		addPoint #(#new, [0,0,0],[0,1,0],[1,1,0],[1,0,0],[0,0,0],[0,0,1],[0,1,1],[1,1,1],[1,0,1],[0,0,1]) giz
 		addPoint #(#new, [0,1,0],[0,1,1]) giz
 		addPoint #(#new, [1,1,0],[1,1,1]) giz
 		addPoint #(#new, [1,0,0],[1,0,1]) giz
 		giz
 	)
 	fn makeGizmos light:off = if isvalidnode node and not isAnimPlaying() do animate off undo off
 	(
 		this.clearGizmos()
 		
 		if update then
 		(
 			hierarchyBBox()
 		)
 		else
 		(
 			size = [1,1,1]
 			offset = [0,0,0]
 		)
 		giz = makeBoxGizmo()
 		giz.transform (translate (scalematrix size) offset)
 		giz.transform (inverse node.transform)
 		this.addGizmoShape giz 0 ye rd
 	)
 	on updateGizmos do 
 	(
 		if isvalidnode (node = getNode()) do 
 		(
 			if not (c = update.controller).VariableExists "node" do 
 			(
 				c.addnode "node" node
 
 				source = "dependson node
"
 				source += "node.children.count
"
 
 				c.setexpression source
 			)
 			--format "make: %
" (join #() node)
 		)
 		makeGizmos()
 	)
 	on create do 
 	(
 		this.update.controller = createinstance float_script
 	)
 	on clone target do 
 	(
 		this.update.controller = createinstance float_script
 	)
 )
 
 fn updateGroupControls event: = 
 (
 	node = callbacks.notificationParam()
 --	format "% %
" event node
 	for group in (getclassinstances GroupControl) do group.makeGizmos()
 )
 callbacks.removescripts id:#progroupcontrol
 callbacks.addscript #nodeLinked "updateGroupControls event:#link" id:#progroupcontrol
 callbacks.addscript #nodeUnlinked "updateGroupControls event:#unlink" id:#progroupcontrol
 

i’m using LO’s function to get children BBox

Can’t figure out how to get your code working Denis, where’s the instruction manual

run the code (or place the script to stdplugs\stdscripts and reload max), after that you will see in create panel -> helpers -> manipulators the object GroupControl. create it. link anything to the control and check. you can also animate the control and its children… the bounding box has to automatically adjust.

Nice!

Put this code on the end of Denis’s if you want the groupbox to be automatically created.

 thegroup = GroupControl pos:selection.center
 for o in selection do o.parent = thegroup

So just to confirm, at the moment moving the members of the group doesn’t change the size of the GroupBox?

Bugs: You can’t move the pivot only, it breaks the box’s transform.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

i know about it. i just don’t have time now to continue the project. to fix it we need to find a way how to send children transform change message to the control.

Well if you change the timeslider it’ll update the bounding box, but not interactively when you move objects.

Bug: Selecting a GroupBox and pressing Z centers on world 0,0,0 not the box.

the project updates:


 plugin simpleManipulator GroupControl
 	name:"GroupControl"
 	classID:#(0x2feb1967, 0x111c058a)
 	--invisible:on
 category:"Manipulators"
 (
 	local updated = off
 	
 	local rd = colorMan.getColor #manipulatorsSelected
 	local ye = colorMan.getColor #manipulatorsInactive
 
 	local node
 	fn getNode = (refs.dependentnodes this)[1]
 
 	local size = [1,1,1], offset = [0,0,0]
 	fn hierarchyBBox =
 	(
 		local bmin = [1e9, 1e9, 1e9]
 		local bmax = [-1e9, -1e9, -1e9]
 		
 		children = deleteitem (join #() node) 1
 		for c in children do 
 		(
 			cmin = c.min
 			cmax = c.max
 		
 			bmin.x = amin bmin.x cmin.x
 			bmin.y = amin bmin.y cmin.y
 			bmin.z = amin bmin.z cmin.z
 
 			bmax.x = amax bmax.x cmax.x
 			bmax.y = amax bmax.y cmax.y
 			bmax.z = amax bmax.z cmax.z
 		)
 		size = bmax - bmin
 		offset = bmin
 	)
 
 	parameters mainParams rollout:mainParams
 	( 
 		update type:#boolean animatable:on
 		links type:#maxobjectTab tabSizeVariable:on
 		gizmocolor type:#rgb animatable:off default:yellow ui:ui_gizmocolor
 	)	
 	rollout mainParams "Parameters"
 	(
 		colorpicker ui_gizmocolor "Gizmo Color:" fieldwidth:32 height:16 align:#right offset:[0,0] modal:off
 	)
 	on canManipulate target return off
 
 	tool create
 	(
 		on mousePoint click do case click of
 		(
 			1: 
 			(
 				nodeTM.translation = gridPoint
 				#stop 
 			)
 		)
 	)
 	mapped fn addPoint p giz = 
 	(
 		if p == #new then giz.startNewLine() else giz.addPoint p
 	)
 	local giz
 	fn makeBoxGizmo = 
 	(
 		giz = manip.makeGizmoShape()
 		addPoint #(#new, [0,0,0],[0,1,0],[1,1,0],[1,0,0],[0,0,0],[0,0,1],[0,1,1],[1,1,1],[1,0,1],[0,0,1]) giz
 		addPoint #(#new, [0,1,0],[0,1,1]) giz
 		addPoint #(#new, [1,1,0],[1,1,1]) giz
 		addPoint #(#new, [1,0,0],[1,0,1]) giz
 		giz
 	)
 	fn makeGizmos light:off = if isvalidnode node and not isAnimPlaying() do animate off undo off
 	(
 		this.clearGizmos()
 		giz = makeBoxGizmo()
 		
 		if update then
 		(
 			hierarchyBBox()
 		)
 		else
 		(
 			size = [1,1,1]
 			offset = [0,0,0]
 		)
 		giz.transform (translate (scalematrix size) offset)
 		giz.transform (inverse node.objecttransform)
 		this.addGizmoShape giz 0 (this.gizmocolor as point4) rd
 	)
 	on updateGizmos do 
 	(
 		if isvalidnode (node = getNode()) do 
 		(
 			if not (c = update.controller).VariableExists "node" do 
 			(
 				c.addnode "node" node
 
 				source = "dependson node
"
 				source += "node.children.count
"
 
 				c.setexpression source
 			)
 			--format "make: %
" (join #() node)
 		)
 		makeGizmos()
 	)
 	on create do 
 	(
 		this.update.controller = createinstance float_script
 	)
 	on clone target do 
 	(
 		this.update.controller = createinstance float_script
 	)
 )
 
 fn updateGroupControls event: = 
 (
 	node = callbacks.notificationParam()
 --	format "%	>> % %
" event node node.parent
 	case event of
 	(
 		#link: if node.parent != undefined do
 		(
 			for group in (getclassinstances GroupControl) where isvalidnode group.node do 
 			(
 				if (finditem (join #() group.node) node) != 0 do
 				(
 					for n in (join #() node) do append group.links (NodeTransformMonitor node:n)
 					group.makeGizmos()
 					exit
 				)
 			)
 		)
 		#unlink: if node.parent != undefined do
 		(
 			for group in (getclassinstances GroupControl) where isvalidnode group.node do 
 			(
 				if (finditem (join #() group.node) node) != 0 do 
 				(
 					children = join #() node
 					for k = group.links.count to 1 by -1 where iskindof group.links[k] NodeTransformMonitor do
 						if (finditem children group.links[k].node) != 0 do deleteitem group.links k
 					group.makeGizmos()
 					exit
 				)
 			)
 		)
 	)
 )
 callbacks.removescripts id:#progroupcontrol
 callbacks.addscript #nodeLinked "updateGroupControls event:#link" id:#progroupcontrol
 callbacks.addscript #nodeUnlinked "updateGroupControls event:#unlink" id:#progroupcontrol
 

check how i solved the problem of gizmo updating when any group’s child changes it transform.
cool, isn’t it? (thanks LO for the join node trick)

also i fixed the “only pivot changes” bug.

Epic maxscript skills, some really interesting tips there.

The pivot fix appears to have half sorted the Z zooming issue… it at least orbits around the groupBox but it doesn’t have the correct zoom and the it’s a weird offsetted orbit.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

that’s because the manipulator is a specific class. it is always in mode of ignoring zoom extends. there is another trick to solve the issue. i show it when i would have a time.

Some form of callback to catch the Z being pressed or button being pressed, establish the bounding box of the selected group(s), and pass back the transform to the viewport camera?

no! much more elegant. (sorry)
i can give a clue. can the scripted helper delegate a manipulator?

Page 3 / 4