Question on an Animation

Hello,

We are currently working on a sun study for a new home. We know how to create an animation just fine, however, we now wish to include a time stamp within the animation so the client can see the time and date while viewing it so they can see the sun position at any given time and date. Has anyone been able to do something this?

Thank you!

It’s not a feature that you may have overseen in the animation export or in the scenes inspector. You could think of it like a “screen text” (or “note”) that updates whenever the time or date changes.

For such specific needs, SketchUp has been made extensible, and you can use the following short script as an extension. Paste it in Window → Ruby Console or paste it in an empty plain text (txt) file with file extension .rb and save it in the Plugins folder.
You can move the text using the move tool. Do you need a specific time format?

module AE
  module DynamicTimestamp
    def self.add_timestamp(model)
      time = model.shadow_info["ShadowTime"]
      string = time.strftime("%Y-%m-%d %H:%M:%S")
      note = model.add_note(string, 0.8, 0.99)
      observer = TimeObserver.new(note)
      model.shadow_info.add_observer(observer)
    end

    class TimeObserver < Sketchup::ShadowInfoObserver
      def initialize(entity)
        @entity = entity
      end
      def onShadowInfoChanged(shadow_info, type)
        if type == 0 && @entity.valid? # time / date sliders
          time = @entity.model.shadow_info["ShadowTime"]
          string = time.strftime("%Y-%m-%d %H:%M:%S")
          @entity.text = string
        end
      end
    end # class TimeObserver

    unless file_loaded?(__FILE__)
      command = UI::Command.new("Add Timestamp"){
        self.add_timestamp(Sketchup.active_model)
      }
      UI.menu("Plugins").add_item(command)
      file_loaded(__FILE__)
    end

  end # module DynamicTimestamp
end # module AE

Hey @Aerilius,

I’m was really excited to find your response because I’m trying to do a similar thing. I’d like to display a real-time count of instances of components, along with some other information. I’m new to using Ruby, and using Ruby with SketchUp, so I was trying to puzzle your code out.

Could you explain your TimeObserver class? I’m mostly confused about the following:

  def initialize(entity)
    @entity = entity
  end

and

time = @entity.model.shadow_info["ShadowTime"]
string = time.strftime("%Y-%m-%d %H:%M:%S")
@entity.text = string

These seem like they might be crucial to having one updating note, instead of an endless amount of new notes on top of each other.

It is not very clear to me what is unclear to you because I don’t know what you tried to do or what confuses you.

If you get an endless amount of new notes, your code probably creates a new note entity every time the observer is notified about a change of the observered property. That’s why we need to have a reference to the one single note (that we create once when the tool is launched) and just change its text.

By passing the note entity into the constructor of the observer, we tell the observer which note entity to update (and the observer does not need to create any note entities).

  def initialize(entity)
    @entity = entity
  end

When the update method of the observer is called, we can access the entity (because we saved it as an instance variable in the observer instance). We read the new value that we want to display and then apply it as the entity’s text.

string = get_somehow_what_you_want_to_display()
@entity.text = string

In case of a components counter, the desired property is not in shadow info, but we would have to count either from the definitions list, or from a specific component’s instances list. Here the question which observer class to use depends on how you want the counter to work and what it should count (instances of which component, or of all). Potentially you would have to deal with several observers which makes it complicated.

On which event should the number be updated?

One could also simply use a selection observer, and if the selection has size==1 and is a component instance, you read the number of instances of the component and set it as the note’s text. You could even add the component’s name:

@note_entity.text = "#{component_instance.definition.name}: #{component_instance.definition.instances.length}"

@Aerilius,

Thanks for your response - it was exactly what I was hoping for, especially the second paragraph.

I had a hunch that this was what I needed to do, but your explanation helps to confirm my conceptual understanding. I’m familiar with Java and C, somewhat, but the differences between those two languages (especially C, which is what I’m currently actively using) and Ruby was tripping me up. A local friend helped me understand your code at a syntax level; I think I get it now.

I’m in the middle of an apartment design project, and am attempting to write something simple that could display a real-time count of the number of each apartment unit type (each unit type as a component) on the screen, unwindowed (e.g. 1 bedroom = 5, 2 bedroom = 10, total units = 15). I was also thinking of keeping track of the square footages (per unit type, total). This way, I can glance at the numbers while I design, instead of stopping my thought process to manually count the units / calculate square footage, etc.

I was thinking of using a DefinitionsObserver, updating the entire note whenever a component was added or removed, and iterating over the entire definitions array (array?) to get each component’s count (or each relevant component’s count).

One thing that might be troublesome is when I have variations of a base component which I want to display as one type of component (e.g. components A1 = 2, A2 = 5, A3 = 3, B1 = 3, C1 = 1 to display as A = 10, B = 3, C = 1). I think I might be able to figure something out by looking at this, though!

Hey @Aerilius

thanks for the reply on this post. So i tried to do as you have mentioned here and would like to have some clarification since it doesn’t seem to work as expected for me. I pasted the code in ruby console and exported the animation. However, it shows a static time stamp. I would like to see a real time change in the time stamp depending on the shading time of each slide (although it is dynamic in the slides, it is static in the exported video). Also, the time stamp is UTC which I would ilke to change to my time zone. What should I do? TIA.

The plugin listens for changes of the shadow settings in the model. It looks like SketchUp’s animation exporter renders “off screen” without running the model through all scenes, thus the shadow info is not really changed. I wonder how animation plugins can make objects move in exported animations, when I change the ShadowInfoObserver to a FrameChangeObserver, it is also not triggered (maybe @thomthom knows more).

What you can do is to do a screen recording of that area of the screen and run the animation with View → Animation.

That’s a good question - I don’t really know myself how they do that…

On the other side, render engines can because they interact through the API. Maybe it’s just something that affects the animation exporter.

@Aerilius.
I have added this script, and the date stamp is showing up. However, it is not updating as the clock advances from scene to scene when I export an animation. It works fine in the model, but not in the exported video. The time stays constant, even as the sun moves.

Any guidance would be appreciated. Also, can I set this for PST?
Thanks

It should change to PST time zone if you set the UTC offset:

    time = model.shadow_info["ShadowTime"]
    time.localtime("-08:00")
    string = time.strftime("%Y-%m-%d %H:%M:%S")

The method for string formatting has also a %z flag to include the UTC offset literally, but that does not do a conversion. I believe the reason was that the shadow time did not include the time zone and setting it, the string formatter probably respects it by default.

I don’t know how to solve the animation export issue; if SketchUp’s animation exporter uses alternative, inconsistent way to animate shadows between scene transitions without updating shadow info, there is nothing to do. You could fallback to screen recording or taking a timed series of screenshots.

Thank you for the answer. With zero background in coding the link is very helpful.