sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Soften-Edges using by ruby

    Scheduled Pinned Locked Moved Developers' Forum
    23 Posts 7 Posters 4.2k 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.
    • 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
                                    • G Offline
                                      glro
                                      last edited by

                                      @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

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

                                        The unexpected reversion of smoothed edges to solid is a known bug.
                                        Never save when in a edit session. Even an auto-save can trigger this, so never stay inside an edit session for longer than you need to...

                                        TIG

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

                                        Advertisement