### Adjust Tool
#
module Tools2D
class AdjustTool2D

def db(string)
  dir=File.dirname(__FILE__) ### adjust folder to suit tool
  toolname="2Dtools"  ### adjust xxx to suit tool...
  locale=Sketchup.get_locale.upcase
  path=File.join(dir, toolname+locale+".lingvo")
  if not File.exist?(path)
     return string
  else
    deBabelizer(string,path)
  end 
end#def

def getExtents()
    bbox=Sketchup.active_model.bounds
    bbox.add(@ip.position)if @ip and @ip.valid?
    bbox.add(@ip1.position)if @ip1 and @ip1.valid?
    bbox.add(@ip2.position)if @ip2 and @ip2.valid?
    bbox.add(@ip3.position)if @ip3 and @ip3.valid?
    return bbox
end

@@cursor=nil
def initialize()
    @ip1 = nil
    @ip = nil
    @xdown = 0
    @ydown = 0
    @state=0
    @@cursor0=nil
    curpath0=File.join(File.dirname(__FILE__), "Icons", "2Dadjust_cursor0.png")
    @@cursor0=UI::create_cursor(curpath0, 0, 31) if File.exist?(curpath0)
    @@cursor1=nil
    curpath1=File.join(File.dirname(__FILE__), "Icons", "2Dadjust_cursor1.png")
    @@cursor1=UI::create_cursor(curpath1, 0, 31) if File.exist?(curpath1)
end

def activate
    ### get/set reference plane 'z'
    @z=Sketchup.active_model.get_attribute("2Dtools","z",nil)
    Sketchup.active_model.set_attribute("2Dtools","z",0.0.mm)unless @z
    @z=Sketchup.active_model.get_attribute("2Dtools","z",nil)
    ###
    @ip1 = Sketchup::InputPoint.new
    @ip = Sketchup::InputPoint.new
    @drawn = false
    Sketchup.active_model.selection.clear
    @state=0
    self.reset(nil)
    ###
end


def deactivate(view=nil)
    Sketchup::set_status_text("",SB_PROMPT)
    Sketchup::set_status_text("",SB_VCB_LABEL)
    Sketchup::set_status_text("",SB_VCB_VALUE)
    view.invalidate if view
end

def reset(view=nil)
    @state=0
    @edge=nil
    @targets=[]
    @ip.clear
    @ip1.clear
    if view
      view.model.selection.clear
      view.tooltip = nil
      view.invalidate if @drawn
    end
    @edge=nil
    @drawn=false
    @click=false
    @dragging=false ### MOUSE DOWN
    @dragging_msg=db(", Drag for Multiples... ")
    @remove=false
    @remove_msg=db(" Adding: <Shift>=Remove ")
    Sketchup::set_status_text((db("2D Adjust: Select Target Lines... "))+@dragging_msg+(db(" - Double-Click/<Enter> to Adjust Lines")), SB_PROMPT)
    Sketchup::set_status_text("",SB_VCB_LABEL)
end

def onReturn(view)
  view.invalidate
  case @state
   when 0
    if not @targets[0]
      view.invalidate
      Sketchup::set_status_text("",SB_PROMPT)
      Sketchup.send_action("selectSelectionTool:")
    end#if
    Sketchup::set_status_text((db("2D Adjust: Select Lines to Adjust"))+@dragging_msg+(db(" - Double-Click/<Enter> to Select New Target Lines...")), SB_PROMPT)
    Sketchup::set_status_text("",SB_VCB_LABEL)
    @state=1
   when 1
     self.reset(view)
  end#case
end

def onSetCursor()
    #return nil if RUBY_PLATFORM =~ /darwin/
	if @state==0
      UI::set_cursor(@@cursor0) if @@cursor0
    else
      UI::set_cursor(@@cursor1) if @@cursor1
    end#if
end

