Soften-Edges using by ruby
-
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_between
of the face'snormal
,soft
andsmooth
if 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#def
Save 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.0
etc 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:in
draw_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:in
draw_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...
-
@tig said:
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...
yes...it works
this will save me time, since i noticed that some components edges come back visible in my models, for unknown reason...
now with just one clic, the problem is solved
thank you
Advertisement