sketchucation logo sketchucation
    • Login
    Oops, your profile's looking a bit empty! To help us tailor your experience, please fill in key details like your SketchUp version, skill level, operating system, and more. Update and save your info on your profile page today!
    🫛 Lightbeans Update | Metallic and Roughness auto-applied in SketchUp 2025+ Download

    Soften-Edges using by ruby

    Scheduled Pinned Locked Moved Developers' Forum
    23 Posts 7 Posters 4.4k Views 7 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • thomthomT Offline
      thomthom
      last edited by

      No sure if you can - you might have to do it manually.

      Thomas Thomassen — SketchUp Monkey & Coding addict
      List of my plugins and link to the CookieWare fund

      1 Reply Last reply Reply Quote 0
      • J Offline
        Jim
        last edited by

        I don't think it is available through an API method; you will need to write your own soften method.

        Hi

        1 Reply Last reply Reply Quote 0
        • A Offline
          Andreas
          last edited by

          @jim said:

          ... you will need to write your own soften method.

          How does it work? Do you have an idea?

          With best regards from Germany

          Andreas

          1 Reply Last reply Reply Quote 0
          • thomthomT Offline
            thomthom
            last edited by

            Compare the angle_between of the face's normal, soft and smooth if they are within the threshold.

            Thomas Thomassen — SketchUp Monkey & Coding addict
            List of my plugins and link to the CookieWare fund

            1 Reply Last reply Reply Quote 0
            • TIGT Offline
              TIG Moderator
              last edited by

              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 as makesoftsmooth()
              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 like ang=edge.faces[0].normal.angle_between(edge.faces[1].normal) and then use edge.soft=true if ang.radians >= 45.0 etc or whatever the angle you desire [here it's 45 degrees]

              TIG

              1 Reply Last reply Reply Quote 0
              • A Offline
                Andreas
                last edited by

                @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 as makesoftsmooth()
                ...

                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?

                With best regards from Germany

                Andreas

                1 Reply Last reply Reply Quote 0
                • thomthomT Offline
                  thomthom
                  last edited by

                  @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.

                  Thomas Thomassen — SketchUp Monkey & Coding addict
                  List of my plugins and link to the CookieWare fund

                  1 Reply Last reply Reply Quote 0
                  • TIGT Offline
                    TIG Moderator
                    last edited by

                    @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
                      }
                    }
                    ### ???
                    
                    

                    TIG

                    1 Reply Last reply Reply Quote 0
                    • B Offline
                      baldaman
                      last edited by

                      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
                      
                      
                      1 Reply Last reply Reply Quote 0
                      • TIGT Offline
                        TIG Moderator
                        last edited by

                        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 ??

                        TIG

                        1 Reply Last reply Reply Quote 0
                        • B Offline
                          baldaman
                          last edited by

                          Here is the code and the result,
                          I tried with different angles.
                          If I choose 90° nothing is smoothed neither soften.


                          ss.jpg

                          1 Reply Last reply Reply Quote 0
                          • B Offline
                            baldaman
                            last edited by

                            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
                            
                            
                            
                            1 Reply Last reply Reply Quote 0
                            • TIGT Offline
                              TIG Moderator
                              last edited by

                              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...
                              😒

                              TIG

                              1 Reply Last reply Reply Quote 0
                              • B Offline
                                baldaman
                                last edited by

                                😳 😳 😳
                                ... I am soooo stupid!
                                Thank you very much, it works perfectly.
                                Thank you very much master TIG

                                1 Reply Last reply Reply Quote 0
                                • TIGT Offline
                                  TIG Moderator
                                  last edited by

                                  That's OK 😉
                                  I should have spotted the error in your logic earlier too 😮

                                  TIG

                                  1 Reply Last reply Reply Quote 0
                                  • artmusicstudioA Offline
                                    artmusicstudio
                                    last edited by

                                    hello,
                                    this piece of code is very helpful.
                                    in my case this works:

                                    SMOOTH LEFT

                                    model=Sketchup.active_model
                                    ss=group20.entities

                                    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
                                    }

                                    BUT THIS ONE (smoothing with angle limit)
                                    model=Sketchup.active_model
                                    ss=group20.entities

                                    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
                                    }

                                    is quit by following:

                                    VAR. 0.1 k
                                    load '01.rb'
                                    Error: #<NoMethodError: undefined method normal' 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:in each' 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

                                    1 Reply Last reply Reply Quote 0
                                    • TIGT Offline
                                      TIG Moderator
                                      last edited by

                                      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 !

                                      TIG

                                      1 Reply Last reply Reply Quote 0
                                      • artmusicstudioA Offline
                                        artmusicstudio
                                        last edited by

                                        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

                                        1 Reply Last reply Reply Quote 0
                                        • G Offline
                                          glro
                                          last edited by

                                          @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?

                                          1 Reply Last reply Reply Quote 0
                                          • TIGT Offline
                                            TIG Moderator
                                            last edited by

                                            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

                                            1 Reply Last reply Reply Quote 0
                                            • 1
                                            • 2
                                            • 1 / 2
                                            • First post
                                              Last post
                                            Buy SketchPlus
                                            Buy SUbD
                                            Buy WrapR
                                            Buy eBook
                                            Buy Modelur
                                            Buy Vertex Tools
                                            Buy SketchCuisine
                                            Buy FormFonts

                                            Advertisement