def onMouseMove(flags, x, y, view)
  case @state
   when 0
    Sketchup::set_status_text((db("2D Adjust: Select Target Lines... "))+@dragging_msg+@remove_msg+(db" - Double-Click/<Enter> to Adjust Lines"), SB_PROMPT)
    Sketchup::set_status_text("",SB_VCB_LABEL)
    @ip.pick view, x, y
    if @ip != @ip1
        view.invalidate if @ip.display? or @ip1.display?
        @ip1.copy! @ip
        view.tooltip = db("Target-Line")#@ip1.tooltip
    end
    # Check if the mouse was moved far enough to find another line.
    # This is used so that you can pick lines by dragging
    if @click and (x-@xdown).abs > 10 || (y-@ydown).abs > 10
        @dragging=true
        @dragging_msg=db("- Select Lines by Dragging Cursor over them...")
    end
    if @click and @dragging
        @edge=self.edge_below_mouse_drag(view,x,y)
        self.target_lines(view)if @edge
    end#if
   when 1
    Sketchup::set_status_text((db("2D Adjust: Select Lines to Adjust"))+@dragging_msg+(db(" - Double-Click/<Enter> to Select New Target Lines...")), SB_PROMPT)
    Sketchup::set_status_text("",SB_VCB_LABEL)
    @ip.pick view, x, y
    if @ip != @ip1
        view.invalidate if @ip.display? or @ip1.display?
        @ip1.copy! @ip
        view.tooltip = db("Line to Adjust")#@ip1.tooltip
    end
    # Check if the mouse was moved far enough to find another line.
    # This is used so that you can pick lines by dragging
    if @click and (x-@xdown).abs > 10 || (y-@ydown).abs > 10
        @dragging=true
        @dragging_msg=db("- Select Lines by Dragging Cursor over them...")
    end
    if @click and @dragging
        @edge=self.edge_below_mouse_drag(view,x,y)
        self.adjust_line(view)if @edge
    end#if
  end#case
end

def onLButtonDown(flags, x, y, view)
  case @state
   when 0
    @click=true
    @ip1.pick view, x, y
    if @ip1.valid?
        p1=@ip1.position;p1.z=@z
        Sketchup::set_status_text((db("2D Adjust: Select Target Lines... "))+@dragging_msg+@remove_msg+(db(" - Double-Click/<Enter> to Adjust Lines")), SB_PROMPT)
        Sketchup::set_status_text("",SB_VCB_LABEL)
        @xdown = x
        @ydown = y
    end
    ### check if extg edge
    ph=view.pick_helper
    ph.do_pick(x,y)
    picked_edge=ph.picked_edge
    ###@edge=nil
    @edge=picked_edge if picked_edge
    ###
    self.target_lines(view) if @edge
    ###
   when 1
    @click=true
    @ip1.pick view, x, y
    if @ip1.valid?
        p1=@ip1.position;p1.z=@z
        Sketchup::set_status_text((db("2D Adjust: Select Lines to Adjust"))+@dragging_msg+(db(" - Double-Click/<Enter> to Select New Target Lines...")), SB_PROMPT)
        Sketchup::set_status_text("",SB_VCB_LABEL)
        @xdown = x
        @ydown = y
    end
    ### check if extg edge
    ph=view.pick_helper
    ph.do_pick(x,y)
    picked_edge=ph.picked_edge
    ###@edge=nil
    @edge=picked_edge if picked_edge
    ###
    self.adjust_line(view)if @edge
  end#case
end

def onLButtonUp(flags, x, y, view)
     # If we are doing a drag, then ? ...
    view.lock_inference
    @dragging=false
    @click=false
    @dragging_msg=db(", Drag for Multiples... ")
    if @remove
        @remove_msg=db(" Removing: <Shift>=Add ")
    else
        @remove_msg=db(" Adding: <Shift>=Remove ")
    end#if
    ### check if any targets left
    still_targets=false
    @targets.each{|e|(still_targets=true; break)if e.valid?}
    self.reset(view)if not still_targets
end

def onLButtonDoubleClick(flags, x, y, view)
      view.invalidate
  case @state
   when 0
    if not @targets[0]
      view.invalidate
      Sketchup::set_status_text("",SB_PROMPT)
      Sketchup.send_action("selectSelectionTool:")
    end#if
    Sketchup::set_status_text((db("2D Adjust: Select Lines to Adjust"))+@dragging_msg+(db(" - Double-Click/<Enter> to Select New Target Lines...")), SB_PROMPT)
    Sketchup::set_status_text("",SB_VCB_LABEL)
    @state=1
   when 1
     self.reset(view)
  end#case
end

def onKeyDown(key, repeat, flags, view)
    if @state==0 and key==VK_SHIFT  ### SHIFT = Toggles Add/remove
      if @remove
        @remove=false; @remove_msg=db(" Adding: <Shift>=Remove ")
      else
        @remove=true; @remove_msg=db(" Removing: <Shift>=Add ")
      end#if
      Sketchup::set_status_text((db("2D Adjust: Select Target Lines... "))+@dragging_msg+@remove_msg+(db(" - Double-Click/<Enter> to Adjust Lines")), SB_PROMPT)
    end#if
