Notifications
Clear all

[Closed] Changing Link Constrained Inheritance

After I create a link constraint for an object, I can no longer change it’s inheritance flags using maxscript. However, I can stiill manually check them on/off through the hierarchy menu. Anyone know why or a way around this?

3 Replies

why? no idea – they still seem to take effect; odd.

looks like getInheritanceFlags returns an empty bitArray as well.

How to get around it? I was hoping to spot something in the link constraint itself… e.g. internally-governed link info bits… but alas, nothing in properties/interfaces.

So… time for more scarycode… at least I finally abstracted that darn checkbox checking/unchecking code…


-- toggle an UI checkbox's checked state via UI messages/notifications
-- usage:
--   hwnd -- HWND of the control
--   state -- checked state.  1 = check, 0 = uncheck
-- result:
--   value: OK
--   effect: should check/uncheck the checkbox and have its change effected
fn setUICheckboxState hwnd state = (
	local BN_CLICKED = 0 -- clicky message ID
	local BM_SETCHECK = 241 -- checkbutton toggle message ID
	local WM_COMMAND = 273 -- windows command message

	local parent = UIAccessor.getParentWindow hwnd
	local id = UIAccessor.getWindowResourceID hwnd
	windows.sendMessage hwnd BM_SETCHECK state 0
	windows.sendMessage parent WM_COMMAND ((bit.shift BN_CLICKED 16) + id) hwnd
	OK
)

-- change to the Link Info panels in Hierarchy mode
-- usage:
--   openLinkInfoUI
-- result:
--   value: OK
--   effect: will change to the Link Info panels in Hierarchy Mode
fn openLinkInfoUI = (
	-- toggle to hierarchy mode
	max hierarchy mode
	-- get all the UI elements currently presented in max
	local maxHWND = windows.getMaxHWND()
	local maxChildren = windows.getChildrenHWND maxHWND

	-- loop over them
	for child in maxChildren do (
		-- if we find the Link Info button
		if (child[5] == "Link Info") then (
			-- press it
			UIAccessor.pressButton child[1]
			-- and bail early
			exit
		)
	)
	OK
)

-- get the Hierarchy>Link Info panel>Inherit rollout's checkboxes
-- usage:
--   getInheritCheckboxes()
-- result:
--   value: array of hwnds
--   effect: will change to the Link Info panels in Hierarchy Mode
-- depends on:
--   openLinkInfoUI
fn getInheritCheckboxes = (
	-- open the Link Info UI
	openLinkInfoUI()
	
	-- get all the UI elements currently presented in max
	local maxHWND = windows.getMaxHWND()
	local maxChildren = windows.getChildrenHWND maxHWND

	-- some variables to help keep track of where we are in perusing the max UI
	local foundTab = false
	local foundPanel = false
	
	-- an array to hold the actual checkboxes
	local checkboxes = #()
	
	-- loop over the UI elements
	for child in maxChildren do (
		-- find the Hierarchy Task command panel first
		if (child[4] == "HierarchyTask") then (
			foundTab = true
		)
		-- if we've found the Hiearchy Task command panel...
		if (foundTab) then (
			-- then get its children (the rollouts and all the elements therein)
			if (child[4] == "RollupPanelTitle") then (
				-- look for the Inherit rollout
				if (child[5] == "Inherit") then (
					foundPanel = true
				)
			)
		) -- foundTab

		-- if we've found the Inherit rollout..
		if (foundPanel) then (
			-- check if the current UI element is the "Move:" groupbox label
			-- if it is, we can bail early
			-- (it is listed -after- all 9 checkboxes(!))
			if (child[5] == "Move:") then ( exit )

			-- otherwise, see if we're dealing with a button
			-- ( checkboxes are buttons - don't ask :) )
			else if (child[4] == "Button") then (
				-- and if we are, added the UI element's HWND
				-- (all we need for further processing)
				-- to our little checkboxes array
				append checkboxes child[1]
			)
		) -- foundPanel
	)
	-- return the result, which should be our 9 checkboxes
	checkboxes
) -- getInheritCheckboxes

-- set inheritance flags via UI messages.
-- usage:
--   setInheritanceFlagsUI <node> <flags> [error:&errorVar]
--   <node> = any valid node
--   <flags> = bitArray #{MoveX,MoveY,MoveZ,RotX,RotY,RotZ,ScaleX,ScaleY,ScaleZ}
--   [error:&errorVar] = optional by-parameter variable to store error message
-- result:
--   value: false = an error occurred, check the errorVar if supplied
--   value: OK = Inheritance flags set via UI
--   effect: appropriate Link Info>Inherit checkboxes checked/unchecked
-- depends on:
--   getInheritCheckboxes
--	 openLinkInfoUI
--   setUICheckboxState
fn setInheritanceFlagsUI obj flags &error: = (
	-- validate the node first, if it doesn't check out..
	if (not (isValidNode obj)) then (
		-- set the error message and return false
		error = "supplied object is not a valid node"
		false
	)
	-- if the node is valid..
	else (
		-- ..make sure it's selected
		select obj
		-- grab the checkboxes from the Inherit rollout
		local inheritCheckboxes = getInheritCheckboxes()
		-- validate the result, if not quite right..
		if (inheritCheckboxes.count != 9) then (
			-- then set the error message and return false
			error = "could not retrieve Inherit checkboxes"
			false
		)
		-- if the checkboxes are all good..
		else (
			-- ..then proceed
			-- trap for #all and #none by simply creating our own flags bitArray
			if (flags == #all) then ( flags = #{1..9} )
			else if (flags == #none) then ( flags = #{} )
			
			-- loop over all checkboxes
			for i = 1 to 9 do (
				-- get their intended state from the flags bitArray
				local state = if (flags[i]) then ( 1 ) else ( 0 )
				-- and set their state
				setUICheckboxState inheritCheckboxes[i] state
			)

			-- return OK
			OK
		) -- inheritCheckBoxes.count == 9
	) -- isValidNode obj == true
) -- setInheritanceFlagsUI

[size=2]Note that there’s no keepPos: parameter as there is for the standard setInheritanceFlags. I’m not entirely sure what that does in case you use it, but if it does what I suspect it does from the Max Help file, you can easily store the object’s current position in world space, change the link info, and then restore that position.

Other than that, usage of [/size][size=2]setInheritanceFlagsUI [/size][size=2]is the same as for [/size][size=2]setInheritanceFlags, except that your UI will show what’s going on, etc.

I commented pretty much everything in the code – you can remove the comment lines if you just need the functionality.

Edit: just some more comments, for the function headers
[/size]

Many thanks!! I will check this out & it may lead to more questions

Thanks too, from the POV of a lurker :)… this stuff isn’t covered very well!