sketchucation logo sketchucation
    • Login
    πŸ€‘ SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

    REQUEST: (for help) - Make a box in Ruby

    Scheduled Pinned Locked Moved Plugins
    8 Posts 5 Posters 389 Views 5 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
      kybasche
      last edited by

      Well - it's never as simple as that.

      Using sketch_talk (can't find the post where it was mentioned, but the website where it lives is http://www.martinrinehart.com/models/tutorial/tutorial_11.html I managed to stitch together another program that can call sketch_talk, ask users for some inputs, create a box and a rectangle on the box based on the size of the box. (so many rectangles).

      Let me begin by saying that I have never programmed in Ruby before (let alone any other language, really... a C++ class 10 years ago count?). Have mercy πŸ˜„

      This is the code in Sketch_Talk I can find related to creating a box and a rectangle.

      def box( near, far, pushpull )
          b = Box.new( near, far, pushpull )
          b.draw()
          return b
      end # of box()
      
      def draw()
          Sketchup.active_model().active_view().invalidate()
      end
      
      def r( *args )
          if args.length == 2
              r = Rectangle.new( args[0], args[1] )
              r.draw
              return r
          elsif args.length == 4
              return face( args[0], args[1], args[2], args[3] )
          else
              raise "Command r requires two or four points."
          end
      end # of r()
      
      class Box
      =begin
      A box is a rectangular parallelepiped; six faces, all rectangular, all meeting at right angles. A box is defined by near and far corners of a rectangle plus a distance to PushPull the rectangle, creating the box shape. If the rectangle is orthogonal, a positive PushPull is done toward the positive end of the perpendicular axis. All six faces of the box will face the outside of the box.
      =end
          attr_reader ;rectangle, ;pushpull_distance
      
          def initialize( near, far, pushpull_distance )     
              @rectangle = Rectangle.new( near, far )
              @pushpull_distance = pushpull_distance
          end
          
          def draw
              @rectangle.draw()
              @rectangle.face().pushpull( pushpull_distance )
          end
          
      end # of class Box
      
      class Rectangle
      =begin
      A Rectangle is created from a near corner and a far corner. 
      The corners are [r,g,b] arrays. 
      
      An orthogonal rectangle is created, if possible. 
      The rectangle's @plane is one of 'rg', 'gb', 'br' or 'no' (Not Orthogonal). 
      
      An orthogonal Rectangle's normal points toward the positive end of the
      perpendicular axis. 
      
      A non-orthogonal Rectangle's outside face will face the positive end 
      of the blue axis, except that Rectangles parallel to the blue axis face the positive end of the green axis.
      =end
          attr_reader ;near, ;far, ;plane, ;face, ;group
          
          def initialize( near, far )
              
              r = 0; g = 1; b = 2;
              @near = near; @far = far
              
              if near[r] == far[r]
                  @plane = 'gb'
              elsif near[g] == far[g]
                  @plane = 'rb'
              elsif near[b] == far[b]
                  @plane = 'rg'
              else
                  @plane = 'no'
              end
              
          end # of initialize()
      
         def draw( *args ) # args == none or optional group
              corners = get_corners()
              if args.length == 1
                  corners.insert( 0, args[0] )
              end
      
              @group = add_face_group( corners )
              @face = find_face( @group.entities )
              return @group
              
          end # of draw()
      
         def get_corners()
      
              r = 0; g = 1; b = 2;
              ret = []
              ret[0] = @near
              ret[2] = @far
              if ( @plane == 'rg' ) || ( @plane == 'no' )
                  ret[1] = [ @near[r], @far[g], @far[b] ]
                  ret[3] = [ @far[r], @near[g], @near[b] ]
              elsif @plane == 'gb'
                  ret[1] = [ @near[r], @near[g], @far[b] ]
                  ret[3] = [ @near[r], @far[g], @near[b] ]
              else # @plane == 'rb'
                  ret[1] = [ @near[r], @near[g] ,@far[b] ]
                  ret[3] = [ @far[r], @near[g], @near[b] ]
              end
      
              return ret
      
          end # get_corners()
      
      end # of class Rectangle
      

      And here's what I was messing around with last night:

      ########################
      # blackbox.rb
      ########################
      
      require 'sketchup'
      load '/r/martins_sketch_talk2.rb'
      
      #unless file_loaded?("blackbox.rb")
      #  mymenu = UI.menu('Plugins').add_submenu('Dereks #Plugin Collection')
      #  mymenu.add_item('Black Box Creator') 
      #  {(Blackbox.new(true))}
      #  file_loaded("blackbox.rb")
      #end
      
      def boxes()
      
      all
      del
      
      glazing_ratio = 0.5
      building_height = 15.0
      eW_NsRatio = 1.5
      width = 25
      inputs = [0,0,0]
      
      prompts = ['Glazing Ratio;', 'Building Height;', 'EW to NS ratio;']
      defaults = [glazing_ratio, building_height, eW_NsRatio]
      inputs = UI.inputbox(prompts, defaults, 'blackbox')
      
      glazing_ratio = inputs[0].to_f
      building_height = 12*inputs[1].to_f
      eW_NsRatio = inputs[2].to_f
      width *= 12
      
      #create initial box
      box ([0,0,0], [width,width/(eW_NsRatio),0], building_height)
      
      #add windows to front side based on glazing area
      area_front = building_height * width
      window_area_front = area_front * glazing_ratio
      window_ratio = width/building_height
      window_height = (window_area_front/window_ratio)**0.5
      window_width = window_area_front/window_height
      r ([(width-window_width)/2,0,(building_height-window_height)/2],[(width+window_width)/2,0,(building_height+window_height)/2])
      
      end
      
      # End of blackbox.rb
      

      You'll note a bunch of things, I'm sure - but here are my most immediate questions:

      The box and rectangle are each created as a group, but I can't understand from the code WHY they are created as a group. How would I change this? Even just exploding them after creation would be fine for me at this point...

      I was trying to follow some other scripts to understand how one puts a plugin into the Plugins dropdown, but couldn't figure it out. Using the Ruby Code Editor plugin from this site - I got as far as you can see in the code above. But don't understand the {My_module::my_method} line (assume is has to do with "when you click on this - what is supposed to happen")

      Finally - is there a way to set materials through a Ruby script? Let's say I wanted the box to be wood, but the rectangle to be glass, for instance

      There you have it - I want to make a box with a window. Anyone feel like pointing a n00b in the right direction?

      Great forum - btw. πŸ‘

      Derek

      1 Reply Last reply Reply Quote 0
      • K Offline
        kybasche
        last edited by

        Bit of an update:

        I've hacked my "plugin" a bit more.

        1. Fixed the "menu" problem - the plugin now properly displays in the menu and will run when I tell it to.
        2. Fixed the "shapes as groups" problem with the exploder.rb plugin's recursiveExploder function

        Can't figure out how to "paint" an object, though.

        I want the initial rectangle to be translucent glass. The box doesn't need to have any special material assignment.

        Any tips for assigning a material to an entity if that material is not in the model already?
        And by creating the box after the "window" - will the translucency be lost?

        (TO DO: Learn how to create layers. Learn how to set entity attributes like layer.)
        I'll keep trying πŸ˜„

        Derek

        1 Reply Last reply Reply Quote 0
        • Chris FullmerC Offline
          Chris Fullmer
          last edited by

          Hey Derek, are you still using Martin's plugin? I don't think any of us here know what his plugin does. It might very well force the creation of new objects to always be as components or groups. If you're going to be making your own plugin, I'd recommend not building it using his as a base. Plus it will be easier for us to help debug if you are just using the regular SketchUp API, instead of Martin's.

          Lately you've been tan, suspicious for the winter.
          All my Plugins I've written

          1 Reply Last reply Reply Quote 0
          • TIGT Offline
            TIG Moderator
            last edited by

            Make a reference to the model to avoid too much typing
            model=Sketchup.active_model

            Decide in which 'context' the box will be: there are several possibilities.
            ents=model.entities
            which is the model's entities even if you are currently inside a group-edit etc.
            ents=model.active_entities
            which is the entities that are 'current'; e.g. could still be the model's entities or if you're inside a group-edit it's the group's entities, or inside an component-instance-edit its the component's definition's entities.
            or if you have reference to a group or definition it can be specified as that entities context thus:
            ents=group.entities
            or
            ents=definition.entities

            For this example we will make a group and add a box to it - there are very good reasons for this - as groups separate geometry so we won't affect anything existing as we work - we can explode it later if desired...
            first make the empty group in the active_entities
            group=model.active_entities.add_group()
            then make a reference to its entities
            ents=group.entities

            Now lets specify the four coplanar points for the box's base
            points=[[0,0,0], [1,0,0], [1,1,0], [0,1,0]]

            Add a rectangle face (1" square)
            face=ents.add_face(points)

            Note - the direction you add the points to make the face affects whether it looks up or down... BUT for a face drawn at z=0 Sketchup always makes it looking down!

            Now make a box from the face 1" high
            face.pushpull(-1)
            Note that a pushpull is in the direction of the face, so as it's looking down we use -1 to extrude it up in the other direction...

            You now have a box drawn inside a group.
            To explode that group use
            group.explode

            This is a relatively simple thing to do - try with other shapes and face orientations...

            Tips: if you make a face that is the 'wrong-way-round' use face.reverse! to flip it to look the other way OR change the +/- of the pushpull distance.
            Any numbers are taken as inches, irrespective of the models units; however you can specify other units if desired - e.g. face.pushpull(-2.5**.cm**) will make the box 2.5cm high etc...

            TIG

            1 Reply Last reply Reply Quote 0
            • K Offline
              kybasche
              last edited by

              🀣

              I knew it had to be easy.

              Speaking of which - does anyone have recommendation for good learning resources, that I might at some point get to asking useful questions?

              Thanks a bunch for all the help!

              Derek

              1 Reply Last reply Reply Quote 0
              • jolranJ Offline
                jolran
                last edited by

                @unknownuser said:

                Speaking of which - does anyone have recommendation for good learning resources, that I might at some point get to asking useful questions?

                Well, this forum πŸ˜„

                Depending on your level of expertise, Automatic Sketchup is a good start.

                http://www.autosketchup.com/

                1 Reply Last reply Reply Quote 0
                • thomthomT Offline
                  thomthom
                  last edited by

                  @kybasche said:

                  :roflmao:

                  I knew it had to be easy.

                  Speaking of which - does anyone have recommendation for good learning resources, that I might at some point get to asking useful questions?

                  Thanks a bunch for all the help!

                  Derek

                  Have a look at the sticky thread in the Developers section. An important part to pay attention is wrapping your code in a module to avoid clashes with other scripts.

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

                  1 Reply Last reply Reply Quote 0
                  • TIGT Offline
                    TIG Moderator
                    last edited by

                    Well said thomthom...
                    My code snippets will work in the Ruby Console for testing...
                    BUT a typical format for simple code is
                    ` module Kybasche
                    def self.box()

                    box code in here

                    end
                    endThen Kybasche.box()` draws a box
                    You add to it with extra code, like a dialog for its sizes or material[s]...
                    If you want to make a tool [class] where you pick points etc then this can be done inside the module too...

                    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