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

    Interaction with objects for simulation

    Scheduled Pinned Locked Moved Developers' Forum
    16 Posts 4 Posters 462 Views 4 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.
    • N Offline
      nickinwv
      last edited by

      Good evening,
      I'm new to plugin programming, though I've been using Sketchup for several years on an occasional basis and have programming experience in other languages - as an engineer, not a dedicated programmer. I am trying to write a simulation for bicycling, but can't see how to make it respond to controls like Sketchy Physics does. Can anyone give me ideas on how to go about it. I've tried the animation command in the API, and just drawing/redrawing the model after calculating each frame and neither does what I want. The model will have to respond to changes in hill slope, rider power, winds and braking. The reason I prefer not to use SP is that I want it to run fast enough to have smooth movement (I'm on an XP machine). Any help would be appreciated.
      Thank you and Happy Holidays,
      Nick

      1 Reply Last reply Reply Quote 0
      • N Offline
        nickinwv
        last edited by

        Anybody? I'm kind of anxious to find a solution.
        Thanks.
        Nick

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

          SketchUp has NO understanding of physics built into its core. You will have to program that yourself, or use an existing physics library and then tie it into SketchUp - which is what Sketchyphysics does. It uses an existing C or C# (or something) physics library.

          So you have to write the physics yourself, or borrow them. Not for the faint of heart in my opinion.

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

          1 Reply Last reply Reply Quote 0
          • N Offline
            nickinwv
            last edited by

            @chris fullmer said:

            SketchUp has NO understanding of physics built into its core. You will have to program that yourself, or use an existing physics library and then tie it into SketchUp - which is what Sketchyphysics does. It uses an existing C or C# (or something) physics library.

            So you have to write the physics yourself, or borrow them. Not for the faint of heart in my opinion.

            Chris,
            Thanks for the reply. The physics part is easy for me, I've been doing that professionally for 30-some years and I'm making a simplified model of the physics. What I don't get is how to animate Sketchup interactively (like SketchyPhysics does). I've only seen examples of scripted or key-frame animations, what I want to do is have the animation respond to changes that occur in each frame. Looked at the ruby source for Sketchy Physics and couldn't see how they do it there. Was wondering if anyone else has done this and can explain it or point me to a good example.
            Thanks.
            Nick

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

              Haven't done anything like that, but have you looked at the Animation class? http://code.google.com/apis/sketchup/docs/ourdoc/animation.html

              And Group.move! & ComponentInstance.move! - moves a group/component instnace without adding the event to the undo stack.

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

              1 Reply Last reply Reply Quote 0
              • N Offline
                nickinwv
                last edited by

                @thomthom said:

                Haven't done anything like that, but have you looked at the Animation class? http://code.google.com/apis/sketchup/docs/ourdoc/animation.html

                And Group.move! & ComponentInstance.move! - moves a group/component instnace without adding the event to the undo stack.

                Thanks for the response thomthom, that's actually where I started with guidance from Martin Rhinehart's excellent tutorial series. However, as he explains, you can't use that for interactive animation because Sketchup computes the numerical stuff and graphic stuff in separate threads. Don't want to get too deep in the explanation here, but the end result is that the image skips from the start of the animation to the end without showing any of the scenes in between. Martin doesn't know any way around that, I'm trying to find one. Chris Phillips must have found a way because Sketchy Physics does it, not sure if anyone else has.
                Thanks again,
                Nick

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

                  @nickinwv said:

                  Don't want to get too deep in the explanation here, but the end result is that the image skips from the start of the animation to the end without showing any of the scenes in between.

                  It does? That's very odd. I thought that was the very purpose of that class to avoid that... πŸ˜• It's the kind of behaviour I'd expect from a loop - perhaps a timer loop.

                  You hadn't wrapped things up in a start_operation, did you?

                  So what about a timer loop?

                  Or... call view.refresh - which should force a refresh.

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

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

                    I'm pretty sure its the animation class. That lets you animate things - objects in the model - while the model is still active. Its how Dynamic components do it as well I think.

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

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

                      Nick, do you have a bare bones example of an Animation where only the start and end displays in the viewport? Maybe we can spot anything that's blocking the middle bit?

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

                      1 Reply Last reply Reply Quote 0
                      • Dan RathbunD Offline
                        Dan Rathbun
                        last edited by

                        If you wish to do things when the frame changes I think you'll need to use "the little-known" FrameChangeObserver

                        Google posted a full length example in the official Sketchup Blog (last year or more.)

                        Todd Burch, of Smustard, cleaned up the code, and posted the "cleaner" version at Smustard.com.

                        see this post for more links: http://forums.sketchucation.com/viewtopic.php?f=180&t=29163&p=254729&hilit=framechangeobserver#p254729

                        I'm not here much anymore.

                        1 Reply Last reply Reply Quote 0
                        • N Offline
                          nickinwv
                          last edited by

                          Good evening,
                          Thank you for your replies, sorry I'm so late in responding - I've been preoccupied with other things for a month.

                          1. Dan, I wasn't able to comprehend the frameobserver that you referred to. Would it be possible to post a simple example?

                          2. Here's a simple example of what I've tried with the "animation" command that doesn't work. It uses Martin Rhinehart's TransformableCI. My example is just the last few lines....

                          /r/anim1.rb - sample Animation

                          require 'sketchup'

                          transformable_ci.rb - a ComponentInstance with easy, transform!-based transformations

                          from Edges to Rubies - The Complete SketchUp Tutorial

                          Copyright 2010, Martin Rinehart

                          require 'sketchup'

                          $radians_per_degree = Math::PI/180.0

                          class TransformableCI
                          =begin
                          A TransformableCI can do move, rotate and scale transformations. The
                          developer creates a TransformableCI from a ComponentInstance and then
                          applies move(), rotate() and/or scale() methods directly, without needing
                          Transformation objects or methods.

                          Internally, the transformations are performed with the
                          ComponentInstance.transform!() method, recording changes on the undo stack
                          and redrawing immediately. (Use a MovableCI if you do not want to record
                          undo changes and view changes immediately .)

                          This is documented in the tutorial's Chapter 16.
                          =end

                          attr_reader :inst, :trans
                          
                          def initialize( inst )
                              @inst = inst
                              @trans = inst.transformation.to_a()
                          end # of initialize
                          
                          def move( *args ) # Point3d or Vector3d or [r,g,b]
                              arg = args[0]
                              if args.length == 3
                                  vec = Geom::Vector3d.new( args[0], args[1], args[2] )
                                  xform = Geom::Transformation.new( vec )
                                  @inst.transform!( xform )
                              elsif arg.is_a?( Array )
                                  vec = Geom::Vector3d.new( args[0] )
                                  xform = Geom::Transformation.new( vec )
                                  @inst.transform!( xform )
                              elsif arg.is_a?( Geom::Vector3d )
                                  xform = Geom::Transformation.new( args[0] )
                                  @inst.transform!( xform )
                              elsif arg.is_a?( Geom::Point3d )
                                  xform = inst.transformation().to_a()
                                  xform[12] = arg[0]; xform[13] = arg[1]; xform[14] = arg[2]
                                  @inst.transformation= xform
                              else
                                  raise "move cannot handle " + args[0].to_s()
                              end
                          end # of move()
                          
                          def rotate( point, plane_or_axis, degrees )
                              axis = make_axis(plane_or_axis)
                              degrees *= $radians_per_degree
                              xform = Geom::Transformation.rotation( point, axis, degrees )
                              @inst.transform!( xform )
                          
                          end # of rotate()
                          
                          def scale( *args )
                              case args.length
                                  when 1 then xform = Geom::Transformation.scaling( 
                                      args[0] )
                                  when 2 then xform = Geom::Transformation.scaling( 
                                      args[0], args[1] )
                                  when 3 then xform = Geom::Transformation.scaling( 
                                      args[0], args[1], args[2] )
                                  when 4 then xform = Geom::Transformation.scaling( 
                                      args[0], args[1], args[2], args[3] )
                              end
                              @inst.transform!( xform )
                          end # of scale()
                          

                          support functions

                          def make_axis( plane_or_axis )
                          
                              if plane_or_axis.is_a?( String )
                                  case plane_or_axis
                                      when 'rg' then axis = [0,0,1]
                                      when 'rb' then axis = [0,1,0]
                                      when 'gb' then axis = [1,0,0]
                                      else
                                          raise "Plane must be 'rg', 'rb', 'gb' or an axis."
                                  end
                              else
                                  axis = plane_or_axis
                              end
                          
                              return axis
                          
                          end # of make_axis()
                          
                          def inspect()
                              return '#<Transformable' + @inst.to_s() + '>'
                          end # of inspect()
                          

                          end # of class MovableCI

                          #================= Beginning of test code ===================
                          $mvbl = TransformableCI.new( Sketchup.active_model().selection()[0] )

                          for $i in [1..10] do
                          $mvbl.move( Geom::Vector3d.new(1, 0, 0) )
                          Sketchup.active_model().active_view().invalidate()
                          end
                          #================= endf test code ===========================

                          1 Reply Last reply Reply Quote 0
                          • Dan RathbunD Offline
                            Dan Rathbun
                            last edited by

                            1) Please enclose all code within [ code ] ... [ /code ] bbCode tags. You can edit your message... highlite all the code and click the [**Code**] button, on the edit post toolbar. (Those buttons are there to help you be a better poster!)

                            2) It is not necessary to repost Martin's code unless you modified it in some way (and you should have renamed it, and wrapped it within your own toplevel namespace, if you did.) Martin ALSO should have done this (and I "bitched" at him many times, but he decided to use the global ObjectSpace as his own, anyway)

                            3) The simple example is posted in the Google Sketchup API Blog:
                            http://sketchupapi.blogspot.com/2009/07/dynamic-components-that-react-to-scene.html

                            4) It is not formmatted correctly (if you cut and paste it from the webpage,) so Todd Burch reformatted it, and posted it here:
                            http://www.smustard.com/forum/viewtopic.php?f=9&t=25

                            IF you use it, RENAME the class "FrameChangeObserver" to something else, WITHIN your own toplevel namespace.
                            Ex:

                            module WVnick # <<-- unique toplevel namespace
                              module AnimTest
                                class FrameSpy
                                  # modified callback methods
                                  # from the Google example
                                end
                            
                                # your AnimTest code that uses
                                # an instance of your FrameSpy class
                            
                                # other methods, etc.
                            
                              end # module
                            end # module
                            

                            I'm not here much anymore.

                            1 Reply Last reply Reply Quote 0
                            • Dan RathbunD Offline
                              Dan Rathbun
                              last edited by

                              It does not work because (likely,) when the code loads, the part at the bottom runs (or is evaluated,) and there is probably no selection, so nothing happens.

                              You need to write event driven method code, that happens when the user chooses a menu item, or using a SelectionObserver subclass (beware of bugs in this class,) when the user changes the selection, or when the user presses a toolbar button, or using some other observer subclass, when something else happens.

                              You should be defining your code within your namespace. (And separating your various projects with sub-namespaces.)
                              When you do, you do NOT use global variables. (They are not needed and clutter up everyone's else global environment.)
                              Use local constants, module/class @@varnames, instance @varnames, or local varnames, WITHIN your namespaces (modules and classes.)

                              Please read some other free books (besides just Martin's tutorial. His work is heavily influenced by Java, and IMHO is not the Ruby way.)

                              The link in my signature line will lead to a bunch of info (dowmloadable books, etc.) I highly recommend read the old 'Pick-Axe' "Programming Ruby" even though it was written circa v1.6.x, it's still valid (except for the object reference.)

                              I'm not here much anymore.

                              1 Reply Last reply Reply Quote 0
                              • N Offline
                                nickinwv
                                last edited by

                                Dan,
                                Thanks for the quick, instructive and helpful reply. I have no formal training in any computer language and thus have been struggling with Ruby. Just when I'm thinking I've learned enough to get by I come across something that I need to know and that may take some time to understand. Given that this is strictly a hobby project right now that time is limited. I've got some questions - would it be better to correspond with you privately?

                                Main question is "Do I need SU Pro to use dynamic components?" I don't currently have it, or money to buy it.

                                I'm trying the FrameChangeObserver to see if that works any better.

                                btw The code i posted ran without errors, it just didn't do what I wanted it to. It moved the box 1 step and not 100.

                                1 Reply Last reply Reply Quote 0
                                • Dan RathbunD Offline
                                  Dan Rathbun
                                  last edited by

                                  @nickinwv said:

                                  btw The code i posted ran without errors, it just didn't do what I wanted it to. It moved the box 1 step and not 100.

                                  It ran only once, because there is only ONE object in the Array as you wrote it:

                                  for i in *Array_Literal_with_1_element* do
                                  ...
                                  end

                                  It happens that the single element is a Range object, but it does not matter what kind of object the elements are.

                                  To USE the Range as the loop control, you need to use:
                                  for i in 1..10
                                  ...
                                  end

                                  or
                                  steps = Array.new(10)

                                  [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
                                  then
                                  for i in steps
                                  ...
                                  end

                                  or simplier:
                                  10.times do |i|
                                  ...
                                  end

                                  NOTE: Be careful with the do keyword ! It is required if the loop statement is all on a single line. But if your iteration is a block over multiple lines, you must omit it, or the interpreter will not parse it correctly and give you and "unexpected end" or an "end expected" error. (Basically it cannot match up the " end"s with the correct blocks.)

                                  The times iterator method needs either a do .. end, or { ... }.

                                  There is also the upto iterator method:
                                  start = 1 stop = 10 start.upto(stop) do |i|
                                  ...
                                  end

                                  also can use literals:
                                  1.upto(10) do |i|
                                  ...
                                  end

                                  I'm not here much anymore.

                                  1 Reply Last reply Reply Quote 0
                                  • Dan RathbunD Offline
                                    Dan Rathbun
                                    last edited by

                                    @nickinwv said:

                                    "Do I need SU Pro to use dynamic components?"

                                    Not to use.

                                    You can can insert them (from say the 3D Warehouse, or the samples installed with Sketchup.)
                                    You can copy them, scale them, move them, etc.

                                    You can change their options.

                                    You can interact with them, via the Click Interact tool. (You'd need to turn on the DC toolbar.)

                                    Pro is only required if you wish to create or edit DCs via the app's GUI.
                                    Setting their options is somewhat involved (and there's a whole separate forum here for discussing DCs.)

                                    Advice...

                                    1. Learn Standard Ruby first. (The Sketchup API is just 3 modules, with encapsulated classes, that extends Ruby.)
                                    2. Then start with simple plugins and macros first. (Learn to crawl, before you try to walk, and before attempting to run.)
                                    3. Study what others have done first. (Stand on the shoulders of giants. Pay attention to the work of the most prolific coders in the Code Snippets index, and the Plugins Index (Plugins Forum).)
                                      Animation is an advanced catagory. Make sure you visit the Code Snippets index. (Jim Foltz posted an animation example I believe.)

                                    I'm not here much anymore.

                                    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