MS + DotNet MultiThreading with objects creation

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
  04 April 2013
MS + DotNet MultiThreading with objects creation

Hi,

I was wondering if it was possible to run a maxscript in multithreading with DotNet ( with BackgroundWorker ) and creating objects, moving, adding modifiers on them ?

I was trying with this, but it seems to crash max all the time :


myThreads = #()

fn doSomeStuff =
(
for i = 1 to 10000 do Box lengthsegs:1 widthsegs:1 heightsegs:1 length:10 width:10 height:10 

print "done"
)

for i = 1 to 8 do
(
myThreads[i] = dotNetObject "system.componentModel.backgroundWorker"
dotnet.addEventHandler myThreads[i] "DoWork" doSomeStuff
myThreads[i].runWorkerAsync()
)


Thank you for your help
 
  04 April 2013
Originally Posted by GreySize: I was wondering if it was possible to run a maxscript in multithreading with DotNet ( with BackgroundWorker ) and creating objects, moving, adding modifiers on them ?

no. it's not possible.
 
  04 April 2013
Well thank's DenisT, i'll try something else
 
  04 April 2013
I can be done indirectly.. but you'll loose any advantages of multi threading and it's not very efficient but for small things it works great.

If you create a global array onto which you can push strings of maxscript from your backgroundworker thread you can execute those strings in the main thread via a execute command in dotnet timer like so:


 script_queue=#()
 
 fn scanScript = (
 
 	if (script_queue.count>0) do
 	(
 		scr=script_queue[1];
 		deleteItem script_queue 1
 		try(
 			execute scr[1]
 		) catch
 		(
 			print "**MXS ERROR**"
 		)
 	)
 )

scriptExecuter = dotNetObject "System.Windows.Forms.Timer"
 dotnet.addEventHandler scriptExecuter "tick" scanScript
scriptExecuter.interval = 100
scriptExecuter.start()
 
__________________
The GPU revolution will not be rasterized! - http://www.jdbgraphics.nl

Last edited by jonadb : 04 April 2013 at 08:05 AM.
 
  04 April 2013
Thank you Jonadb, your solution seems to be for heavy calculation beside little maxscript viewport operation, is it ?

In fact my script run through all the vertex of an object ( and through the timeline) and it create a plane on each vertex ( with normal orientation), then i add on each modifiers and finally at the end of the frame it convert all the separate plane into a single edit poly. Then next frame is started.

I was thinking about cutting the timeline and then calling through DotNet 8 times 3ds max (1 per thread) and running the script, and finally regrouping the resulting geometry inside the same max.
 
  04 April 2013
Originally Posted by GreySize: Thank you Jonadb, your solution seems to be for heavy calculation beside little maxscript viewport operation, is it ?


I could be of use for heavy calculations with little output but 'm using it for socket communications. A background thread receives maxscript commands via TCP/IP that needs to be executed in the main thread via above method.

One tip for combining a bazilion small object into one mesh.. Abuse ProBoolean in 'attach' mode, it doesn't alter geometry just attached everything into on big mesh very quickly.

Small example where $main if your base mesh


for obj in selection do
(
ProBoolean.SetOperandB $main obj 4 0
)


Then you can either collapse that to editmesh/poly or jsut leav it as proboolean object. I use this for a cloud script and it does 20000 planes in a few seconds.
__________________
The GPU revolution will not be rasterized! - http://www.jdbgraphics.nl
 
  04 April 2013
Ok, thank you for the tips about the proboolean works great !

I keep searching about launching other 3ds max, opening the same scene , starting the same script but with other frame to perform.

Ps : I don't get if you pass through TCP/IP to start things on the same computer or if you use it to start things through network
 
  04 April 2013
Originally Posted by GreySize: Ps : I don't get if you pass through TCP/IP to start things on the same computer or if you use it to start things through network


See this video for an early prototype of what I'm building in my spare time where the snippet is from: http://vimeo.com/47002666

With 'shelllaunch' you can start any program, including max.

Waht you could do is save your scene 8 times, each with a different name that includes a framerange but before you do that set a startupscript that extracts the frameranges from the filenames and starts the calculation for them after which it automatically saves the file.

So you get 8 files like this:

file_0_200.max
file_201_400.max
etc

Start Max via shelllaunch, each loading a different file.. the startup script kicks in and performs the operation on set ranges and saves when done. Merge results into on file and you're done


edit: sorry, not in a startup script directly but make a startup script that sets an 'filePostOpen' eventhandler which performs the calculations..
__________________
The GPU revolution will not be rasterized! - http://www.jdbgraphics.nl
 
  04 April 2013
Originally Posted by jonadb: I could be of use for heavy calculations with little output but 'm using it for socket communications. A background thread receives maxscript commands via TCP/IP that needs to be executed in the main thread via above method.

One tip for combining a bazilion small object into one mesh.. Abuse ProBoolean in 'attach' mode, it doesn't alter geometry just attached everything into on big mesh very quickly.

Small example where $main if your base mesh


  for obj in selection do
  (
  ProBoolean.SetOperandB $main obj 4 0
  )
  


Then you can either collapse that to editmesh/poly or jsut leav it as proboolean object. I use this for a cloud script and it does 20000 planes in a few seconds.


