How to determine "From Point" and "Constrained on Line" in Ruby?

Okay. I think I’ve got something…
The code below may not that clear as professional’s made, but at least it is doing what I wanted… and again sorry about the my ugly variable names, and missing comments… :slight_smile:
Any suggestion, mistake correction or improvement recommendation are welcome!
The complete operations are wrapped into one start_operation / commit_operation, just for now, but real implementation most likely will be different…

Some explanation shortly: It is more or less clear now that SU native inference will catch the axes even there are no edge drawn there, but could not catch the line determined only by two Point3d or InputPoint. Therefor if I want to catch inference line which is not on axes, I have to “turn” one of the axis “under his arm”. From SU version 2016 it is possible, but in older versions I must use an other workaround: put ConstructionLine and give some extra job to user. :wink:

class Tool_lock_to_face_normal
SU_VER_OK = ( Sketchup.version.to_i >= 16 )? true : false unless defined? SU_VER_OK
  def initialize
    @ip = Sketchup::InputPoint.new
    # Remember for original axes !! Note: SU version !! 
    if SU_VER_OK
      @orig_origin, @orig_xaxis, @orig_yaxis, @orig_zaxis = Sketchup.active_model.axes.to_a
    else
      puts "I'm  too old to do this on sloped face :-)" 
    end
    Sketchup.active_model.start_operation('Lock_test', true)
  end
  
  def reset(view)
    view.lock_inference
    @cline.erase! if @cline && @cline.valid?
    view.invalidate
    Sketchup.active_model.axes.set(@orig_origin, @orig_xaxis, @orig_yaxis, @orig_zaxis) if SU_VER_OK 
  end
  def onCancel(reason, view)
    reset(view)
  end
  def deactivate(view)
    reset(view)
    Sketchup.active_model.commit_operation
  end  
  def getExtents
    bb = Geom::BoundingBox.new
    bb.add(@ip.position)
    bb      
  end  
  
  def onMouseMove(flags, x, y, view)
    @ip.pick(view, x, y)
    @line = inference_line(@ip, view) if @ip.face
    view.invalidate
    p "inf_locked: #{view.inference_locked?}"
  end

  def onKeyDown(key, repeat, flags, view)
  puts "k"
    if( key == CONSTRAIN_MODIFIER_KEY )
      if( view.inference_locked? )
        view.lock_inference
      else
        view.lock_inference(@ip)
      end
    end 
  end
  
  def draw(view)
    draw_line(@line, view)
    @ip.draw(view)
    view.tooltip = @ip.tooltip
    #just to see where are we...
    view.draw_points( @ip.position, 5, 4, "blue" ) if @ip
    view.draw_points( @ip_av.position, 5, 2, "orange" ) if @ip_av
    view.draw_points( @ip_avo.position, 5, 1, "red" ) if @ip_avo
    if !SU_VER_OK && !view.inference_locked? && @line
      view.draw_text(view.screen_coords(@ip.position), "\n\nI told you, I can't infer to this sloped face!\nDo it yourself with Shift key!\nYou've got a helpline." ) 
    end
  end

  def inference_line(ip, view)
      vn =  ip.face.vertices.length
      all = ORIGIN
      ip.face.vertices.each{|v| all += ORIGIN.vector_to(v.position)}
      av = Geom::Point3d.new( all.x/vn, all.y/vn, all.z/vn )  
      avo = av.offset(ip.face.normal)
      inf_line = [av, (av - avo).normalize]
      @ip_av=Sketchup::InputPoint.new(av)
      @ip_avo=Sketchup::InputPoint.new(avo)
      para = ( ip.face.normal.parallel?(X_AXIS) || ip.face.normal.parallel?(Y_AXIS) || ip.face.normal.parallel?(Z_AXIS) )? true : false
      Sketchup.active_model.axes.set(@orig_origin, @orig_xaxis, @orig_yaxis, @orig_zaxis) if para && SU_VER_OK
      if SU_VER_OK 
        unless para
          new_origin = av
          new_zaxis = ip.face.normal
          new_xaxis = new_zaxis.axes[0]
          new_yaxis = new_zaxis.axes[1]       
          Sketchup.active_model.axes.set(new_origin, new_xaxis, new_yaxis, new_zaxis) 
        end
      else
        @cline.erase! if @cline && @cline.valid?
        @cline = Sketchup.active_model.active_entities.add_cline(av, (av - avo)) unless para
      end
      view.lock_inference(@ip_av,@ip_avo)
      return inf_line
  end

  def draw_line(line, view)
    return unless line
    view.line_width = 3
    view.set_color_from_line(line[0], @ip.position )
    view.draw(GL_LINES, line[0], @ip.position)
  end
end
Sketchup.active_model.select_tool(Tool_lock_to_face_normal.new)

SU2018:
lock_test_SU2018
SU2015:
lock_test_SU2015s


I’m still interested how can you “remember”, and how to go back to e.g. parallel or perpendicular lock?

1 Like