• Login
sketchucation logo sketchucation
  • Login
⚠️ Libfredo 15.4b | Minor release with bugfixes and improvements Update

Double Offset

Scheduled Pinned Locked Moved Plugins
8 Posts 4 Posters 1.4k 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.
  • P Offline
    Pixero
    last edited by 9 Feb 2018, 10:22

    Is there a plugin that works like the offset tool but offsets the edge to both directions at once?

    1 Reply Last reply Reply Quote 0
    • S Offline
      samnorth
      last edited by 9 Feb 2018, 11:11

      Perhaps Offset Loops [hidden] in dropdown menu of Quad Face Tools? Use Control key to get the dual offset. I think TT said previously it's still in development and it's not very robust.

      tut here from Winning with SU
      https://www.youtube.com/watch?v=1fwkI_shOcQ&t=641s

      1 Reply Last reply Reply Quote 0
      • P Offline
        pilou
        last edited by 9 Feb 2018, 12:20

        @unknownuser said:

        Is there a plugin that works like the offset tool but offsets the edge to both directions at once?

        Sure! 😄
        By Sdmitch : MULTIPLE Offsets has this function inside! And many more! 😉

        Frenchy Pilou
        Is beautiful that please without concept!
        My Little site :)

        1 Reply Last reply Reply Quote 0
        • P Offline
          Pixero
          last edited by 9 Feb 2018, 13:07

          Thanks for the ideas. The Offset loops keep crashing for me and the multiple offset script isn't in "realtime" like the offset tool in SU but I'll look into them.

          1 Reply Last reply Reply Quote 0
          • P Offline
            pilou
            last edited by 9 Feb 2018, 13:33

            Maybe you can ask Sdmitch to modify its plugin for have repetition of the function at each new selection ?

            Frenchy Pilou
            Is beautiful that please without concept!
            My Little site :)

            1 Reply Last reply Reply Quote 0
            • C Offline
              CadFather
              last edited by 10 Feb 2018, 19:36

              TIG's offset can do it - i modified the code to repeat the steps one positive and one negative values. works well, though there are some odd imprecisions.

              https://sketchucation.com/forums/viewtopic.php?p=331303#p331303

              let me know if you want the code pasted in too

              1 Reply Last reply Reply Quote 0
              • P Offline
                Pixero
                last edited by 11 Feb 2018, 09:06

                Yes please post the modified code.

                1 Reply Last reply Reply Quote 0
                • C Offline
                  CadFather
                  last edited by 11 Feb 2018, 21:31

                  hope TIG is ok with it:

                  main 2 routines:

                  
                  
                  @@dist=nil
                  
                    
                   def initialize(dist=nil)
                     @toolname="extrudeEdgesByOffset"
                     if dist==0
                       puts 'Extrude Edges by Offset' + '; Offset cannot be 0.'
                       return nil
                     end#if
                     model=Sketchup.active_model
                     ss=model.selection
                     edges=[]
                     ss.each{|e|edges << e if e.class==Sketchup;;Edge}
                     if not edges[1]
                       if not dist
                         UI.messagebox('Extrude Edges by Offset') + ('; Must Select >=2 Edges.')
                       else
                         puts 'Extrude Edges by Offset' + '; Must Select >=2 Edges.'
                       end
                       return nil
                     end#if
                     verts=[]
                     edges.each{|e| verts << e.vertices}
                     verts.flatten!
                     verts.uniq!
                     pts=[]
                     verts.each{|v| pts << v.position}
                     cop=true
                     vec=Geom;;Vector3d.new(0,0,0)
                     edges[0..-2].each_with_index{|e,i| vec=e.line[1].cross(edges[i+1].line[1])}
                     vec=Z_AXIS.clone if vec.length==0 ### all in line
                     plane=[pts[0],vec]
                     pts.each{|p|
                       if not p.on_plane?(plane)
                         cop=false
                         break
                       end
                     }
                     if not dist
                       if not cop
                         UI.messagebox('Extrude Edges by Offset') + ('; Edges must be coplanar.')
                         return nil
                       end
                       @@dist=0.to_l if not @@dist
                       Sketchup;;set_status_text(("Extrude Edges by Offset")+"; "+("Distance; "), SB_PROMPT)
                       results=inputbox(["Distance; "],[@@dist],"Extrude Edges by Offset"+"...")
                       return nil if not results
                       if results[0]==0
                         UI.messagebox('Extrude Edges by Offset'+'; Offset cannot be 0!'+"\n"+"Try again"+"...")
                         results=inputbox(["Distance; "],[@@dist],"Extrude Edges by Offset"+"...")
                         return nil if not results or results[0]==0
                       end#if
                       @@dist=results[0]
                     else ### dist passed as arg
                       if not cop
                         puts 'Extrude Edge by Offset'+'; Edges must be coplanar.'
                         return nil
                       end
                       @@dist=dist.to_l
                     end#if
                     ###
                     model.start_operation("Extrude Edges by Offset"+' '+@@dist.to_s)
                     dist=@@dist
                     group=model.active_entities.add_group()
                     ents=group.entities
                     ###
                     if edges.length==verts.length ### looped
                       ###
                       tface=ents.add_face(pts)
                       ###
                  	 fverts=tface.outer_loop.vertices
                  	 fpts=[]
                  		0.upto(fverts.length-1) do |a|
                  			vec1=(fverts[a].position-fverts[a-(fverts.length-1)].position).normalize
                  			vec2=(fverts[a].position-fverts[a-1].position).normalize
                  			vec3=(vec1+vec2).normalize
                  			if vec3.valid?
                  				ang=vec1.angle_between(vec2)/2
                  				ang=180.degrees if vec1.parallel?(vec2)
                  				vec3.length=dist/Math;;sin(ang)
                  				t=Geom;;Transformation.new(vec3)
                  				if fpts.length > 0
                  					if not (vec2.parallel?(fpts.last.vector_to(fverts[a].position.transform(t))))
                  						t=Geom;;Transformation.new(vec3.reverse)
                  					end
                  				end
                  				fpts << fverts[a].position.transform(t)
                  			end
                  		end
                  	  nface=ents.add_face(fpts)
                        tface.erase! if tface.valid? and dist>0
                        nface.erase! if nface.valid? and dist<0
                        face=nil; ents.each{|e|face=e if e.class==Sketchup;;Face}
                        face.reverse! if face.normal.z<0
                        ol=face.outer_loop
                        verts=ol.vertices if dist<0
                        il=(face.loops-[ol])[0]
                        verts=il.vertices if dist>0
                        verts.each_with_index{|vert,a|
                                  vec1=(verts[a].position.vector_to(verts[a-(verts.length-1)].position)).normalize
                  				vec2=(verts[a].position.vector_to(verts[a-1].position)).normalize
                  				vec3=(vec1+vec2).normalize
                  				if vec3.valid?
                  					ang=vec1.angle_between(vec2)/2
                  					ang=90.degrees if vec1.parallel?(vec2)
                  					vec3.length= -dist/Math;;sin(ang)
                  					t=Geom;;Transformation.new(vec3)
                                      p=verts[a].position
                  					pt=p.transform(t)
                                      ents.add_line(p,pt)
                  				end
                        }
                        ###
                        tr=Geom;;Transformation.new()
                        len=ents.length
                        len.times{ents.intersect_with(true, tr, ents, tr, true, ents.to_a)}
                        ###
                        cedges=[]; ents.each{|e|cedges << e if e.class==Sketchup;;Edge}
                        ###
                      else ### open ended
                        ###
                        edges.each{|e|ents.add_line(e.start.position, e.end.position)}
                        edges=ents.to_a
                        es=[]
                        ee=[]
                        se=[]
                        edges.each{|e|
                          if not e.start.edges[1]
                            es=e.start
                            ee=e.end
                            se=e
                            break
                          elsif not e.end.edges[1]
                            es=e.end
                            ee=e.start
                            se=e
                            break
                          end#if
                        }
                        nedges=[se]
                        verts=[es,ee]
                        (edges.length-1).times{
                          edges.each{|e|
                            next if nedges.include?(e)
                            if e.start==ee
                              verts << e.vertices
                              ee=e.end
                              nedges << e
                            elsif e.end==ee
                              verts << e.vertices
                              ee=e.start
                              nedges << e
                            end
                          }
                        }
                        verts.flatten!
                        verts.uniq!
                        ###
                        opts=[]
                        verts.each_with_index{|vert,a|
                          if a==0 #special case for start vertex
                  				v=verts[a].position.vector_to(verts[a+1].position).normalize
                  				f=dist/dist.abs
                  				t=Geom;;Transformation.rotation(verts[0].position, vec, 90.degrees*f)
                  				vec3=v.transform(t)
                  				vec3.length=dist.abs
                  				opts << verts[a].position.transform(vec3)
                  	    elsif a==verts.length-1 #special case for end vertex
                  				v=verts[a-1].position.vector_to(verts[a].position).normalize
                  				f=dist/dist.abs
                  				t=Geom;;Transformation.rotation(verts[a].position, vec, 90.degrees*f)
                  				vec3=v.transform(t)
                  				vec3.length=dist.abs
                  				opts << verts[a].position.transform(vec3)
                  		else
                  				vec1=(verts[a].position.vector_to(verts[a+1].position)).normalize
                  				vec2=(verts[a].position.vector_to(verts[a-1].position)).normalize
                  				vec3=(vec1+vec2).normalize
                  				if vec3.valid?
                  					ang=vec1.angle_between(vec2)/2
                  					ang=90.degrees if vec1.parallel?(vec2)
                  					vec3.length=dist/Math;;sin(ang)
                  					t=Geom;;Transformation.new(vec3)
                  					if not vec2.parallel?(opts[-1].vector_to(verts[a].position.transform(t)))
                  					  t=Geom;;Transformation.new(vec3.reverse)
                  					end
                  					opts << verts[a].position.transform(t)
                  				end
                  		end#if
                        }
                        begin
                          nedges=ents.add_edges(opts)
                        rescue
                          nedges=[]
                        end
                        pts=[]
                        verts.each{|v|pts << v.position}
                        ents.erase_entities(edges)
                        begin
                          edges=ents.add_edges(pts)
                        rescue
                          edges=[]
                        end
                        pts.each_with_index{|p,i|ents.add_line(pts[i],opts[i])}
                        ###
                        tr=Geom;;Transformation.new()
                        len=ents.length
                        len.times{ents.intersect_with(true, tr, ents, tr, true, ents.to_a)}
                        ###
                        cedges=[]; ents.each{|e|cedges << e if e.class==Sketchup;;Edge}
                        cedges.length.times{
                          ents.to_a.each{|e|
                            next if e.class!=Sketchup;;Edge or not e.valid?
                            e.find_faces
                          }
                        }
                        ents.to_a.each{|e|e.reverse! if e.class==Sketchup;;Face and e.normal.z<0}
                        ###
                      end#if
                      ###
                  
                  
                      model.commit_operation
                  
                        
                  # CREATE  REVERSE GROUP
                        
                      
                       model.start_operation("Extrude Edges by Offset - Reverse Side"+' '+@@dist.to_s)
                     dist=@@dist*-1
                     group=model.active_entities.add_group()
                     ents=group.entities
                     ###
                     if edges.length==verts.length ### looped
                       ###
                       tface=ents.add_face(pts)
                       ###
                  	 fverts=tface.outer_loop.vertices
                  	 fpts=[]
                  		0.upto(fverts.length-1) do |a|
                  			vec1=(fverts[a].position-fverts[a-(fverts.length-1)].position).normalize
                  			vec2=(fverts[a].position-fverts[a-1].position).normalize
                  			vec3=(vec1+vec2).normalize
                  			if vec3.valid?
                  				ang=vec1.angle_between(vec2)/2
                  				ang=180.degrees if vec1.parallel?(vec2)
                  				vec3.length=dist/Math;;sin(ang)
                  				t=Geom;;Transformation.new(vec3)
                  				if fpts.length > 0
                  					if not (vec2.parallel?(fpts.last.vector_to(fverts[a].position.transform(t))))
                  						t=Geom;;Transformation.new(vec3.reverse)
                  					end
                  				end
                  				fpts << fverts[a].position.transform(t)
                  			end
                  		end
                  	  nface=ents.add_face(fpts)
                        tface.erase! if tface.valid? and dist>0
                        nface.erase! if nface.valid? and dist<0
                        face=nil; ents.each{|e|face=e if e.class==Sketchup;;Face}
                        face.reverse! if face.normal.z<0
                        ol=face.outer_loop
                        verts=ol.vertices if dist<0
                        il=(face.loops-[ol])[0]
                        verts=il.vertices if dist>0
                        verts.each_with_index{|vert,a|
                                  vec1=(verts[a].position.vector_to(verts[a-(verts.length-1)].position)).normalize
                  				vec2=(verts[a].position.vector_to(verts[a-1].position)).normalize
                  				vec3=(vec1+vec2).normalize
                  				if vec3.valid?
                  					ang=vec1.angle_between(vec2)/2
                  					ang=90.degrees if vec1.parallel?(vec2)
                  					vec3.length= -dist/Math;;sin(ang)
                  					t=Geom;;Transformation.new(vec3)
                                      p=verts[a].position
                  					pt=p.transform(t)
                                      ents.add_line(p,pt)
                  				end
                        }
                        ###
                        tr=Geom;;Transformation.new()
                        len=ents.length
                        len.times{ents.intersect_with(true, tr, ents, tr, true, ents.to_a)}
                        ###
                        cedges=[]; ents.each{|e|cedges << e if e.class==Sketchup;;Edge}
                        ###
                      else ### open ended
                        ###
                        edges.each{|e|ents.add_line(e.start.position, e.end.position)}
                        edges=ents.to_a
                        es=[]
                        ee=[]
                        se=[]
                        edges.each{|e|
                          if not e.start.edges[1]
                            es=e.start
                            ee=e.end
                            se=e
                            break
                          elsif not e.end.edges[1]
                            es=e.end
                            ee=e.start
                            se=e
                            break
                          end#if
                        }
                        nedges=[se]
                        verts=[es,ee]
                        (edges.length-1).times{
                          edges.each{|e|
                            next if nedges.include?(e)
                            if e.start==ee
                              verts << e.vertices
                              ee=e.end
                              nedges << e
                            elsif e.end==ee
                              verts << e.vertices
                              ee=e.start
                              nedges << e
                            end
                          }
                        }
                        verts.flatten!
                        verts.uniq!
                        ###
                        opts=[]
                        verts.each_with_index{|vert,a|
                          if a==0 #special case for start vertex
                  				v=verts[a].position.vector_to(verts[a+1].position).normalize
                  				f=dist/dist.abs
                  				t=Geom;;Transformation.rotation(verts[0].position, vec, 90.degrees*f)
                  				vec3=v.transform(t)
                  				vec3.length=dist.abs
                  				opts << verts[a].position.transform(vec3)
                  	    elsif a==verts.length-1 #special case for end vertex
                  				v=verts[a-1].position.vector_to(verts[a].position).normalize
                  				f=dist/dist.abs
                  				t=Geom;;Transformation.rotation(verts[a].position, vec, 90.degrees*f)
                  				vec3=v.transform(t)
                  				vec3.length=dist.abs
                  				opts << verts[a].position.transform(vec3)
                  		else
                  				vec1=(verts[a].position.vector_to(verts[a+1].position)).normalize
                  				vec2=(verts[a].position.vector_to(verts[a-1].position)).normalize
                  				vec3=(vec1+vec2).normalize
                  				if vec3.valid?
                  					ang=vec1.angle_between(vec2)/2
                  					ang=90.degrees if vec1.parallel?(vec2)
                  					vec3.length=dist/Math;;sin(ang)
                  					t=Geom;;Transformation.new(vec3)
                  					if not vec2.parallel?(opts[-1].vector_to(verts[a].position.transform(t)))
                  					  t=Geom;;Transformation.new(vec3.reverse)
                  					end
                  					opts << verts[a].position.transform(t)
                  				end
                  		end#if
                        }
                        begin
                          nedges=ents.add_edges(opts)
                        rescue
                          nedges=[]
                        end
                        pts=[]
                        verts.each{|v|pts << v.position}
                        ents.erase_entities(edges)
                        begin
                          edges=ents.add_edges(pts)
                        rescue
                          edges=[]
                        end
                        pts.each_with_index{|p,i|ents.add_line(pts[i],opts[i])}
                        ###
                        tr=Geom;;Transformation.new()
                        len=ents.length
                        len.times{ents.intersect_with(true, tr, ents, tr, true, ents.to_a)}
                        ###
                        cedges=[]; ents.each{|e|cedges << e if e.class==Sketchup;;Edge}
                        cedges.length.times{
                          ents.to_a.each{|e|
                            next if e.class!=Sketchup;;Edge or not e.valid?
                            e.find_faces
                          }
                        }
                        ents.to_a.each{|e|e.reverse! if e.class==Sketchup;;Face and e.normal.z<0}
                        ###
                      end#if
                      ###
                      model.commit_operation
                      
                    Sketchup.send_action("selectSelectionTool;")
                    end#def
                  
                  
                  1 Reply Last reply Reply Quote 0
                  • 1 / 1
                  1 / 1
                  • First post
                    1/8
                    Last post
                  Buy SketchPlus
                  Buy SUbD
                  Buy WrapR
                  Buy eBook
                  Buy Modelur
                  Buy Vertex Tools
                  Buy SketchCuisine
                  Buy FormFonts

                  Advertisement