[Closed] setFocus by current Axis
I want my tool to be able to set focus on particular control when user select an axis.
Suppose I have a node selected and want to move it by X axis. I click X axis in viewport and the corresponding control gets focused.
In reality If I zoom out or move pivot outside of nodes mesh and click any axis again nothing is focused anymore (since node mesh hittest failed I suppose).
Is there anything besides mouse hook that I can use to make it work properly?
thx
try (destroydialog X ) catch ()
rollout X "" (
spinner sx "x:"
spinner sy "y:"
spinner sz "z:"
fn setFocusByCurrentAxis ev nodes = (
if not ::x.open and selection[1] != undefined then (::nodeEvent = undefined; gc light:true) else (
case (toLower (toolMode.AxisConstraints as string))[1] of (
"x" : setFocus sx
"y" : setFocus sy
"z" : setFocus sz
)
)
)
on x open do (
global nodeEvent = undefined
gc light:true
global nodeEvent = NodeEventCallback selectionChanged:setFocusByCurrentAxis
)
on x close do (
global nodeEvent = undefined
gc light:true
)
)
createDialog X
yes… i’ve checked SDK AxisChangeCallback with RegisterAxisChangeCallback… it works very well. I don’t know why it’s not published to MXS. I’ve added it to my mxs extension now
I don’t like using timers for a lasting tasks like that, but if it can run in background thread and don’t leak memory that could be a solution.
I tried using mouse hook and it works perfect, but it’s a huge amount of extra code. If there’s another option it would be great
I found a c# way of doing it.
using Autodesk.Max;
namespace axisChangeOps{
public class axisCallback : Autodesk.Max.Plugins.AxisChangeCallback {
public string src = "";
public override void Proc( IInterface ip ) {
ManagedServices.MaxscriptSDK.ExecuteStringMaxscriptQuery( src );
}
}
public class axisChangeHandler {
private axisCallback cb = new axisCallback();
public void register( string str ) {
IInterface ii = GlobalInterface.Instance.MAXScriptInterface;
this.cb.Proc( ii );
this.cb.src = str;
ii.RegisterAxisChangeCallback( this.cb );
}
public void unregister() {
GlobalInterface.Instance.MAXScriptInterface.UnRegisterAxisChangeCallback( this.cb );
}
}
}
and a little mxs wrap
(
global axisChangeOps
fn compileAxisChangeOps forceRecompile:false = (
if forceRecompile or not iskindof ::axisChangeOps dotnetobject or (::axisChangeOps.GetType()).name != "Assembly" do
(
local source = "
using Autodesk.Max;
namespace axisChangeOps
{
public class axisCallback : Autodesk.Max.Plugins.AxisChangeCallback
{
public string src = \"\";
public override void Proc( IInterface ip ) {
ManagedServices.MaxscriptSDK.ExecuteStringMaxscriptQuery( src );
}
}
public class axisChangeHandler
{
private axisCallback cb = new axisCallback();
public void register( string str )
{
IInterface ii = GlobalInterface.Instance.MAXScriptInterface;
this.cb.Proc( ii );
this.cb.src = str;
ii.RegisterAxisChangeCallback( this.cb );
}
public void unregister()
{
GlobalInterface.Instance.MAXScriptInterface.UnRegisterAxisChangeCallback( this.cb );
}
public void dispose() {
this.unregister();
cb.Dispose();
}
}
}"
compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
compilerParams.ReferencedAssemblies.Add "System.dll"
compilerParams.ReferencedAssemblies.Add (getdir #maxroot + "autodesk.max.dll")
compilerParams.ReferencedAssemblies.Add (getdir #maxroot + "ManagedServices.dll")
compilerParams.GenerateInMemory = on
csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #( source )
if (compilerResults.Errors.Count > 0 ) then
(
local errs = stringstream ""
for i = 0 to (compilerResults.Errors.Count-1) do
(
local err = compilerResults.Errors.Item[i]
format "Error:% Line:% Column:% %
" err.ErrorNumber err.Line err.Column err.ErrorText to:errs
)
format "%
" errs
return undefined
)
axisChangeOps = compilerResults.CompiledAssembly
ok
)
)
compileAxisChangeOps forceRecompile:false
)
fn axisChangeCallback = (
format "%
" toolMode.AxisConstraints
)
cb = dotnetobject "axisChangeOps.axisChangeHandler"
cb.register "execute \"::axisChangeCallback()\""
Impressive, Sergey!
You are getting really nice tools and they show the way for other challenges. Thanks!
good! SDK can do it a little cleaner because i can directly pass mxs function. so it can be local. which is cool. also i added id which you can use to enable/disable and register/unregister callback.
Thanks, Andres.
There’s also commandMode change callback left and then my all-in-one transform type-in complete.