Notifications
Clear all

[Closed] Fast attach algorithm

I needed to attach several thousand splines, so I modified Tyson’s cluster attach to support splines.
Thought this may be of use to someone else somewhere:


  --select the splines you want to attach, then run the script
  (
 	function splineAttach objArr =
 	(
 		j = 1
 		undo off
 		(
 			while objArr.count > 1 do
 			(
 				if j+1 > objArr.count then (j = 1) else 
 				(
 					convertToSplineShape objArr[j];  updateShape objArr[j]
 					convertToSplineShape objArr[j+1];  updateShape objArr[j+1]
 					addAndWeld objArr[j] objArr[j+1] 0.0;  updateShape objArr[j]
 					deleteItem objArr (j+1)
 					j += 1
 				)
 			)
 		)
 		return objArr[1]
 	)
 	local mySelection = selection as array
 	splineAttach mySelection
 )
  

*edit – missed a case

why do you think this method faster than the simple linear one? did you compare?
fast attach algorithm works well only and specifically for editable polys, because of the way how poly update is implemented.

why do you think this method faster than the simple linear one? did you compare?

I didn’t compare, just needed to attach several thousand splines and didn’t want to do it by hand. I was already familiar with this method, refactoring tyson’s function only took a few minutes. I am interested to see if a linear attach is faster. What conclusions do you have about linear vs. cluster spline attach?

*now that i’m pushing the fn, i see that it doesn’t scale well. tried to attach 10,201 circles and max went unresponsive. attaching 100 was no problem. guess i’ll code a linear spline attach instead…

Ah, here is a much nicer spline attach fn:


--select the splines you want to attach, then run the script
  (
	 function splineAttach objArr =
	 (
		local myCopy = copy objArr[1];  convertToSplineShape myCopy;  delete objArr[1]
		for j=2 to objArr.count by 1 do
		(
			convertToSplineShape objArr[j]
			updateShape objArr[j]
			addAndWeld myCopy objArr[j] 0.0
			updateShape myCopy
		)
	 )
	 local mySelection = selection as array
	 splineAttach mySelection
 )

I’m not sure if the “updateShape objArr[j]” is necessary.
I’ll run some times on the fns and post comparisons.

Linear spline attach for 100 circles: 253ms.
Linear spline attach for 1111 circles: 346905ms.

Cluster spline attach for 100 circles: 162ms
Cluster spline attach for 1111 circles: 10168ms.

Cluster spline attach is WAY faster.

Am I missing something, or is attaching splines slower than polys or meshes?

Code I’m using for comparisons:


 --select the splines you want to attach, then run the script
 (
 	(
 	source = ""
 	source += "using System;
"
 	source += "using System.Runtime.InteropServices;
"
 	source += "class WindowsGhosting
"
 	source += "{
"
 	source += " [DllImport(\"user32.dll\")]
"
 	source += " public static extern void DisableProcessWindowsGhosting();
"
 	source += "}
"
 
 	csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
 	compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
 
 	compilerParams.GenerateInMemory = on
 	compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
 
 	assembly = compilerResults.CompiledAssembly
 	windowsGhosting = assembly.CreateInstance "WindowsGhosting"
 	windowsGhosting.DisableProcessWindowsGhosting()
 	)
 
 	local ts = timestamp()
 	local mem = heapfree
 	
 	 function splineAttach objArr =
 	 (
 		local myCopy = copy objArr[1];  convertToSplineShape myCopy;  delete objArr[1]
 		for j=2 to objArr.count by 1 do
 		(
 			convertToSplineShape objArr[j]
 			updateShape objArr[j]
 			addAndWeld myCopy objArr[j] 0.0
 			updateShape myCopy
 			if ((random 1 10) == 5) then (print (objArr.count-j))
 		)
 		return objArr.count
 	 )
 	
 	local mySelection = selection as array
 	 local total = splineAttach mySelection
 	
 	format "Time: %ms
" (timestamp()-ts)
 	format "Memory: %
" (mem-heapfree)
 	format "Splines Attached: %
" (total)
  )
   
 

     --select the splines you want to attach, then run the script
(
	  (
	source = ""
	source += "using System;
"
	source += "using System.Runtime.InteropServices;
"
	source += "class WindowsGhosting
"
	source += "{
"
	source += " [DllImport(\"user32.dll\")]
"
	source += " public static extern void DisableProcessWindowsGhosting();
"
	source += "}
"

	csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
	compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"

	compilerParams.GenerateInMemory = on
	compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)

	assembly = compilerResults.CompiledAssembly
	windowsGhosting = assembly.CreateInstance "WindowsGhosting"
	windowsGhosting.DisableProcessWindowsGhosting()
	)

	local ts = timestamp()
	local mem = heapfree
	
	 function splineAttach objArr =
	 (
		 j = 1
		local theCount = objArr.count
		 undo off
		 (
			 while objArr.count > 1 do
			 (
				 if j+1 > objArr.count then (j = 1) else 
				 (
					 convertToSplineShape objArr[j];  updateShape objArr[j]
					 convertToSplineShape objArr[j+1];  updateShape objArr[j+1]
					 addAndWeld objArr[j] objArr[j+1] 0.0;  updateShape objArr[j]
					 deleteItem objArr (j+1)
					 j += 1
					if ((random 1 10) == 5) then (print (objArr.count))
				 )
			 )
		 )
		 return theCount
	 )
	
	 local mySelection = selection as array
	 local total = splineAttach mySelection
	
	format "Time: %ms
