Notifications
Clear all

[Closed] Is it possible to select arbitrary FFD control points?

I have a box with applied FFD 3x3x3.
Run a script. Control points 1,3,5,7 are selected, so, I can use the Gizmo to move it(without selecting them one by one in the viewport).
Is it possible?

4 Replies

no! i couldn’t find any way to select (or get selection of FFD gizmo points) via mxs, therefore i wrote a c++/SDK script extension.

I found the code below(I modified it a little) in this forum, which shows the indexes of the selected FFD control points.

So, the solution is to abandon the idea.

(
 	-- usage:
   -- <array>getSelectedCPs <ffdModifier>
   -- output array contains selected control points as <int>index for each CP
   
 	function GetSelectedFFDCPs _FFDmod =
 	(
 		-- defines
 		WM_SETFOCUS = 0x007
 	 
 		-- back up some stuff we'll be changing
 		oldCommandMode = toolmode.commandmode
 		cmdPanelMode = getCommandPanelTaskMode()
 		modPanelObj = modpanel.getCurrentObject()
 		oldSubObjectLevel = subObjectLevel
 		oldModEnabledInViews = _FFDmod.enabledInViews
 	 
 		-- disable the modifier in viewports to speed up some calculations
 		_FFDmod.enabledInViews = false	 
 		-- let's collect all the control points' current positions
 		theMaster = _FFDmod[#master]
 		theCount = theMaster.numsubs
 		animateAll _FFDmod
 		curPositions = for i = 1 to theCount where theMaster[i].value != undefiend collect theMaster[i].value			
 		-- go into modify mode
 		setCommandPanelTaskMode #modify	 
 		-- select the modifier
 		modpanel.setCurrentObject _FFDmod	 
 		-- go to the control point sub-object level
 		subObjectLevel = 1	 
 		-- change to move mode
 		toolmode.commandmode = #move	 
 		-- open the transform type-in dialog
 		max tti		
 		-- find the tti dialog
 		local desktopHWND = windows.getDesktopHWND()
 		local desktopChildren = windows.getChildrenHWND desktopHWND
 		local tti
 		for child in desktopChildren do 
 		(
 			if (child[5] == "Move Transform Type-In") do 
 			(
 				tti = child
 				exit
 			)
 		)
 		if (tti == undefined) do ( return false )	   
 		-- get the tti's handle
 		local ttiHWND = tti[1]		  
 		-- get its children
 		local ttiChildren = windows.getChildrenHWND ttiHWND		  
 		-- set focus to the X Offset custedit control
 		UIAccessor.sendMessage ttiChildren[10][1] WM_SETFOCUS 0 0
 		-- change its value via the proper edit control - let's just offset by 1.0 unit
 		UIAccessor.setWindowText ttiChildren[12][1] "1.0"
 		-- now set focus to the Y offset custedit control
 		UIAccessor.sendMessage ttiChildren[13][1] WM_SETFOCUS 0 0	 
 		-- now, let's collect the new positions.
 		newPositions = for i = 1 to theCount where theMaster[i].value != undefiend collect theMaster[i].value				
 		-- set focus to the X Offset custedit control
 		UIAccessor.sendMessage ttiChildren[10][1] WM_SETFOCUS 0 0
 		-- change its value via the proper edit control - move the control points back 1.0 unit
 		UIAccessor.setWindowText ttiChildren[12][1] "-1.0"
 		-- now set focus to the Y offset custedit control
 		UIAccessor.sendMessage ttiChildren[13][1] WM_SETFOCUS 0 0		
 		-- close that tti dialog
 		UIAccessor.CloseDialog ttiHWND
 		-- now let's figure out what the difference between the two arrays is
 		selectedCPs = for i = 1 to curPositions.count where (curPositions[i] != newPositions[i]) collect i	 
 		-- restore stuff
 		_FFDmod.enabledInViews = oldModEnabledInViews
 		setCommandPanelTaskMode cmdPanelMode
 		if (modPanelObj != undefined) do
 		(
 			modpanel.setCurrentObject modPanelObj
 		)
 		if (oldSubObjectLevel != undefined) do
 		(
 			subObjectLevel = oldSubObjectLevel
 		)
 		toolmode.commandmode = oldCommandMode
 		--
 		selectedCPs
 	)
 	selCP = GetSelectedFFDCPs selection[1].modifiers[1]
 	format "selCP: % 
" selCP	
 )

If you are using a ffd modifier over top the box click the animate all button and this will enable all the control points tracks. Then you can grab each point with this code.

$.ffd2x2x2.controlpoint1

You’ll have to manually set a key on all points to enable the tracks for the ffd gizmos.

Cheers!
Nick

I know this, but the goal is to select some of the control points via script, not by hand.