Taken from KScher’s topic I want to get the desired points! I’m a newbie and really need help with the code as well as instructions on how to write this code.
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
I’m sorry, I’m not yet proficient in how to post and reply even though I’ve consulted the guidelines.
I repeated DanRathbun’s method and created 2 D35 margin hole drilling vectors, but the problem happened again: the coordinate axis was not as expected.
class GrooveToolA
def initialize
@selected_face = nil
@selected_edge = nil
@transformations = IDENTITY
@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) # get the path to the selected element
if path
last_entity = path.last
if @step == 1 && last_entity.is_a?(Sketchup::Face)
@selected_face = last_entity
@selected_path = path # keep the path to the face
@transformations = ph.transformation_at(0)
elsif @step == 2 && last_entity.is_a?(Sketchup::Edge) && @selected_face.edges.include?(last_entity)
@selected_edge = last_entity
# There is no need to store the path to the edge, as it must be in the same context as the face
end
end
view.invalidate
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 = IDENTITY
@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", "21.5"]
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
get_groove_points
#points = get_groove_points()
model.start_operation("Create Groove", true)
# We define the context based on the stored path
container = @selected_path[-2] # The penultimate element in the path is the parent container
entities = nil
if container.is_a?(Sketchup::ComponentInstance) || container.is_a?(Sketchup::Group)
# We make the container unique if it is not the root context of the model
unique_container = container.make_unique
entities = unique_container.definition.entities
else
entities = model.active_entities # If not in a group or component, we use the model context
end
if entities
a_layer = model.layers.add("ABF-D35")
model.active_layer = a_layer
#-----------------------------------------------------------------
@cachmep = 100.mm
group_line_1 = entities.add_group
group_face_1 = entities.add_group
@line_1 = group_line_1.entities.add_line(@pt1, @pt4)
@face_1 = group_face_1.entities.add_face(@pt1, @pt2, @pt3, @pt4)
group_line_1.erase!
group_face_1.erase!
line_vector_1 = @line_1.line[1].normalize
offset_vector_1 = @face_1.normal * line_vector_1
offset_vector_1.length = @cachmep / scale_factor(offset_vector_1)
test_point_1 = @pt1.offset(offset_vector_1)
if @face_1.classify_point(test_point_1) == Sketchup::Face::PointOutside
offset_vector_1.reverse!
end
start_point_1 = @pt1.offset(offset_vector_1)
end_point_1 = @pt4.offset(offset_vector_1)
radius_1 = 17.5.mm / scale_factor(offset_vector_1)
group1 = entities.add_group
group1.name = "ABF_D35"
group1.material = "orange"
circle1 = group1.entities.add_circle(start_point_1, @face_1.normal, radius_1)
#-----------------------------------------------------------------
group_line_2 = entities.add_group
group_face_2 = entities.add_group
@line_2 = group_line_2.entities.add_line(@pt2, @pt3)
@face_2 = group_face_2.entities.add_face(@pt1, @pt2, @pt3, @pt4)
group_line_2.erase!
group_face_2.erase!
line_vector_2 = @line_2.line[1].normalize
offset_vector_2 = @face_2.normal * line_vector_2
offset_vector_2.length = @cachmep / scale_factor(offset_vector_2)
test_point_2 = @pt2.offset(offset_vector_2)
if @face_2.classify_point(test_point_2) == Sketchup::Face::PointOutside
offset_vector_2.reverse!
end
start_point_2 = @pt2.offset(offset_vector_2)
end_point_2 = @pt3.offset(offset_vector_2)
radius_2 = 17.5.mm / scale_factor(offset_vector_2)
group2 = entities.add_group
group2.name = "ABF_D35"
group2.material = "orange"
circle2 = group2.entities.add_circle(start_point_2, @face_2.normal, radius_2)
#-----------------------------------------------------------------
layer0 = model.layers.add("Layer0")
model.active_layer = layer0
#-----------------------------------------------------------------
else
UI.messagebox("Не вдалося ідентифікувати контекст для створення пазу.")
end
model.commit_operation
end
# This method will calculate a scale factor at the direction of
# given vector
def scale_factor(vector)
vector.normalize.transform(@transformations).length.to_f
end
def get_groove_points
edge_vector = @selected_edge.line[1].normalize
offset_vector = @selected_face.normal * edge_vector
offset_vector.length = @groove_offset / scale_factor(offset_vector)
# Checking if an offset point lies on a face
test_point = @selected_edge.start.position.offset(offset_vector)
if @selected_face.classify_point(test_point) == Sketchup::Face::PointOutside
offset_vector.reverse!
end
# Apply offset to create groove start points
offset_start_point = @selected_edge.start.position.offset(offset_vector)
offset_end_point = @selected_edge.end.position.offset(offset_vector)
# Determination of additional points for forming the width of the groove
offset_vector.length = @groove_width / scale_factor(offset_vector)
width_start_point = offset_start_point.offset(offset_vector)
width_end_point = offset_end_point.offset(offset_vector)
@pt1 = offset_start_point
@pt2 = offset_end_point
@pt3 = width_end_point
@pt4 = width_start_point
#puts points.inspect
#return points
end
# This method wont be used...
def compute_transformation(path)
transformation = Geom::Transformation.new
path.each do |entity|
if entity.respond_to?(:transformation)
transformation *= entity.transformation
end
end
transformation
# ... however an alternative one-liner method:
# transformation = path[0..-2].map(&:transformation).inject(IDENTITY, :*)
end
def draw_highlight(view)
if @selected_face
points = @selected_face.outer_loop.vertices.map(&:position)
transformed_points = points.map { |point| point.transform(@transformations) }
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) }
view.line_width = 5
view.drawing_color = 'blue'
view.draw(GL_LINES, transformed_points)
end
end
end
Sketchup.active_model.select_tool(GrooveToolA.new)