" (timestamp()-ts)
	format "Memory: %
" (mem-heapfree)
	format "Splines Attached: %
" (total)
 )
  
   
 

denis, what do you think of this?

first of all i want to say that the testing of any tool/function/method for performance and memory usage is a very practice.
i don’t trust your result of the linear spline attaching of many nodes. it looks too slow for me with no reason. but… if the cluster method is faster we have to take it in account…
if you would like to make a test scene, we can organize a challenge.
i haven’t met a task of spline-shape massive attach before. if it’s a vital problem we can brainstorm it…

Cluster Spline Attach


 Time: 883569ms
 Memory: -1777152L
 Splines Attached: 10201
 

I’m not even going to try the Linear attach for 10201 circles.
I would probably be waiting for a day or two.

There’s got to be a faster way to attach a # of splines greater than 10,000.
Or am I missing something here?

that’s looks absolute crazy… i think that simply recreate and add 10,000 splines to the shape has to be much faster.

if you would like to make a test scene, we can organize a challenge.
i haven’t met a task of spline-shape massive attach before. if it’s a vital problem we can brainstorm it…

Great idea. Here is a test scene:


  (	--
  	resetMaxFile #noPrompt
  	clearListener()
  	local myCircle = circle radius:10
  	for j=1 to 1000 do
  	(
  		local randCirc = copy myCircle
  		randCirc.pos = [0,0,j]
  	)
  	select $*
  )
  

That will setup the scene with 1000 circles over [0,0,0].

And here are the snippets for comparison again:

Linear:


  --select the splines you want to attach, then run the script
  (
  	(
  	source = ""
  	source += "using System;
"
  	source += "using System.Runtime.InteropServices;
"
  	source += "class WindowsGhosting
"
  	source += "{
"
  	source += " [DllImport(\"user32.dll\")]
"
  	source += " public static extern void DisableProcessWindowsGhosting();
"
  	source += "}
"
  
  	csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
  	compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
  
  	compilerParams.GenerateInMemory = on
  	compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
  
  	assembly = compilerResults.CompiledAssembly
  	windowsGhosting = assembly.CreateInstance "WindowsGhosting"
  	windowsGhosting.DisableProcessWindowsGhosting()
  	)
  
  	local ts = timestamp()
  	local mem = heapfree
  	
  	 function splineAttach objArr =
  	 (
  		local myCopy = copy objArr[1];  convertToSplineShape myCopy;  delete objArr[1]
  		for j=2 to objArr.count by 1 do
  		(
  			convertToSplineShape objArr[j]
  			updateShape objArr[j]
  			addAndWeld myCopy objArr[j] 0.0
  			updateShape myCopy
  			if ((random 1 10) == 5) then (print (objArr.count-j))
  		)
  		return objArr.count
  	 )
  	
  	local mySelection = selection as array
  	 local total = splineAttach mySelection
  	
  	format "Time: %ms
" (timestamp()-ts)
  	format "Memory: %
" (mem-heapfree)
  	format "Splines Attached: %
" (total)
   )
  

Cluster Attach:


    --select the splines you want to attach, then run the script
  (
  	(
  	source = ""
  	source += "using System;
"
  	source += "using System.Runtime.InteropServices;
"
  	source += "class WindowsGhosting
"
  	source += "{
"
  	source += " [DllImport(\"user32.dll\")]
"
  	source += " public static extern void DisableProcessWindowsGhosting();
"
  	source += "}
"
  
  	csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
  	compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
  
  	compilerParams.GenerateInMemory = on
  	compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
  
  	assembly = compilerResults.CompiledAssembly
  	windowsGhosting = assembly.CreateInstance "WindowsGhosting"
  	windowsGhosting.DisableProcessWindowsGhosting()
  	)
  
  	local ts = timestamp()
  	local mem = heapfree
  	
  	 function splineAttach objArr =
  	 (
  		 j = 1
  		local theCount = objArr.count
  		 undo off
  		 (
  			 while objArr.count > 1 do
  			 (
  				 if j+1 > objArr.count then (j = 1) else 
  				 (
  					 convertToSplineShape objArr[j];  updateShape objArr[j]
  					 convertToSplineShape objArr[j+1];  updateShape objArr[j+1]
  					 addAndWeld objArr[j] objArr[j+1] 0.0;  updateShape objArr[j]
  					 deleteItem objArr (j+1)
  					 j += 1
  					if ((random 1 10) == 5) then (print (objArr.count))
  				 )
  			 )
  		 )
  		 return theCount
  	 )
  	
  	 local mySelection = selection as array
  	 local total = splineAttach mySelection
  	
  	format "Time: %ms
" (timestamp()-ts)
  	format "Memory: %
" (mem-heapfree)
  	format "Splines Attached: %
" (total)
   )
  

My results (i5 3.3ghzX4 16gb ram max2012):

Linear:
Time: 253828ms
Memory: 3954488L
Splines Attached: 1001

Cluster:
Time: 8270ms
Memory: 3799632L
Splines Attached: 1001

first of all i want to say that the testing of any tool/function/method for performance and memory usage is a very practice. i don’t trust your result of the linear spline attaching of many nodes. it looks too slow for me with no reason.

I’m sure the code could be optimized further, but I’ve tested it and stand by my results. I invite anyone to write a faster attach fn for splines, as I’m building some tile patterns from splines and could really use a fast method of attaching 1000+ splines.

Page 4 / 5