Notifications
Clear all

[Closed] Can't create fast split/crack algorithm

I need to split object into chunks of given size.
I wrote few versions of script, but each was too slow.


  undo off
  (
  	local startTime = timeStamp()
  	disableSceneRedraw()
  	progressStart "Chooping geometry..."
  
  	local object = $
  					
  	resetXForm object
  	convertToMesh object
  	meshOp.autoedge object object.Edges 0 -- make all faces triangles
  	convertToPoly object
  
  	local chunkSize = 80
  
  	local Xsize = object.max.x - object.min.x
  	local Xchunks = ceil ((Xsize as float)/chunkSize)
  	local XchunkSize = (Xsize as float)/Xchunks
  
  	local Ysize = object.max.y - object.min.y
  	local Ychunks = ceil ((Ysize as float)/chunkSize)
  	local YchunkSize = (Ysize as float)/Ychunks
  	format "
X chunks: %, Y chunks %" Xchunks Ychunks
  
  	local chunkFaces = for i=1 to Xchunks*Ychunks collect #()
  
  	local pos, idx
  	local faceCount = polyop.getNumFaces object
  	for i=1 to faceCount do
  	(
  		pos = polyop.getFaceCenter object i
  		pos -= object.min
  
  		idx = (ceil (pos.x/XchunkSize)) + (Xchunks * (floor (pos.y/YchunkSize)))
  
  		append chunkFaces[idx] i
  
  		progressUpdate (100*i/faceCount)
  	)
  
  	local chunkName, chunks = #()
  	for i=1 to chunkFaces.count do
  	(
  		if chunkFaces[i].count > 0 then
  		(
  			object.wirecolor = random white black
  			chunkName = (uniqueName "Chunk_")
  			polyop.detachFaces object chunkFaces[i] delete:false asNode:true name:chunkName
  			append chunks (getNodeByName chunkName)
  
  			progressUpdate (100*i/chunkFaces.count)
  		)
  	)
  
  	delete object
  
  	enableSceneRedraw()
  	progressEnd()
  
  	print chunks
  	print( "Chooping time: " + (((timeStamp()-startTime)/1000.) as string) + "s" )
  )

For me execution time for Teapot with radius 400 and 40 segments is more than one minute.
This script will chooping game map before export.

I saw “split chelenge” thread, but I not found better isue.

18 Replies

