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…
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.
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:
SU2015:
I’m still interested how can you “remember”, and how to go back to e.g. parallel or perpendicular lock?