sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Fix and improve the code

    Scheduled Pinned Locked Moved Developers' Forum
    1 Posts 1 Posters 12 Views 1 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • K Offline
      kostiaarh
      last edited by

      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.

      1 Reply Last reply Reply Quote 0
      • 1 / 1
      • First post
        Last post
      Buy SketchPlus
      Buy SUbD
      Buy WrapR
      Buy eBook
      Buy Modelur
      Buy Vertex Tools
      Buy SketchCuisine
      Buy FormFonts

      Advertisement