Mini-Challenge #3


#1

http://forums.cgsociety.org/showthread.php?f=98&t=244321&highlight=fast+attach
http://forums.cgsociety.org/showthread.php?f=98&t=635477&highlight=fast+attach
and finally
http://forums.cgsociety.org/showthread.php?f=98&t=922140&highlight=fast+attach

it’s all about how to attach nodes faster.
the last link shows absolutely GREAT solution by ivanisavich (http://forums.cgsociety.org/member.php?u=19108)

the question is: can you do it faster?

so, try to attach multiple poly-nodes (~100+) to a poly-node as fast as possible. (memory is not an issue this time). it must be new algorithm, not just smart optimization of ivanisavich’s.

[i][b]Let’s get ready to rumble!

[/b][/i]unified attach layout:


#2

please show all your ideas even if they are slower. it might be a bright idea but with wrong implementation. also it will be very interesting to discuss why one or another solution doesn’t really work, or doesn’t work as expected.
mxs has some specific problems working with arrays, pointers to node, etc.
show your idea and we will try to optimize it.


#3

Ok, I gotta jump in on this one. I’ll try to have something posted before Saturday morning. :slight_smile:


#4

Oooh, I will def. be watching this one. I was searching for a faster method, and found some, but it would be cool if it can be faster yet.

I am using cloneops now and also attaching somewhat randomly instead of linierly. I took part of the code from soulburn though, so I don’t take credit for it.


#5

How does this look for the layout?

  I'm guessing we're creating/convert the teapots before we calculate any time, correct?

(the script below doesn’t perform any fast methods, just an example of the layout i’ll be using)


      (
  	fn createTeapots howManyTeapots: 1000 =
  	(
  		/*
  		===============
  		Here we delete all objects, create the teapots, select them, and zoom extents, the function returns the teapot array
  		===============
  		*/
  		delete objects
  		local arrayToReturn = #()
  
  		for j = 1 to 1000 do
  			append arrayToReturn (teapot pos:[random -100 100, random -100 100, random 0 100])
  		select geometry
  		actionMan.executeAction 0 "311"  -- Tools: Zoom Extents All Selected
  		
  		clearSelection()
  		
  		arrayToReturn
  	)
  	
  	rollout roAttachSpeedTest "1000 Teapot Speed Test"  width: 220
  	(
  		button btnRunSpeedTest "Run Speed Test"
  		group ""
  		(
  			radioButtons rbSpeedTest "Choose Test:" labels:#("Test 1", "Test 2", "Test 3") columns:1 default: 3 align:#center
  		)
  		group ""
  		(
  			radioButtons rbMeshOrPoly "Pre-Convert Teapots to" labels:#("Editable Mesh", "Editable Poly") columns:1 default:1 align:#center
  		)
  		label labSpeedTestCaption ""
  
  		on roAttachSpeedTest open do
  		(
  			if (queryBox "Reset Max scene before continuing?" beep:false) then
  				resetMaxFile #noprompt
  			
  			actionMan.executeAction 0 "50026"  -- Tools: Maximize Viewport Toggle
  			
  			if objects.count != 0 then
  				delete objects
  
  		)
  		on btnRunSpeedTest pressed do
  		(
  			with undo off
  			(
  				if rbMeshOrPoly.state == 1 then
  				(
  					convertToMesh(createTeapots())
  					convertToPoly geometry[1]
  				)
  				else
  				(
  					convertToPoly(createTeapots())
  				)
  						
  				gc()
  				
  				if rbSpeedTest.state == 1 then
  				(
  					local theCurrTime = timeStamp()
  					(
  						messageBox "Test 1 hasn't been implimented yet." beep:false
  					)
  					local endTime = timeStamp()
  					labSpeedTestCaption.text = ("Test Attach 1 process took " + ((endTime - theCurrTime) as string) + "ms." )
  					
  				)
  				
  				if rbSpeedTest.state == 2 then
  				(
  					local theCurrTime = timeStamp()
  					messageBox "Test 2 hasn't been implimented yet." beep:false
  					local endTime = timeStamp()
  					labSpeedTestCaption.text = ("Test Attach 1 process took " + ((endTime - theCurrTime) as string) + "ms." )
  				)
  				if rbSpeedTest.state == 3 then
  				(
  					local theCurrTime = timeStamp()
  					messageBox "Test 3 hasn't been implimented yet." beep:false
  					local endTime = timeStamp()
  					labSpeedTestCaption.text = ("Test Attach 1 process took " + ((endTime - theCurrTime) as string) + "ms." )
  				)
  			)			
  		)
  	)
  	
  	CreateDialog roAttachSpeedTest style:#(#style_toolwindow, #style_resizing, #style_sysmenu) fgcolor:([0,255,64]) bitmap:
  	undefined 
  	
  )
      

#6

I had a feeling this challenge would be coming. :slight_smile:
I think we need a specific test case (1000 teapots as j83 suggested is fine by me), as different algorithms are better for different cases.


#7

are you ready? i’m cheating as usually. honestly i spent days to beat the vanisavich’s algorithm.


#8

tomorrow i will provide the standard test for fastest poly attach algorithm. all players will have the same field.


#9

I don’t know if I have time to join, but spent at least an half our in bed thinking of new ways to do this :slight_smile:

Great challenge!
-Johan


#10

My first attempt… cluster attach with a twist.
From my tests it seems to be 25 times faster than cluster attach. Can anyone confirm?

fn megaClusterAttach objs =
(
	gc()
	local ts = timestamp()
	with undo off with redraw off
	(
		local att = meshop.Attach
		local snap = snapShotAsMesh
		local del = deleteItem
		local j = 1
		local meshes = for o in objs collect snap o
		while meshes.count > 1 do
		(
			att meshes[j] meshes[j+1]
			del meshes (j+1)
			j += 1
			if (j + 1) > meshes.count then j = 1
		)
		delete objs
		local result = editable_mesh name:"Result"
		result.mesh = meshes[1]
		print (timeStamp()-ts)
	)	
)

edit: didn’t notice the output must be editablepoly. Adding a convertTo command to the result adds considerable time, though still 4 times faster than cluster attach.


#11

This works fine for small collections, but explodes with 100 teapots… I was hoping that proboolean’s merge would be fast since no geometry calculations are done… And you can pass it an array of nodes to merge so no need for iterating over a selection in maxscript…


objs=$selection as array

main=objs[1]
deleteitem objs 1
 
ProBoolean.CreateBooleanObjects  main objs  3 2 1


#12

the final object has to be an EDITABLE POLY.


#13

create proboolean object, add attaching nodes with merge operation and move method, and convert to poly.
right?

could you provide a time result?


#14

Yeah that was the plan, the convert to poly is missing from the script but that’s trivial.

When I use it on a 100 teapots max freezes so I can’t produce a time for a 1000 teapots. I didn’t look for a solution jet since I have actual work to do :slight_smile:


#15

i’ve posted unified test with [b]ivanisavich /b and [b]3dsmax /b methods. the test generates defined amount of boxes in different range and order. small boxes has to be attach to big box. my method is caster. it’s hidden temporarily.

see the code and use custom slot for your algorithm following the template. let me know if need any assistance.

the code is http://forums.cgsociety.org/attachment.php?attachmentid=162171

next time when you want to show your method please just post the customAttach function:


 	fn customAttach source nodes pb:pb1 = 
 	(
 		count = nodes.count
 		 <loop> while not keyboard.escpressed do
 		(
 			pb.value = nodes.count*100./count
	   /*
		   your attach method with counting number of attached vertices
	   */
 		)
 		source
 	)
 

#16

i’ve double-checked. ProBoolean Merge is not the same as Attach.


#17

The result is the same ( N nodes > 1 node ) or I’m I missing something?

Edit: btw… I’ve looked at the mesher object as wel, there seems to be an ‘extranodes’ exposed to maxscript… but I can’t seem to feed it multiple nodes?


#18

with your test case my method is a bit slower than regular cluster attach because the test objects are already editable_polys. I was testing with teapot primitives earlier, in which case converting each object to a poly (cluster attach method) is much slower.
I will look for a method which is more optimized for this test case.


#19

boolean merge is some kind of union with keeping all source and target vertices. the method generates the intersection border.


#20

there is a myth that attaching or some other extensive operations are faster with UNDO OFF. check the test. it’s not TRUE. but it’s a subject of another discussion.