[Closed] Cast Scene Object to IINode
I wanna convert this function to the c# version:
fn DotNet_InterpCurve3D theShape Prm =
(
maxGlobal = (dotnetclass "autodesk.max.globalinterface").instance
inode = maxGlobal.COREInterface14.GetINodeByHandle theShape.inode.handle asdotnetobject:true
iobj = (inode.EvalWorldState maxGlobal.COREInterface.Time true asdotnetobject:true).Obj
pos = iobj.interpCurve3D 0 0 Prm 0
[pos.x,pos.y,pos.z]
)
At the beginning I just want to know how we can cast a max object to IINode? I got error with this code:
– Runtime error: No ‘MyFunction’ method found which matched argument list
using Autodesk.Max;
namespace MyProject
{
public static class MyClass
{
public static void MyFunction(IINode node)
{
}
}
}
I also tested IValue but no chance to work.
I suppose it is due to the fact that maxscript INode is actually a wrapper and not an IINode your c# function expects.
You can either pass the handle to get the node or you can execute maxscript on c# side using ExecuteMAXScriptScript to get FPValue
I didn’t get what you said about ExecuteMAXScriptScript, but handler works perfect:
using Autodesk.Max;
namespace MyProject
{
public static class MyClass
{
public static IPoint3 InterpCurve3D(uint handle,float param)
{
var g = GlobalInterface.Instance;
var i = g.COREInterface14;
IINode node = i.GetINodeByHandle(handle);
IObject obj = node.EvalWorldState(g.COREInterface.Time, true).Obj;
ISplineShape shape = obj as ISplineShape;
return shape.InterpCurve3D(0, 0, param, 0);
}
}
}
_InterpCurve3D = (dotnetclass "MyProject.MyClass").InterpCurve3D
fn MyInterpCurve3D Spline Param:.5 =
(
Pos = _InterpCurve3D Spline.inode.handle Param
[pos.x,pos.y,pos.z]
)
MyInterpCurve3D Spline
It works fine for me… What’s the problem? What are you passing as parameter?
maxGlobal = (dotnetclass "autodesk.max.globalinterface").instance
inode = maxGlobal.COREInterface14.GetINodeByHandle theShape.inode.handle --asdotnetobject:true (don't need it)
test = dotnetClass "MyProject.MyClass"
test.MyFunction inode
I didn’t know we should send the handler, and I was trying to pass the object directly as IINode, that was not correct.
Comparing to Max version is 80 times slower and seek much more memory:
.Net >> time:878 memory:764872L
Max >> time:10 memory:196L
To take advantage of C #, you have to code the more possible in C#, specially loops and calculations. If not, you lose all the advantages when calling the functions from maxscript and converting back the returned data to maxscript.
I’ve just checked it and it is indeed works ok with INode
(
local source = "using Autodesk.Max;
public class Test2 {
static public void toggleNode( IINode node ){ node.Hide(!node.IsObjectHidden);}
}
"
compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
compilerParams.ReferencedAssemblies.Add "System.dll"
compilerParams.ReferencedAssemblies.Add (getdir #maxroot + "autodesk.max.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
)
compilerResults.CompiledAssembly.createInstance "Test2"
delete objects
gc()
t = Teapot isSelected:true
g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
inode = g.COREInterface.GetINodeByHandle t.inode.handle
try (destroydialog X ) catch ()
rollout X "" (
button btn "toggle"
on btn pressed do (
(dotnetclass "Test2").toggleNode inode
redrawViews()
)
)
createDialog X pos:[100,100]
)
Of course works, because you converted .inode to the IINode before passing to the function. I want to do minimal code in MaxScript, So I prefer to pass handler.
and here’s the fpvalue. Not sure if it is useful, but it may help you pass some arbitrary data to c# side
(
local source = "using Autodesk.Max;
public class Test3 {
static public string getMXSvariable( string nodeVar ){
var g = Autodesk.Max.GlobalInterface.Instance;
IFPValue fpv = g.FPValue.Create();
g.ExecuteMAXScriptScript( (\"::\" + nodeVar), true, fpv);
return fpv.N.Name;
}
}
"
compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
compilerParams.ReferencedAssemblies.Add "System.dll"
compilerParams.ReferencedAssemblies.Add (getdir #maxroot + "autodesk.max.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
)
compilerResults.CompiledAssembly.createInstance "Test3"
delete objects
gc()
t = Teapot()
tt = Teapot name:"SomeName"
g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
inode = g.COREInterface.GetINodeByHandle t.inode.handle
global tmpVar = t
format ">> % - %
" t ((dotnetclass "Test3").getMXSvariable "tmpVar")
format ">> % - %
" tt ((dotnetclass "Test3").getMXSvariable "tt") -- will fail because[b] tt [/b]is local
)
I’ve found this thread where, at its end, I shew a curious method to send maxscript entities to C# using rootnode custom attributes:
http://forums.cgsociety.org/showthread.php?p=8172164#post8172164