Notifications
Clear all

[Closed] Get AnimHandle from .NET object

So I want to create an instance of something via .NET, maxscript side:

iGlobal = (dotNetClass "Autodesk.Max.GlobalInterface").Instance

sid = (dotNetClass "Autodesk.Max.SClass_ID").Geomobject
cid = iGlobal.Class_ID.Create (dotNetClass "Autodesk.Max.BuiltInClassIDA").TEAPOT_CLASS_ID.value__ (dotNetClass "Autodesk.Max.BuiltInClassIDB").TEAPOT_CLASS_ID.value__

tpot = iGlobal.COREInterface.CreateInstance sid cid
iGlobal.Animatable.GetHandleByAnim tpot

The teapot here is just an example, I know I can use createInstance Teapot, that’s not the point – there are quite a few classes that can’t be constructed that way. Anyway, this gives me a runtime error, although maxscript reference says the UIntPtr –> IntegerPtr conversion is handled implicitly:

Unable to cast object of type 'System.UIntPtr' to type 'System.IntPtr'.

I don’t want to go full retard with compiling stuff, yet I want to make it do this

(
	str  = "using System;
"
	str += "using Autodesk.Max;
"

	str += "namespace HatersCorner
"
	str += "{
"
	str += "	public class Playground
"
	str += "	{
"
	str += "		private static IGlobal global = Autodesk.Max.GlobalInterface.Instance;
"

	str += "		private static readonly SClass_ID sid = SClass_ID.Geomobject;
"
	str += "		private static readonly IClass_ID cid = global.Class_ID.Create((uint)BuiltInClassIDA.TEAPOT_CLASS_ID, (uint)BuiltInClassIDB.TEAPOT_CLASS_ID);
"

	str += "		public static long GimmeGimme()
"
	str += "		{
"
	str += "			IGeomObject teapot = (IGeomObject)global.COREInterface.CreateInstance(sid, cid);
"
	str += "			UIntPtr animHandle = global.Animatable.GetHandleByAnim(teapot);
"
	str += "			return (long)(ulong)animHandle;
"
	str += "		}
"
	str += "	}
"
	str += "}
"

	csharpProvider = dotNetObject "Microsoft.CSharp.CSharpCodeProvider"
	compilerParams = dotNetObject "System.CodeDom.Compiler.CompilerParameters"

	compilerParams.ReferencedAssemblies.AddRange #(pathConfig.getDir #maxRoot + "Autodesk.Max.dll")
	compilerParams.GenerateInMemory = true
	compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(str)

	::gg = compilerResults.CompiledAssembly.CreateInstance "HatersCorner.Playground"
)
getAnimByHandle (gg.GimmeGimme())

Of course, I can make it only create that instance without returning anything – create something before that and get that last animHandle and after creating this instance, try incrementing that number and checking with getAnimByHandle if it’s the right class… but that’s really fugly…

7 Replies
 lo1

What’s wrong with casting?

return unchecked((IntPtr)(long)(ulong)animHandle);

That code was there just to explain what I want to do maxscript side (I’m perfectly okay with long, heck, even a string would do). What I’m asking is in the first code block: how to get the animHandle of dotNetObject that already exists… i.e. get it from that MAXScript wrapper class, that I can pass to the Animatable.GetHandleByAnim. If it didn’t try to go the implicit conversion route, I’d be so happy to get the System.UIntPtr – but there’s no way to force it to return that, is there?

The whole problem is maxscript trying to be helpful and convert that for me – and failing at that.

 lo1

Oh, I missed the scrolling in the first code block, took me like 5 readings to get the point.

You can use the asDotnetObject flag when calling any dotnet method, this prevents maxscript from trying to cast the return value.

uintptr = iGlobal.Animatable.GetHandleByAnim tpot asDotNetObject:on
animHndl = uintptr.ToUint64()

That’s wonderful, I owe you one! It never occured to me that you can do that with methods, too, thought only getProperty had this flag :bowdown:

Wow! Thanks lo.
I’ve tried to solve the problem without luck. ‘Asdotnetobject:on’. I didn’t know of that.

Okay, so I’m stuck again. I create a curve point and want to access its pos, which is a Point2 type:

pt = iGlobal.CurvePoint.Create()
showProperties pt "P" --> .P : <Autodesk.Max.IPoint2>

Basic property access fails:

pt.P
-- Runtime error: dotNet runtime exception: Unable to cast object of type 'Autodesk.Max.Wrappers.Point2' to type 'Autodesk.Max.ICurvePoint'.

The exact same error with asDotnetObject:on

getProperty pt #P asDotnetObject:on
-- Runtime error: dotNet runtime exception: Unable to cast object of type 'Autodesk.Max.Wrappers.Point2' to type 'Autodesk.Max.ICurvePoint'.

While when doing it pure .NET-side, none of that happens and for example this will give me the correct Point2 return type:

public static object GetPointPos() {
	return global.CurvePoint.Create().P;
}

Any idea what’s going on here?

I can’t get it either.
It’s curious as “in” property or “out” that are Point2 too work fine.