Good evening the community!
I am new to the forum, although I have been using sketchup for many years.
I have not yet taken the time to train myself at Ruby.
I’m a landscape artist, and I draw my dynamic components of plants.
I would like to vary them according to the date of the sketchup shadows. Depending on the seasons, appear fruits, flowers, autumn foliage …
Sketchup does not propose to return this date information in the dynamic component functions!
This is only possible with a Ruby script.
I would like a code for:
Select all the dynamic components of the model and set them the “DateShadow” attribute that corresponds to the shadow date of the model.
Thanks Dan
Thanks for the responsiveness and quality of the response.
I will try with the help of another comrade on the Biblio3D forum to put this into practice.
I come back to you to tell you how progresses!
Our first step was to use elevation of the sun and angle
But the summer and spring seasons overlap with fall and winter.
It joins a celestial vault trigonometric located in Paris.
The zones are drawn according to the values provided by the values of the elevation of the sun and sketchup angles in the functions of the dynamic component.
thanks again
Best regards
I begin to understand your code, which proposes a change of state of a season attribute according to a list of 4 possible values.
With a return to the first value if one has reached the last one.
If I want more flexibility on the value of the non-season attribute but dateShadow.
For a flowering may last only a few weeks. And who are not the same as his neighbor. And yet both bloom in spring!
Without artificially varying season value. I prefer to retrieve in value the date of the shadows of the model.
This will allow me to vary it easily.
It lacks a right mouse click to “Update dateShadow attibut in dynamic component”
I did not try
I wanted to know if I was first on the right track!
Here is my first jet
Thank you for showing me my mistakes.
# encoding: UTF-8
require "sketchup.rb"
module SimJoubert
module SeasonalComponents
extend self
MENU_TEXT = "Update dateShadow DC attibuts"
DICT = "dynamic_attributes"
def command
selset = Sketchup::active_model.selection
if selset.empty?
# update ALL seasonal components
update_dc_date_attribut(Sketchup::active_model.definitions)
else
# update ONLY selected seasonal components
update_dc_date_attribut(selset)
end
end
def get_seasonal_dcs(collection)
# Filter the referenced collection to
dlist = Sketchup::active_model.definitions
dcs = dlist.select {|d| d.attribute_dictionary(DICT,false) }
# select only seasonal dynamic components
seasonal = dcs.select {|d| d.get_attribute(DICT,"Season",false) }
# as shown in previous posted example.
end
def update_dc_date_attribut(collection)
seasonal = get_seasonal_dcs(collection)
# 1. Retrieve data from shadowinfo into local variables,
model = Sketchup.active_model
shadowinfo = model.shadow_info
# 2. Iterate the seasonal component definitions
value = shadowinfo["DayOfYear"]
# writing the data into dictionary attributes.
seasonal.each {|d| d.set_attribute(dict,"Season",value) }
end
# other code / methods here
unless file_loaded?(__FILE__)
UI.add_context_menu_handler do |context_menu|
context_menu.add_item(MENU_TEXT) { command() }
end # context_menu_handler
end
end # plugin module
end # outer namespace module
I don’t know how stylised the code in the message .
It looks like you are using single quotes not backticks. The backtick is the character on the key at upper left of your keyboard, with tilde ~ as the shifted char.
I have a ‘date’ attribute and I want ruby to update my attibut date with the date generated by the shadows
For example if I take today’s date, ‘shadowinfo [’ DayOfYear ‘]’ returns me how to write a piece of code to update the value ‘shadowinfo [’ DayOfYear ‘]’ in the ‘date’ attribute of My dynamic component
I am french and very bad in english, sorry for my english translated by google
I tried without success!
I can not set the “Season” attribute with the value of the day variable.
def update_dc_date_attribut(collection)
# seasonal = get_seasonal_dcs(collection)
# 1. Retrieve data from shadowinfo into local variables,
model = Sketchup.active_model
shadowinfo = model.shadow_info
# 2. Iterate the seasonal component definitions
day = shadowinfo["DayOfYear"]
UI.messagebox("le Jour de l'année est: " + day.to_s)
# writing the data into dictionary attributes.
seasonal.each {|d| d.set_attribute(DICT,"Season",day) }
end
DC attribute keys must be all lowercase.
(We were referring to the attribute label, which can be title case.)
So we must reference it as “season” instead.
This uses a dict local variable, instead of the module constant DICT, in the update_dc_date_attribut() method. We also need to use the lowercase attribute key name “season” instead of the attribute text label.
There also was an error in the get_seasonal_dcs() method where it checked for seasonal attributes.
(Besides using the correct lowercase key name,) when the “season” attributes were unset, or nil, the test for the attribute returned nil, which caused the boolean test inside the select() method’s block to give false result even upon dictionaries with a “season” key. (In the Ruby language, nil and false evaluate as boolean FALSE, but all other objects evaluate as boolean TRUE.)
So this fails with brand new unset (empty) “season” attributes:
# encoding: UTF-8
require "sketchup.rb"
require "pp"
module SimJoubert
module SeasonalComponents
extend self
@@context_menu_set ||= false
@@debug ||= false
MENU_TEXT = {
:update => "Update season DC attibuts",
:create => "Create season DC attibuts"
}
DICT = "dynamic_attributes"
SEASON_ATTR = "season"
def command_create(selset)
return if selset.empty?
# Make the definitions of selected components
# or groups seasonal:
create_dc_date_attribut(selset)
end
def command_update(selset)
if selset.empty?
# update ALL seasonal components
update_dc_date_attribut(Sketchup::active_model.definitions)
else
# update ONLY selected seasonal components
update_dc_date_attribut(selset)
end
end
def debug
@@debug
end
def debug=(arg)
@@debug =( arg ? true : false )
end
def get_seasonal_dcs(collection=nil)
# Filter the referenced collection
if collection.nil?
dlist = Sketchup::active_model.definitions
dlist.reject! {|d| d.image? }
elsif collection.all? {|o| o.is_a?(Sketchup::ComponentDefinition) }
dlist = collection.reject {|d| d.image? }
else
insts = collection.grep(Sketchup::ComponentInstance)
groups = collection.grep(Sketchup::Group)
dlist = insts.map{|i| i.definition } + groups.map{|g| g.definition }
dlist.uniq!
end
dcs = dlist.select {|d| d.attribute_dictionary(DICT,false) }
# select only seasonal dynamic components
seasonal = dcs.select {|d|
d.attribute_dictionary(DICT,false).keys.include?(SEASON_ATTR)
}
if @@debug
puts "#{Module::nesting[0].name}: debug is true."
puts "The 'dlist' array:"
pp dlist
puts "The 'dcs' array:"
pp dcs
puts "The 'seasonal' array:"
pp seasonal
end
return seasonal
end
def create_dc_date_attribut(selected)
# 1. Retrieve data from shadowinfo into local variables,
model = Sketchup.active_model
shadowinfo = model.shadow_info
value = shadowinfo["DayOfYear"]
if @@debug
puts "The 'day of year' value:"
pp value
puts # blank line
end
# Writing the data into dictionary attributes.
selected.each {|obj|
next unless obj.respond_to?(:definition)
obj.definition.set_attribute(DICT,SEASON_ATTR,value)
}
end
def update_dc_date_attribut(collection)
seasonal = get_seasonal_dcs(collection)
# 1. Retrieve data from shadowinfo into local variables,
model = Sketchup.active_model
shadowinfo = model.shadow_info
# 2. Iterate the seasonal component definitions
value = shadowinfo["DayOfYear"]
if @@debug
puts "The 'day of year' value:"
pp value
puts # blank line
end
# writing the data into dictionary attributes.
seasonal.each {|d| d.set_attribute(DICT,SEASON_ATTR,value) }
end
# other code / methods here
unless file_loaded?(__FILE__) || @@context_menu_set
UI.add_context_menu_handler do |context_menu|
selset = Sketchup::active_model.selection
context_menu.add_item(MENU_TEXT[:update]) { command_update(selset) }
unless selset.empty?
context_menu.add_item(MENU_TEXT[:create]) { command_create(selset) }
end
end # context_menu_handler
@@context_menu_set = true
end
end # plugin module
end # outer namespace module
On the Ruby console you have to use ctrl+enter to continue on a new line. Otherwise enter causes the console to immediately evaluate whatever it has so far.
This is not true in a Ruby source file, it is peculiar to SketchUp’s Ruby console.