• 登入
sketchucation logo sketchucation
  • 登入
ℹ️ GoFundMe | Our friend Gus Robatto needs some help in a challenging time Learn More

Custom Dynamic Component Functions = Ruby links

已排程 已置頂 已鎖定 已移動 Developers' Forum
30 貼文 9 Posters 12.1k 瀏覽
正在載入更多貼文
  • 從舊到新
  • 從新到舊
  • 最多點贊
回覆
  • 在新貼文中回覆
登入後回覆
此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
  • J 離線
    jeff hammond
    最後由 編輯 2011年5月7日 下午6:12

    i'm having second thoughts about diving too far into this stuff 😄

    but, with the stairs, i think i can accomplish what i want with a few clicks using the outliner, selection toys, and outer shell.
    i'm going to try to make the stairs today and i'll upload a .skp showing the DC result and the desired 'finished' component.

    with the other thing (the arc to angle blend), i would want it to do everything it's doing except there's a face or possibly a thickness to it.. (imagine that outline being drawn on a piece of 3/4ply and cut out).
    i can accomplish that now but i have to explode everything a few times in order to make a face.. i haven't used bomb.rb in a year or two because it was super slow but maybe it wouldn't be that bad on this(?).. i'll give that a shot in a little bit.

    dotdotdot

    1 條回覆 最後回覆 回覆 引用 0
    • T 離線
      TIG Moderator
      最後由 編輯 2011年5月8日 上午11:14

      To make the DC stringer as a 'solid 3D object' you'd still do the 'inputs' as before, BUT then output them to a new custom function - called say '=jcstringer(height,riser,board)' in the DC that runs when you update one of the values. You would not necessarily need the built-in DC functions used to calculate number of notches etc as these are now done inside Ruby-side code...
      The associated custom Ruby code would be 'def jcstringer(a)', which always takes its input as one array 'a', so height=a[0].to_l, riser=a[1].to_l, board=a[2].to_l etc...
      You could also pass a variable stringer-width, tread-width, and any other data etc etc...

      We can readily find the DC instance's definition and thereby its entities.
      First you'd erase that definition's entities: then take the passed values, use iterations etc and make a set of coplanar points for each vertex of the 'cut' stringer and add a face to the DC defn's entities using those. Then pushpull that face to the right width [here 2"] and finally do a Ruby-side DC redraw etc [if needed].
      This way you'll get a full 3D solid object as the stringer without any subcomponents in it.
      Whenever that stringer's value is changed the Ruby side discards the old geometry and makes new geometry...

      Initially it might be easier to start with something like a simple L-shape 'box' with 3 or 4 changeable dims. Then try remaking that with a custom function in Ruby code called from the DC. Once that's cracked you can move on to the more complex iterations etc in the Ruby to make 'step-notches' etc...

      TIG

      1 條回覆 最後回覆 回覆 引用 0
      • D 離線
        Dan Rathbun
        最後由 編輯 2011年5月8日 上午11:19

        @unknownuser said:

        (http://forums.sketchucation.com/viewtopic.php?f)":242wng0h]
        @jim said:

        Drop this in your plugins folder...

        class DCFunctionsV1
        > >   protected
        > >   def atan2(*a)
        > >     return Math;;atan2(a[0], a[1])
        > >   end
        > > end
        > > 
        

        Lemme do a quick fix on that...

        class DCFunctionsV1
        >   protected
        >   def atan2(a)
        >     return Math;;atan2(a[0], a[1]).radians
        >   end
        > end
        > 
        

        You are correct for the argument, in that the DC extension always passes the function arguments as an Array (so the ***** expansion operator is not needed.)

        However, all the other trig functions do not have built-in radians to degrees conversion, and to follow convention, the internal code for the function should be as Jim showed.

        If you wish degrees from a result that returns radians, you should use the DC function degrees( *radian_arg* ), as in:

        degrees( atan2(n1,n2) )

        require('dynamiccomponents.rb')
        if defined?($dc_observers)
          # only if DC extension is active
          class DCFunctionsV1
            protected
            def atan2(a)
              return Math;;atan2(a[0], a[1])
            end #def
          end #class
        end #if
        
        

        NOTE: modifying this class no longer makes it version 1

        I'm not here much anymore.

        1 條回覆 最後回覆 回覆 引用 0
        • T 離線
          TIG Moderator
          最後由 編輯 2011年5月8日 下午4:14

          Jeff

          This is the cut-stringer as a Ruby formula

          def jh_stringer(ar) ### ar==array of data...
            ###
            ents=Sketchup.active_model.entities ### for testing
            ### for a DC class DCFunctionsV1 class def you change to
            ### ents=@source_entity.definition.entities
            ###
            h=ar[0].to_l ### total height floor to floor e.g. 48"
            r=ar[1].to_l ### max riser e.g. 7.25"
            b=ar[2].to_l ### stringer board size e.g. 10" [from 2x10]
            ###
            g=9.25  ### going [i.e. tread size] 9.25"
            t=2.00  ### stringer thickness 2"
            tt=1.00 ### tread thickness say 1" ? ***
            hh=h-tt
            n=((hh/r)+0.5).round
            r=h/n
            a=Math.atan(r/g)
            b1=r/Math.acos(a)
            b2=b-b1
            gg=g*n
            bt=(b*Math.cos(a))-r
            g1=gg-((hh-bt)/Math.tan(a))
            pts=[[0,0,0]] ### start at the bottom of the first riser
            n.times{|i|                     ### no lower tread to 1st riser
              pts << [g*i,0,r+(r*i)-tt]     ### front edge of each tread
              pts << [g+(g*i),0,r+(r*i)-tt] ### back edge of each tread
            }
            pts << [gg,0,(hh-bt)]   ### the top u/side of stringer
            pts << [g1,0,0]         ### the bottpm u/side of stringer
            ###
            f=ents.add_face(pts)
            f.pushpull(t)
          end
          

          As a test def it makes the stringer in model entities.
          See the note on how to add it to the DC definition etc...
          Use as a custom function =jh_stringer(height, rise, stringer_boardwidth)

          TIG

          1 條回覆 最後回覆 回覆 引用 0
          • J 離線
            jeff hammond
            最後由 編輯 2011年5月9日 上午5:20

            tig, thanks

            i gotta admit though, i really don't feel like going down that rabbit hole.. i can see the possible addiction and i don't think i can afford another addiction at this point in my life 😄

            i tried out a new approach and i think it's going to work out good for me.. i can make these types of DCs a lot faster/easier because there are less factors to account for as these cutters only need to be exact on their cutting edges.. lengths/thicknesses/positions etc. can just run wild in many cases.
            for final components with multiple parts, i'll be able to reuse certain cutters instead of needed to reenter the parameters etc..

            here's the stringer example...

            (not fine tuned enough to deal with out_of_norm dimensions --ie. 12" rise etc.)

            i think this opens up a lot of possibilities with DCs (at least with the way my brain works 😄 )
            i'll try some things out this week with more complex shapes (ie- the things that i'd actually want to use DCs for) and post the results if they end up being decent..

            [edit] - i guess i should point out that this method requires sketchup PRO.. but that's obvious, right? : )


            click pic -> bigger

            dotdotdot

            1 條回覆 最後回覆 回覆 引用 0
            • J 離線
              jeff hammond
              最後由 編輯 2011年5月9日 上午6:06

              so, i've yet to see a good example of a DC stair stringer so i tried making one of my own (all of the other ones appear to ignore the fact that stairs are typically built out of standard sized materials) [but, if anyone knows of some good ones, feel free to share : ) ] ..very early into it, i ran into the problem (rather, limitation?) of dynamic components..

              you can't change angles of faces/edges/etc on a component.. to do that, you have to break the component down into smaller sub-components and by doing so, you lose the ability to have a single/solid component..

              if you ruby geniuses could figure out a way to either A) add faces to nested edges or b) find a way to control individual faces/edges within a component via DC then these things could be awesome.. otherwise, DCs appear to be limited to cubes for any practical construction application (and that's a huge limit imo because the cube type stuff is super easy to draw anyway)..

              here's the file for my Stringer dc:

              (re-upped.. fixed small error)

              if that stringer could somehow become one solid component then i'd be --> 😍

              otherwise, it's still a decent (and definite timesaver) calculator for the stringer but it's not so good for making .skp drawings of them.. regardless, i'm going to expand on the DC to include the support wall and stringer cap which will still let me make super quick cutlists on the job site..

              dotdotdot

              1 條回覆 最後回覆 回覆 引用 0
              • T 離線
                TIG Moderator
                最後由 編輯 2011年5月9日 上午8:32

                That's fine if you're happiest with this approach...

                TIG

                1 條回覆 最後回覆 回覆 引用 0
                • Q 離線
                  quiver
                  最後由 編輯 2012年4月5日 下午1:32

                  @unknownuser said:

                  if you ruby geniuses could figure out a way to either A) add faces to nested edges or b) find a way to control individual faces/edges within a component via DC then these things could be awesome.. otherwise, DCs appear to be limited to cubes for any practical construction application (and that's a huge limit imo because the cube type stuff is super easy to draw anyway)..

                  I wholeheartedly echo that request.. this would overcome a variety of issues for my work. I design for events, and have made all my own lighting fixtures / speakers / projectors etc, which are all DC's that I can adjust the attributes of (some of my library is published here: http://sketchup.google.com/3dwarehouse/cldetails?mid=e94a8eafed72d755701d728505a21ed0&prevstart=12). But I come across that stumbling block frequently, with wanting to do something as simple as move one face of a cube (not in alignment with the cube, but side-to-side.. like a parrallelogram)..

                  Custom functions are a helpful half-way point but if everyone needs the same ruby script installed to be able to utilise it, they don't serve all that well. Is there any way to address individual edges/faces of a component using ruby in a DC spreadsheet formula? If I can do that, and modify them using existing functions, then I'd be more than satisfied.

                  Thanks !

                  1 條回覆 最後回覆 回覆 引用 0
                  • J 離線
                    Jim
                    最後由 編輯 2012年4月7日 下午4:30

                    @unknownuser said:

                    --use component options to determine dimensions
                    --in outliner, click on 'CUTTERS'
                    --select 'Outer Shell' via solid tools
                    --select 'Subtract' via solid tools
                    --click on the orange board (stringer_uncut)
                    --explode
                    --the stringer will be a single solid component named 'Stringer'

                    Once the DC is configured, these steps could be automated into a single step (via a menu or tool button.) I am making the assumption of consistent Component names being used i.e Components named "Cutters" are always subtacted from Components named "Stringer_Uncut"

                    Hi

                    1 條回覆 最後回覆 回覆 引用 0
                    • J 離線
                      jeff hammond
                      最後由 編輯 2012年4月8日 上午12:42

                      @jim said:

                      Once the DC is configured, these steps could be automated into a single step (via a menu or tool button.) I am making the assumption of consistent Component names being used i.e Components named "Cutters" are always subtacted from Components named "Stringer_Uncut"

                      hey Jim.

                      since the time of this thread, I have automated the finishing parts of the DC using AppleScript. I found a pretty decent way to create macros for sketchup.. the macros are osx 'services' which (can) reside in a specific app's menus (or they can be available system wide)

                      which reminds me. maybe I should type up a thread showing how to accomplish this.

                      dotdotdot

                      1 條回覆 最後回覆 回覆 引用 0
                      • D 離線
                        Dan Rathbun
                        最後由 編輯 2012年4月8日 上午1:53

                        Jeff.. please DO.

                        Then if we can find a PC complement (likely OLE,) these "services" could be wrapped as Ruby objects or classes. A platform conditional if block would define the Ruby interface, using AppleScript on the Mac, and OLE on PC. In this way we could have a cross-platform Ruby interface for plugins.

                        I'm not here much anymore.

                        1 條回覆 最後回覆 回覆 引用 0
                        • J 離線
                          jeff hammond
                          最後由 編輯 2012年4月8日 上午2:33

                          @dan rathbun said:

                          Jeff.. please DO.

                          Then if we can find a PC complement (likely OLE,) these "services" could be wrapped as Ruby objects or classes. A platform conditional if block would define the Ruby interface, using AppleScript on the Mac, and OLE on PC. In this way we could have a cross-platform Ruby interface for plugins.

                          hmm. I'm not too sure it would work with what you're suggesting. (at least the way I've been going about it)

                          I'm doing GUI scripting so it's basically just keystrokes and menu items.. you can accomplish quite a bit this way (I actually have one script that uses a little but of ruby in there via the console 😄 )

                          the thing that's good about it is it's not very complicated so a lot of people should be able to make their own macros this way (and a bonus is that you don't have to install any additional software)..

                          dotdotdot

                          1 條回覆 最後回覆 回覆 引用 0
                          • J 離線
                            Jim
                            最後由 編輯 2012年4月8日 上午2:55

                            @unknownuser said:

                            I'm doing GUI scripting so it's basically just keystrokes and menu items..

                            The Windows equivalent can be accomplished via Windows Scripting.

                            Here's a VBScript example:

                            Sub Wait
                            	Wscript.Sleep(1500)
                            End Sub
                            
                            set WshShell = WScript.CreateObject("WScript.Shell")
                            'WshShell.AppActivate "- SketchUp"
                            Command = """C;\Program Files (x86)\Google\Google SketchUp 8\SketchUp.exe"""
                            'MsgBox Command
                            WshShell.Run(Command)
                            Wait
                            WshShell.SendKeys "%u" ' My SU Shortcut to open Ruby Console
                            Wait
                            WshShell.AppActivate "Ruby Console"
                            Wait
                            WshShell.SendKeys "require_all 'c;/plugins'{ENTER}"
                            
                            
                            
                            

                            Hi

                            1 條回覆 最後回覆 回覆 引用 0
                            • J 離線
                              jeff hammond
                              最後由 編輯 2012年4月8日 上午3:18

                              @jim said:

                              @unknownuser said:

                              I'm doing GUI scripting so it's basically just keystrokes and menu items..

                              The Windows equivalent can be accomplished via Windows Scripting.

                              Here's a VBScript example:

                              set WshShell = WScript.CreateObject("WScript.Shell")
                              > 'WshShell.AppActivate "- SketchUp"
                              > Command = "C;\Program Files (x86)\Google\Google SketchUp 8\SketchUp.exe"
                              > MsgBox Command
                              > WshShell.Run Command
                              > WScript.Sleep 1000
                              > WshShell.SendKeys "%u" ' My SU Shortcut to open Ruby Console
                              > WScript.Sleep 1000
                              > WshShell.AppActivate "Ruby Console"
                              > WScript.Sleep 1000
                              > WshShell.SendKeys "require_all 'c;/plugins'"
                              > WScript.Sleep 1000
                              > WshShell.SendKeys "{ENTER}"
                              > 
                              

                              is something like that easy to run from within sketchup? (that's sort of the beauty of osx services.. they become a menu item so activating the script is the same for anything else in sketchup.)

                              regardless, you guys could probably write a macro recorder in ruby that in turn produces these services :enlighten:

                              nothing to do with recording cursor movement etc.. AppleScript can't handle it.. (eg- edit component, select all, explode, generate faces, exit component)

                              those steps are what ruby watches, then places the commands in a .scpt format and moves them to the services folder.

                              [edit-- sorry for not cleaning up the quotes in my replies.. im on a phone and deleting big chunks of text is no fun 😄 ]

                              dotdotdot

                              1 條回覆 最後回覆 回覆 引用 0
                              • D 離線
                                Dan Rathbun
                                最後由 編輯 2012年4月8日 上午4:19

                                Yep.. what Jim said.. however, his example can also be written in Ruby (on PC using the Win32ole.so extension, which many users have already installed to their "Plugins" directory, or they have it in their full Ruby library directory, if they have installed the full Ruby edition, and pushed it's lib path into the $LOAD_PATH array.)

                                So to use the "SendKeys" example (which seems to be a common function name in many of the programming languages available, from low-level C, to the higher level languages such as VB, C# etc.)

                                Goal: To provide a cross-platform Ruby method, named SendKeys() that sends keystrokes to the Sketchup application.

                                1) Choose a community namespace. As an example, lets say (for argument's sake,) this will go within the SKX project namespace, and beneath that we'll wrap it within a GUI submodule.

                                module SKX; end # make sure outer namespace is defined
                                
                                module SKX;;GUI
                                
                                  if RUBY_PLATFORM =~ /(darwin)/i # on Mac
                                
                                    def self.SendKeys(keystring)
                                      # the Mac code using AppleScript
                                    end
                                
                                  else # on Windows
                                
                                    def self.SendKeys(keystring)
                                      # the WIN code using Windows Scripting Host
                                    end
                                
                                  end
                                
                                end # module SKX;;GUI
                                

                                This is the one file approach, which may not be the best, because it makes everyone update their file(s) even when a revision is made for a certain platform. I show it to make an important point about Ruby, in that it is a dynamic language that can be defined during runtime. (In this example, we would define the same method, two different ways, depending upon which platform it will run on.)

                                The separate file approach may be better. Where a user chooses an install package for the proper platform, so that their "Plugins/SKX/GUI" directory, only contains the Ruby object definitions for their platform.

                                To use this proposed feature, scripters would simply require the proper module definition file:

                                require("SKX/GUI/keyboard.rb") SKX::GUI::SendKeys("require_all 'c:/plugins'"+SKX::GUI::KBD::ENTER)

                                P.S.: Locally within a custom module or class, a scripter can create 'nickname' shortcut references that point at long nested qualified objects, like:
                                gui = SKX::GUI @kbd = SKX::GUI::KBD
                                or even:
                                ENTER = SKX::GUI::KBD::ENTER
                                So don't be afraid of well organized, multi-nested module namespaces.
                                Also.. if say, the KBD submodule was just a mixin module of constants, scripters could, if they wished, mix it into their module(s) or class(es) by inclusion:

                                module Author;;FancyPlugin
                                  require("SKX/GUI/keyboard.rb")
                                  include(SKX;;GUI;;KBD)
                                  # now all constants in KBD module, are mixed in.
                                end
                                

                                💭

                                I'm not here much anymore.

                                1 條回覆 最後回覆 回覆 引用 0
                                • J 離線
                                  jeff hammond
                                  最後由 編輯 2012年4月8日 下午5:10

                                  the wording in AppleScript is keystroke.

                                  keystroke "v" (for the v key)
                                  keystroke "V" (is for shift + v)
                                  keystroke "V" using command down (for shift-cmmd-v or paste in place)

                                  likewise, you can also do menu items:

                                  click menu item "Outer Shell" of menu "Tools"

                                  dotdotdot

                                  1 條回覆 最後回覆 回覆 引用 0
                                  • D 離線
                                    Dan Rathbun
                                    最後由 編輯 2012年4月8日 下午10:28

                                    @unknownuser said:

                                    the wording in AppleScript is keystroke.

                                    Yea.. and what is the point your making ??

                                    I'm not here much anymore.

                                    1 條回覆 最後回覆 回覆 引用 0
                                    • J 離線
                                      jeff hammond
                                      最後由 編輯 2012年4月9日 上午12:19

                                      @dan rathbun said:

                                      @unknownuser said:

                                      the wording in AppleScript is keystroke.

                                      Yea.. and what is the point your making ??

                                      just saying that ruby could write the macro script. (but I'm pretty sure I'm not thinking about doing this the right way 😉 )

                                      like if a user turns on the macro recorder (.rb plugin) then does a series of commands they want to automate then click 'stop ecording'(or whatever).. ruby will then write the commands used in a scpt file in the format of my previous post.. then puts it in the services folder so the user now has a sketchup macro without leaving sketchup or manually typing up an AppleScript.

                                      edit. oh, I was also just saying it's 'keystroke' in applescript as opposed to 'sendkeys'

                                      dotdotdot

                                      1 條回覆 最後回覆 回覆 引用 0
                                      • bmikeB 離線
                                        bmike
                                        最後由 編輯 2012年4月9日 上午1:23

                                        Jeff,

                                        Very much hope you do a thread on how to use services in Mac. I've moved back to Mac after a too long trip through various PCs and am very curious about Services, AppleScript, and Automator. Anything you put together for Services in SketchUp would be appreciated.

                                        mike beganyi design + consulting llc

                                        1 條回覆 最後回覆 回覆 引用 0
                                        • J 離線
                                          jeff hammond
                                          最後由 編輯 2012年4月9日 下午4:35

                                          @bmike said:

                                          Jeff,

                                          Very much hope you do a thread on how to use services in Mac. I've moved back to Mac after a too long trip through various PCs and am very curious about Services, AppleScript, and Automator. Anything you put together for Services in SketchUp would be appreciated.

                                          I'm going to do a thread today on it.
                                          I think I'll keep it super basic at first then the thread can evolve from there into the other possibilities.

                                          dotdotdot

                                          1 條回覆 最後回覆 回覆 引用 0
                                          • 1
                                          • 2
                                          • 1 / 2
                                          • 第一個貼文
                                            最後的貼文
                                          Buy SketchPlus
                                          Buy SUbD
                                          Buy WrapR
                                          Buy eBook
                                          Buy Modelur
                                          Buy Vertex Tools
                                          Buy SketchCuisine
                                          Buy FormFonts

                                          Advertisement