Results 1 to 14 of 14

Thread: DotNet in max syntax

  1. #1
    Technical Director jsdude's Avatar
    Join Date
    Sep 2008
    Location
    Montreal
    Posts
    26

    Default DotNet in max syntax



    Hi,

    Long time since I've posted something ... but lately been coding from scratch a Maxscript Dotnet pipeline and been using dotnet structure directly in maxscript enums, arrays list and dictionary. but here's my problem I'm currently using my own dll to create me empty list and dictionary does anyone know the constructor syntax to create directly List and Dictionary in maxscript?

    Best,

  2. #2
    undefined
    Join Date
    Sep 2009
    Posts
    9

    Default

    I think array list is:
    Code:
    theList = dotnetobject "System.Collections.arrayList"
    Not sure about dictionary.

  3. #3
    Tech-Art Lead, Amazon.com ObsidianPC's Avatar
    Join Date
    Nov 2008
    Location
    Seattle, WA
    Posts
    50

    Default I may be full of it

    I recall reading somewhere that MaxScript doesn't support generics, like Dictionary<T,T> or List<T>

    I am not sure.


    You might be able to store the type of a Dictionary<string, object>, for example, in a variable in your dotNet dll and then pass that through to MaxScript - using the type stored in the variable you might be able to create that in MaxScript.
    Alexander Hogan
    Technical Art Lead, Amazon Game Studios
    alex at alex hogan dot com

    "A tech artist looks at the glass and says 'I don't know about full or empty, but you're definitely using twice as much glass as you need. . .' "

  4. #4
    Technical Director jsdude's Avatar
    Join Date
    Sep 2008
    Location
    Montreal
    Posts
    26

    Default

    Well so far it does not support the creation of them but you can use them with the ".Item" to iterate / access their value if their created with a custom dll.
    To replace the typed list I'll definitely use the "System.Collections.arrayList" tried it works well and its cool cause its an (object or variant) list :)
    Id still like to do dictionary directly cause then my re skinning script wouldn't have extra dependence but hey nothing's perfect thanks guys!

  5. #5
    Technical Director jsdude's Avatar
    Join Date
    Sep 2008
    Location
    Montreal
    Posts
    26

    Default

    Well found the way to do it on cgtalk
    mySuperDictionary = dotnetobject "System.Collections.Generic.Dictionary`2[System.String,System.String]"

    Here's the thread http://forums.cgsociety.org/archive/.../t-668343.html

  6. #6
    I Code Art djTomServo's Avatar
    Join Date
    Jul 2008
    Location
    Santa Clara, CA
    Posts
    485

    Default

    For anyone using Python .NET in Maya, generics are treated the same way, ie the exact type you want needs to be bound to a specific named instance before you can use it.
    Seth - The Original Develifter
    About.me

  7. #7
    Administrator Rob Galanakis's Avatar
    Join Date
    Jun 2008
    Location
    Reykjavik, Iceland
    Posts
    1,242

    Default

    Yeah, JSDude, there's some .net to get the type of a dotnetobject in Max (classOf doesn't work, obviously). You can use that string to initialize the type, even the really strange generic type strings they give. Also remember that you can't iterate over items in the list, you need to turn the list into an array (myList.ToArray())

    You may also have better luck with creating a helper class with static constructors. So, instead of:
    myDict = DotNetObject "System.Collections.Generic.Dictionary`2[System.String,System.String]"
    you'd have:
    myDict = (DotNetClass "MyNameSpace.MyGenericsHelperClass").MakeStringStr ingDict()
    You could probably do ".MakeDict" take two Type values instead, but how one would pass that from Max to .NET I'm not sure (perhaps just a ".MakeDict (DotNetClass "System.String") (DotNetClass "System.String")" would work, not sure).
    Forum Administrator
    www.robg3d.com

  8. #8
    Technical Director jsdude's Avatar
    Join Date
    Sep 2008
    Location
    Montreal
    Posts
    26

    Default

    Hi Rob,
    Yep early on I had my custom Dll to build my dictionaries but I wanted to share my script with one of our other projects here so the DotNetObject "System.Collections.Generic.Dictionary`2[System.String,System.String]" syntax is working fine. As for passing dotnet object as argument to dotnet functions in maxscript it works great to! And to iterate on dotnet list I do use the toarray but its also acessible with the .Item property but I prefer using it as array cause dont have to sdo a for to loop ;)

  9. #9

    Default

    FWIW, you can iterate through the contents of a .NET collection using an enumerator:

    Code:
    sdict = dotnetobject "System.Collections.Generic.Dictionary`2[System.String,System.Char]"
    
    sdict.add "eh" "a"
    sdict.add "bee" "b"
    sdict.add "sea" "c"
    
    it = sdict.GetEnumerator()
    while it.MoveNext() do
    (
    	format "Key: % Value: %\n" it.current.key it.current.value
    )
    
    slist = dotnetobject "System.Collections.Generic.List`1[System.String]"
    
    slist.add "eh"
    slist.add "bee"
    slist.add "sea"
    
    it = slist.GetEnumerator()
    while it.MoveNext() do
    (
    	format "current: % \n" it.current
    )
    Last edited by biddle; 09-23-2009 at 09:41 PM.

  10. #10

    Default

    More .NET generic syntax fun...

    The "System.Collections.Generic" namespace is split across (at least) two assemblies, mscorlib.dll and System.dll. I found that in order to contruct a generic container that is defined in the System.dll (like Stack, LinkedList, SortedDictionary, etc.) you must specify the type argument with the full 'Assembly Qualified Name'

    so

    dotnetobject "System.Collections.Generic.LinkedList`1[System.String]")

    will fail, but

    dotnetobject "System.Collections.Generic.LinkedList`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]")

    works just fine!

    For convenience, you probably just want to retrieve the qualified name for any type arguments once, and do it on the fly.

    Here's a sample using the .NET generic LinkedList

    Code:
    stringAQN= (dotnet.gettype "System.String").AssemblyQualifiedName
    llist = dotnetobject ("System.Collections.Generic.LinkedList`1[[" + stringAQN + "]]")
    
    llist.AddFirst "AAA"
    llist.AddFirst "BBB"
    linkC = llist.AddLast "CCC"
    
    it = llist.GetEnumerator()
    while it.MoveNext() do format "it.current = % \n" it.current
    
    llist.AddBefore linkC "xxx"
    
    it = llist.GetEnumerator()
    while it.MoveNext() do format "it.current = % \n" it.current
    
    llist.Remove (llist.Find "AAA")
    
    it = llist.GetEnumerator()
    while it.MoveNext() do format "it.current = % \n" it.current
    Check out System.Collections.Generic and Systems.Collections.Specialized for other collections (and remember to check which assembly they come from!)

  11. #11
    Technical Director jsdude's Avatar
    Join Date
    Sep 2008
    Location
    Montreal
    Posts
    26

    Default

    Hey thanks for the last tip that's pretty cool
    It becomes really useful using .Net in max script when doing redistributable complex scripts.
    For all my pipeline stuff I trend do it more in .Net using my own assemblies but for Tech anim stuff since its always the same the .Net max script combo save a lot of work :)
    Best,

  12. #12
    Technical Artist MoP's Avatar
    Join Date
    Jul 2008
    Location
    London, UK
    Posts
    88

    Default

    Hey, sorry to dig up an old thread, but my question is pretty relevant to this stuff...

    I've started implementing SVN integration into 3dsmax using SharpSvn through dotNet, it was really easy to get the basic stuff working, but now I've hit a roadblock.

    Basically I need to create a Collection of class SvnLogEventArgs (which is a SharpSvn class), and I can't figure it out.

    Making a Collection of String objects is easy since it's a System thing (as in Biddle's great example):
    Code:
    local aqn = ( dotNet.getType "System.String" ).AssemblyQualifiedName
    local logItems = dotNetObject ("System.Collections.ObjectModel.Collection`1[[" + aqn + "]]")
    This works fine.

    But then I try to make a Collection using the SharpSvn class, like so:
    Code:
    local aqn = ( dotNet.getType "SharpSvn.SvnLogEventArgs" ).AssemblyQualifiedName
    local logItems = dotNetObject ("System.Collections.ObjectModel.Collection`1[[" + aqn + "]]")
    And it ends up spitting the error:
    -- Runtime error: Cannot resolve type: System.Collections.ObjectModel.Collection`1[[SharpSvn.SvnLogEventArgs, SharpSvn, Version=1.6016.1637.10768, Culture=neutral, PublicKeyToken=d729672594885a28]]


    I'm guessing that's because I've only defined "SharpSvn" from within Maxscript by using LoadAssembly pointing at the SharpSvn.dll directly, and so the dotNet method it uses to construct the Collection has no concept of where this class is coming from (since it's not a default Windows DLL).

    Am I on the right track there? Is there any way to make this work from within Maxscript or am I out of luck?

    Can anyone suggest a better route?
    Last edited by MoP; 10-14-2011 at 02:30 PM. Reason: moved bold tag -_-

  13. #13
    Administrator Rob Galanakis's Avatar
    Join Date
    Jun 2008
    Location
    Reykjavik, Iceland
    Posts
    1,242

    Default

    Make a helper function in pure .NET to create it and call it from MXS:

    Code:
    class SharpSvnHelpers
    {
        public static Collection<SvnLogEventArgs> CreateCollection()
        {
            return new Collection<SvnLogEventArgs>();
        }
    }
    In max:
    Code:
    logItems = (dotNetClass "MyAssembly.SharpSvnHelpers").CreateCollection()
    Or actually you could probably generalize this and have .NET create any generic collection through reflection and you can pass the type of collection and generic items as Type objects or strings.
    Forum Administrator
    www.robg3d.com

  14. #14

    Default GetLogs in sharpSvn

    Hey Guys,
    The problem still exists with me.. I am always getting 0 when i try to get the logs. Can any one help me? MoP, Did u find any solution? the code:

    Code:
    sharpSvnPath =  local Path, -- Change it to where ever the sharpSvn dll is
    	dll = dotNet.loadAssembly(sharpSvnPath+"SharpSvn.dll"),
    	mainClass = "SharpSvn",
    	client = dotnetObject (dotnetclass (mainClass + ".svnClient")),
    
    fn fetchLogs = 
    (
    	local logArgs =  dotnetObject(dotNetClass(mainClass+".SvnInfoArgs"))
    	local logEvntArgs = ( dotNet.getType (mainClass+".SvnInfoEventArgs") ).AssemblyQualifiedName
    -- 		local logItems = dotnetObject ("System.Collections.ObjectModel.collection`1[["+logEvntArgs+"]]")
    	logItems = dotNetObject ("System.Collections.Generic.List`1[["+logEvntArgs+"]]")
    -- 		local logItems2 = dotnetObject ("System.Collections.arrayList")
    	local uri =  (dotnetclass (mainClass + ".SvnTarget")).Fromstring(repoPath)		
    				
    	client.getInfo uri logArgs logItems
    	
    	print (logItems.Revision)
    )

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •