This is a continuation of my grooving tool coding attempts posted here: "Points are no planar" error message when creating a face - #8 by KScher
I would like to ask you to solve another problem that I am facing and I don’t know how to solve it. The tool code works well on unscaled objects. But if I scale the group, the face creation points are calculated incorrectly. How can this be solved for scalable objects?
class GrooveTool
def initialize
@selected_face = nil
@selected_edge = nil
@transformations = []
@step = 1
update_status_text
end
def activate
reset_tool
end
def deactivate(view)
view.invalidate
end
def onMouseMove(flags, x, y, view)
ph = view.pick_helper
ph.do_pick(x, y)
path = ph.path_at(0)
if path
last_entity = path.last
if @step == 1 && last_entity.is_a?(Sketchup::Face)
@selected_face = last_entity
@transformations = compute_transformation(path)
view.invalidate
elsif @step == 2 && last_entity.is_a?(Sketchup::Edge)
@selected_edge = last_entity
@transformations = compute_transformation(path)
view.invalidate
end
end
end
def onLButtonDown(flags, x, y, view)
if @step == 1 && @selected_face
@step = 2
update_status_text
elsif @step == 2 && @selected_edge
prompt_for_groove_parameters
reset_tool
end
view.invalidate
end
def draw(view)
draw_highlight(view)
end
private
def reset_tool
@selected_face = nil
@selected_edge = nil
@transformations = []
@step = 1
update_status_text
end
def update_status_text
Sketchup.status_text = case @step
when 1
"Оберіть площину"
when 2
"Оберіть край на площині"
end
end
def prompt_for_groove_parameters
prompts = ["Groove width (mm)", "Groove depth (mm)", "Groove offset (mm)"]
defaults = ["10", "5", "50"]
input = UI.inputbox(prompts, defaults, "Setting groove")
if input
@groove_width, @groove_depth, @groove_offset = input.map { |value| value.to_f / 25.4 }
create_groove
end
end
def create_groove
return UI.messagebox("Необхідно виділити як площину, так і край!") if @selected_face.nil? || @selected_edge.nil?
model = Sketchup.active_model
points = get_groove_points()
begin
model.start_operation("Create Groove", true)
groove_face = @selected_face.parent.entities.add_face(points)
groove_face.pushpull(-@groove_depth) if groove_face && groove_face.valid?
rescue => e
UI.messagebox("Error creating groove: #{e.message}")
ensure
model.commit_operation
end
end
def get_groove_points
edge_vector = @selected_edge.line[1].normalize
offset_vector = @selected_face.normal * edge_vector
if @groove_offset > 0
offset_vector.length = @groove_offset
test_point = @selected_edge.start.position.offset(offset_vector)
if @selected_face.classify_point(test_point) == Sketchup::Face::PointOutside
offset_vector.reverse!
end
offset_start_point = @selected_edge.start.position.offset(offset_vector)
offset_end_point = @selected_edge.end.position.offset(offset_vector)
offset_vector.length = @groove_width
width_start_point = offset_start_point.offset(offset_vector)
width_end_point = offset_end_point.offset(offset_vector)
else
offset_start_point = @selected_edge.start.position
offset_end_point = @selected_edge.end.position
width_vector = @selected_face.normal * edge_vector
width_vector.length = @groove_width
test_width_point = offset_start_point.offset(width_vector)
if @selected_face.classify_point(test_width_point) == Sketchup::Face::PointOutside
width_vector.reverse!
end
width_start_point = offset_start_point.offset(width_vector)
width_end_point = offset_end_point.offset(width_vector)
end
points = [
offset_start_point, offset_end_point, width_end_point, width_start_point
]
return points
end
def compute_transformation(path)
transformation = Geom::Transformation.new
path.each do |entity|
if entity.respond_to?(:transformation)
transformation *= entity.transformation
end
end
transformation
end
def draw_highlight(view)
if @selected_face
points = @selected_face.outer_loop.vertices.map(&:position)
transformed_points = points.map { |point| point.transform(@transformations) } if @transformations.is_a?(Geom::Transformation)
view.drawing_color = 'yellow'
view.draw(GL_POLYGON, transformed_points)
end
if @selected_edge
points = @selected_edge.vertices.map(&:position)
transformed_points = points.map { |point| point.transform(@transformations) } if @transformations.is_a?(Geom::Transformation)
view.line_width = 5
view.drawing_color = 'blue'
view.draw(GL_LINES, transformed_points)
end
end
end
Sketchup.active_model.select_tool(GrooveTool.new)