Notifications
Clear all

[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

9 Replies

Have you tried with timer(dotnet or mxs)?

deleted… needs a little test

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

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()\""

1 Reply
(@aaandres)
Joined: 11 months ago

Posts: 0

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.