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

    Turning a selection into a face?

    Scheduled Pinned Locked Moved Developers' Forum
    40 Posts 4 Posters 626 Views 4 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

      That method doesn't return faces, it just makes them !
      To find them try...
      ` edges=sel.grep(Sketchup::Edge)
      ofaces=[]
      edges.each{|e|ofaces << e.faces}
      ofaces.flatten!
      ofaces.uniq!

      edges.each{|e|e.find_faces}
      nfaces=[]
      edges.each{|e|nfaces << e.faces}
      nfaces.flatten!
      nfaces.uniq!The array 'nfaces' is all of the faces that are now attached to the edges - old and new. To find just the new faces try... faces=nfaces-ofaces`
      Where 'faces' is the array of those...

      TIG

      1 Reply Last reply Reply Quote 0
      • T Offline
        tomot
        last edited by

        I did not know that this is a 2 stage process, 1: find & 2: return

        $newface1=sel.grep(Sketchup;;Face) #finds face only!
        $newface1.pushpull $inset
        

        So How do I implement a pushpull of $newface1?

        [my plugins](http://thingsvirtual.blogspot.ca/)
        tomot

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

          First off...
          Don't use $ variables !
          If the vars are spread across different methods in the same class/module use @.
          Otherwise why use them at all...
          Try
          newface1.pushpull(inset)
          or
          @newface1.pushpull(@inset)
          Depending on the +/-ve value of the face it dictates the extrusion relative to the face.normal.
          Note that the face.normal can be determined prior to the pushpull and then face.reverse! if it's the 'wrong orientation', for example you want the face to be 'down' so a +ve inset moves the pushpull down too then test face.normal.z<0, and if not you can use face.reverse! before the pushpull is done...

          TIG

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

            @tomot said:

            I did not know that this is a 2 stage process, 1: find & 2: return

            $newface1=sel.grep(Sketchup;;Face) #finds face only!
            > $newface1.pushpull $inset
            

            So How do I implement a pushpull of $newface1?

            sel.grep(Sketchup::Face)
            This returns an array of all faces in the colletion (in this case selection)

            <span class="syntaxdefault"><br />faces&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">sel</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">grep</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Face</span><span class="syntaxkeyword">)&nbsp;}<br /></span><span class="syntaxcomment">#&nbsp;Push/pull&nbsp;all&nbsp;faces<br /></span><span class="syntaxdefault">faces</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each&nbsp;</span><span class="syntaxkeyword">{&nbsp;|</span><span class="syntaxdefault">face</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">face</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">pushpull</span><span class="syntaxkeyword">(&nbsp;</span><span class="syntaxdefault">distance&nbsp;</span><span class="syntaxkeyword">)&nbsp;}<br />&nbsp;</span><span class="syntaxdefault"></span>
            

            If you want only one entity, use find():

            <span class="syntaxdefault"><br />face&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">sel</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">find&nbsp;</span><span class="syntaxkeyword">{&nbsp;|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">is_a</span><span class="syntaxkeyword">?(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Face</span><span class="syntaxkeyword">)&nbsp;}<br /></span><span class="syntaxdefault">face</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">pushpull</span><span class="syntaxkeyword">(&nbsp;</span><span class="syntaxdefault">distance&nbsp;</span><span class="syntaxkeyword">)<br />&nbsp;</span><span class="syntaxdefault"></span>
            

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

            1 Reply Last reply Reply Quote 0
            • T Offline
              tomot
              last edited by

              @tig said:

              First off...
              Don't use $ variables !
              snip

              I was using $ variables only to check what my face code was actually being selecting in the Ruby Console. I still trying to resolved this issue. 😢

              [my plugins](http://thingsvirtual.blogspot.ca/)
              tomot

              1 Reply Last reply Reply Quote 0
              • T Offline
                tomot
                last edited by

                @thomthom said:

                sel.grep(Sketchup::Face)
                This returns an array of all faces in the colletion (in this case selection)

                <span class="syntaxdefault"><br />faces </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> sel</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">grep</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Face</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">}<br /></span><span class="syntaxcomment"># Push/pull all faces<br /></span><span class="syntaxdefault">faces</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each </span><span class="syntaxkeyword">{</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">|</span><span class="syntaxdefault">face</span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> face</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">pushpull</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> distance </span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault"></span>
                

                If you want only one entity, use find():

                <span class="syntaxdefault"><br />face </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> sel</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">find </span><span class="syntaxkeyword">{</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">is_a</span><span class="syntaxkeyword">?(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Face</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">face</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">pushpull</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> distance </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"></span>
                

                That's precisely my problem in a larger nutshell 😄 , I'm trying to use RickW's offset.rb which draws a 2nd offset on the initial "sel" selected face. Since there now 2 faces I'm having difficulty selecting the offset face for pushpull that the offset.rb created, and NOT the initial "sel" selected face for pushpull. (I can post a pic if my description falls short)

                [my plugins](http://thingsvirtual.blogspot.ca/)
                tomot

                1 Reply Last reply Reply Quote 0
                • Dan RathbunD Offline
                  Dan Rathbun
                  last edited by

                  @tomot said:

                  I'm trying to use RickW's offset.rb which draws a 2nd offset on the initial "sel" selected face.

                  Please do not use that script AS IS. We need to put it on the Quarantine List.

                  It overrides the API Array#offset method, and adds methods to both API and Ruby Core base classes.

                  You can use ideas from the methods that do not change base classes (by re-writing them and putting them inside your own namespace.)

                  So... anyway Rick's offset method should have returned a reference to the added face, because it uses Entities#add_face()

                  To use that method inside youir OWN namespace, you need to pass a reference to the original face into the method, and replace all self references within the method to the reference name of the passed face argument.

                  Example 1 (The internals have not been changed much, but an undo operation has been added):

                  module Tomot
                    module SomePlugin
                      class << self
                  
                        def offset_a_face( face, dist )
                  
                          unless face.is_a?(Sketchup;;Face)
                            fail(TypeError,"Sketchup;;Face instance expected for 1st argument",caller)
                          end
                  
                          unless dist.is_a?(Numeric)
                            fail(TypeError,"Numeric subclass expected for 2nd argument",caller)
                          else
                            if dist.zero?
                              unless $VERBOSE.nil?
                                puts("Tomot;;SomePlugin;WARNING; offset_a_face(); Offset distance was zero.")
                              end
                              return nil
                            end
                          end
                  
                          new_face = nil # this method's return value
                  
                          pi = Math;;PI
                          verts = face.outer_loop.vertices
                          pts   = []
                          
                          # CREATE ARRAY pts OF OFFSET POINTS FROM FACE
                          
                          0.upto(verts.length-1) do |a|
                            vec1 = (verts[a].position-verts[a-(verts.length-1)].position).normalize
                            vec2 = (verts[a].position-verts[a-1].position).normalize
                            vec3 = (vec1+vec2).normalize
                            if vec3.valid?
                              ang = vec1.angle_between(vec2)/2
                              ang = pi/2 if vec1.parallel?(vec2)
                              vec3.length = dist/Math;;sin(ang)
                              t = Geom;;Transformation.new(vec3)
                              if pts.length > 0
                                vec4 = pts.last.vector_to(verts[a].position.transform(t))
                                if vec4.valid?
                                  unless (vec2.parallel?(vec4))
                                    t = Geom;;Transformation.new(vec3.reverse)
                                  end
                                end
                              end
                              
                              pts.push(verts[a].position.transform(t))
                            end
                          end
                  
                          # CHECK FOR DUPLICATE POINTS IN pts ARRAY
                          #
                          duplicates = []
                          pts.each_index do |a|
                            pts.each_index do |b|
                              next if b==a
                              duplicates<<b if pts[a]===pts[b]
                            end
                            break if a==pts.length-1
                          end
                          duplicates.reverse.each{|a| pts.delete(pts[a])}
                  
                          # CREATE FACE FROM POINTS IN pts ARRAY
                          #
                          if pts.length > 2
                            begin
                              #
                              if Sketchup.version.to_i > 6
                                face.model.start_operation('Offset Face',true)
                              else
                                face.model.start_operation('Offset Face')
                              end
                                #
                                new_face = face.parent.entities.add_face(pts)
                                #
                              face.model.commit_operation()
                              #
                            rescue
                              face.model.abort_operation()
                              raise() # to outer rescue clause
                            end # begin
                          end # if
                  
                        rescue TypeError
                  
                          raise() # just re-raise the Exception
                  
                        rescue => e # any other Exceptions;
                  
                          unless $VERBOSE.nil?
                            puts("Tomot;;SomePlugin;WARNING; offset_a_face(); #{face.inspect} did not offset; #{pts}")
                            puts("Error; #<#{e.class.name}; #{e.message}>")
                            puts(e.backtrace) if $VERBOSE
                          end
                          raise() # re-raise to any debugger in use
                  
                        else # when no errors;
                  
                          return new_face
                  
                        end # offset_a_face()
                  
                      end # proxy class
                    end # module SomePlugin
                  end # module Tomot
                  

                  💭

                  I'm not here much anymore.

                  1 Reply Last reply Reply Quote 0
                  • Dan RathbunD Offline
                    Dan Rathbun
                    last edited by

                    Example 2 : Here is a shorter edition that uses a vector or an array as the 2nd argument, and leverages the API's built-in Geom::Point3d#offset! method.

                    You can create a vector to pass as the 2nd argument, or call the method with an array literal, to say, offset the face by 10 units in the positive Z direction:
                    offset_a_face( @face, [0,0,10.0] )

                    module Tomot
                      module SomePlugin
                        class << self
                    
                          def offset_a_face( face, vect )
                    
                            unless face.is_a?(Sketchup;;Face)
                              fail(TypeError,"Sketchup;;Face instance expected for 1st argument",caller)
                            end
                     
                            unless vect.is_a?(Geom;;Vector3d) || vect.is_a?(Array)
                              fail(TypeError,"Geom;;Vector3d or Array expected for 2nd argument",caller)
                            else
                              vect = Geom;;Vector3d.new(*vect) if vect.is_a?(Array)
                              if vect.length.zero?
                                unless $VERBOSE.nil?
                                  puts("Tomot;;SomePlugin;WARNING; offset_a_face(); Offset vector length was zero.")
                                end
                                return nil
                              end
                            end
                    
                            new_face = nil # this method's return value
                    
                            verts = face.vertices
                    
                            # CREATE ARRAY pts OF OFFSET POINTS FROM FACE
                            pts = verts.map {|v| v.position.offset!(vect) }
                    
                            # CREATE FACE FROM POINTS IN pts ARRAY
                            #
                            if pts.length > 2
                              begin
                                #
                                if Sketchup.version.to_i > 6
                                  face.model.start_operation('Offset Face',true)
                                else
                                  face.model.start_operation('Offset Face')
                                end
                                  #
                                  new_face = face.parent.entities.add_face(pts)
                                  #
                                face.model.commit_operation()
                                #
                              rescue
                                face.model.abort_operation()
                                raise() # to outer rescue clause
                              end # begin
                            end # if
                    
                          rescue TypeError
                     
                            raise() # just re-raise the Exception
                    
                          rescue => e # any other Exceptions;
                    
                            unless $VERBOSE.nil?
                              puts("Tomot;;SomePlugin;WARNING; offset_a_face(); #{face.inspect} did not offset; #{pts}")
                              puts("Error; #<#{e.class.name}; #{e.message}>")
                              puts(e.backtrace) if $VERBOSE
                            end
                            raise() # re-raise to any debugger in use
                    
                          else # when no errors;
                    
                            return new_face
                    
                          end # offset_a_face()
                    
                        end # proxy class
                      end # module SomePlugin
                    end # module Tomot
                    

                    💭

                    I'm not here much anymore.

                    1 Reply Last reply Reply Quote 0
                    • Dan RathbunD Offline
                      Dan Rathbun
                      last edited by

                      Example 3 : a one-liner (with no error trapping, etc.)

                      Assume @vect is either an Array or a Geom::Vector3d instance:

                      @nface = @oface.parent.entities.add_face(@oface.vertices.map {|v| v.position.offset!(@vect) })
                      

                      I'm not here much anymore.

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

                        @tomot said:

                        That's precisely my problem in a larger nutshell 😄 , I'm trying to use RickW's offset.rb which draws a 2nd offset on the initial "sel" selected face. Since there now 2 faces I'm having difficulty selecting the offset face for pushpull that the offset.rb created, and NOT the initial "sel" selected face for pushpull. (I can post a pic if my description falls short)

                        <span class="syntaxdefault"><br />model&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model<br />entities&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_entities<br />sel&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">selection<br /><br /></span><span class="syntaxcomment">#&nbsp;Grab&nbsp;a&nbsp;list&nbsp;of&nbsp;existing&nbsp;faces<br /></span><span class="syntaxdefault">original_faces&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">grep</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Face</span><span class="syntaxkeyword">)<br /><br /></span><span class="syntaxcomment">#&nbsp;First&nbsp;offset&nbsp;face<br /></span><span class="syntaxdefault">face&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">sel</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">find&nbsp;</span><span class="syntaxkeyword">{&nbsp;|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">is_a</span><span class="syntaxkeyword">?(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Face</span><span class="syntaxkeyword">)&nbsp;}<br /></span><span class="syntaxdefault">offset</span><span class="syntaxkeyword">(&nbsp;</span><span class="syntaxdefault">face</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">20.mm&nbsp;</span><span class="syntaxkeyword">)&nbsp;</span><span class="syntaxcomment">#&nbsp;I&nbsp;don't&nbsp;know&nbsp;what&nbsp;the&nbsp;real&nbsp;method&nbsp;is&nbsp;there.<br /><br />#&nbsp;Then&nbsp;Push-pull&nbsp;inner&nbsp;face<br /></span><span class="syntaxdefault">faces&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">grep</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Face</span><span class="syntaxkeyword">)&nbsp;-&nbsp;</span><span class="syntaxdefault">original_faces<br />inner_face_from_offset&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">faces</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">first&nbsp;</span><span class="syntaxcomment">#&nbsp;*should*&nbsp;be&nbsp;just&nbsp;one&nbsp;face<br /></span><span class="syntaxdefault">inner_face_from_offset</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">pushpull</span><span class="syntaxkeyword">(&nbsp;</span><span class="syntaxdefault">500.mm&nbsp;</span><span class="syntaxkeyword">)<br />&nbsp;</span><span class="syntaxdefault"></span>
                        

                        Untested

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

                        1 Reply Last reply Reply Quote 0
                        • Dan RathbunD Offline
                          Dan Rathbun
                          last edited by

                          @thomthom said:

                          I don't know what the real method is there.

                          It was my Example 1 (above) but Rick's edition was an instance method added to the Sketchup::Face class. (I re-wrote it to pass the face instance into the method.)

                          As shown in my one-liner (Example 3) a method is not really even needed.
                          @oface is the old face in the selection.
                          The new face will be @nface, and then just do the push-pull on it.

                          I'm not here much anymore.

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

                            @dan rathbun said:

                            Example 3 : a one-liner (with no error trapping, etc.)

                            Assume @vect is either an Array or a Geom::Vector3d instance:

                            @nface = @oface.parent.entities.add_face(@oface.vertices.map {|v| v.position.offset!(@vect) })
                            

                            That just offsets in an direction - we're talking about offsetting in terms of what the Offset tool does.

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

                            1 Reply Last reply Reply Quote 0
                            • T Offline
                              tomot
                              last edited by

                              Tig, thomthom and Dan, thanks for your input it will take me a few days to digest your input, and try putting your input into use.
                              but thomthom is right, I'm looking for the statement that allows me to offset the face the offset.rb creates.

                              I was hoping a simple Boolean expression in the API would have served a very useful purpose, in this particular instance. 😢

                              [my plugins](http://thingsvirtual.blogspot.ca/)
                              tomot

                              1 Reply Last reply Reply Quote 0
                              • Dan RathbunD Offline
                                Dan Rathbun
                                last edited by

                                @tomot said:

                                ... but thomthom is right, I'm looking for the statement that allows me to offset the face the offset.rb creates.

                                OK... then first of all the Example 1 re-write of Rick's method mimics the native offset tool, and returns the newly created offset face.

                                (Just ignore Examples 2 & 3, as I did not understand what was needed and may have misunderstood what Rick's code was doing.)

                                If you wish to AGAIN apply an offset, pass the newly created face and a new offset distance (or whatever distance,) into the method a second time.

                                If you wish to move it or something else ... do whatever by using the returned reference as needed.

                                Here is test script wrapped as Tomot::Offset, that adds right-click mouse "Offset Face" commands to the popup menu, but differs in result from the native tool by setting the selection to the new face. (The native tool does not change the selection set.) It also uses an inputbox to get the distance, ... but in practice you would bypass that and your code would supply the needed distance value.

                                module Tomot
                                  module Offset
                                    class << self
                                
                                      def offset_a_face( face, dist )
                                
                                        unless face.is_a?(Sketchup;;Face)
                                          fail(TypeError,"Sketchup;;Face instance expected for 1st argument",caller)
                                        end
                                
                                        unless dist.is_a?(Numeric)
                                          fail(TypeError,"Numeric subclass expected for 2nd argument",caller)
                                        else
                                          if dist.zero?
                                            unless $VERBOSE.nil?
                                              puts("Tomot;;Offset;WARNING; offset_a_face(); Offset distance was zero.")
                                            end
                                            return nil
                                          end
                                        end
                                
                                        new_face = nil # this method's return value
                                
                                        pi = Math;;PI
                                        verts = face.outer_loop.vertices
                                        pts   = []
                                
                                        # CREATE ARRAY pts OF OFFSET POINTS FROM FACE
                                
                                        0.upto(verts.length-1) do |a|
                                          vec1 = (verts[a].position-verts[a-(verts.length-1)].position).normalize
                                          vec2 = (verts[a].position-verts[a-1].position).normalize
                                          vec3 = (vec1+vec2).normalize
                                          if vec3.valid?
                                            ang = vec1.angle_between(vec2)/2
                                            ang = pi/2 if vec1.parallel?(vec2)
                                            vec3.length = dist/Math;;sin(ang)
                                            t = Geom;;Transformation.new(vec3)
                                            if pts.length > 0
                                              vec4 = pts.last.vector_to(verts[a].position.transform(t))
                                              if vec4.valid?
                                                unless (vec2.parallel?(vec4))
                                                  t = Geom;;Transformation.new(vec3.reverse)
                                                end
                                              end
                                            end
                                
                                            pts.push(verts[a].position.transform(t))
                                          end
                                        end
                                
                                        # CHECK FOR DUPLICATE POINTS IN pts ARRAY
                                        #
                                        duplicates = []
                                        pts.each_index do |a|
                                          pts.each_index do |b|
                                            next if b==a
                                            duplicates<<b if pts[a]===pts[b]
                                          end
                                          break if a==pts.length-1
                                        end
                                        duplicates.reverse.each{|a| pts.delete(pts[a])}
                                
                                        # CREATE FACE FROM POINTS IN pts ARRAY
                                        #
                                        if pts.length > 2
                                          begin
                                            #
                                            if Sketchup.version.to_i > 6
                                              face.model.start_operation('Offset Face',true)
                                            else
                                              face.model.start_operation('Offset Face')
                                            end
                                              #
                                              new_face = face.parent.entities.add_face(pts)
                                              #
                                            face.model.commit_operation()
                                            #
                                          rescue
                                            face.model.abort_operation()
                                            raise() # to outer rescue clause
                                          end # begin
                                        end # if
                                
                                      rescue TypeError
                                
                                        raise() # just re-raise the Exception
                                
                                      rescue => e # any other Exceptions;
                                
                                        unless $VERBOSE.nil?
                                          puts("Tomot;;Offset;WARNING; offset_a_face(); #{face.inspect} did not offset; #{pts}")
                                          puts("Error; #<#{e.class.name}; #{e.message}>")
                                          puts(e.backtrace) if $VERBOSE
                                        end
                                        raise() # re-raise to any debugger in use
                                
                                      else # when no errors;
                                
                                        return new_face
                                
                                      end # offset_a_face()
                                      
                                      #{ get_dist(face)
                                      #
                                      #  Prompts for a distance, then calls offset_a_face()
                                      #  If a new offset face is created, it will be set as
                                      #    a single object of the current model's selection.
                                      #
                                      def get_dist(face)
                                        result = UI.inputbox(['Offset distance ;   '],[0],'Offset a Face')
                                        if result
                                          ret = offset_a_face(face,result[0])
                                          if ret
                                            sel = Sketchup.active_model.selection
                                            sel.clear
                                            sel.add(ret)
                                          else
                                            return nil
                                          end
                                        else
                                          return nil
                                        end
                                      end #}
                                
                                    end # proxy class
                                
                                    unless file_loaded?(File.basename(__FILE__))
                                
                                      UI.add_context_menu_handler {|popup|
                                        unless Sketchup.active_model.selection.empty?
                                          sel = Sketchup.active_model.selection
                                          if sel.single_object? && sel[0].is_a?(Sketchup;;Face)
                                            face = sel[0]
                                            popup.add_item('Offset Face',10) { get_dist(face) }
                                          else
                                            face = sel.find {|o| o.is_a?(Sketchup;;Face) }
                                            if face # (nil if no face was selected)
                                              popup.add_item('Offset First Face',11) { get_dist(face) }
                                            end
                                          end
                                        end
                                      }
                                
                                      file_loaded(File.basename(__FILE__))
                                
                                    end
                                
                                  end # module Offset
                                end # module Tomot
                                

                                Question to the room at large: Regarding line 137, which is faster for large selection sets ?
                                face = sel.find {|o| o.is_a?(Sketchup::Face) }
                                OR
                                face = sel.grep(Sketchup::Face)[0]

                                Keep in mind both need to be fololowed by a nil test conditional, viz:
                                if face

                                ❓

                                I'm not here much anymore.

                                1 Reply Last reply Reply Quote 0
                                • T Offline
                                  tomot
                                  last edited by

                                  Dan thanks for your code, however regarding your last piece of code.
                                  I'm unclear as to how to use it.

                                  If I save your code as as offset.rb and replace it with the original offset.rb then load it in the console, I get an error in the console when I right click on selected face.

                                  Is this the way you intended it to be used? Please explain further!
                                  and just to make sure, please see the attachment regarding the face in question.


                                  offset.png

                                  [my plugins](http://thingsvirtual.blogspot.ca/)
                                  tomot

                                  1 Reply Last reply Reply Quote 0
                                  • Dan RathbunD Offline
                                    Dan Rathbun
                                    last edited by

                                    YES, make a selection, then right-click the selection (or a single face,) and an inputbox should pop up to enter a distance.

                                    IF you get an error, it would help if you paste the error message into a post.

                                    I'm not here much anymore.

                                    1 Reply Last reply Reply Quote 0
                                    • T Offline
                                      tomot
                                      last edited by

                                      @dan rathbun said:

                                      IF you get an error, it would help if you paste the error message into a post.

                                      there is also no "offset" reference in the context menu


                                      offset1.png

                                      [my plugins](http://thingsvirtual.blogspot.ca/)
                                      tomot

                                      1 Reply Last reply Reply Quote 0
                                      • Dan RathbunD Offline
                                        Dan Rathbun
                                        last edited by

                                        @Tomot ... you have no profile information showing.

                                        (1) What SketchUp version ?

                                        (2) What SketchUp edition (Free or Pro) ?

                                        (3) What Platform & Operating System ?

                                        Lastly... if you are using an old version that does not support the 2nd ordinal position argument for add_item(), then remove that argument, and the menu items will just be at the end of the popup menu.

                                        The popup menu items are really just for testing... you can directly call the methods just as the menu items do, and remove the popup menu code.

                                        The code is an example.

                                        I'm not here much anymore.

                                        1 Reply Last reply Reply Quote 0
                                        • T Offline
                                          tomot
                                          last edited by

                                          @dan rathbun said:

                                          @Tomot ... you have no profile information showing.

                                          (2) What SketchUp edition (Free or Pro) ?

                                          Pro, My bad its working, after update!

                                          [my plugins](http://thingsvirtual.blogspot.ca/)
                                          tomot

                                          1 Reply Last reply Reply Quote 0
                                          • Dan RathbunD Offline
                                            Dan Rathbun
                                            last edited by

                                            @tomot said:

                                            Pro, My bad its working, after update!

                                            You may also be interested in this from TIG:

                                            [Plugin] TIG-Smart_offset v2.1

                                            I have not tried it, so I do not know if it sets the new offset face as the selection.

                                            TIG ?

                                            I'm not here much anymore.

                                            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