dotNet + MXS


#241

Thanks mike I’ll give that a try but I suspect it’ll hit the same performance snag.

The problem is the Maxscript while loop is taking too long. (Less than 1ms per loop but still too long. :D)

I’m hoping there is a .net method of converting it to a dataformat inside of .net that Max can understand since it would skip the Maxscript bottleneck.

ActiveX had the SafeWrapper datastructure which you could convert to an array almost instantaneously. In that case I would do a SQL Query through ODBC to the SafeWrapper and then convert that to an array. The whole operation even for thousands of records would take about 50ms.

Is there a .net nxn array which can be converted similarly into a max nxn array? That would at least give me a .net datastructure target to attempt to achieve.


#242

dotnetobject “System.object[]” numcol cannot be resolved.

What exactly are you attempting to do there?

It looks like you’re trying to pull an entire row at once into an array. Is that possible? I think you can only get one column from the row at a time. (hence the enormous bottle neck building a new row one item at a time, one row at a time.)


#243

How does system.object work? On another project using a treeView I was able to place data in the form of a struct into the .tag property of treeView nodes. This allowed me to store reference to several things that I needed to know about those nodes. I’m not working with pictureBox and it isn’t allowing the struct, says it is not a system.object. I can place strings and floats in and even an array but once I place any of the data that I want to store it give me this error.

Any suggestions?


#244

Just a sidenote. I wrote a script which generates and executes a CSV file 6 times faster than using the .getvalue or .item array building approach. Ughhhh. There’s got to be a faster way to get that data out.

Maybe I’ll just have to hand it off to python and back really fast. I was really hoping to keep everything native max.


#245

Further performance testing:

I tried the exact same code except instead of assigning “readerobject.item[x]” I just used an existing array as the source and it ran 8x faster. So the slowdown is in the readerobject.item[x] part of the code. Everytime you make a .item[x] or .getvalue[x] it slows down a bit.

Could it be Maxscript attempting to translate the .net value being returned into a maxscript value? If it is it would further reinforce my idea that the less .net data exchanges the better.


#246

Thats odd. I was suggesting you try reading the values into a .NET array

On my system (max9) the following test of a 2 element array:

arry = dotnetobject “system.object[]” 2
arry.set 0 (dotnetobject “System.Int32” 42)
arry.set 1 (dotnetobject “System.String” “Forty Two”)
arry.get 0
arry.get 1

generates…

dotNetObject:System.Object[]
undefined
undefined
42
“Forty Two”


#247

There it goes. that worked. : /

Ok I’ll try and fidget it about some more. Thanks.

EDIT: Ha! The error message just meant it was getting passed undefined data. “Numcols” was misspelled.

EDIT2: Ok your script successfully gets the data out of the reader and into .net arrays about 5-6x faster than building max arrays. But… the time it takes to execute all the array.get col loops puts it back to where it started with performance. Is there a fast way to convert a .net array to a max array all at once?


#248

I hope you mean how do they work in the context of Maxscript? It would take a book (or a least the first chapter of a book) to detail the .NET class system :slight_smile:

From a Maxscript point of view, the “System.Object” is the ultimate ‘superClassOf()’ every other .NET class.


#249
  Unfortunately I have simple routines that call 'Array.ConvertAll' to go from a .NET array of one type to a .NET array of another type, (System.Object[] to System.Int32[] for example) but nothing like SafeArrayWrapper that will go to/from maxscript arrays.

#250

I imagine that trying to pass a MXS struct as the data to store in the tag fails because the MXS data type is not derived from a System.Object and the code in the mxsdotnet.dlx isn’t sophisticated enough to automagically box it up in some sort of proxy.

Did you try storing the data you want to keep in the tag in a .NET container class, like a HashTable?

ht = dotnetObject “System.Collections.HashTable”

http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx

You could also experiment with creating a “System.Object[]” array of the correct size, fill it will the values in your struct and then assign that to the tag.

A peculiarity I found when working with System.Object[] arrays (other than being 0-based) is that you must call the .get and .set methods directly (the standard [] array syntax won’t work) which means you have to pass only .NET objects to the setter. MXS isn’t able to convert MXS data to a System.Object for you and will complain that it can’t find an appropriate method if you pass it an MXS data type (even if it is something that is trivial to convert, like a string or integer)