end

def resume(view)
  view.invalidate
  case @state
   when 0
    Sketchup::set_status_text((db("2D Adjust: Select Target Lines... "))+@dragging_msg+@remove_msg+(db(" - Double-Click/<Enter> to Adjust Lines")), SB_PROMPT)
    Sketchup::set_status_text("",SB_VCB_LABEL)
   when 1
    Sketchup::set_status_text((db("2D Adjust: Select Lines to Adjust"))+@dragging_msg+(db(" - Double-Click/<Enter> to Select New Target Lines...")), SB_PROMPT)
    Sketchup::set_status_text("",SB_VCB_LABEL)
  end#case
end

def draw(view)
    view.line_width=6
    if @state==0
      view.drawing_color="orangered"
    else
      view.drawing_color="cyan"
    end#if
    @targets.each{|e|view.draw_line(e.start.position,e.end.position)if e.valid?}
end

def edge_below_mouse_drag(view, x, y)
    ph=view.pick_helper
    ph.do_pick(x, y, 10)
	ent=ph.best_picked
	if ent and ent.class==Sketchup::Edge
	    @ip.pick view, x, y
	    return ent
	else
		return nil
	end#if
end

def target_lines(view)
  if @remove
    @targets=@targets-[@edge]
  else
    @targets<<@edge
  end#if
=begin
  ### extras if not a 'vanilla edge'
  if @edge.curve
    if @remove
      @edge.curve.edges.each{|e|@targets=@targets-[e]}
    else
      @edge.curve.edges.each{|e|@targets<<e}
    end#if
  end#if
=end
end#def

