Double Offset

Double Offset

Postby Pixero » Fri Feb 09, 2018 11:22 am

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

Re: Double Offset

Postby samnorth » Fri Feb 09, 2018 12:11 pm

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
0

samnorth 
Premium Member
Premium Member
 

Re: Double Offset

Postby pilou » Fri Feb 09, 2018 1:20 pm

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! ;)

2
Frenchy Pilou
Is beautiful that please without concept!
Speedy Galerie
User avatar
pilou 
Top SketchUcator
 

Re: Double Offset

Postby Pixero » Fri Feb 09, 2018 2:07 pm

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.
0
User avatar
Pixero 
 

Re: Double Offset

Postby pilou » Fri Feb 09, 2018 2:33 pm

Maybe you can ask Sdmitch to modify its plugin for have repetition of the function at each new selection ?
0
Frenchy Pilou
Is beautiful that please without concept!
Speedy Galerie
User avatar
pilou 
Top SketchUcator
 

Re: Double Offset

Postby CadFather » Sat Feb 10, 2018 8:36 pm

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
0
Quarr-IT - SketchUp Training from the Master.. http://quarr-it.com/
User avatar
CadFather 
PluginStore Author
PluginStore Author
 

Re: Double Offset

Postby Pixero » Sun Feb 11, 2018 10:06 am

Yes please post the modified code.
0
User avatar
Pixero 
 

Re: Double Offset

Postby CadFather » Sun Feb 11, 2018 10:31 pm

hope TIG is ok with it:

main 2 routines:

Code: Select all

@@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
0
Quarr-IT - SketchUp Training from the Master.. http://quarr-it.com/
User avatar
CadFather 
PluginStore Author
PluginStore Author
 

SketchUcation One-Liner Adverts

by Ad Machine » 5 minutes ago



Ad Machine 
Robot
 



 

Return to Plugins

Who is online

Users browsing this forum: No registered users and 12 guests

Visit our sponsors: