[Code] Scarpino's SphereTool Sample ver 2.1.0

[Code] Scarpino's SphereTool Sample ver 2.1.0

Postby Dan Rathbun » Thu Feb 09, 2012 3:02 pm

    Automatic SketchUp
    Creating 3-D Models in Ruby
    by Matthew Scarpino

    SphereTool Sample Plugin (correction - Topic is WIP)
    page 260 ..

    This sample has been corrected to:
    • Wrap the tool class inside a plugin module, within an author toplevel module.
    • Use variables inside the namespace instead of global variables.
    • Separate plugin code, from tool code into two files, to show file spanning, and how to save indents.
    • Use active_entities instead of entities, so a user can add a sphere to a group or component.
    • Add a rescue block and Undo operation around the geometry drawing code, for safety.



    SphereMaker

    ver 2.0.0 : 02-09-2012
    • initial posting
    ver 2.1.0 : 02-10-2012
    • added some model tracking in to account for switching back and forth between models on Mac.
    ver 2.2.0 : 02-11-2012
    • ! BACKPORT: Tracking models proves to be problematic. Reverted to singleton use of the SphereTool class.
    • ~ Method tool() backported to the 2.0.0 use() method's functionality. Creates the tool instance, only if needed, and/or returns a reference to it.
    VERSION 2.2.1 : 02-14-2012
    • Removed definition of WIN and MAC constants. (Not used, nor relevant to this example.)

    This sample plugin file (below, along with the toolbar icon files,) should go in it's own subdir, of the author's subdir, of the "Plugins" dir.
    "Plugins/Scarpino/SphereMaker/spheremaker.rb"
    Code: Select all
    #  ---------------------------------------------------------
    #   file : 'spheremaker.rb'
    #   by   :  Dan Rathbun
    #{ ---------------------------------------------------------
    #{  Description:
    #
    #   Example of namespace wrapping the 'spheretool.rb' file,
    #   from "Automatic SketchUp" by Matthew Scarpino, pg 260.
    #}
    #  ---------------------------------------------------------
    #{  Versions:
    #
    #   2.0.0  :  02-09-2012
    #   + initial posting (not tested)
    #
    #   2.1.0  :  02-10-2012
    #   + Added tool() method for model tracking to account
    #       for switching back and forth between models on
    #       Mac.  Returns tool instance per model.
    #   ~ Changed use() method to call tool() and select it
    #       as the active tool.
    #
    #   2.2.0  :  02-11-2012
    #   ! BACKPORT: Tracking models proves to be problematic.
    #       Reverted to singleton use of the SphereTool class.
    #   ~ Method tool() backported to the 2.0.0 use() method's
    #       functionality. Creates the tool instance, only if
    #       needed, and/or returns a reference to it.
    #
    #   2.2.1  :  02-14-2012
    #   ~ Removed definition of WIN and MAC constants.
    #     (Not used, nor relevant to this example.)
    #}
    #}  ---------------------------------------------------------

      #{# DEPENDENCIES
      #
        require('sketchup.rb')
      #
      #}#
     
    module Scarpino  # <-- Author's namespace

      module SphereMaker # <-- plugin namespace
     
        ### CONSTANTS
        #
        VERSION = '2.2.1'

       
        ### MODULE VARIABLES
        #
        @@cmd     = nil unless defined?(@@cmd)
        @@tool    = nil unless defined?(@@toolset)
        @@toolbar = nil unless defined?(@@toolbar)
     

        ### Load the tool code for SphereTool
        #
        require('Scarpino/SphereMaker/spheretool.rb')
        #
        ### class SphereTool is now local to this module
     

        ### MODULE METHODS

        #  cmd()
        #    Returns a reference to this plugin's UI::Command object.
        def self.cmd
          @@cmd
        end
     
        #  tool()
        #    Returns the tool instance. Creates one if needed.
        def self.tool
          if not @@tool
            @@tool = SphereTool.new
          else
            @@tool
          end
        end # def
       
        #  toolbar()
        #    Returns a reference to this plugin's UI::Toolbar object.
        def self.toolbar
          @@toolbar
        end

        #  use()
        #    Gets the tool instance, and makes it
        #      the active tool for the model argument.
        #    [Defaults to use the active model.]
        #
        def self.use( mod = Sketchup.active_model )
          #
          unless mod.is_a?(Sketchup::Model)
            raise(TypeError,"Sketchup::Model argument expected.",caller)
          end
          #
          mod.select_tool( self.tool )
          #
        end # def


        ### RUN ONCE
        #
        unless file_loaded?(File.basename(__FILE__))
     
          # Create the Command object
          @@cmd = UI::Command.new("Sphere") { self.use }
           
          # Configure the Command's appearance
          @@cmd.small_icon = "sphere_small.gif"
          @@cmd.large_icon = "sphere_large.gif"
          @@cmd.tooltip = "Create a sphere"
          # Create and configure the Toolbar
          @@toolbar = UI::Toolbar.new "Sphere"
          @@toolbar.add_item @@cmd
          @@toolbar.show
     
          file_loaded(File.basename(__FILE__))
        end
        #
        ### RUN ONCE
     
      end # module SphereMaker
    end # module Scarpino

    The global methods file_loaded and file_loaded? come from 'sketchup.rb', which is in the "Tools" dir.



    SphereTool

    ver 2.0.0 : 02-09-2012
    • initial posting (not tested)
    • $ents changed to @@ents, and made to use the active_entities, instead of model.entities
    • $c_point changed to @@c_point
    • Added undo operation and rescue block around model geometry creation.

    ver 2.1.0 : 02-10-2012
    • @@ents changed to @ents
    • @@c_point changed to @c_point
    • Added tracking of current editing context. (User can change editing context "on-the-fly" anytime via the right-click popup menus, "Edit Group" and "Close Group", etc.)
    • Added query method edit_context_changed?()
    UNDER REVISION


    This file is: "Plugins/Scarpino/SphereMaker/spheretool.rb"
    Code: Select all
    # ---------------------------------------------------------
    # file : 'spheretool.rb'
    # from : "Automatic SketchUp"
    # by   : by Matthew Scarpino
    # page : 260
    # ---------------------------------------------------------
    # ver  : 2.1.0
    # edit : Dan Rathbun
    # ---------------------------------------------------------
    require('sketchup.rb')

    class Scarpino::SphereMaker::SphereTool
     
      ### CONSTANTS
      #
      VERSION = '2.1.0'


      ### INIT INSTANCE VARIABLES
      #
      # Set up the private method initialize(), which
      # is called by the class constructor method new().
      #
      def initialize(*args)
        @mod  = Sketchup.active_model
        @ents = nil
        @c_point = nil
        @pt1 = Sketchup::InputPoint.new
        @pt2 = Sketchup::InputPoint.new
      end
      private(:initialize)


      ### CONTROL CALLBACK METHODS
      #
        #  activate()
        #
        def activate()
          @ents = @mod.active_entities
            # The points clicked by the user
          @c_point = nil
          @pt1.clear
          @pt2.clear
            # The initial state (user hasn't clicked yet)
          @first_click = false
        end
       
        #  deactivate( view )
        #
        def deactivate( view )
          if @first_click
            @ents.erase_entities( @c_point ) if @c_point
            @c_point = nil
          end
          @ents = nil # we want to refresh this each time
        end

        #  edit_context_changed?()
        #
        def edit_context_changed?()
          ents_now = @mod.active_entities
          unless bool = ents_now.equal?(@ents)
            if @first_click && @c_point
              # move c_point to new context
              @ents.erase_entities( @c_point )
              #
              @ents = ents_now
              @c_point = @ents.add_cpoint @pt1.position
            end
          end
          return bool
        end

        #  suspend( view )
        #
        def suspend( view )
          #
        end

        #  reset()
        #    Return to original state
        #
        def reset()
          @pt1.clear
          @pt2.clear
          @first_click = false
        end

        #  resume( view )
        #
        def resume( view )
          # check if editing context has changed
          edit_context_changed?
          #
          view.invalidate
        end
      #
      ###

      ### KEYPRESS CALLBACK METHODS
      #
        #  onCancel( flags, view )
        #    Respond when user presses Escape
        #
        def onCancel( flags, view )
          if @first_click
            @ents.erase_entities( @c_point ) if @c_point
            @c_point = nil
          end
          reset
        end

        #  onMouseMove( flags, x, y, view )
        #    If the user clicked, draw a line.
        #
        def onMouseMove( flags, x, y, view )
          if @first_click
            @pt2.pick view, x, y, @pt1
            view.invalidate
          end
        end
       
        #  onLButtonDown( flags, x, y, view )
        #    Check the state, then draw a sphere or a point.
        #
        def onLButtonDown( flags, x, y, view )
          if @first_click
            # check if editing context has changed
            edit_context_changed?
            if (@pt1.position.distance @pt2.position) > 0
              # Remove the construction point
              @ents.erase_entities @c_point
              @c_point = nil
              draw_sphere
            end
          else # this is the first click
            # get the active editing context
            @ents = @mod.active_entities
            @pt1.pick view, x, y
            @c_point = @ents.add_cpoint @pt1.position
            @first_click = true
          end
        end
      #
      ###

      ### DRAWING METHODS
      #
        #  draw( view )
        #
        def draw( view )
          if @first_click && @pt2.valid?
            view.set_color_from_line @pt1.position, @pt2.position
            view.line_width = 3
            view.draw_line @pt1.position, @pt2.position
          end
        end

        #  draw_sphere()
        #    Draw the sphere
        #
        def draw_sphere
          # Draw the circles
          begin
            @mod.start_operation('Draw Sphere')
              #
              rad = @pt1.position.distance @pt2.position
              circle = @ents.add_circle @pt1.position, [1, 0, 0], rad
              path = @ents.add_circle @pt1.position, [0, 1, 0], rad + 1
              circle_face = @ents.add_face circle
              # Extrude the sphere and erase the extrusion path
              circle_face.followme path
              @ents.erase_entities path
              #
            @mod.commit_operation
          rescue
            @mod.abort_operation
          ensure
            reset
          end
        end
      #
      ###
     
      ### RUN ONCE
      #
      thisfile = File.basename(__FILE__)
      file_loaded( thisfile ) unless file_loaded?( thisfile )
     
    end # class Scarpino::SphereMaker::SphereTool


    Then in the "Plugins" dir, the author puts a SketchupExtension registration script.
    "Plugins/Scarpino_spheremaker_ext.rb"
    (To Do - insert "_ext" ruby script here )
    I suggest prepending your extension loader scripts with your Author namespace+"_", and appending the filename with "_ext" (so we all know that it registers a Sketchup extension.)

    See the following Google Sketchup API blog posts:See also my sample at SCF:

    :idea:
    0
    Last edited by Dan Rathbun on Tue Feb 14, 2012 6:55 pm, edited 7 times in total.
      I'm not here much anymore. But a PM will fire email notifications.
      User avatar
      Dan Rathbun 
      PluginStore Author
      PluginStore Author
       

      Re: [Code] Scarpino's SphereTool Sample

      Postby Dan Rathbun » Thu Feb 09, 2012 3:52 pm

      Just a not that this sample tool should work OK for PC.. but not for MAC with multiple models.

      I'll have to add some model tracking in to account for switching back and forth between models.
      0
        I'm not here much anymore. But a PM will fire email notifications.
        User avatar
        Dan Rathbun 
        PluginStore Author
        PluginStore Author
         

        Re: [Code] Scarpino's SphereTool Sample

        Postby driven » Thu Feb 09, 2012 7:51 pm

        Hi Dan,

        If people are working through Matt's Tutorials the path could remain /Library/Application Support/Google SketchUp */SketchUp/plugins/asu_example_code/Ch11/sphere_tool.rb...

        I did a lot of testing for Mat's book and I didn't have a problem with this one one the mac, where do you think it will fail?

        The one we just couldn't get working on a mac, in the time frame for publication, was 'Skel Animation', please, please have a look at it


        Just curious...
        0
        learn from the mistakes of others, you may not live long enough to make them all yourself...

        driven 
        PluginStore Author
        PluginStore Author
         

        Re: [Code] Scarpino's SphereTool Sample

        Postby Dan Rathbun » Thu Feb 09, 2012 10:25 pm

        driven wrote:If people are working through Matt's Tutorials the path could remain /Library/Application Support/Google SketchUp */SketchUp/plugins/asu_example_code/Ch11/sphere_tool.rb...

        My point is that as the example is.. it violates good practice. It is not wrapped in an Author namespace. We cannot all be defining classes in the global ObjectSpace. There will be clashes. The identifier "SphereTool" is just too common.

        Likewise.. it makes sense to have the textnames of your filespaces match your Ruby namespaces. It makes it much easier, when the time comes to type a require statement.

        driven wrote:I did a lot of testing for Mat's book and I didn't have a problem with this one one the mac, where do you think it will fail?

        It will fail because the entities object is shared. In the example it used $ents, and I changed it to a class var @@ents.

        If you have 2 models, open, and are using the the sphere tool on both models, and switch back and forth, between models... the tool should get confused. Both as to what context to add the geometry into, and what one to erase the center $c_point from.

        I've already changed $ents / @@ents and $c_point / @@c_point to instance vars in the tool code.
        I have also already modified the plugin methods, to track models, use the correct one, and keep an separate instance of the tool for each model.

        driven wrote:The one we just couldn't get working on a mac, in the time frame for publication, was 'Skel Animation', please, please have a look at it

        Well, not having a Mac.. it will be difficult, unless I can spot some obvious booboo (or am aware of some kind bug on Mac.)

        I did not really choose this one... it was posted publically by Keld, so I got "hooked"...
        0
        Last edited by Dan Rathbun on Thu Feb 09, 2012 11:04 pm, edited 1 time in total.
          I'm not here much anymore. But a PM will fire email notifications.
          User avatar
          Dan Rathbun 
          PluginStore Author
          PluginStore Author
           

          Re: [Code] Scarpino's SphereTool Sample ver 2.1.0

          Postby Dan Rathbun » Thu Feb 09, 2012 11:02 pm


            Updated examples to VERSION 2.1.0

            Seems to work well on PC.

            Mac testing welcome (as it wants to be a cross-platform coding example.)
            0
              I'm not here much anymore. But a PM will fire email notifications.
              User avatar
              Dan Rathbun 
              PluginStore Author
              PluginStore Author
               

              Re: [Code] Scarpino's SphereTool Sample ver 2.1.0

              Postby driven » Thu Feb 09, 2012 11:07 pm

              I'll try and find all my notes re. skell, interestingly, from what you just outlined, it may suffer from 'entities confusion', sometimes it ran and other times it just melted SU...

              With Mat's help, I attempted to have this one work along the user drawn axis, so you could e.g. create a string of pearls.

              Could you add or suggest how that could be done?

              Then it's quite different from all the others.

              john

              sphereTool.png
              0
              learn from the mistakes of others, you may not live long enough to make them all yourself...

              driven 
              PluginStore Author
              PluginStore Author
               

              Re: [Code] Scarpino's SphereTool Sample ver 2.1.0

              Postby Dan Rathbun » Thu Feb 09, 2012 11:37 pm

              driven wrote:With Mat's help, I attempted to have this one work along the user drawn axis, so you could e.g. create a string of pearls.

              Could you add or suggest how that could be done?

              See a new post (... I must have been reading your mind.)
              I made a Library edition:
              [ Code ] Scarpino's SphereUtil Sample
              0
              Last edited by Dan Rathbun on Thu Feb 09, 2012 11:38 pm, edited 1 time in total.
                I'm not here much anymore. But a PM will fire email notifications.
                User avatar
                Dan Rathbun 
                PluginStore Author
                PluginStore Author
                 

                Re: [Code] Scarpino's SphereTool Sample ver 2.1.0

                Postby driven » Thu Feb 09, 2012 11:38 pm

                Ok, all works on my mac,
                I had to add the full path to the
                require("/Library/Application Support/Google SketchUp 8/SketchUp/plugins/Scarpino/SphereMaker/spheretool.rb")
                and I used a couple of icons I had from the last play, and I just used same full folder path for them as well.
                sphere_large.gif
                sphere_small.gif

                I'll make some nicer ones if you want, this was my first attempt at making icons in SU... john
                0
                learn from the mistakes of others, you may not live long enough to make them all yourself...

                driven 
                PluginStore Author
                PluginStore Author
                 

                Re: [Code] Scarpino's SphereTool Sample ver 2.1.0

                Postby Dan Rathbun » Thu Feb 09, 2012 11:50 pm

                driven wrote: I had to add the full path ... john

                Oh to get SU to find the icons ??

                I can prepend the icon paths with: File.basename(__FILE__)

                ... the UI::Command class is cranky sometimes, with the icon locations.

                The icons look fine.. it's an example anyway.

                I could tie it all up in an rbz for easy download. (Need to do the extension registration script first.)
                0
                  I'm not here much anymore. But a PM will fire email notifications.
                  User avatar
                  Dan Rathbun 
                  PluginStore Author
                  PluginStore Author
                   

                  Re: [Code] Scarpino's SphereTool Sample ver 2.1.0

                  Postby driven » Thu Feb 09, 2012 11:58 pm

                  Dan Rathbun wrote: VERSION 2.1.0
                  added some model tracking in to account for switching back and forth between models on Mac.


                  I don't follow what's meant to happen, can't see anything new in my context menu.
                  When you switch between models, you switch tool and undo stacks automatically.

                  am I being dim? john

                  Oh to get SU to find the icons ??
                  no, before trying with icons, the path was failing.
                  I always use full or defined paths with require, it seems flakey. i.e. require path + "find"
                  OT: have you use find.rb with SU, it really shows up problems with 'Path' on mac's.
                  0
                  learn from the mistakes of others, you may not live long enough to make them all yourself...

                  driven 
                  PluginStore Author
                  PluginStore Author
                   

                  Re: [Code] Scarpino's SphereTool Sample ver 2.1.0

                  Postby Dan Rathbun » Fri Feb 10, 2012 12:09 am

                  Well it on PC we can use a singleton instance of a tool, there's only one stack, and model.

                  But on Mac, this example now makes a new tool for each model's toolstack, but only ONCE.

                  His example was actually creating a new instance EACH time the toolbar button was clicked. That makes ruby garbage collection do more work.
                  And he was having ALL instances (models,) share 2 global variables. $ents and $c_point
                  0
                  Last edited by Dan Rathbun on Sat Feb 11, 2012 5:05 am, edited 1 time in total.
                    I'm not here much anymore. But a PM will fire email notifications.
                    User avatar
                    Dan Rathbun 
                    PluginStore Author
                    PluginStore Author
                     

                    Re: [Code] Scarpino's SphereTool Sample ver 2.1.0

                    Postby Dan Rathbun » Sat Feb 11, 2012 5:05 am

                    driven wrote:I don't follow what's meant to happen, can't see anything new in my context menu.

                    Just a note, that when I referred to context menu, I was referring to entering and exiting group/component edit modes, via the context popup items "Edit Group" and "Close group".

                    You have to point to the group and right-click the mouse (or you don't see these items on the popup.)

                    Previously, the example tool, ignored any change in context, in fact, it was hard-coded to ALWAYS use the model's entities. So as Matt wrote it, you could not draw a sphere inside a group or component.

                    So in 2.0.0, I changed it to use active_entities, but once the construction point (for the center,) was drawn, the tool would put the sphere in the edit context of the c_point, even if the user had changed the edit context.

                    Version 2.1.0, checks to see if the edit context has changed when the second click is made, and acts within the new context, instead.
                    0
                      I'm not here much anymore. But a PM will fire email notifications.
                      User avatar
                      Dan Rathbun 
                      PluginStore Author
                      PluginStore Author
                       

                      Re: [Code] Scarpino's SphereTool Sample ver 2.1.0

                      Postby driven » Sat Feb 11, 2012 5:37 am

                      @dan,
                      I missed the fact you started the 2nd thread for this. I had 'another look at line tool, but what I meant is more like the Cyl.class at the bottom.

                      i.e. After the user draws a line, a base circle 'path' is created, then at the line's 'mid-position' a 'filled circle' at 90º to path, with rad 1/2 line length is created, then the follow-me, clean-up, etc...
                      You end up with the new axis aligned to the original drawn line and could select the end point to continue a 'string of pearls'... If you the intersect those, the geometry could be line-up, without having to rotate groups manually. However, clytool dosen't work here...

                      I've been distracted by almost having a WebDialog do the same things as my macMessage video shows. [but it's an 'almost' standard webdialog].

                      john
                      0
                      learn from the mistakes of others, you may not live long enough to make them all yourself...

                      driven 
                      PluginStore Author
                      PluginStore Author
                       

                      Re: [Code] Scarpino's SphereTool Sample ver 2.1.0

                      Postby Dan Rathbun » Sat Feb 11, 2012 9:32 am

                      driven wrote:@dan, I missed the fact you started the 2nd thread for this. I had 'another look at line tool, but what I meant is more like the Cyl.class at the bottom.

                      Oh OK. Well.. you wish to do it the easy way, huh ? :P

                      That's subclassing a current class... a topic for a new thread.
                      0
                        I'm not here much anymore. But a PM will fire email notifications.
                        User avatar
                        Dan Rathbun 
                        PluginStore Author
                        PluginStore Author
                         

                        Re: [Code] Scarpino's SphereTool Sample ver 2.1.0

                        Postby Dan Rathbun » Sun Feb 12, 2012 11:37 am

                        driven wrote:I'll make some nicer ones if you want, this was my first attempt at making icons in SU... john

                        A note about toolbar icons.

                        GIFs are not the best. (They are good for print ads, cartoons, etc.) But the edges look ragged.

                        You should save as PNG, as the edges are anti-aliased. (smoothed via blending.)
                        0
                          I'm not here much anymore. But a PM will fire email notifications.
                          User avatar
                          Dan Rathbun 
                          PluginStore Author
                          PluginStore Author
                           

                          SketchUcation One-Liner Adverts

                          by Ad Machine » 5 minutes ago



                          Ad Machine 
                          Robot
                           



                           

                          Return to Developers' Forum

                          Who is online

                          Users browsing this forum: No registered users and 22 guests