def adjust_line(view)
  model=view.model
 model.start_operation(db("Adjust Line"))
  if @edge.valid?
    ents=@edge.parent.entities
  else
    return nil
  end#if
  pt=@ip1.position
  p0=@edge.vertices[0].position;p1=@edge.vertices[1].position
  nearpt=p0;nearpt=p1 if pt.distance(p0)>=pt.distance(p1)
  if not @edge.curve ### ==vanilla edge
    int=self.get_intersection(view)
    if int
      if @edge.faces[0]
        edge=ents.add_line(nearpt,int)##############
        lay=@edge.layer if edge
        mat=@edge.material if edge
        edge.layer=lay if lay
        edge.material=mat if mat
        if @targets.include?(@edge)
          @targets<<edge if edge
        end#if
      else ### lone line
        nearvert=@edge.vertices[0]
        nearvert=@edge.vertices[1]if p0.distance(pt)>p1.distance(pt)
        farvert=@edge.other_vertex(nearvert)
        nearpoint=nearvert.position
        farpoint=farvert.position
        farvert_target=false
        farvert.edges.each{|e|
          if @targets.include?(e) and e!=@edge
            farvert_target=true
            break
          end#if
        }
        if nearpoint==int and farvert_target
          @edge.erase!
          @targets=@targets-[@edge]
        elsif farpoint==int
          @edge.erase!
          @targets=@targets-[@edge]
        else
          @edge.erase!#v3.4 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
          @targets=@targets-[@edge]#v3.4 <<<<<<<<<<<<<<<<<<<<<<<<<<<<
          edge=ents.add_line(farpoint,int)############
          edge.layer=lay if lay
          edge.material=mat if mat
          if @targets.include?(@edge)
            @targets<<edge if edge
          end#if
        end#if
      end#if
    end#if
  else ### part of a Curve
    if not @edge.curve.class==Sketchup::ArcCurve
      puts db("It's a 'Curve'.")
      int=self.get_intersection(view)
     if int and not @edge.faces[0]
        nearvert=@edge.vertices[0]
        nearvert=@edge.vertices[1]if p0.distance(pt)>p1.distance(pt)
        farvert=@edge.other_vertex(nearvert)
        nearpoint=nearvert.position
        farpoint=farvert.position
        farvert_target=false
        farvert.edges.each{|e|
          if @targets.include?(e) and e!=@edge
            farvert_target=true
            break
          end#if
        }
        connected=0
        nearvert.edges.each{|e|connected+=1 if e.curve==@edge.curve}
        if nearpoint==int and farvert_target ### one edge curve !
          @edge.erase!
          @targets=@targets-[@edge]
        elsif connected != 2
          pts=[]
          @edge.curve.vertices.each{|v|pts<<v.position.to_a}
          ct=0;pts.each{|p|
            if p==nearpoint.to_a
              pts[ct]=int
            end#if
            ct+=1
          }
          lay=@edge.layer; mat=@edge.material
          @edge.curve.edges.each{|e|e.erase! if e.valid?}
          curve=ents.add_curve(pts)
          curve.each{|e|e.layer=lay;e.material=mat}
          if @targets.include?(@edge)
            @targets=@targets-[@edge]
            @targets<<curve
            @targets.flatten!.uniq!
          end#if
        else ### mid vertex so add new line...
          edge=ents.add_line(nearpt,int)
          lay=@edge.layer if edge
          mat=@edge.material if edge
          edge.layer=lay if lay
          edge.material=mat if mat
          if @targets.include?(@edge)
            @targets<<edge if edge
          end#if
        end#if
      elsif int and @edge.faces[0]
        edge=ents.add_line(nearpt,int)
        lay=@edge.layer if edge
        mat=@edge.material if edge
        edge.layer=lay if lay
        edge.material=mat if mat
        if @targets.include?(@edge)
          @targets<<edge if edge
        end#if
      end#if
    else ### == Arc / Circle / Polygon
      puts db("It's an ArcCurve...")
      int_edge_s=self.test_intersections(view)
      if not int_edge_s
        puts db("No Intersecting Target Line.")
        return nil
      end#if
      arc=@edge.curve
      an_arc=false
      edgecount=0
      arc.edges.each{|e|edgecount=0
        e.vertices.each{|v|
          v.edges.each{|ee|edgecount+=1 if ee.curve==arc}
        }
        if edgecount<4
          an_arc=true; break
        end#if
      }
      if not an_arc and not @edge.faces[0]
        ### it's  NOT an Arc but == Circle OR Polygon OR it has face(s)
        if self.is_polygon?(arc) ### it's a polygon
          puts db("and it's a Polygon.")
          is_poly=true
        else ### it's a circle - make new arc bit...
          puts db("and it's a Circle.")
          is_poly=false
        end#if 'is_poly' no longer used ???
        ### this 'test' makes these into 'split into 2 parts' so treat as 'arc'...
        arc=@edge.curve
        arc.edges.each{|e|e.erase! if e.valid?}
        ###
      elsif an_arc ### it's an Arc !
        puts db("and it's an Arc.")
        if not @edge.faces[0]
          int_edge_s=test_intersections(view)
          int_edge=nil
          ents.each{|e|int_edge=e if e.class==Sketchup::Edge and e.to_s==int_edge_s}
          ### we know arc should/could intersect target already int_edge.
          ### either 0, 1 or 2 edges of Arc might intersect target...
          ### if 0, extend the arc to the target using pickpoint
          ### if 1, extend from picked end to target OR if target is near picked end erase whole arc
          ### if 2, erase part of arc back to target on picked side using pickpoint
          ### int_edge is intersecting edge with picked edge in arc
          poss_ints=[]### possible intersection points of arc's edges and int_edge
          @edge.curve.edges.each{|e|
            poss_ints<<Geom.intersect_line_line([e.start.position,e.end.position],[int_edge.start.position,int_edge.end.position])
          }
          actual_ints=[]### actual intersections in poss_ints
          poss_ints.each{|p|
            @edge.curve.edges.each{|e|
              actual_ints<<p if p.is_between_points?(e.start.position,e.end.position)
            }if p
          }if poss_ints[0]
          ### we can have 0, 1 or 2 actual points
          arcedges=@edge.curve.edges
          tlines=[]
          actual_ints.each{|p|
            tline=ents.add_line(p,[p.x,p.y,p.z+0.4.mm])
            tlines<<tline
          }
          ### tlines will split the Arc
          arc=@edge.curve
          ### see if broken in bits
          if arcedges != @edge.curve.edges and (@edge != arc.first_edge and @edge != arc.last_edge)
            puts db("Arc broken by Line.")
            puts db("... and Partially Erased...")
            arc.edges.each{|e|e.erase! if e.valid?}if arc.valid?
            arc.edges.each{|e|@targets=@targets-[e]}if arc.valid? and @targets.include?(@edge)
            tlines.each{|e|e.erase! if e.valid? and not e.faces[0]}###tidy up
          else
            ###puts "Arc intact."
            ### find 'loose ends' as might be 'on' int_edge
            loose_ends=[]
            arc.vertices.each{|v|edgct=0
              v.edges.each{|ee|edgct+=1 if ee.curve==arc}
              loose_ends << v.position.to_a if edgct <2
            }
            loose_ends.uniq!
            int_edge=nil
            ents.each{|e|int_edge=e if e.class==Sketchup::Edge and e.to_s==int_edge_s}
            eends=[@edge.start.position,@edge.end.position]
            if loose_ends[1]and loose_ends[0].on_line?([int_edge.start.position,int_edge.end.position]) and loose_ends[1].on_line?([int_edge.start.position,int_edge.end.position])
              puts db("Arc Intersects Target-Line Twice - Erased.")
              arc.edges.each{|e|e.erase! if e.valid?}
              arc.edges.each{|e|@targets=@targets-[e]}if @edge.valid? and @targets.include?(@edge)
            elsif loose_ends[1]and loose_ends[0].on_line?([int_edge.start.position,int_edge.end.position]) and not eends.include?(loose_ends[1])
            ###v3.4
              puts db("Arc Intersects Target-Line Once - Erased [Segment Picked was NOT Extentable]*")
              arc.edges.each{|e|e.erase! if e.valid?}if arc.valid?
              arc.edges.each{|e|@targets=@targets-[e]}if arc.valid? and @targets.include?(@edge)
            elsif loose_ends[1]and loose_ends[1].on_line?([int_edge.start.position,int_edge.end.position]) and not eends.include?(loose_ends[0])
            ###v3.4
              puts db("Arc Intersects Target-Line Once - Erased [Segment Picked was Not Extendable]*")
              arc.edges.each{|e|e.erase! if e.valid?}if arc.valid?
              arc.edges.each{|e|@targets=@targets-[e]}if arc.valid? and @targets.include?(@edge)
            else ### can extend ???###v3.4 as either it doesn't touch target-line OR if one end does the picked segment is extenable...
              connected=false
              if @edge.start!=arc.vertices.first and @edge.start!=arc.vertices.last and@edge.end!=arc.vertices.first and @edge.end!=arc.vertices.last
                #connected=true ##################
                #### omit thi stest for now...
              end#if
              ##################
              if connected ### to other geometry BUT not target-line
                UI.beep
                puts db("A 'Connected' Arc Segment cannot be Extended.")
                puts db("Tip: Draw a 3-point Circle through the Arc")
                puts db("and Erase unwanted parts...")
              else ### it's a lone edge - try to extend
                ### get arc info ready to make new arc
                center=arc.center
                xaxis=arc.xaxis
                normal=arc.normal
                radius=arc.radius
                sang=arc.start_angle
                 eang=arc.end_angle
                sango=sang
                eango=eang
                segs=arc.count_edges
                firstedge=arc.first_edge
                lastedge=arc.last_edge
                firstvert=firstedge.start
                firstvert=firstedge.end if firstvert.edges[1]
                lastvert=lastedge.start
                lastvert=lastedge.end if lastvert.edges[1]
                extdvert=firstvert if firstvert.edges.include?(@edge)
                extdvert=lastvert if lastvert.edges.include?(@edge)
                ### int: intersecting point at 90degrees
                intp=center.project_to_line([int_edge.start.position,int_edge.end.position])
                adj=intp.distance(center)
                ang=Math::acos(adj/radius)
                if normal.z>=0
                  ang= -ang if (sango+eango).abs >=180.degrees ###
                else
                  ang= -ang
                  ang= -ang if (sango+eango).abs >=180.degrees ###
                end#if
                if extdvert==firstvert #############################
                  ang= -ang
                end#if
                endp=center.offset((intp-center),radius)
                tr=Geom::Transformation.rotation(center,normal,ang)
                endp.transform!(tr)
                if extdvert==firstvert
                  #puts "first v"
                  if sango+eango<=180.degrees
                    if normal.z>=0
                       sang=xaxis.angle_between(endp-center)*-1
                    else
                       sang=xaxis.angle_between(endp-center)*-1
                    end#if
                  else
                    #puts ">>>"
                    if normal.z>=0
                       sang=xaxis.angle_between(endp-center)*-1
                    else
                       sang=xaxis.angle_between(endp-center)*1
                    end#if
                  end#if
                else
                  #puts "last v"
                  if sango+eango<=180.degrees
                    if normal.z>=0
                       eang=xaxis.angle_between(endp-center)
                    else
                       eang=360.degrees-xaxis.angle_between(endp-center)
                    end#if
                  else
                    if normal.z>=0
                      #puts ">>>"
                       eang=360.degrees-xaxis.angle_between(endp-center)
                    else
                      #puts ">>>"
                       eang=-360.degrees+xaxis.angle_between(endp-center)
                    end#if
                  end#if                 
                end#if
                ###
                arc.edges.each{|e|e.erase! if e.valid?}
                segs=(segs*(360.degrees)/(eango-sango)).ceil
                ents.add_arc(center,xaxis,normal,radius,sang,eang,segs)
                puts db("Arc Extended.")
                ###
              end#if
            end#if
          end#if
        else ### has faces so treat it differently !!!
          UI.beep
          puts db("Arc is Faced, and cannot be trimmed,")
          puts db("also an Attached Arc cannot be extended.")
          puts db("Tip: Draw a 3-point Circle through the Arc")
          puts db("and Erase unwanted parts...")
          ###
        end#if        
      end#if
    end#if
  end#if
 model.commit_operation