Maybe I'm wrong but according to mxs help there is no addmethod 4

 <void>SetOperandA boolnode
 <void>SetOperandB boolnode node addMethod matMethod
 The third argument is  an integer controlling the operation to be performed and corresponding to the  radio button state in the UI. Possible values are: 
 
 
 0 -Union 
 
  1 -Intersection 
 
  2 -Subtraction 
 
  3 -Merge 
 
  The fourth argument  is an integer defining the method to add operands B, corresponding to the radio  button state in the UI. Possible values are: 
 
  0 -Reference 
 
  1 -Copy 
 
  2 -Move 
 
  3 -Instance 
 
  The fifth argument is  an integer controlling the material mdethod and corresponding to the radio  button state in the UI. Possible values are: 
 
  0 -Apply Operand Method 
 
  1 -Retain Original Material
 
 

Can you show a small example of your method.
__________________
Looking in the right side. [bgaTools]
 
  04 April 2013
It's a secret method But you can see them UI for ProBoolean, just count the radio button starting at 0, somehow 4 and 5 aren't listen in the docs.

0=Union
1=Intersection
2=Subtraction
3=Merge
4=Attach <= this is what we want
5=Insert
__________________
The GPU revolution will not be rasterized! - http://www.jdbgraphics.nl
 
  04 April 2013
Originally Posted by jonadb: It's a secret method But you can see them UI for ProBoolean, just count the radio button starting at 0, somehow 4 and 5 aren't listen in the docs.

0=Union
1=Intersection
2=Subtraction
3=Merge
4=Attach <= this is what we want
5=Insert

Very nice. I did not know about that.
And how can I perform this "attach" method in this example if is not a secret

 delete objects
 shift = on
 tea = teapot radius:10 name:"main"
 for z = 0 to 9 do 
 (
 	shift = not shift
 	for x = 0 to 9 do 
 	(
 		main = (copy $main)
 		main.pos = if shift then [30*x,0,20*z] else [10+30*x,0,20*z]
 		in coordsys local main.rotation =  (random (eulerAngles 0 0 0) (eulerAngles 0 0 359))
 		main.wirecolor = (clr = random black white ; clr.s = 255. ; clr)
 	)
 )
 delete $main
 ProBoolean.SetOperandA $.main001
 -- . . . ???
 
__________________
Looking in the right side. [bgaTools]

Last edited by gazybara : 04 April 2013 at 12:05 PM.
 
  04 April 2013
Originally Posted by jonadb: See this video for an early prototype of what I'm building in my spare time where the snippet is from: http://vimeo.com/47002666

That's amazing Jon, well done!
__________________

 
  04 April 2013
Originally Posted by DanGrover: That's amazing Jon, well done!

Yup, I agree with you. Very powerful method.
__________________
Looking in the right side. [bgaTools]
 
  04 April 2013
Originally Posted by gazybara: And how can I perform this "attach" method in this example if is not a secret


Like so:


delete objects
 shift = on
 teamain = teapot radius:10 name:"teamain"
 
 ProBoolean.createBooleanObject  $teamain undefined 4 1 0   --create master boolean with no operant B (undefined)
 
 tea = teapot radius:10 name:"sub"
  
 for z = 0 to 9 do 
 (
	 shift = not shift
	 for x = 0 to 9 do 
	 (
		 sub = (copy $sub)
		 sub.pos = if shift then [30*x,0,20*z] else [10+30*x,0,20*z]
		 in coordsys local sub.rotation =  (random (eulerAngles 0 0 0) (eulerAngles 0 0 359))
		 sub.wirecolor = (clr = random black white ; clr.s = 255. ; clr)
		ProBoolean.SetOperandB $teamain sub 4 0   -- keep adding B operands
	)
 )
__________________
The GPU revolution will not be rasterized! - http://www.jdbgraphics.nl
 
  04 April 2013
Hey Jonathan,
your attach method is very fast!
This is the test on the *Teapot Wall*
#1 TEST

 (
 delete objects
 shift = off
 geo = Editable_Mesh transform:(matrix3 1) wirecolor:yellow name:"teamain"	
 ProBoolean.createBooleanObject  $teamain undefined 4 1 0   --create master boolean with no operant B (undefined)
 tea = teapot radius:10 name:"sub"
 gc()
 t1 = timestamp()
 m1 = heapfree	
 for z = 0 to 19 do 
 (
 	shift = not shift
 	for x = 0 to 19 do 
 	(
 		sub = (copy $sub)
 		sub.pos = if shift then [30*x,0,20*z] else [10+30*x,0,20*z]
 		in coordsys local sub.rotation =  (random (eulerAngles 0 0 0) (eulerAngles 0 0 359))
 		ProBoolean.SetOperandB $teamain sub 4 0   -- keep adding B operands
 	)
 )
 delete $sub
 format "time:% memory:%\n" ((timestamp()- t1 as float)/1000) (m1-heapfree)
 )
 

The result > time:0.328 memory:224184L

#2 TEST


 (
 delete objects
 shift = off
 geo = Editable_Mesh transform:(matrix3 1) wirecolor:yellow name:"teamain"	
 tea = teapot radius:10 name:"sub"
 gc()
 t1 = timestamp()
 m1 = heapfree	
 for z = 0 to 19 do 
 (
 	shift = not shift
 	for x = 0 to 19 do 
 	(
 		sub = (copy $sub)
 		sub.pos = if shift then [30*x,0,20*z] else [10+30*x,0,20*z]
 		in coordsys local sub.rotation =  (random (eulerAngles 0 0 0) (eulerAngles 0 0 359))
 		attach geo sub
 	)
 )
 delete $sub
 format "time:% memory:%\n" ((timestamp()- t1 as float)/1000) (m1-heapfree)
 )
 

The result > time:24.684 memory:224184L

Huge difference in speed.
Thanks again for this example.
__________________
Looking in the right side. [bgaTools]
 
Thread Closed share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright ©2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 07:30 PM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.