Dynamic Components reacting to Scene (aka Page) changes

Dynamic Components reacting to Scene (aka Page) changes

Postby snicolo » Tue Jul 28, 2009 12:43 am

Hi All,

I just wrote a blogpost about Dynamic Components reacting to scene changes.

You can find it at http://sketchupapi.blogspot.com/2009/07/dynamic-components-that-react-to-scene.html

enjoy.
Simone.
0
Simone Nicolo
QA Manager
www.sketchup.com
User avatar
snicolo 
 

Re: Dynamic Components reacting to Scene (aka Page) changes

Postby Chris Fullmer » Tue Jul 28, 2009 1:00 am

That's great, thanks Simone! I'll look it over when I get a chance, but it sounds quite interesting.

Chris
0
Lately you've been tan, suspicious for the winter.
All my Plugins I've written
User avatar
Chris Fullmer 
SketchUp Team
SketchUp Team
 

Re: Dynamic Components reacting to Scene (aka Page) changes

Postby JClements » Tue Aug 04, 2009 7:48 pm

Here is an sample file that Simone created.

After installing the script and opening SU and the .skp file, click on each scene to see what it looks like.
Then add any geometry to the model and replay the scenes and observe what a scene then displays.

I think you can see the possibilities for creating "triggers" to a model.
0
John | Illustrator | Beaverton, Oregon

JClements 
Premium Member
Premium Member
 

Re: Dynamic Components reacting to Scene (aka Page) changes

Postby Phil Rader AIA » Sat Aug 08, 2009 3:34 am

That is cool. Thanks Simone
0

Phil Rader AIA 
Premium Member
Premium Member
 

Re: Dynamic Components reacting to Scene (aka Page) changes

Postby goga63 » Thu Jan 09, 2014 3:25 pm

the plugin works perfectly. But I would like to add the ability to input values for scene changes.
I added code first :
Code: Select all
menu = UI.menu("PlugIns").add_item("Scenes") {
  prompts = ["looping scene ?  "]
  input = UI.inputbox prompts
  $sOptions_scenes=input
    }

you can now set the number of scenes in the cycle
and changed the code:
Code: Select all
attributes[SCENE_TRIGGER] = (((attributes[SCENE_TRIGGER].to_i+1)%5)).to_s

...to this:
Code: Select all
scene_loop = [$sOptions_scenes].to_i
attributes[SCENE_TRIGGER] = (((attributes[SCENE_TRIGGER].to_i+1)%scene_loop)).to_s


unfortunately the last piece of code does not work
Can someone suggest a solution ?
Here's the entire code of the modified plugin:
Code: Select all
#useful constants
# Copyright 2005-2008, Google, Inc.

# Permission to use, copy, modify, and distribute this software for
# any purpose and without fee is hereby granted, provided that the above
# copyright notice appear in all copies.

# THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#

# This code snippets allows you to have Dynamic Components
# that modify themselves based on a Scene Change
#
# They need to have at the top level the following attributes
# "scene_change" a boolean value that if true force the DC to react to scene changes
# and if false has the DC ignore the scene change
# and
# "scene_trigger" which is the index that is incremented every time there is a scene change and
# it is used to change attributes for the DC. 



# Attach our observer.
 menu = UI.menu("PlugIns").add_item("Scenes") {
  prompts = ["looping scene ?  "]
  input = UI.inputbox prompts
  $sOptions_scenes=input
    }


# Copyright 2005-2008, Google, Inc.

# Permission to use, copy, modify, and distribute this software for
# any purpose and without fee is hereby granted, provided that the above
# copyright notice appear in all copies.

# THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#

# This code snippets allows you to have Dynamic Components
# that modify themselves based on a Scene Change
#
# They need to have at the top level the following attributes
# "scene_change" a boolean value that if true force the DC to react to scene changes
# and if false has the DC ignore the scene change
# and
# "scene_trigger" which is the index that is incremented every time there is a scene change and
# it is used to change attributes for the DC.
#
#
# Author: Simone Nicolo

require 'sketchup.rb'


# Define the Frame Change Observer which is documented in the Pages class.
class FrameChangeObserver

def initialize
# @current page is used to make sure that the observer is only triggered by page changes
# This is to workaround the PC bug that does not correctly populate the fromPage variable in the
# callback to frameChange.
@current_page = Sketchup.active_model.pages.selected_page


end

# Callback triggered by the Frame change observer.
# fromPage is populated with the page we were coming from, toPage is
# populated with the page we were transitioning to
# and percent done contains the percentage of the transition that
# has completed.
def frameChange(fromPage, toPage, percent_done)

# If there has been a page change and it has completed
if (not toPage.nil? and percent_done == 1) then
if @current_page != toPage then
#update the current page
@current_page = toPage
#find the DCs that need redrawing, and redraw them.
find_dc_for_redraw
end
end
end