end#def adjust_line

def get_intersection(view)
  pt=@ip1.position
  p0=@edge.vertices[0].position;p1=@edge.vertices[1].position
  nearpt=p0;nearpt=p1 if pt.distance(p0)>=pt.distance(p1)
  farpt=p1;farpt=p0 if pt.distance(p1)>pt.distance(p0)
  ints=[]
  @targets.each{|e|
    if e.valid? and int=Geom::intersect_line_line(@edge.line,e.line)
      ints<<[int.distance(nearpt),int.to_a] if int
    end#if
  }
  ints.sort! ### shortest distance first...
  return nil if not ints[0]
  if ints[1] and ints[0][1].distance(nearpt)==0 ### at least two intersections
    return ints[1][1]### nearest intersection to picked point on edge that's > 0
  else
    return ints[0][1]### nearest intersection to picked point on edge even if ==0
  end#if
end#get_int

def test_intersections(view)
  arc=@edge.curve
  center=arc.center
  radius=arc.radius
  ints=[]
  @targets.each{|e|
    if e.valid?
      int=center.project_to_line(e.line)
      ints<<[int.distance(center),int.to_a,e.to_s]if int.distance(center)<radius
    end#if
  }
  ints.sort! ### shortest distance first...
  return nil if not ints[0]
  return ints[0][2]### nearest intersecting edge to picked point on edge even if ==0
