Fix and improve the code
-
Please help me to fix and improve the code.
I have a problem with calculating the dimensions of scaled objects and objects rotated relative to global axes.
First, the code was written, which uses the method of calculating the dimensions of the object by the points of the edges (thanks for the tip from the official Sketchup forum). And this method works well with objects rotated relative to global axes.
Here is the code.
This code calculates dimensions correctly in rotated relative to global axes, but incorrectly in scaled objects.class TestTool def initialize @ip = Sketchup;;InputPoint.new @hovered_inst = nil end def onMouseMove(flags, x, y, view) @ip.pick(view, x, y) @ph = view.pick_helper @in_path = @ip.face ? @ip.face.parent.instances ; nil @hovered_inst = @in_path&.first if @in_path view.invalidate end def draw(view) @ip.draw(view) if @ip.valid? view.draw_points(@ip.position, 40, 5, "red") if @ip.valid? view.tooltip = @hovered_inst&.name if @hovered_inst.is_a?(Sketchup;;Group) || @hovered_inst.is_a?(Sketchup;;ComponentInstance) entity = @hovered_inst edges = entity.definition.entities.select { |e| e.is_a?(Sketchup;;Edge) } points = edges.flat_map { |e| [e.start.position, e.end.position] } min_x, max_x = points.minmax_by { |p| p.x }.map(&;x) min_y, max_y = points.minmax_by { |p| p.y }.map(&;y) min_z, max_z = points.minmax_by { |p| p.z }.map(&;z) length = (max_x - min_x) * 25.4 width = (max_y - min_y) * 25.4 thickness = (max_z - min_z) * 25.4 dimensions = [length, width, thickness].sort length = dimensions.last width = dimensions[1] thickness = dimensions.first area = (length * width / 1000000).round(2) text = "Ім'я; #{entity.name}\nДовжина; #{length.round(1)} мм\nШирина; #{width.round(1)} мм\nТовщина; #{thickness.round(1)} мм\nПлоща; #{area} м.кв." draw_text_with_bigger_font(view, [20, 20], text, 16) end end def draw_text_with_bigger_font(view, position, text, font_size) options = { color; "red", font; "Arial", size; font_size, bold; true, align; TextAlignLeft } view.draw_text(position, text, options) end end Sketchup.active_model.select_tool(TestTool.new)
But then I ran into a bug and found that it was calculating the dimensions of the scaled object incorrectly. I tried to fix it in the code.
Here is the code.This code correctly defines dimensions in scaled groups, but incorrectly in rotated relative to global axes.
### In the updated code, a new transform_point method was added, which applies the transformation matrix of the object to the specified points. ### This method is used to transform the vertex coordinates of the edges before dimensioning. class TestTool def initialize @ip = Sketchup;;InputPoint.new @hovered_inst = nil end def onMouseMove(flags, x, y, view) @ip.pick(view, x, y) @ph = view.pick_helper @in_path = @ip.face ? @ip.face.parent.instances ; nil @hovered_inst = @in_path&.first if @in_path view.invalidate end def draw(view) @ip.draw(view) if @ip.valid? view.draw_points(@ip.position, 40, 5, "red") if @ip.valid? view.tooltip = @hovered_inst&.name if @hovered_inst.is_a?(Sketchup;;Group) || @hovered_inst.is_a?(Sketchup;;ComponentInstance) entity = @hovered_inst edges = entity.definition.entities.select { |e| e.is_a?(Sketchup;;Edge) } transformed_points = edges.flat_map { |e| transform_point(entity.transformation, e.start.position, e.end.position) } min_x, max_x = transformed_points.minmax_by { |p| p.x }.map(&;x) min_y, max_y = transformed_points.minmax_by { |p| p.y }.map(&;y) min_z, max_z = transformed_points.minmax_by { |p| p.z }.map(&;z) length = (max_x - min_x) * 25.4 width = (max_y - min_y) * 25.4 thickness = (max_z - min_z) * 25.4 dimensions = [length, width, thickness].sort length = dimensions.last width = dimensions[1] thickness = dimensions.first area = (length * width / 1000000).round(2) text = "Ім'я; #{entity.name}\nДовжина; #{length.round(1)} мм\nШирина; #{width.round(1)} мм\nТовщина; #{thickness.round(1)} мм\nПлоща; #{area} м.кв." draw_text_with_bigger_font(view, [20, 20], text, 16) end end def transform_point(transformation, *points) points.map { |pt| transformation * pt } end def draw_text_with_bigger_font(view, position, text, font_size) options = { color; "red", font; "Arial", size; font_size, bold; true, align; TextAlignLeft } view.draw_text(position, text, options) end end Sketchup.active_model.select_tool(TestTool.new)
I try to combine these two methods, but nothing works). What am I doing wrong?
I will be very grateful for tips.
Advertisement