Try this:


  undo off
   (
  	 local startTime = timeStamp()
  	 disableSceneRedraw()
  	 progressStart "Chooping geometry..."
   
  	 local object = $
  					 
  	 resetXForm object
  	 convertToMesh object
  	 meshOp.autoedge object object.Edges 0 -- make all faces triangles
  	 convertToPoly object
   
  	 local chunkSize = 80
   
  	 local Xsize = object.max.x - object.min.x
  	 local Xchunks = ceil ((Xsize as float)/chunkSize)
  	 local XchunkSize = (Xsize as float)/Xchunks
   
  	 local Ysize = object.max.y - object.min.y
  	 local Ychunks = ceil ((Ysize as float)/chunkSize)
  	 local YchunkSize = (Ysize as float)/Ychunks
  	 format "
X chunks: %, Y chunks %" Xchunks Ychunks
   
  	 local chunkFaces = for i=1 to Xchunks*Ychunks collect #{} --this is now a bitarray
   
  	 local pos, idx
  	 local faceCount = polyop.getNumFaces object
  	 for i=1 to faceCount do
  	 (
  		 pos = polyop.getFaceCenter object i
  		 pos -= object.min
   
  		 idx = (ceil (pos.x/XchunkSize)) + (Xchunks * (floor (pos.y/YchunkSize)))
   
  		 chunkFaces[idx][i] = true --we set the bit with face index to true to collect it
   
  		 progressUpdate (100*i/faceCount)
  	 )
   
  	 local chunkName, chunks = #()
  	 for i=1 to chunkFaces.count do
  	 (
  		 if chunkFaces[i].count > 0 then
  		 (
  			newObject = copy object --clone the object
  			newObject.wirecolor = random black white --assign random color
  			newObject.name = uniqueName "Chunk_" --assign new name
  			polyOp.deleteFaces newObject (#{1..faceCount}-chunkFaces[i]) --delete all faces but the ones we want
  			 append chunks newObject
  			 progressUpdate (100*i/chunkFaces.count)
  		 )
  	 )
   
  	 delete object
   
  	 enableSceneRedraw()
  	 progressEnd()
   
  	 print chunks
  	 print( "Chopping time: " + (((timeStamp()-startTime)/1000.) as string) + "s" )
   )

Basically, detaching faces to a new node seems to be slower than cloning the node and deleting all faces that are not the ones you want. On my machine, the time for 400 radius 40 segments teapot went down from 49 seconds to 22 seconds.
Note that I switched the chunkFaces array to an array of bitarrays to be able to invert it quickly.

You code won’t works for me.
It throws “unknown system exception” (in middle of process O.o) at line:

newObject = copy object --clone the object
  But in your method I don't need longer to work on editable_poly. 
  I needed that because of the meshOp no provides detach to node operation.
  So I used mesh instead of poly and now it works, and works much faster.
  Time shrink from 54s to 3s!
  Thanks so much
  
  Here is final code:
  undo off
         (
      	   local startTime = timeStamp()
      	   disableSceneRedraw()
      	   progressStart "Chooping geometry..."
         
      	   local object = $
      					   
      	   resetXForm object
      	   convertToMesh object
      	   meshOp.autoedge object object.Edges 0 -- make all faces triangles
         
      	   local chunkSize = 80
         
      	   local Xsize = object.max.x - object.min.x
      	   local Xchunks = ceil ((Xsize as float)/chunkSize)
      	   local XchunkSize = (Xsize as float)/Xchunks
         
      	   local Ysize = object.max.y - object.min.y
      	   local Ychunks = ceil ((Ysize as float)/chunkSize)
      	   local YchunkSize = (Ysize as float)/Ychunks
      	   --format "
X chunks: %, Y chunks %" Xchunks Ychunks
         
      	   local chunkFaces = for i=1 to Xchunks*Ychunks collect #{} --this is now a bitarray
         
      	   local pos, idx
      	   local faceCount = object.numFaces 
      	   for i=1 to faceCount do
      	   (
      		   pos = meshop.getFaceCenter object i
      		   pos -= object.min
         
      		   idx = (ceil (pos.x/XchunkSize)) + (Xchunks * (floor (pos.y/YchunkSize)))
         
      		   chunkFaces[idx][i] = true --we set the bit with face index to true to collect it
         
      		   progressUpdate (100*i/faceCount)
      	   )
         
      	   local chunkName, chunks = #()
      	   for i=1 to chunkFaces.count do
      	   (
      		   if chunkFaces[i].numberset > 0 then
      		   (
      			  local newObject = copy object --clone the object
      			  newObject.wirecolor = random black white --assign random color
      			  newObject.name = uniqueName "Chunk_" --assign new name
      			  meshOp.deleteFaces newObject (#{1..faceCount}-chunkFaces[i]) --delete all faces but the ones we want
      			  append chunks newObject
      		   )
      
      		 progressUpdate (100*i/chunkFaces.count)
      	   )
         
      	   delete object -- delete original
         
      	   enableSceneRedraw()
      	   progressEnd()
         
      	   --print chunks
      	   print( "Chopping time: " + (((timeStamp()-startTime)/1000.) as string) + "s" )
         )

Awesome, glad it works!
Not sure why it would crash on the copying – what version of Max was that in?

Um it crashing also with mesh, but on larger objects than with poly.
I using max 2010

I have no idea for that. I will mess wit garbage collecting.
EDIT: gc() no solves problem

It crashed mine too after running on a 100×100 plane. I’m using max 9 sp2 x64.

I created relay simple script that has same problem:


  convertToMesh $
  
  copies = #()
  for i=1 to 3000 do
  (
  	local c = copy $
  	c.pos = random [-100,-100,-100] [100,100,100]
  
  	local faces = #{}
  	--for j=1 to c.numFaces do if (random 0 1) == 1 then faces[j] = true -- random faces
  	faces = #{1..20} -- first 20 faces
  	meshOp.deleteFaces c.mesh faces--*/
  
  	append copies c
  )
  
  print copies
  

It happens often for custom object (rarely for primitives)

I tried fix that, but no success

1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

I created a plane with 100×100 segments and run the above code. My memory went up to 17GB, but no crash. My heapSize was 74973184L (75MB) due to other scripts run before that. My Heap is set to 64MB initial size in the Preferences. The machine has 16 GB RAM.

Out of curiosity, how much is your Heap size? And is this in 32 or 64 bit?

It seems memory problem.
After some changes it gives me “out of memory” error dialog.

It works when new objects are deleted soon after delete the faces (only one chunk is exists at the moment). It makes possible to export chunks during detaching them.

[CENSORED WORDS HERE]
It still throwing the exception when copying.
Now I have no idea how to do it:banghead:

Page 1 / 2