Smooth / Soft group edges

Why does this code take a long time and runing SketchUp menus the effect is immediate? Is there any instructions to do the same directly, like group.soft=true / group.smooth=true?

model = Sketchup.active_model
selection = model.selection
edges=[]
selection.to_a.each{|e|
   edges << e if e.class==Sketchup::Edge
   e.entities.each{|ee|edges << ee if ee.class==Sketchup::Edge}if e.class==Sketchup::Group
}
edges.each{|edge|
ang=edge.faces[0].normal.angle_between(edge.faces[1].normal)
   if edge.faces[1]
     edge.soft=true if ang < 20.degrees
     edge.smooth=true if ang < 20.degrees
   end

The #soft and the #smooth instance methods can be apply only for the edges. You have to do recursively similar as in your example… however I think it could be optimized more.

As far as i know, since Ruby API is just a wrapper on top of C++ core, I guess, the “SketchUp menus the effect is immediate” is much more effective because it written naively in C++ … (But I’m not much familiar with this… even I’m not really sure if it s C++ at all :wink: )

Extract the group[s] from the selection…

model = Sketchup.active_model
selection = model.selection
groups = selection.grep(Sketchup::Group)
### now examine the selected group[s] entities for suitable edges...
groups.each{|group|
  edges = group.entities.grep(Sketchup::Edge)
  edges.each{|edge|
    ang = edge.faces[0].normal.angle_between(edge.faces[1].normal)
    if edge.faces[1]
      edge.soft=true if ang < 20.degrees
      edge.smooth=true if ang < 20.degrees
    end
  }
}

It would be better to put the angle calculation inside the if-end

Try adding

model.start_operation("Soften/Smooth Edges", true)

and

model.commit_operation

around your model changes to prevent the view from redrawing at each change.

1 Like

@dezmo
How about this to minimize the ‘testing’ and weirdness with multi-faced edges? …

###...
edges.each{|edge|
    if edge.faces.length == 2
      ang = edge.faces[0].normal.angle_between(edge.faces[1].normal)
      if ang < 20.degrees
        edge.soft=true
        edge.smooth=true
      end
    end
  }
###

@ene_su
Clearly the OP’s post is just a snippet of code…
It needs to be enclosed inside its own modules[s] and as you suggest the model.start/commit_operations need adding to ensure undoing etc…

2 Likes

I like it too…and I like Ruby because it can be infinitely varied… :slight_smile: (the grep have it’s “own” each “built in” and so on… )

model = Sketchup.active_model
selection = model.selection
model.start_operation("Soften/Smooth Edges", true)
selection.grep(Sketchup::Group){|gr|
  gr.entities.grep(Sketchup::Edge){|e|
    if e.faces[1] && e.faces[0].normal.angle_between(e.faces[1].normal) < 20.degrees
      e.soft=true
      e.smooth=true
    end
  }
}
model.commit_operation
2 Likes

This is called multi-paradigm. (The i is long and the g is silent.)


The only thing I’d change to speed it up a bit, is to not force Ruby to create the edge’s face array 3 times.

model = Sketchup.active_model
selection = model.selection
model.start_operation("Soften/Smooth Edges", true)
  selection.grep(Sketchup::Group) { |gr|
    gr.entities.grep(Sketchup::Edge) { |e|
      f = e.faces
      if f[1] && f[0].normal.angle_between(f[1].normal) < 20.degrees
        e.soft=true
        e.smooth=true
      end
    }
  }
model.commit_operation
2 Likes