mini-challenge #3 was all about this problem… http://forums.cgsociety.org/showthread.php?f=98&t=982499&highlight=mini-challenge
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.