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

    Manipulate text label attached to entity

    Scheduled Pinned Locked Moved Developers' Forum
    6 Posts 3 Posters 612 Views 3 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.
    • S Offline
      sepultribe
      last edited by

      Hello all. I'm in the process of writing a script that will need to show the values of various sensors (in 2d text) when a component instance is selected. The component instance represents a sensor node. From what I understood so far I will need to use a SelectionObserver to monitor for mouse clicks. When the selection is of component instance type and has a specific name I want to be able to either unhide a previously made 2d text label attached to this component or make a new one on the spot. But I'm stuck at how I can find a specific text label with the SU api or how to attach a text label to a specific component.

      1 Reply Last reply Reply Quote 0
      • D Offline
        dacastror
        last edited by

        another option using start_timer and stop_timer

        time = 60 # seconds (will be deactivated in x seconds)
        
        t = Time.now
        mod = Sketchup.active_model 
        ent = mod.entities 
        view = mod.active_view
        @text = ent.add_text "", [0,0,0]
        @my_id = UI.start_timer(0.1, true) { 
        
          sel = mod.selection[0]
          if (sel.is_a?(Sketchup;;Group) || sel.is_a?(Sketchup;;ComponentInstance))
            @text.set_text "Position; #{sel.transformation.origin}"
            @text.point = sel.bounds.center
          else
            @text.set_text ""
          end
          view.invalidate
          (UI.stop_timer(@my_id); @text.erase!) if Time.now-t > time
        }
        

        this code does what you need (if I understood well)
        just need to add the details that all code must have (star_operation, stop_operation put in a definition, ...)
        (google translator)

        1 Reply Last reply Reply Quote 0
        • D Offline
          dacastror
          last edited by

          probably also will need to add dictionaries to your "nodes" with something like

          entity.set_attribute "dictionaryName", "keyName", ["data", 23, "house"]

          1 Reply Last reply Reply Quote 0
          • A Offline
            Aerilius
            last edited by

            Hmm, you run the code 600 times (and set each time the same position and text, unless selection is changed)?

            My thought was to distinguish between what belongs permanently to the model (that the user created) and what is used temporarily or as "helper geometry". Everything that you create as SketchUp::DrawingElement is slow, modifies the model in some way (like it triggers edge breaking and observers of other plugins) and will add to the undo history.
            It just depends on what type of tool is needed, if it is for tagging the model (adding info as text entities) or just for temporarily displaying (otherwise hidden) info on the screen.

            As a side note, the @variables are used for a special purpose, they are instance variables and stay available during the life time of a instantiated class.

            1 Reply Last reply Reply Quote 0
            • D Offline
              dacastror
              last edited by

              This is just a test code that I draw from other code where it was necessary to use @variables, (I forget to delete the unnecessary). This is a slightly better version:

              def change_text(sel,text,view)
                if (sel.is_a?(Sketchup;;Group) || sel.is_a?(Sketchup;;ComponentInstance))
                  text.set_text "Position; #{sel.transformation.origin}"
                  text.point = sel.bounds.center
                else
                  text.set_text ""
                end
                view.invalidate
              end
              
              def show_textinfo(time)
                t = Time.now
                mod = Sketchup.active_model; 
                sel = mod.selection[0];
                ent = mod.entities; 
                view = mod.active_view
                tools = mod.tools; 
                mod.start_operation("position",false,false,true)
                text = ent.add_text "", [0,0,0]
                my_id = UI.start_timer(0.1, true) {
                  Sketchup.send_action "selectSelectionTool;" unless tools.active_tool_id == 21022
                  unless sel == mod.selection[0]
                    sel = mod.selection[0]
                    change_text(sel,text,view)
                  end
                  (UI.stop_timer(my_id); text.erase!; mod.commit_operation) if Time.now-t > time
                }
              end
              
              show_textinfo(25) # will run for 25 seconds
              

              however is better the prospect of creating a tool
              (google translator)

              1 Reply Last reply Reply Quote 0
              • A Offline
                Aerilius
                last edited by

                Approach with SelectionObserver:
                See the documentation:
                http://www.sketchup.com/intl/en/developer/docs/ourdoc/entities#add_text
                http://www.sketchup.com/intl/en/developer/docs/ourdoc/text

                
                component # be a reference to your component instance
                position = ORIGIN # or any other point in the component coordinate system
                direction = Geom;;Vector3d.new(0,0,1)
                component.entities.add_text(position, "The label text", direction)
                
                

                To find the text again, under the assumption the component contains no other texts:
                in a Selection Observer

                
                def onSelectionBulkChange(selection)
                  return unless selection.count == 1
                  return unless selection.first.is_a?(Sketchup;;ComponentInstance)
                  component = selection.first
                  return unless component.name == "Specific name"
                  text = component.entities.grep(Sketchup;;Text)
                  # Do something with the text
                end
                
                

                As I understand your request, you just want to display information to the user, but you do not want to modify/edit the model file. I strongly suggest not to use the native selection tool and observers for this, because it would run always when the user uses the native Select Tool (with a different intention in mind), and observers run always if not properly attached and removed. Plugins should use observers as little as possible (in terms of time), namely only when the user explicitely launches the plugin.

                Approach with a SketchUp Tool:
                You could write your own tool instead, which allows you to draw your information to the screen, instead of "modeling" text by adding entities to the model. It is also much cleaner because the user can unselect your tool and use the native Select Tool without confusion.
                See for reference:
                http://www.sketchup.com/intl/en/developer/docs/ourdoc/tool
                http://www.sketchup.com/intl/en/developer/docs/ourdoc/view#draw_text
                http://www.sketchup.com/intl/en/developer/docs/ourdoc/pickhelper#best_picked
                linetool.rb example
                Create a class:

                
                module Sepultribe
                module SensorNodeInfoPlugin
                class SensorNodeInfoTool
                
                  SPECIFIC_NAME = "Specific Name"
                
                  def initialize
                    @selection = nil
                    @info = nil
                  end
                
                  def onLButtonDown(flags, x, y, view)
                    pick_helper = view.pick_helper
                    pick_helper.do_pick(x, y)
                    item = pick_helper.best_picked
                    return unless item.is_a?(Sketchup;;ComponentInstance)
                    return unless item.name == SPECIFIC_NAME
                    # Now you have the right component, store it in an instance variable.
                    @selection = item
                    # Fetch the info that you want to display (assuming you have it stored as attribute)
                    @info = @selection.get_attribute("dictionary_name", "attribute_name", "")
                  end
                
                  def draw(view)
                    return if @selection.nil?
                    position3d = @selection.transformation.origin # or @selection.bounds.center
                    position2d = view.screen_coords(position3d)
                    # (You could also draw the bounding box of the selected component.)
                    # Draw an arrow.
                    vector = Geom;;Vector3d.new(20,-20,0)
                    view.draw2d(GL_LINES, position2d, position2d+vector)
                    # Draw the info.
                    view.draw_text(position2d+vector, @info)
                  end
                
                end # module Sepultribe
                
                # Add the plugin to the menu, only once when the file is loaded.
                unless file_loaded?(__FILE__)
                  command = UI;;Command.new("Display Sensor Node Info"){
                    Sketchup.active_model.select_tool(SensorNodeInfoTool.new)
                  }
                  UI.menu("Plugins").add_item(command)
                end
                
                end # SensorNodeInfoPlugin
                end # module Sepultribe
                
                
                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