Soften-Edges using by ruby
-
No sure if you can - you might have to do it manually.
-
I don't think it is available through an API method; you will need to write your own soften method.
-
@jim said:
... you will need to write your own soften method.
How does it work? Do you have an idea?
-
Compare the
angle_betweenof the face'snormal,softandsmoothif they are within the threshold. -
Make an array of the selected edges [or of the edges within selected groups etc].
Iterate through those edges and test it they have >1 face.
Soft/Smooth them...def makesoftsmooth() model=Sketchup.active_model ss=model.selection ### You can assemble any collection of edges ### Here it's from the model's current selection edges=[] ss.to_a.each{|e| edges << e if e.class==Sketchup;;Edge e.entities.each{|ee|edges << ee if e.class==Sketchup;;Edge}if e.class==Sketchup;;Group } edges.each{|edge| if edge.faces[1] edge.soft=true edge.smooth=true end } end#defSave code as makesoftsmooth.rb or use the def as part of a broader tool.
Execute it asmakesoftsmooth()
This softens ALL edges that have at least 2 faces - but if you want to soften edges based on angle between its two faces use something likeang=edge.faces[0].normal.angle_between(edge.faces[1].normal)and then useedge.soft=true if ang.radians >= 45.0etc or whatever the angle you desire [here it's 45 degrees] -
@tig said:
Make an array of the selected edges [or of the edges within selected groups etc].
Iterate through those edges and test it they have >1 face.
Soft/Smooth them...> def makesoftsmooth() > model=Sketchup.active_model > ss=model.selection > ### You can assemble any collection of edges > ### Here it's from the model's current selection > edges=[] > ss.to_a.each{|e| > edges << e if e.class==Sketchup;;Edge > e.entities.each{|ee|edges << ee if e.class==Sketchup;;Edge}if e.class==Sketchup;;Group > } > edges.each{|edge| > if edge.faces[1] > edge.soft=true > edge.smooth=true > end > } > end#def >Save code as makesoftsmooth.rb or use the def as part of a broader tool.
Execute it asmakesoftsmooth()
...Thank you!
That works well, if the edges not in a group.
But on edges in a group it doesn´t work.
What should I do so that it acts on the edges in a group? -
@tig said:
Make an array of the selected edges [or of the edges within selected groups etc].
Iterate through those edges and test it they have >1 face.The native soft+smooth tool doesn't soft+smooth any edges that is connected to more or less than 2 faces.
-
@thomthom said:
@tig said:
Make an array of the selected edges [or of the edges within selected groups etc].
Iterate through those edges and test it they have >1 face.The native soft+smooth tool doesn't soft+smooth any edges that is connected to more or less than 2 faces.
OK just adjust the code so that it's a
edge.faces[1] and not edge.faces[2]test...***To work on a group's edges
###... add this into the mix... groups=[] ss.to_a.each{|e|groups << e if e.class==Sketchup;;Group} groups.each{|group| group.entities.to_a.each{|e| if e.class==Sketchup;;Edge and e.faces.length==2 ###*** e.soft=true e.smooth=true end#if } } ### ??? -
Dear TIG, I tried to edit you code in order to be able to choose the smooth angle but I didn't succeed.
WHat am I doing wrong?def ss() model=Sketchup.active_model ss=model.selection ### You can assemble any collection of edges ### Here it's from the model's current selection edges=[] ss.to_a.each{|e| edges << e if e.class==Sketchup;;Edge e.entities.each{|ee|edges << ee if e.class==Sketchup;;Edge}if e.class==Sketchup;;Group } edges.each{|edge| if edge.faces[1] ang=edge.faces[0].normal.angle_between(edge.faces[1].normal) edge.soft=true if ang.radians >= 45.0 edge.smooth=true if ang.radians >= 45.0 end } end#def -
I haven't tested it but it looks OK - except I'd have used
edge.soft=true if ang >= 45.degrees edge.smooth=true if ang >= 45.degrees
rather than
edge.soft=true if ang.radians >= 45.0 edge.smooth=true if ang.radians >= 45.0
There's a type in the group part use ee NOT e...
e.entities.each{|ee|edges << ee if **ee**.class==Sketchup::Edge}if e.class==Sketchup::Group
But but ought to work ?
If you get it to 'puts' edges and ang.radians etc as it iterates through what is shown in the Ruby Console ?? -
Here is the code and the result,
I tried with different angles.
If I choose 90° nothing is smoothed neither soften.

-
Oups, here is the code
def ss() model=Sketchup.active_model ss=model.selection ### You can assemble any collection of edges ### Here it's from the model's current selection edges=[] ss.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 >= 45.degrees edge.smooth=true if ang >= 45.degrees end } end#def -
The angle between adjacent faces on the cylinder's curve is 360/numsegs = 15 degrees for 24 segements so that is less than 45 degrees so they won't be smoothed !
I suspect you want to smooth edges that are NOT >= 45.degrees - so reverse the logic of the test to
edge.soft=true if ang < 45.degrees edge.smooth=true if ang < 45.degrees
and then 'sharp' edges will be kept 'solid' but edges with faces with similar normals will get smoothed
So a right-angle arris stays sharp and a nearly flat surface gets smoothed...

-

... I am soooo stupid!
Thank you very much, it works perfectly.
Thank you very much master TIG -
That's OK

I should have spotted the error in your logic earlier too
-
hello,
this piece of code is very helpful.
in my case this works:SMOOTH LEFT
model=Sketchup.active_model
ss=group20.entitiesYou can assemble any collection of edges
Here it's from the model's current selection
edges=[]
ss.to_a.each{|e|
edges << e if e.class==Sketchup::Edge
e.entities.each{|ee|edges << ee if e.class==Sketchup::Edge}if e.class==Sketchup::Group
}
edges.each{|edge|
if edge.faces[1]
edge.soft=true
edge.smooth=true
end
}BUT THIS ONE (smoothing with angle limit)
model=Sketchup.active_model
ss=group20.entitiesYou can assemble any collection of edges
Here it's from the model's current selection
edges=[]
ss.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 < 45.degrees
edge.smooth=true if ang < 45.degrees
end
}is quit by following:
VAR. 0.1 k
load '01.rb'
Error: #<NoMethodError: undefined methodnormal' for nil:NilClass> C:/Program Files (x86)/Google/Google SketchUp 8/Plugins/01.rb:1516:indraw_stairs'
C:/Program Files (x86)/Google/Google SketchUp 8/Plugins/01.rb:1515:ineach' C:/Program Files (x86)/Google/Google SketchUp 8/Plugins/01.rb:1515:indraw_stairs'
C:/Program Files (x86)/Google/Google SketchUp 8/Plugins/01.rb:973:in `each'any idea about the "normal" problem?
thanx stan
-
Recast:
edges.each{|edge| ang=edge.faces[0].normal.angle_between(edge.faces[1].normal) if edge.faces[1] edge.soft=true if ang < 45.degrees edge.smooth=true if ang < 45.degrees end }as
edges.each{|edge| if edge.faces[1] ang=edge.faces[0].normal.angle_between(edge.faces[1].normal) edge.soft=true if ang < 45.degrees edge.smooth=true if ang < 45.degrees end }because in YOUR version you are trying to get the normal of ALL edge's faces even if an edge doesn't have any faces ! Or if the face only has one face YOUR version fails when it can't find the normal of the non-existent second face !
-
YEAP!
smooth like a sup of tea with milk on a sunny afternon......
smoothing works perfect , thanx a lot ("again what learned", as we say here in bavaria)
lost a ot of time today with fighting again coordinate systems, whatever i do, the elements don't place themselves sometimes , where i expect them to, it seems, that within groups and components the time & space works different sometimes.....
stan -
@tig said:
@thomthom said:
@tig said:
Make an array of the selected edges [or of the edges within selected groups etc].
Iterate through those edges and test it they have >1 face.The native soft+smooth tool doesn't soft+smooth any edges that is connected to more or less than 2 faces.
OK just adjust the code so that it's a
edge.faces[1] and not edge.faces[2]test...***To work on a group's edges
> ###... add this into the mix... > groups=[] > ss.to_a.each{|e|groups << e if e.class==Sketchup;;Group} > groups.each{|group| > group.entities.to_a.each{|e| > if e.class==Sketchup;;Edge and e.faces.length==2 ###*** > e.soft=true > e.smooth=true > end#if > } > } > ### ??? >it works for groups, but not for components...
is it possible? -
Assuming
ss=Sketchup.active_model.selection...defns=[] ss.grep(Sketchup;;ComponentInstance).each{|e|defns << e.definition} defns.uniq! defns.each{|defn| defn.entities.grep(Sketchup;;Edge).each{|e| if e.faces.length==2 e.soft=true e.smooth=true end } }or something similar...
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register LoginAdvertisement