Soften Edges within API

I am trying to figure out a way to soften the edges of a group without having to specify the exact edge. In the tray there is a nice little tool with a slider where you can adjust the angle between the normals but I am not seeing this method in the API.

You simply have to iterate over all the edges, ignore those with not exactly 2 bounded faces, calculate angle between the bounded face’s normals and soft/smooth if the angle is below a certain threshold value. There are no nice shortcuts I’m afraid.

I tend to erase co-planer with this type of method…

def erase_coplaner(edges)
	# erase hidden or coplaner but avoid others
	edges.each do |e|
	  next if e.deleted?
	  e.hidden   = false if e.hidden?
	  e.soft     = false if e.soft?
	  e.smooth   = false if e.smooth?
	  e.find_faces if e.faces.length == 0
	  e.erase! if  e.faces.length == 2 && e.faces[0][1].normal).abs > 0.9999999999999
end #erase_coplaner


Comparing the normal will fail with small features or close to degenerate faces.
To match what SketchUp to consider two faces coplanar you’d have to get best fit plane for all the vertices in the two faces and then check if they are all on the plane.

Something like this: Bitbucket


This affects the same collection you are iterating. … a no-no.

Please use: edges.to_a.each

Only if an Entities object is passed to erase_coplaner which is quite unlikely given an error would be thrown if it contained any other Entity types. The edges are most likely passed as an Array, e.g. created by Entities#grep.

1 Like

An array is a collection type object, which can suffer the same fate as any other collection type object. (Ie the “modification of the collection by it’s own loop error” happens to array as well as thinly wrapped C++ collections.)

Entity.erase! doesn’t remove the Entity from an Array. Only from an Entities collection an Entity is removed by the erase! method. In an Array there will still be a reference to DeletedEntity.


okay I gotcha. My bad! :blush: (Not enough coffee yet today.) :coffee:

1 Like

in the full code it is passed from a grep

    i     = d.instances[0]
    idef  = i.definition
    dents = idef.entities
    edges = dents.grep(Sketchup::Edge)

next if e.deleted?

is there ‘incase’ the array tries to reprocess one…


This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.