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

    Using an observer to delete a screen note

    Scheduled Pinned Locked Moved Developers' Forum
    31 Posts 5 Posters 3.7k 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.
    • J Offline
      Jim
      last edited by

      The ShadowInfo is part of the model, so when you open an existing model or start a new model, you need to attach your observer to the new ShadowInfo.

      You can automate this by using an AppObserver to notify the script when a model is opened or created, and attach the ShadowInfoObserver at that time.

      Note on Macs, you can have more than a single Model open. Not so on Windows where there is always only a single Model available.

      Hi

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

        Wouldn't this be a perfect job for the FrameChangeObserver ??

        I'm not here much anymore.

        1 Reply Last reply Reply Quote 0
        • J Offline
          Jim
          last edited by

          I don't think the FrameChangeObserver works either when exporting an animation.

          Hi

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

            That's interesting. I've never noticed that observer (I tend to stay away form them after hearing all of Thom's problems with them). That seems like it would be a great one to use here if only it worked during animation export.

            Chris

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

            1 Reply Last reply Reply Quote 0
            • P Offline
              pvbuero
              last edited by

              Hello,

              it's a pity that I read this post just now, when I finished my little plugin using the shadowinfo_observer to achieve exactly what danbig described. Display the Shadowtime for different shading situations.
              My Plugin works perfectly. I was proud of it until I tried an animation export 😑
              Is this problem solved by now?
              It seems not very sophisticated to me, to write notes on every page which are hidden when another page is displayed...
              is there no other way ?

              Matthias

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

                @chris fullmer said:

                That's interesting. I've never noticed that [FrameChangeObserver observer] ...

                Yes that is because is one of the API missing class boo-boos. It IS mentioned within the API, in passing.
                Pages.add_frame_change_observer
                Pages.remove_frame_change_observer

                It was featured (documented) in the Sketchup API BlogSpot:
                Dynamic Components that react to scene (aka page) changes

                ('scenes.rb') Code properly formatted (by Todd Burch) at:
                http://www.smustard.com/forum/viewtopic.php?f=9&t=25

                It basically only has one event callback:
                frameChange( fromPage, toPage, percent_done ),
                the intialize method, plus any custom method(s) you need inside to keep your code readable and organized.

                @chris fullmer said:

                That seems like it would be a great one to use here if only it worked during animation export.

                I guess the animation export is a manual 'built-in' C++ side plugin? And as such all Ruby processing stops? (..similar to what happens when the App Modal 'Preferences' dialog opens.)
                .. or is it a special way of running an Animation object?

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • D Offline
                  danbig
                  last edited by

                  I, for one, have decided that I have a knack for attempting the most complicated tasks as my "test project" in a new area. πŸ˜’

                  Matthias: I'm sorry that you got so far before realizing the issue with the shadowinfo_observer. This is a lesson that I've learned too many times: test code at the smallest possible snippets, and verify it's functionality individually before putting it all together into a larger code block.

                  1 Reply Last reply Reply Quote 0
                  • P Offline
                    pvbuero
                    last edited by

                    @danbig said:

                    I, for one, have decided that I have a knack for attempting the most complicated tasks as my "test project" in a new area. πŸ˜’

                    danbig,
                    It's dawning on me that this might be true for me too πŸ˜’

                    I try the approach with one note per page. Hopefully this will be more successful πŸ˜‰

                    Matthias

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

                      It really is not all that difficult to make your script export a series of jpgs that can then turned into a movie (its more dificult for the user though 😞 ). But if you feel that is an option, you could try writing your own export method and then you can update the screen text for each frame easily that way.

                      Chris

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

                      1 Reply Last reply Reply Quote 0
                      • P Offline
                        pvbuero
                        last edited by

                        @chris fullmer said:

                        It really is not all that difficult to make your script export a series of jpgs
                        Chris

                        Chris,

                        can I also export directly into an avi file somehow ?
                        To make it a bit easier for the user ... πŸ˜‰

                        Matthias

                        1 Reply Last reply Reply Quote 0
                        • D Offline
                          danbig
                          last edited by

                          @chris fullmer said:

                          It really is not all that difficult to make your script export a series of jpgs that can then turned into a movie (its more dificult for the user though 😞 ). But if you feel that is an option, you could try writing your own export method and then you can update the screen text for each frame easily that way.

                          Chris

                          "Difficult" being a relative term here. πŸ˜‰

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

                            Oh I agree. But really exporting an image is not that hard. For me, the hardest part BY FAR was getting it recognize the location I was trying to save it. I really struggle with ruby and files/paths. Its is remarkably painful. But you might be able to use the save dialog box and let the user supply the path easier than hard coding like I think I did.

                            Chris

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

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

                              @pvbuero said:

                              @chris fullmer said:

                              It really is not all that difficult to make your script export a series of jpgs

                              can I also export directly into an avi file somehow ?
                              To make it a bit easier for the user

                              A thot... πŸ’­

                              .. I wonder if MS MediaPlayer or MovieMaker or PhotoStory could be run in batch mode, to stitch a collection of image files (in a folder,) into a AVI, by calling the exe with command line parameters.

                              Many of the old SlideShow executables would do similar for a slideshow. (Which is now built into XP.)

                              If not, perhaps out there somewhere, is a command line "AVI maker" executable that would do the job.

                              I'm not here much anymore.

                              1 Reply Last reply Reply Quote 0
                              • D Offline
                                danbig
                                last edited by

                                Call me unambitious, but I'm back to the strategy of placing the screen note on each scene, and hiding it on all the others. It would work for my workflow, and it seems digestible for me.

                                I could then use the standard "export to animation" function to either jpg or avi, and (I think) it would come out as expected.

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

                                  I really don't blame you, that is a sensible way to do it I think.

                                  @Dan R., there is a free command line encoder called mencoder that will take a series of still images and turn it into any video format. It is Win, Mac, Linus capable too. I have thought to write a ruby to test out its capabilities half a dozeon times, and jhust never fully sat down and done it. If anyone ever does look at it, it would be awesomw if they posted their code snippet that interacts with that command line encoder.

                                  Chris

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

                                  1 Reply Last reply Reply Quote 0
                                  • P Offline
                                    pvbuero
                                    last edited by

                                    @danbig said:

                                    Call me unambitious, but I'm back to the strategy of placing the screen note on each scene, and hiding it on all the others. It would work for my workflow, and it seems digestible for me.
                                    I could then use the standard "export to animation" function to either jpg or avi, and (I think) it would come out as expected.

                                    I made it that way and it works:

                                     
                                    shadowtime_on_screen = [sunrise..sunset]
                                    
                                     for hour in sunrise..sunset
                                      time = Time.gm(2010,month,day,hour,minute,00)
                                      shadowinfo["ShadowTime"]= time
                                      shadowinfo["DisplayShadows"]= true 
                                      shadowtime_on_screen[hour] = Sketchup.active_model.add_note (shadInf.shadowtimetxt,0.1,0.2)
                                      shadowtime_on_screen[hour].hidden = true
                                     end
                                      for hour in sunrise..sunset
                                       time = Time.gm(2010,month,day,hour,minute,00)
                                       shadowinfo["ShadowTime"]= time
                                       shadowtime_on_screen[hour].hidden = false
                                       page = Sketchup.active_model.pages.add time.strftime("%d %b %H;%M Uhr")
                                       shadowtime_on_screen[hour].hidden = true
                                       page.delay_time= 0
                                       page.transition_time= 3
                                     end
                                    

                                    First I create all the notes on the screen and hide them, then I unhide one by one and create the corresponding pages.

                                    My next step will be to allow steps which are different from one hour... and as I learnd here I have to deal with jquery (sigh) to enter the start and the end time...

                                    Matthias

                                    1 Reply Last reply Reply Quote 0
                                    • D Offline
                                      danbig
                                      last edited by

                                      @unknownuser said:

                                      I made it that way and it works:

                                       
                                      shadowtime_on_screen = [sunrise..sunset]
                                      
                                       for hour in sunrise..sunset
                                        time = Time.gm(2010,month,day,hour,minute,00)
                                        shadowinfo["ShadowTime"]= time
                                        shadowinfo["DisplayShadows"]= true 
                                        shadowtime_on_screen[hour] = Sketchup.active_model.add_note (shadInf.shadowtimetxt,0.1,0.2)
                                        shadowtime_on_screen[hour].hidden = true
                                       end
                                        for hour in sunrise..sunset
                                         time = Time.gm(2010,month,day,hour,minute,00)
                                         shadowinfo["ShadowTime"]= time
                                         shadowtime_on_screen[hour].hidden = false
                                         page = Sketchup.active_model.pages.add time.strftime("%d %b %H;%M Uhr")
                                         shadowtime_on_screen[hour].hidden = true
                                         page.delay_time= 0
                                         page.transition_time= 3
                                       end
                                      

                                      Is this code ready to execute through the console or webconsole? I get an "undefined local variable" error for sunrise when I evaluate it.

                                      What I'd like to do is merge your code, above, with this script (Chris essentially wrote this, and I have simply tweeked it to suit my needs):
                                      I'm not as concerned with sunrise and sunset, if those values are used in your script. I prefer to set the start and stop times myself, and create the screen notes associated with the times and intervals I have chosen.

                                      model = Sketchup.active_model
                                      si = model.shadow_info
                                      ps = model.pages
                                      si["DisplayShadows"]= true
                                      #set the year, month, day, and time of first shading scene as follows; (year,month,day,hour,min,sec)
                                      t = Time.gm(2010,"dec",1,9,0,0).to_i
                                      
                                      
                                      #set number of days to repeat
                                      31.times do |day|
                                      si["ShadowTime_time_t"]=t
                                      page = ps.add
                                      #set scenes to save camera position (true or false)
                                      status = page.use_camera=false
                                      #set scene transition time to 0 from PM of previous day to AM of next day
                                      page.transition_time = 0.0
                                      #set hours from first scene for day until second scene for the same day (sec*min*hours)
                                      t= t+(60 * 60 * 6)
                                      si["ShadowTime_time_t"]=t
                                      page = ps.add
                                      status = page.use_camera=false
                                      page.transition_time = -1
                                      #set hours from second scene for day, until first scene of next day (sec*min*hours)
                                      t= t+(60 * 60 * 18)
                                      end
                                      
                                      
                                      1 Reply Last reply Reply Quote 0
                                      • Dan RathbunD Offline
                                        Dan Rathbun
                                        last edited by

                                        @danbig said:

                                        Is this code ready to execute through the console or webconsole?
                                        NO.. because it is NOT wrapped in a module. When you run code like this in the console (or webconsole,) it runs INSIDE class Object. EVERYTHING in Ruby is a subclass of class Object, and inherits all of it's methods, constants and most important, it's local variables. (Say "Reference clashes, boys and girls!")
                                        When you declare a sunrise var (or any other var using a common word like start and stop,) in the console (ie, in Object,) you run the risk of clashing (overwriting,) a var of the same name, by another script (if it is also not module wrapped.)

                                        @danbig said:

                                        I get an "undefined local variable" error for sunrise when I evaluate it.
                                        You'd get the same for sunset.
                                        It's obviously a snippet from a larger script, where these local vars are predefined, most likely grabbing them from the model's ShadowInfo settings.

                                        Stay within YOUR namespace, YOUR namespace is your friend. It protects your code from the rest of the world, and visa versa.
                                        Don't have a namespace?
                                        Let's invent one, how about Danbig ?? (..you can chose another, but for example's sake..)

                                        In EACH and EVERYONE of your Ruby script files, all your code will be wrapped inside a Danbig module block, like:
                                        ` module Danbig

                                        code goes here.

                                        end # Danbig`
                                        Then for each separate plugin, you create a submodule inside YOUR Danbig namespace, so that YOUR plugins do not clash with each other. Like:

                                        module Danbig
                                          module ShadowAnim
                                            #
                                            # code goes here.
                                            #
                                          end # ShadowAnim
                                        end # Danbig
                                        

                                        The beauty is that module and class definitions can span across multiple files (but method defs cannot, a method def will totally redefine any method that is already defined***.)

                                        *** This is why you should NOT define methods in the console (inside Object,) as they will often end up redefining someone else's method, or worse (and it's happened,) one of the important Ruby methods of Object or Kernel [which is mixed-into Object,] causing problems for EVERYONE.)

                                        Anyhow.. you'd refer to your animation start method as:
                                        Danbig::ShadowAnim.start
                                        using the **::** scope operator.

                                        Now you don't need $global vars to share settings or info among your plugins. Just create either CONSTANTS, @@class vars or @attributes inside the Danbig module.
                                        Constants can be refered to (in individual plugin submodules,) as Danbig::CONSTANTNAME
                                        For @@ or @ vars you'd make getter and setter methods inside Danbig. It's easy to make @vars with the attr_accessor method.
                                        ` module Danbig

                                        setup common @vars for ALL my plugins

                                        attr_accessor(:time,:starttime,:endtime,:danbigmenu) #etc.
                                        endcreates attribute vars: @time @starttime @endtime @danbigmenuand methods: Danbig.time Danbig.starttime Danbig.endtime Danbig.danbigmenu Danbig.time= Danbig.starttime= Danbig.endtime= Danbig.danbigmenu=After attr_accessorthe @vars will all be nil, but you can (below that in code,) set them to an initial value inside the Danbig initialize` method.

                                        Oh! There I go again.. ranting on Namespaces. For more info from some of my other rants...
                                        http://forums.sketchucation.com/viewtopic.php?f=180&t=24356&p=255792#p254458
                                        and beginning post 4 at:
                                        http://groups.google.com/group/sketchupruby/browse_frm/thread/4f22a3ac2c3a8603/4d538051fc7cbf75?lnk=gst&q=File+spanning#4d538051fc7cbf75

                                        I'm not here much anymore.

                                        1 Reply Last reply Reply Quote 0
                                        • P Offline
                                          pvbuero
                                          last edited by

                                          it 's just an extract of the script with the part where the notes are added and where the pages are added with the corresponding note unhidden...
                                          My script is far from perfect therefore I'didn't want to post it here.

                                          If you keep in mind, that it's the work of a beginner you can see it here complete:

                                          require 'sketchup'
                                          
                                          Sketchup.send_action "showRubyPanel;"
                                          
                                          class ShadowInformation
                                           @@shadowinfo = Sketchup.active_model.shadow_info
                                           def sunrisetxt
                                             @sunrisetext = @@shadowinfo["SunRise"].gmtime.strftime("Sonnenaufgang;  %H;%M Uhr")
                                           end
                                          
                                           def sunsettxt
                                             @sunsettext = @@shadowinfo["SunSet"].gmtime.strftime("Sonnenuntergang;  %H;%M Uhr")
                                           end
                                           def shadowdatetxt
                                            @shadowdatetxt = @@shadowinfo["ShadowTime"].gmtime.strftime("Tag des Jahres;  %d.%b")
                                           end
                                          
                                          def shadowtimetxt
                                            @shadowtimetxt = @@shadowinfo["ShadowTime"].gmtime.strftime("Uhrzeit;  %H;%M")
                                           end
                                          end
                                          
                                          
                                          UI.menu("Plugins").add_item("Shadowanimation"){create_scenes}
                                          
                                          def create_scenes
                                          
                                           shadInf = ShadowInformation.new
                                           #UI.messagebox shadInf.shadowtimetxt
                                           @xpos_shadowtime = 0.1
                                           @ypos_shadowtime = 0.2
                                          
                                           shadowinfo = Sketchup.active_model.shadow_info
                                           #Stunde des Sonnenauf- und Untergang ermitteln
                                           von_Stunde = (shadowinfo["SunRise"].gmtime.hour.to_s)
                                           bis_Stunde = ((shadowinfo["SunSet"].gmtime.hour + 1).to_s)
                                          
                                          
                                           # Hier werden die Parameter fΓΌr die Verschattungsanimation abgefragt
                                           prompts = ["von-Stunde", "bis-Stunde"]
                                           defaults = [von_Stunde,bis_Stunde]
                                           list = ["1|2|3|4|5|6|7|8|9|10|11|12|","12|13|14|15|16|17|18|19|20|21|22|23|24"]
                                           input = UI.inputbox prompts, defaults, list, "Verschattungsanimation Voreinstellungen"
                                          
                                           sunrise = input[0].to_i
                                           sunset = input[1].to_i
                                           minute = 00
                                           day = shadowinfo["ShadowTime"].gmtime.day
                                           month = shadowinfo["ShadowTime"].gmtime.month
                                          
                                           shadowtime_on_screen = [sunrise..sunset]
                                          
                                           for hour in sunrise..sunset
                                            time = Time.gm(2010,month,day,hour,minute,00)
                                            shadowinfo["ShadowTime"]= time
                                            shadowinfo["DisplayShadows"]= true 
                                            shadowtime_on_screen[hour] = Sketchup.active_model.add_note (shadInf.shadowtimetxt,0.1,0.2)
                                            shadowtime_on_screen[hour].hidden = true
                                           end
                                            for hour in sunrise..sunset
                                            time = Time.gm(2010,month,day,hour,minute,00)
                                            shadowinfo["ShadowTime"]= time
                                            shadowtime_on_screen[hour].hidden = false
                                            page = Sketchup.active_model.pages.add time.strftime("%d %b %H;%M Uhr")
                                            shadowtime_on_screen[hour].hidden = true
                                            page.delay_time= 0
                                            page.transition_time= 3
                                           end
                                          Sketchup.active_model.add_note (shadInf.sunrisetxt,0.1,0.05)
                                          Sketchup.active_model.add_note (shadInf.sunsettxt,0.1,0.1)
                                          Sketchup.active_model.add_note (shadInf.shadowdatetxt,0.1,0.15)
                                          end
                                          

                                          The idea is, that you can choose the starting- and the end-hour and that sunrise-hour and sunset-hour are the default values...

                                          The next step would be the input of a start- and a end-time (instead of only the hour) and a that the time between the scenes could be choosen free. (instead of one hour steps).

                                          Matthias

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

                                            @pvbuero said:

                                            If you keep in mind, that it's the work of a beginner you can see it here complete:

                                            A few issues I see at first glance:

                                            It's NOT wrapped in a module with YOUR namespace name.

                                            ONLY Ruby base classes should ever be defined at the top level. "Base class" means a generic global class used by the entire Ruby world (not just the Sketchup scripting realm.)

                                            If you only need one copy of the code, it should probably be a module.
                                            But if say (on a Mac where there can be more than 1 model open,) if each model needs it's own 'copy' (called an instance,) then a class is the thing to write (probably within a module that tracks and controls the instances of your class.)
                                            ie:

                                            
                                            module Pvbuero
                                              module ShadowAnimManager
                                                class ShadowInformation
                                                  # instance methods
                                                end #class
                                                # menu setup code
                                                # other run once code
                                                def create_scenes
                                                  # code here
                                                end #def
                                              end #mod
                                            end #mod
                                            
                                            

                                            call it as: Pvbuero::ShadowAnimManager.create_scenes
                                            (you can name your submodules whatever you wish, it's YOUR namespace.)

                                            I'm not here much anymore.

                                            1 Reply Last reply Reply Quote 0
                                            • 1
                                            • 2
                                            • 2 / 2
                                            • First post
                                              Last post
                                            Buy SketchPlus
                                            Buy SUbD
                                            Buy WrapR
                                            Buy eBook
                                            Buy Modelur
                                            Buy Vertex Tools
                                            Buy SketchCuisine
                                            Buy FormFonts

                                            Advertisement