end#get_arc_int

def is_polygon?(curve)
    curve.edges.each{|e|
      e.vertices.each{|v|
        if not v.edges[1]
          return false ### it's an arc
          break
        end#if
      }
    }
    ### if we get here it might be a polygon !!!
    model=Sketchup.active_model
    entities=model.active_entities
    edge=curve.edges[0]
    all_connected=edge.all_connected
    tgroup=entities.add_group(all_connected)
    es=edge.start.position
    ee=edge.end.position
    group=tgroup.copy
    tgroup.explode
    gents=group.entities
    gedges=[]
    gents.each{|e|gedges<<e if e.class==Sketchup::Edge}
    gedge=nil
    gedges.each{|e|
      e.smooth=false
      e.soft=false
      gedge=e if (e.start.position==es and e.end.position==ee)or(e.start.position==ee and e.end.position==es)}
    ### remove all faces so only face and pushpull's remain
    gents.each{|e|e.erase! if e.class==Sketchup::Face}
    gedge.find_faces
    face=nil
    gents.each{|e|face=e if e.class==Sketchup::Face}
    return false if not face
    face.pushpull(1.0)
    edges=[]
    gents.each{|e|edges<<e if e.class==Sketchup::Edge}
    edges.each{|e|
      if e.smooth? and e.soft?
        group.erase! if group.valid?
        return false ### a circle
      end#if
    }
    group.erase! if group.valid?
    return true ### a polygon
end#def

class Geom::Point3d
	def is_between_points?(pt1,pt2)
		d1=(self.distance(pt1)+self.distance(pt2))
		d2=pt1.distance(pt2)+0
		if (d1<=d2) or (d1-d2<1e-10)
	      return true #if self != pt1 and self != pt2
		end
		return false
    end#def
end #class Geom::Point3d

end#class

end#mod
#-----------------------------------------------------------------------------
# shortcut
#def adjusttool2D
   #Sketchup.active_model.select_tool AdjustTool2D.new
#end
######-----------------------------------------------