so instead of:

arry = dotnetObject “System.Object[]” 1
arry[1] = 99
print arry[1]

use:

arry.set 0 (dotNetObject “System.Int32” 99)
print (arry.get 0)


#251

Interesting as it does work with treeview node as I was stuffing a struct with a bunch of data in it. I find major inconsistancies with dot net like this. The same parameter in one control will work differerntly then in another. Very odd.

My problem is I want to store &refferences of parameter block params. I"m able to store simple floats directly without having to use dotNet floats, strings work as well.

I will have a poke at some of this but I have the feeling that It will not work as I want.


#252

How would I set bitwise combination like im told to in “System.Text.RegularExpressions.RegexOptions” I’ve tried a load of things but cant get it to work.


#253
 Just to keep it interesting, instead of using bit.and() you have to call the dotNet.CombineEnums() helper function:

    regex_options_class = dotNetClass "System.Text.RegularExpressions.RegexOptions" 
    regex_flags = dotNet.combineEnums regex_options_class.IgnorePatternWhitespace \
        	  regex_options_class.Multiline \
        	 regex_options_class.IgnoreCase
          

This results in:

regex_flags.tostring()
“IgnoreCase, Multiline, IgnorePatternWhitespace”


#254

Ah cheers man!


#255

I just got back to this Mike. I’m guessing because I’m looking to store references to param block parameters this will not work as there will not be a syste.object of the right class to store the parameters. Is this correct? Again, I’m not looking to store the value of the param but a reference to it. Any suggestions are welcome. I’m just trying to find a cleaner way to deal with the code that I have. Being able to contain ever thing in the control would be nice and neat and easy to setup.


#256

Ugh. I don’t think storing hard references from one system in the other is going to work. Even if it didn’t crash I expect you’d need to be extra careful to keep from leaking memory. You don’t want the maxscript garabage collector mistakenly tossing out something that you stored a reference to in a .NET container (or hanging on to something that .NET has discarded)

Forgive me if this is too trivial, but if your paramblocks are large and you aren’t deleting them dynamically then perhaps adding a static layer of indirection might help? Store references to the paramblocks in an plain old MXS array, then store the integer indices into that array in the tag fields of the .NET items. The maxscript array will act as a cache to the larger items.

(I’m actually away from the office for a couple of weeks and don’t have anything to test this out on at the moment…)


#257

Thanks Mike, this is sort of what Im doing now. Just bugged me that I could do it in one dotNetObject and not in another. I have had to work around my best case senerio. Thanks for the time, I can see where the stabiliy would be a problem.


#258

I’m an idiot and I admit it. I hear that once you do that it is the first steps to recovery.

The problem I’ve been having in not being able to store a struct in the tag property and I know that I was doing it before…well, I also found the answer before and I just didn’t look deep enough into the past code to see what I was doing. What you do is use dotNetMxsValue…so

treeNode=dotNetObject "system.windows.forms.treeNode"

aVal=10
struct testSt (name,val)
st=testSt()
st.name="Bill"
st.val=&aVal

treeNode.tag=dotNetMxsValue st

Now I have to go and change a couple hundred lines of code:S


#259

Arrrgggh! Do you know how long I’ve been trying to figure that out!! bangs head against wall that is going to make life so much easier!! I had written a number lookup methods to work around it!!

Thanks for the share!!


#260

Nice find Paul.

I'm running into a problem with that myself. 

I'm trying to convert some code I was using activeX web browser to .net web browser object.

I'm basically trying to convert this example to maxscript for now: http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.objectforscripting(VS.80).aspx

The ObjectForScripting property expects a system object. 
I need that object to be an instance of a struct, so I can call its methods from within the website (using javascript). 


Anyone have something like this working? There has to be a way to do this. The web browser object is pretty useless if we can't get stuff in and out.

for example


  struct test
  (
 		name,
  		fn start = (
  			
 			print "hello"
  		)
 )
  t = test()
  t.name = "Mike"
  wb.ObjectForScripting = dotNetMxsValue &t  
  
  --how do i call the start method from a .net "object" holding a reference to a struct instance?
  bad = dotNetMxsValue &t
  bad.start() -- obviously not the way :)