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.
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better π
Register LoginAdvertisement