[Solved] My script keeps bugsplatting :(
-
If you can't see the error messages, send them to a file.
azuby
-
you mean error messages in the ruby console? I'm note sure there are any since Sketchup simple crashes...
-
Just realised that I didn't specify which function caused the error. It's the Select Connected Planar Faces, Select Connected by Material and Select Connected by Layer.
-
It's odd, I've commented out every action, leaving just the method calls and loops in. Still crashes.
-
When I have some loops in my codes, I put this to exit the loop when I've a bug...
bug = 0 lst = [] while lst.class == Array && bug < 500 bug += 1 end puts bug.to_s
If you don't have bug variable, his code crashes Skecthup.
Your bug perhaps comes from a bugged loop ? -
That's what I'm wondering. But I don't understand why or what causes it. The script works fine for smaller meshes. But when there's about 100-110 faces with entities it has to traverse it bugsplats.
(I did some test with similar code. Though I has to put in a sleep command in order to see the number before SU splatted.) -
You have probably a memory leak. Check amount of memory SU uses.
I had a big headache with SU2KT. It was the way I was writing entities into a hash.
Google didn't even bother to help me.Tomasz
-
But it only loops through entities and adds it to the selection if it doesn't already contain that entity. Doesn't build a hash at all, even though I had plans for that for a variation of the tool.
I wonder if it's because it's recursing method.
Extract of the methods (contained in a module originally)
### FACES ### ----------------------------------------------------------- # --- Select Connected Planar Faces --- def self.select_connected_planar_faces sel = Sketchup.active_model.selection original_face = sel[0] original_vector = original_face.normal self.get_planar_faces(original_face.edges, original_vector) end def self.get_planar_faces(edges, vector) sel = Sketchup.active_model.selection # Loop through all the edges... edges.each { | edge | # ...get the faces and add the planar faces we haven't selected yet edge.faces.each { | face | if face.normal == vector && !sel.contains?(face) sel.add( face ) self.get_planar_faces(face.edges, vector) end } } end
-
Maybe it crashes because the code run across the same entity so many times.
Maybe if I build a list if all entities I've checked and make sure I don't check the ones I have I can avoid the crash. For whatever reason it might be...
-
It appear to be the recursive part of the script. I just tried the Loop from Edge method I wrote earlier on a strip of 1x200 squares and that crashed as well.
But I don't know how I can do this without recursive methods.
Does this sound like a SketchUp bug rather than a script bug? I've not experienced any scripting languages that crashes on recursive methods like this.
-
Hey Thomthom,
Is this happening for you in SU6 or 7 or both?
There were a whole class of what we called "iterator" bugs that we fixed in SU7. These had to do with looping across entities in models. This crash sounds like it's similar.
Cheers,
-
Yes. I was working with SU7, but I just tried SU6 and it happend there as well.
I just did little recursing test:
def self.select_connected_planar_faces @debug = 0 self.recursive end @debug = 0 def self.recursive @debug += 1 puts @debug self.recursive end
The script reaches 489 (last number I see in the console before SU splats.
Doesn't seem to be related to iterating entities as this code simply is an infinite recursive loop.But it will be triggered easily when iterating over lots of geometry.
So I suppose this is one for the bug reports? Any preferred channel? Any way to track bug reports?
-
Appears that deep recursing is a problem in many languages. http://stackoverflow.com/questions/233013/how-does-your-favorite-language-handle-deep-recursion
-
I refactored the code to an iterative loop instead of recursing.
### FACES ### ----------------------------------------------------------- # --- Select Connected Planar Faces --- def self.select_connected_planar_faces sel = Sketchup.active_model.selection face = sel[0] vector = face.normal edges = face.edges while faces = select_connected(edges) # We now have a list of connected faces... edges.clear() faces.each { |face| # ...check each face if it's co-planar if !sel.contains?(face) && face.normal == vector sel.add( face ) edges += face.edges end } end end def self.select_connected(edges) ents = [] edges.each { |edge| ents += edge.faces } return (ents.length > 0) ? ents ; nil end
Success! Haven't run into any limits yet.
Basically: recursing is bad!
-
@unknownuser said:
Basically: recursing is bad!
...
............................................
I often use this method... -
Well, as long as you know that the recursing won't goo too deep it's ok. But when iterating over geometry it easily loops hundred or thousands of time which is when you end up with a call stack error.
When I was looking around for a solution of this I found some interesting reading that converting to iterative loops instead of recursing can be much more efficient.
-
Yep. Iterative method can save time compared with the recursive method... But recursing is much more beautiful !!
Advertisement