[Closed] Maxscript, SDK and .NET
Okey lets say I want to make a maxscript function with max sdk that adds .NET Button to form user gives to the maxscript function.
Looking at the source code of maxsdotNet plugin it seems that the argument given to the max sdk function is DotNetObjectWrapper, however max sdk doesn’t really have any information on how to handdle these. How would I get the .NET form (or actually MaxCustomControls.MaxForm) out of the wrapper so I can use it as standard .NET stuff?
Do I have to take all classes from maxsdotNet sources and compile them along with my plugin or what? Would that even work?
MaxCustomControls is a standard .NET assembly so you can add it as a .NET dependency in the Project settings.
But I don’t really understand what you’re trying to do. I think to speed up your script, you can just use a .NET assembly without coding a MAXScript extension that will be really hard to implement.
In fact, you can use the MaxForm in a .NET assembly (C# or VB.NET), build your form with the designer and add methods to be able to change controls values and communicate with them in MAXScript code.
I’m trying to recreate scene explorer, so basicly I have to deal large amount of data (>10 000 objects) from 3ds max. I need solid connection to 3ds max scene, taking name of 10 000 objects and listing them into DataGridView. This takes MINUTES with maxscript dotnet connection. There is no way to speed it up with .NET assemblies since I need to take name of each object from 3ds max, .NET doesn’t have any access to 3ds max. Or does it? There is zero documentation about it if it can do it.
So I need 3ds max SDK to connect object data to .NET form. This is still fairly simple. The problem rises when I want to combine maxscript with SDK and .NET since Autodesk decided not to document maxscript .NET connection at all.
In a nutshell. I want to make my own custom .NET maxscript functions. Like:
myAddButtonFunction maxscriptDotNetForm “Hello World button”
which would add .NET button to given .NET form.
What’s slow ?
The processing in MAXScript ?
Sending string to DataGridView with MAXScript ?
The building of the .NET form ?
Maybe your example: myAddButtonFunction maxscriptDotNetForm “Hello World button”
isn’t meaningful for what you’re trying to do, but there’s no advantage to code such method in C++ as in C# it would be easier and faster.
For example, SceneExplorer was designed with 2 .NET assemblies : a C# assembly (with core SceneExplorer Framework) and a C++/CLI, mix of managed and unmanaged plugin code. I think that if we want to use MAXScript a lot, we can avoid the C++/CLI stage and use MAXScript extension but without .NET. Why ?:
If the use of a DataGridView is slow, do that work in C# or VB.NET.
If the MAXScript processing of objects is too slow, code a MAXScript extension but without .NET. So, you can communicate between your MAXScript code and the managed code with basic data types:
MAXScript -> MAXScript Extension -> MAXScript -> C# / VB.NET -> MAXScript etc.
C++ SDK + C++/CLI + MAXScript SDK == real pain :D.
As you can see it, the code of the mxsDotNet DLX is really hard to read because MAXScript SDK isn’t very easy to use and not well designed, C++/CLI is just glue code; very hard to read and use.
for i in 1 to objects.count do DataGridView.Rows.Item[i-1].Cells.Item[0].Value = objects[i].name
That is slow.
And that I want to speed up by creating custom Maxscript function which does it for me. Unfortunately it I just can’t figure out how to get Maxscript .NET Wrapper classes to my project. I tried compiling the mxsdotNet, using the library from that. However I can’t seem to figure out how to get namespaces over.
I get this when I use “using namespace MXS_dotNet;”
error C2871: ‘MXS_dotNet’ : a namespace with this name does not exist
What you can do in this situation is trying to send to a custom .NET assembly method an array of objects names and the DataGridView control. So this heavy loop will be completely done in managed code and should be (for sure!) very much faster than a loop in MAXScript.
I can code this small assembly if you want.
I guess its time to give up on this. Obviously Autodesk never meant anybody to be able to expand their Maxscript .NET connection.
How would you handle maxscript array? I guess you could try converting the whole array into single string but I’m not sure if maxscript string object likes strings with 100 000 chars.
My first try would be to convert the maxscript array to a .NET array. With 10000 objects this can be slow but it’s worse the try!
EDIT:
For example, here is how to convert a MAXScript string array to a .NET string array:
fn mxsArrayToDotNetArray mxsArray =
(
local mxsArrayCount = mxsArray.Count
netArray = dotNetObject "System.String[]" mxsArrayCount
for i = 1 to mxsArrayCount do
(
local netString = dotNetObject "System.String" mxsArray[i]
local netIndex = dotNetObject "System.Int32" (i-1)
netArray.SetValue netString netIndex
)
netArray
)
mxsStrArray = #("Hello", "GoodBye", "DotNet", "ADO")
netStrArray = mxsArrayToDotNetArray mxsStrArray
for i = 0 to (netStrArray.Length-1) do
(
local netIndex = dotNetObject "System.Int32" i
print (netStrArray.GetValue netIndex)
)
dotNetUtils.AssignColumnFromArray (DataGridView dataGridView) (String[] names) (int column)
Here is how to use the dotNetUtils assembly:
dotNet.loadAssembly "dotNetUtils.dll"
dataGridViewUtils = dotNetClass "dotNetUtils.DataGridViewUtils"
dataGridViewUtils.AssignColumnFromArray dataGridView netStrArray 0
I’m not sure the assembly code is good ’cause I’ve never used a DataGridView.
You are right, its slightly faster than working directly with DataGridView cell values. However, even with 1 000 objects it crashes max. I’m not sure where the problem is, even increasing the heapsize doesn’t help. Maxs dotnet connection just can’t handle large amount of data. I wish there would be a way to send sdk pointters to actual dotnet objects with maxscript. It would make everything so easy. Without doing this, there is just no way to get this thing working.
Too bad too sad, thanks for your help anyway.