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.
    • 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
                                      • 1 / 2
                                      • First post
                                        Last post
                                      Buy SketchPlus
                                      Buy SUbD
                                      Buy WrapR
                                      Buy eBook
                                      Buy Modelur
                                      Buy Vertex Tools
                                      Buy SketchCuisine
                                      Buy FormFonts

                                      Advertisement