• Login
sketchucation logo sketchucation
  • Login
⚠️ Libfredo 15.4b | Minor release with bugfixes and improvements Update

[Code]Text label system

Scheduled Pinned Locked Moved Developers' Forum
8 Posts 3 Posters 150 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.
  • P Offline
    PatrickBEL
    last edited by PatrickBEL 31 Oct 2012, 08:42

    Hej, i'm new to ruby but i'm trying to make an label/adressing system.

    I would like to make a tool when i select a component and i run the tool (by shortcut), it places an text label at a fixed position relative to the center of the component or at the right-front-upper corner of the boundingbox.

    next step in my todo list is that the textlabel will be automatically increasing.

    workflow of my tool should be:
    ->select component
    -> run tool
    -> label gets placed "1"
    -> select next component
    -> run tool
    -> label gets placed "2"
    -> etc

    Im not asking for a complete ready code, but ive got some problems with taking of:)

    heres wat ive got for now, but the issue i have now is that the boudingbox is not working

    <span class="syntaxdefault"></span><span class="syntaxkeyword">class&nbsp;</span><span class="syntaxdefault">AdressingTool<br /><br />def&nbsp;Start&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">@</span><span class="syntaxdefault">inpp</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">10</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">10</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">10&nbsp;</span><span class="syntaxcomment">#inputpoint&nbsp;will&nbsp;be&nbsp;replaced&nbsp;by&nbsp;the&nbsp;value&nbsp;of&nbsp;the&nbsp;center&nbsp;of&nbsp;the&nbsp;boundingbox<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">@</span><span class="syntaxdefault">vec</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">10</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">10</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">10&nbsp;&nbsp;</span><span class="syntaxcomment">#Distance<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">bb&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">BoundingBox</span><span class="syntaxkeyword">.new;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">selection</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each&nbsp;</span><span class="syntaxkeyword">{|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">bb</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">bounds</span><span class="syntaxkeyword">)&nbsp;;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">boundb&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">bb</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">bounds<br />&nbsp;&nbsp;&nbsp;&nbsp;center&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">boundb</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">center<br />&nbsp;&nbsp;&nbsp;&nbsp;UI</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">messagebox&nbsp;center<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;mod</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model<br />&nbsp;&nbsp;&nbsp;&nbsp;ent</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities<br />&nbsp;&nbsp;&nbsp;&nbsp;txt</span><span class="syntaxkeyword">=</span><span class="syntaxstring">'Adress&nbsp;comes&nbsp;here'<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">t</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">ent</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_text&nbsp;txt</span><span class="syntaxkeyword">,@</span><span class="syntaxdefault">inpp</span><span class="syntaxkeyword">,@</span><span class="syntaxdefault">vec<br />end<br /><br />end&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxcomment">#end&nbsp;of&nbsp;Class&nbsp;&nbsp;AdressingTool<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">plugin_menu&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">UI</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">menu</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"Plugins"</span><span class="syntaxkeyword">).</span><span class="syntaxdefault">add_item</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"Add&nbsp;adress"</span><span class="syntaxkeyword">)&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">select_tool&nbsp;AdressingTool</span><span class="syntaxkeyword">.new&nbsp;}&nbsp;</span><span class="syntaxdefault"></span>
    
    1 Reply Last reply Reply Quote 0
    • T Offline
      thomthom
      last edited by 31 Oct 2012, 10:08

      @patrickbel said:

      heres wat ive got for now, but the issue i have now is that the boudingbox is not working

      Exactly what "isn't working"? You need to be more specific before we can assist.

      Thomas Thomassen — SketchUp Monkey & Coding addict
      List of my plugins and link to the CookieWare fund

      1 Reply Last reply Reply Quote 0
      • T Offline
        TIG Moderator
        last edited by 31 Oct 2012, 10:43

        A few things I can see...

        Methods [def xxx] always start with a lowercase letter, so it's NEVER
        def **S**tart
        However, the 'start method' that is called when a class is run is always named
        def **initialize**()
        anyway !

        You then use this method to setup your references - @model= etc...
        In a very simple tool you can include all of your code in that method too...

        Specify points and vectors as arrays [x,y,z] OR as proper objects Geom::Vector3d(x,y,z) etc.

        As you currently use only the one method then there is no need to use '@' references [which are used so as to be recognized across the class's methods...] - so a plain reference of ' vec' rather than @vec will suffice because you aren't going to use it in another method...

        You create a boundingbox, then add the bounds of everything selected into it - thus making one giant boundingbox.
        I assume you want to use the boundingbox of each selected object to place some text ?
        If so, do it thus:
        ` Sketchup.active_model.selection.each**{**|e| bb=e.bounds

        do an iterated text placement here on 'bb'

        } ### finally close the 'block' here with the } ...`

        You already have a boundingbox [ bb], so there's NO need to confuse things by redefining it with boundb = bb.bounds which actually breaks it !

        You currently get the boundingbox center with center = **bb**.center BUT then you don't use it.
        Also note that as it's the object's 'center' it might mean that the text is 'internal' to the object 😕
        Why not use pt=bb.max =="top-right corner" - then use ' pt' in the add_text() code as the point used to insert the text, rather than the now completely redundant ' @inpt'...

        Note how [ruby:3fg66dk7]ent=model.entities[/ruby:3fg66dk7] would be better set as [ruby:3fg66dk7]ent=model.active_entities[/ruby:3fg66dk7], because otherwise you could be adding text related to an object in the model's context when you are actually editing a containing group's context ! ... [ruby:3fg66dk7]model.active_entities[/ruby:3fg66dk7] can actually be [ruby:3fg66dk7]model.entities[/ruby:3fg66dk7] OR say [ruby:3fg66dk7]group.entities[/ruby:3fg66dk7] etc depending on the current context...

        It seems your 'txt' isn't always to be the same ? So not [ruby:3fg66dk7]txt='Adress comes here'[/ruby:3fg66dk7] BUT rather an incrementing [ruby:3fg66dk7]'1'[/ruby:3fg66dk7], [ruby:3fg66dk7]'2'[/ruby:3fg66dk7] etc.
        To enable this you need to set a [ruby:3fg66dk7]@@txt[/ruby:3fg66dk7] reference in the class itself BUT just before the [ruby:3fg66dk7]def initialize()[/ruby:3fg66dk7] line as [ruby:3fg66dk7]@@txt='0'[/ruby:3fg66dk7].
        Now make the first line of the [ruby:3fg66dk7]...each{|e| bb=e.bounds[/ruby:3fg66dk7] to be like this
        [ruby:3fg66dk7]...each{|e| @@txt.next!
        bb=e.bounds
        ###...[/ruby:3fg66dk7]
        Then the [ruby:3fg66dk7]@@txt[/ruby:3fg66dk7] should be used in the add_text() code rather than current '[ruby:3fg66dk7]txt[/ruby:3fg66dk7]'.
        Explanation: when the tool is first loaded [at startup] the reference [ruby:3fg66dk7]@@txt[/ruby:3fg66dk7] is initially set to be [ruby:3fg66dk7]'0'[/ruby:3fg66dk7].
        When the tool is first run the first selected object is processed and the reference is incremented to be [ruby:3fg66dk7]'1'[/ruby:3fg66dk7], when the next object is processed the iteration steps up to be [ruby:3fg66dk7]'2'[/ruby:3fg66dk7] etc. If you use the tool later on [in that same session] the [ruby:3fg66dk7]@@txt[/ruby:3fg66dk7] reference will have been remembered with its last used value, so the next use it'll be say [ruby:3fg66dk7]'3'[/ruby:3fg66dk7] ...

        I won't go into making it modular too much but it'd be along these lines

        require 'sketchup.rb'
        module PatrickBEL
        UI.menu("Plugins").add_item("Add address"){Sketchup.active_model.select_tool(self;;AdressingTool.new())}
         class self;;AdressingTool
           def initialize()
             ### code goes here
           end
         end#class
        ens#module
        

        Also note how it's easier if you enclose big lumps of code inside a [ code ] block rather than a [ ruby ] one...
        Also note that since this uses none of the 'Tool' methods [like point picking etc] it doesn't need [ruby:3fg66dk7]{Sketchup.active_model.select_tool(...)}[/ruby:3fg66dk7] and a simple [ruby:3fg66dk7]{self::AdressingTool.new()}[/ruby:3fg66dk7] will suffice. If you were to rewrite it to let you pick objects in turn then it would become a 'Tool' and you WILL need to be run as such !

        Hope all of this helps... sorry about the stream-of-consciousness format... 😒

        TIG

        1 Reply Last reply Reply Quote 0
        • P Offline
          PatrickBEL
          last edited by 1 Nov 2012, 10:45

          Hej TIG,thanks alot!!
          I'm working on it now i'll post the result later.

          1 Reply Last reply Reply Quote 0
          • P Offline
            PatrickBEL
            last edited by 1 Nov 2012, 14:01

            Hej, This is what i got for now.
            It works as should but now i need some improvements.
            -I would like to have a gui or a data input, where i can change the adr,offset,univ values
            I found some information about making input dialogs and so but im not really sure where to put it.

            -the general worflow of the tool could be.
            Plugin menu 1 item, 2submenus: Adress and Adress options.
            select component, run by shortcut Adress (label gets placed)
            select next component, run by shortcut Adress (incremented label gets placed)

            The problem now is that the AdressTool doesn't "quit" automaticly to go back to selection mode. so i can select the next component and run the tool again.

            require 'sketchup.rb'
            module PatrickBEL
            #UI.menu("Plugins").add_item("Add address"){Sketchup.active_model.select_tool(self;;AdressingTool.new())}
            submenu = UI.menu("Plugins").add_submenu("Adressing")
                submenu.add_item("Add address"){Sketchup.active_model.select_tool(self;;AdressingTool.new())}
            
              class self;;AdressingTool
                 @@adr= 1
                 @@offset= 5
                 @@univ='A'
                 @@count= 0
               def initialize()
            
                    vec= [10,10,10]  #Distance
            	bb = Geom;;BoundingBox.new
            	Sketchup.active_model.selection.each {|i| 
            		bb=i.bounds
                            @@txt =@@univ + "." + @@adr.to_s
                            @@adr = @@adr + @@offset
                                           
            		pt=bb.max
                            UI.messagebox(@@txt)
                            model=Sketchup.active_model
                		ent=model.active_entities
                		t=ent.add_text @@txt,pt,vec
            		
            		}
               end
             end#class
            end#module
            
            1 Reply Last reply Reply Quote 0
            • T Offline
              TIG Moderator
              last edited by 1 Nov 2012, 14:58

              Within your existing module []just before the class ends make a new method with the dialog's details

              	   def self.dialog()
              		  results=inputbox(["Start Number; ","Offset Number; ","Prefix String; "],[@@adr, @@offset, @@univ],"AdressingTool-Settings")
              		  return nil unless results ### i.e. the user canceled!
              		  @@adr, @@offset, @@univ = results
              	   end
              
              

              Run this from a second item in the submenu code [added just after the first submenu entry]...

              submenu.add_item("Settings"){self;;AdressingTool.dialog()}
              

              Also [TIP} to make it one step undo-able add Sketchup.active_model.start_operation('AdressingTool') just before you process the selection and Sketchup.active_model.commit_operation after the closing '}'. Also remove the UI.messagebox between each text placement and define 'model=' and 'ent=' at the initialize method's start rather than every iteration of the selection!
              To exit the tool at the end of the initialize method [after the closing '}'] insert
              Sketchup.send_action("selectSelectionTool:")
              If you want to be able to select objects whilst within the tool then this is a whole extra area where you make it a Tool with activate() and other methods to read mouse position and clicks etc and deduce the object below the cursor etc etc... Let's get this working first !
              There's a lot that could be tidied but you are getting there 😄

              TIG

              1 Reply Last reply Reply Quote 0
              • P Offline
                PatrickBEL
                last edited by 12 Nov 2012, 14:37

                This is my code for now, and works perfect except for 1 thing.

                If i select more then one component, it doesn't work, it seems like it only runs one time the iteration.

                Just out of interest, i'm not sure why i'm using @@ now for each variable.

                Is there a way to adopt the layout of my text and change the size to "height" instead of point -size.

                require 'sketchup.rb'
                module PatrickBEL
                #UI.menu("Plugins").add_item("Add address"){Sketchup.active_model.select_tool(self;;AdressingTool.new())}
                submenu = UI.menu("Plugins").add_submenu("Adressing")
                    submenu.add_item("Add address"){Sketchup.active_model.select_tool(self;;AdressingTool.new())}
                    submenu.add_item("Settings"){self;;AdressingTool.dialog()}
                
                  class self;;AdressingTool
                     @@adr= 1
                     @@offset= 1
                     @@univ='A'
                     @@count= 0
                     @@vec= [0,0,0]  #Distance
                   def initialize()
                                model=Sketchup.active_model
                    		ent=model.active_entities
                     
                	bb = Geom;;BoundingBox.new
                	Sketchup.active_model.selection.each {|i|
                                Sketchup.active_model.start_operation('AdressingTool')
                		bb=i.bounds
                                @@txt =@@univ + "." + @@adr.to_s
                                @@adr = @@adr + @@offset
                                               
                		pt=bb.max
                
                    		t=ent.add_text @@txt,pt,@@vec
                                t.display_leader = False
                                Sketchup.send_action("selectSelectionTool;")
                		}
                                Sketchup.active_model.commit_operation
                   end
                   def self.dialog()
                        results=inputbox(["Start Adress; ","Offset Number; ","Universe; ","Adr-posx;","Adr-posy;","Adr-posz;"],[@@adr, @@offset, @@univ, @@vec[0],@@vec[1],@@vec[2]],"PatrickBel-AdressingTool")
                        return nil unless results ### i.e. the user canceled!
                        @@adr, @@offset, @@univ, @@vec[0],@@vec[1],@@vec[2] = results
                   end
                 end#class
                end#module
                
                1 Reply Last reply Reply Quote 0
                • T Offline
                  TIG Moderator
                  last edited by 12 Nov 2012, 15:12

                  Plain variables, or perhaps more correctly 'references', [e.g. x] are only used/changed in their specific def [method] that defines them.
                  Ones starting with @ [e.g. @x] - their current value is accessible to all methods during that instance of the class/module. Any method can define or redefine them,
                  Ones starting with @@ [e.g. @@x] are similar to @ ones, BUT their current value is remembered across multiple uses of that class/module - e.g. good for remebering values last used in dialogs. They need to be 'declared' outside of any method, but after that any method can then redefine them.
                  Constants [starting with a capital letter, or commonly with all caps, e.g. Z_AXIS] are similar to @@ ones, they are remembered across all uses of that class/method, BUT they are not readily changeable - because they are 'constants'!

                  Move your 'start_operation' out of the iteration block [to match the 'commit_'] that way all we become 'undo-able' in one go.
                  The selection.each{} block adds a piece of text to every selected object when the code starts.

                  However, the Sketchup.send_action("selectSelectionTool:") will stop more that one iteration.
                  It simply exits the tool and activates the 'Select' tool.

                  If you want to be able to 'pick objects' in turn you will need to [re]write/launch this as a proper Tool... this will involve getting input-points, reading mouse-positions and mouse-clicks etc... Then using those for new text objects etc...
                  See the API and examples - 'linetool.rb' etc - for some Tool method ideas/examples...
                  Or other authors' tools' .rb files - like say some of my 2dTools...

                  There is limited access to 'Text' objects' properties through the API - see the relevant pages - http://code.google.com/apis/sketchup/docs/ - height is not one of them - unless you make it as '3d-text'... It's a long standing request...

                  TIG

                  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