# This function finds all the DC's that need to be redrawn based on a scene transition and
# on the boolean scene_change attribute if scene_change is true, change and redraw
# the DC on a scene transition, if it is false do not change or redraw the DC.
def find_dc_for_redraw 


entities_list = Sketchup.active_model.entities

if entities_list != []
# For all the entities in the model
entities_list.each do |item|
type = item.typename
case type
# Find the Dynamic Component instances
when "ComponentInstance"
if not item.attribute_dictionaries.nil?
attributes = item.attribute_dictionaries[DICTIONARY_NAME]
# If they have a scene_change attribute that contains true
if (not attributes.nil? and attributes[SCENE_CHANGE] == 1.to_s)
# Increment the scene_trigger attribute.
# Here we are allowing the scene trigger attributes to only have the values
# 1, 2, 3, and 4.


scene_loop = [$sOptions_scenes].to_i

attributes[SCENE_TRIGGER] = (((attributes[SCENE_TRIGGER].to_i+1)%scene_loop)).to_s
if attributes[SCENE_TRIGGER] == "0" then
attributes[SCENE_TRIGGER] = 1.to_s
end
# Redraw the DC using the $dc_observers global variable.
$dc_observers.get_latest_class.redraw_with_undo(item)
end
end
end
end
else
UI.messagebox("There are no entities in this model!")
end
end

end

if not file_loaded? 'scenes.rb'
# Useful constants
# Dynamic Components dictionary name
DICTIONARY_NAME = "dynamic_attributes"
# Boolean attribute that turns on and off the reaction to a scene change for the DC
SCENE_CHANGE = "scene_change"
# Index attribute for the DC that is used to drive changes in the DC.
SCENE_TRIGGER = "scene_trigger"
# Attach the frame chage observer to the global Pages object.
id = Sketchup::Pages.add_frame_change_observer(FrameChangeObserver.new)
file_loaded 'scenes.rb'
end
0

goga63 
 

Re: Dynamic Components reacting to Scene (aka Page) changes

Postby Dan Rathbun » Thu Jan 09, 2014 6:31 pm

(1) It is NOT a plugin, it is a code example.

(2) It is NOT a very good example. (It was written long ago when Simone was new at Ruby.)

Because:

It defines plugin specific objects at the toplevel "main" instance of Object. This includes constants and classes.

It needs to be totally overhauled. (I see at least 1 bug in it. entities_list != [] will always be true because it is not an Array (or subclass,) object.)

Your modifications also violate community rules. Your creating a global var for use with only 1 plugin.

Please explain more specifically what you want to change with an inputbox ?
0
    I'm not here much anymore. But a PM will fire email notifications.
    User avatar
    Dan Rathbun 
    PluginStore Author
    PluginStore Author
     

    Re: Dynamic Components reacting to Scene (aka Page) changes

    Postby goga63 » Thu Jan 09, 2014 6:50 pm

    Dan, thank you for taking the time to answer my question
    In the source code in line :
    Code: Select all
    # Here we are allowing the scene trigger attributes to only have the values
     # 1, 2, 3, and 4.
     attributes[SCENE_TRIGGER] = (((attributes[SCENE_TRIGGER].to_i+1)%5)).to_s 

    determined how many scenes will loop. I would like to change this setting without changing the code. For this I am trying to use the InputBox. Вut my knowledge is not enough. can you help me ?
    P.S. Sorry for my English, I use Google translator
    0

    goga63 
     

    Re: Dynamic Components reacting to Scene (aka Page) changes

    Postby Dan Rathbun » Thu Jan 09, 2014 8:08 pm

    The whole example STILL needs an overhaul... but for now:

    :idea: UI.inputbox returns an array of values, even if there is only 1 input item.

    Code: Select all
    $sOptions_scenes[0]= "5"
    $sOptions_scenes[1]= 5

    menu = UI.menu("PlugIns").add_item("Scenes") {
      prompts = ["looping scene ?  "]
      input = UI.inputbox( prompts,[$sOptions_scenes[1]], "Enter Scenes" ) rescue [$sOptions_scenes[1]]
      $sOptions_scenes[0]=input[0].to_s
      $sOptions_scenes[1]=input[0]
        }


    and further down:

    scene_loop = $sOptions_scenes[0].to_i

    :geek:

    EDIT: DC redraws when the limit is reached, and trigger is reset to 0.
    0
      I'm not here much anymore. But a PM will fire email notifications.
      User avatar
      Dan Rathbun 
      PluginStore Author
      PluginStore Author
       

      Re: Dynamic Components reacting to Scene (aka Page) changes

      Postby goga63 » Fri Jan 10, 2014 7:30 am

      Dan , thanks for your help. I will study it.
      0

      goga63 
       

      SketchUcation One-Liner Adverts

      by Ad Machine » 5 minutes ago



      Ad Machine 
      Robot
       



       

      Return to Developers' Forum

      Who is online

      Users browsing this forum: Google Bot and 22 guests