[Closed] Getting the longest edgeloop of an object
I don’t really know… Probably both make loops similar…
As loops are generated along quads that would be a good starting point.
- Finding edge vertices
- From the new vertices we get next possible edges of the loop
- from here we have to test if there are 4 edges of this vertex
- if the last one is true, then it is not the end of the loop, so we can continue searching for the next element of the loop
- and here comes the tricky part. How to find which one of the four edges is the one that we are looking for. The next part of the loop. I should use some kind of an edge faces test, that is looking for the next edge.
But anyway I don’t think that there is a huge difference between them… Probably they are working the same way. Although I found for example that Modo’s loop handling is a bit crappy, so I’m sure that there are other methods as well that are not as efficient.
Just for the starting point of the topic:
This is the code I modified yesterday with removing the loop parts. It shows the same behavior, the only difference is that this one is slower because of the while loop.
function getLongestLoop = (
startTime = timeStamp()
longestLoop = #(-1E9, #{})
theObj = $
allEdgesArray = (theObj.edges as bitarray) as array
while allEdgesArray.count != 0 do (
selEdge = getEdgeSelection theObj
polyop.setEdgeSelection theObj allEdgesArray[1]
theObj.SelectEdgeLoop()
theLoop = getEdgeSelection theObj
allEdgesArray = ((allEdgesArray as bitarray) - (theLoop as bitarray)) as array
loopLength = 0
for i in theLoop do (
verts = polyop.getedgeverts theObj i
loopLength += distance (polyop.getvert theObj verts[1]) (polyop.getvert theObj verts[2])
)
if loopLength > longestLoop[1] do (
longestLoop[1] = loopLength
longestLoop[2] = theLoop
)
)
return longestLoop
)
l = getLongestLoop()
polyop.setedgeselection $ l[2]
format "Edges : %
Length: %
" l[2] l[1]
print (timeStamp() - startTime)
May I ask why you modified the function I wrote? Did you find a bug or it is just a code restyling?
No not a bug at all. Just another way do to the same thing. A speed comparison if you like… I was just simply courious about the difference between the two functions.
And since the for / in expression is faster then the simple i=1 to something.count, I will change my scripts to that method.
Thank you guys! Awesome!
PolyTools3D: Your script worked perfectly! I’m not sure what you mean by unoptimized, I can’t see a better/faster way to do this. I just have one small question, you give the first index a value of -1E9, why do you do that instead of just having 0? Thanks man!
i was just wrong. editable poly always pre-calculate all loops and never calculates them on the fly. so every edge in a poly loop makes exactly this and only one loop.
Yes that’s what I explained. It doesn’t matter which part of the edge loop you choose, all of them gives you the same result. That’s why I thought it’s a good idea to remove the loop elements, from the array of all edges. I assumed that it is faster than cycling through all the edges, but as it’s revealed it’s not faster at all for my greatest surprise…
But Polytools3D! Why is it faster to cycle through with for/in than for/to or while? I still can’t get it… :surprised
I haven’t profiled your script, but I believe the biggest slowdown is not cause by the loop itself, but by constantly converting from bitarray to array, which also causes a huge memory usage:
(
it = 1000000
itBitArray = #{1..it}
itArray = for j = 1 to it collect j -- For testing don't do (itBitArray as array)
tmpBitArray = #{1..10}
gc(); st = timestamp(); sh = heapfree
for j = 1 to it do a = tmpBitArray
format "time:% ram:%
" (timestamp()-st) (sh-heapfree)
gc(); st = timestamp(); sh = heapfree
for j in itBitArray do a = tmpBitArray
format "time:% ram:%
" (timestamp()-st) (sh-heapfree)
gc(); st = timestamp(); sh = heapfree
for j in itArray do a = tmpBitArray
format "time:% ram:%
" (timestamp()-st) (sh-heapfree)
gc(); st = timestamp(); sh = heapfree
for j = 1 to it do a = tmpBitArray as array
format "time:% ram:%
" (timestamp()-st) (sh-heapfree)
)
about optimization…
because for this algorithm we have to ask every vertex position anyway it’s better to collect them all in advance and use this buffer when we calculate edge length.
in should make the algorithm at least two times faster (maybe more)
the situation becomes worse for higher indexes. check an example:
(
b = #{1..10}
--b = #{10000..10010}
--b = #{100000..100010}
t1 = timestamp()
m1 = heapfree
for k=1 to 1000 do
(
a = b as array
b = a as bitarray
)
format "time:% memory:%
" (timestamp() - t1) (m1 - heapfree)
)
Ok! I see the point now… It’s always a pleasure to learn from you gentlemen…
I think a huge amount of optimization is waiting for me now…