Hi,
I have a heavy model and it contains a lot of flipped faces.
When I do
face.reverse!
If I do this for every face then Sketchup hangs and went to not responding state.
I’m afraid there isn’t any other ways to reverse faces in the Ruby API.
Can you provide an example model and a complete minimal script to illustrate the performance you are seeing?
Here is the script snippet
def start_reverse_op
model = Sketchup.active_model
begin
model.start_operation('Reverse Faces', true, false, true)
check_and_reverse_face(model.entities)
model.commit_operation
rescue
model.abort_opertion
end
end
def check_and_reverse_face(entities)
entities.each {|e|
if e.is_a?(Sketchup::Face)
puts "Face"
reverse_face(e)
elsif e.is_a? (Sketchup::Group)
puts "Group"
check_and_reverse_face(e.entities)
elsif e.is_a? (Sketchup::ComponentInstance)
puts "ComponentInstance"
check_and_reverse_face(e.definition.entities)
end
}
end
def reverse_face(face)
puts "Reversing the face"
back_mat = face.back_material
front_mat = face.material
if(front_mat.nil? && !back_mat.nil?)
face.reverse!
face.material = back_mat
face.back_material = nil
end
end
I could not upload the model as it is more than 4MB.
Here is the link : File upload and sharing. Large file transfers. Free online cloud storage.
Thanks - I’ll have a closer look.
A little side note:
Don’t make operations transparent unless they are meant to chain to the previous operation. For instance, if you do model changes in an observer than you should be making the operation transparent. But by default operations should not be transparent.
I just ran through your example with your attached model:
module Example
# Example.start_reverse_op
def self.start_reverse_op
model = Sketchup.active_model
begin
t = Time.now
model.start_operation('Reverse Faces', true, false)
check_and_reverse_face(model.entities)
model.commit_operation
puts "Elapsed time: #{Time.now - t}s"
rescue
model.abort_opertion
end
end
def self.check_and_reverse_face(entities)
entities.each {|e|
if e.is_a?(Sketchup::Face)
# puts "Face"
reverse_face(e)
elsif e.is_a? (Sketchup::Group)
# puts "Group"
check_and_reverse_face(e.entities)
elsif e.is_a? (Sketchup::ComponentInstance)
# puts "ComponentInstance"
check_and_reverse_face(e.definition.entities)
end
}
end
def self.reverse_face(face)
# puts "Reversing the face"
back_mat = face.back_material
front_mat = face.material
if(front_mat.nil? && !back_mat.nil?)
face.reverse!
face.material = back_mat
face.back_material = nil
end
end
end
It completed in a fraction of a second: Elapsed time: 0.248182s
Note that I removed your puts
statements. Those are expensive - and should be avoided in inner loops. If I run your script with the puts statements I see the same as what you describe.
So the issues here isn’t face.reverse!
- but your puts
debugging statements. When running into performance issues it’s worth making timing tests to assert what is actually causing the slow-down.
Btw, for debugging you might want to look into the debugger: GitHub - SketchUp/sketchup-ruby-debugger: Ruby API debugger for SketchUp 2014 and later.
Can often save you from modifying your source code with puts
when you want to inspect what is going on.
We have a VSCode example project that demonstrate how to set up VSCode for debugging with SketchUp: GitHub - SketchUp/sketchup-extension-vscode-project: VSCode Project for SketchUp Extension Development
Thanks a ton @tt_su.
Will remember the points.