Insert a list of attributes into a component. (With Ruby console)

Hey :wave:. You were asking for the wrong attribute. You should ask for ‘intprocess’ not ‘_intprocess_value’.

Fixed:


require 'csv'

def pega_att(componente, att) # Returns the current value of the attribute.
    # Always check instance first:
    val = componente.get_attribute( 'dynamic_attributes', att)
    if val.nil? # Does not differ from definition:
         val = componente.definition.get_attribute( 'dynamic_attributes', att)
     end
   return val
 end

def monta_linha(componente, csv)
    if componente.is_a?(Sketchup::ComponentInstance)
        nome_componente = componente.definition.name
        material_componente = componente.material ? componente.material.display_name : 'Nenhum material'

        #This attribute does not exist in your component. (see pic)
        #intprocess = pega_att(componente,'_intprocess_value')

        #You only need to ask for the attribute:
        intprocess = pega_att(componente,'intprocess')

        int_mod = pega_att(componente,'int_mod')
        quantity = 1
        int_cat = pega_att(componente,'int_cat')
        int_desc = pega_att(componente,'int_desc')
        int_comp = pega_att(componente,'int_comp')
        int_larg = pega_att(componente,'int_larg')
        int_esp = pega_att(componente,'int_esp')
        int_mat = pega_att(componente,'int_mat')
        int_c1 = pega_att(componente,'int_c1')
        int_c2 = pega_att(componente,'int_c2')
        int_l1 = pega_att(componente,'int_l1')
        int_l2 = pega_att(componente,'int_l2')
        int_veio = pega_att(componente,'int_veio')
        int_obs = pega_att(componente,'int_obs')

        csv << [nome_componente, material_componente, intprocess, int_mod, quantity, int_cat, int_desc, int_comp, int_larg, int_esp, int_mat, int_c1, int_c2, int_l1, int_l2, int_veio, int_obs]

        # Itera sobre as instâncias aninhadas
        componente.definition.entities.each do |entidade_aninhada|
        # Recursivamente chama a função para os componentes aninhados
        monta_linha(entidade_aninhada, csv)
       end
    end
end

# Método principal para exportar nome e material de todos os componentes para CSV
def exportar_itens
  # Obtém a seleção atual no modelo do SketchUp
  selecao = Sketchup.active_model.selection

  # Verifica se há algo selecionado
  if selecao.empty?
    UI.messagebox('Nenhum componente selecionado para exportar.')
    return
  end

  # Escolha do arquivo de destino
  arquivo_csv = UI.savepanel('Exportar arquivo CSV', '', 'int_process_reporter.csv')

  return unless arquivo_csv

  # Abre o arquivo CSV para gravação
  CSV.open(arquivo_csv, 'w', force_quotes: true) do |csv|
    # Cabeçalho do CSV
    csv << ['Nome do Componente', 'Material', 'IntProcess', 'int_mod', 'Quantity', 'int_cat', 'int_desc', 'int_comp', 'int_larg', 'int_esp', 'int_mat', 'int_c1', 'int_c2', 'int_l1', 'int_l2', 'int_veio', 'int_obs']

    # Itera sobre a seleção
    selecao.each do |entidade|
      # Recursivamente chama a função para os componentes aninhados
      monta_linha(entidade, csv)
    end
  end

  UI.messagebox('Exportação concluída com sucesso!')
end

exportar_itens

1 Like

Sim, esse script citado acima foi o primeiro que fiz, rodei aqui de novo e vou mostrar abaixo que mesmo assim o valor não é preenchido na saída, o valor vem vazio.

Usei o script citado.

With the above script I get this csv file:

You can see IntProcess has the values. Not sure why yours looks different and is blank?

2 Likes

Quick confirmation that this worked when I tested it.

2 Likes

Eu gostaria de agradecer a ajuda de todos, realmente o meu script estava errado e foi solucionado, agora eu estou com o novo problema eu criei um script para agrupar componentes existentes na minha biblioteca, e esses componentes têm uma atributo que espera informação do componente agrupado Pai.

Consegui fazer o script para criar o componente e criar um novo atributo mas o componente filho não está atualizando o valor que recebe do componente Pai.

Eu gravei um vídeo e vou postar aqui o link abaixo pra demonstrar o seguinte erro que está acontecendo.

https://youtu.be/VbZr2-mi0vA

Script:
cria_menu_modulo.txt (3.2 KB)

1 Like

A ligação para o seu vídeo parece estar avariada.

2 Likes

Tente colar esse link na URL do seu navegador!

1 Like

Hey thank you for the thank you! :grinning:

Will: right click > dynamic components > redraw update the formula?

1 Like

Eu quem agradesço !!! :sorrindo:

Ok, vou testar, mais existe alguma forma de fazer adicionar essa função no meu script?

1 Like

Eu quem agradesço !!! :sorrindo:

Ok, vou testar, mais existe alguma forma de fazer adicionar essa função no meu script?
Sem precisar iteragir com o componente!!

Yes this can be added to the script. See this thread.

1 Like

Vou fazer aqui :rocket:

Olá… Boa noite aqui no Brasil caro né!!! hshsh.
Gostaria de informar que consegui adaptar o código para redesenhar também.
Acredito que essa simples funcionalidade vai me auxiliar muito nas minhas rotinas de trabalho.
Tenho muitos desafios pela frente e confesso que estou a cada dia mais fascinado com o desenvolvimento \Ruby para SKP. Se puder me ensinar como postar o Código aqui como resposta no formato correto e tabulação… sei que não é o tópico correto mais os que procurei não consegui entender como publicar aqui de forma legível e separado.
Aguardo a ajuda para postar o resultado e também sobre mais uma dificuldade que estou tendo com o caminho do ícone que criei.
TKS !!!

# Define a classe do plugin
class MyPlugin
  # Método chamado quando o botão é clicado
  def self.my_button_action
    novo_modulo
  end

  # Método para criar o botão na barra de ferramentas
  def self.create_toolbar_button
    toolbar = UI::Toolbar.new "IntProcess"

    # Adiciona um botão à barra de ferramentas
    cmd = UI::Command.new("Minha Função do Botão") {
      self.my_button_action
    }
    cmd.small_icon = "C:/Users/dougl/AppData/Roaming/SketchUp/SketchUp 2021/SketchUp/Plugins/IntProcess/img/icon_modulo.png"
    cmd.large_icon = "C:/Users/dougl/AppData/Roaming/SketchUp/SketchUp 2021/SketchUp/Plugins/IntProcess/img/icon_modulo.png"
    cmd.tooltip = "Clique para criar seu Módulo"
    cmd.status_bar_text = "Criar Módulo"
    toolbar = toolbar.add_item(cmd)

    # Mostra a barra de ferramentas
    toolbar.show
  end
end

# Chama o método para criar o botão na barra de ferramentas
MyPlugin.create_toolbar_button

def novo_modulo
  def group_selected_components
    model = Sketchup.active_model
    entities = model.active_entities
    selection = model.selection

    # Cria um grupo temporário para armazenar os componentes
    temp_group = entities.add_group(selection.to_a)

    # Converte o grupo temporário em um novo componente
    new_component = temp_group.to_component

    # Limpa a seleção e seleciona o novo componente
    selection.clear
    selection.add(new_component)

    puts "Componentes agrupados com sucesso!"
  end
  group_selected_components

  # Método para adicionar o atributo "int_mod" ao componente
  def adicionar_atributo(component, value)
    # Adiciona o atributo ao componente
    component.set_attribute('dynamic_attributes', 'int_mod', value)
  end

  # Método para renomear o componente com o valor do atributo "int_mod"
  def renomear_component(component)
    # Obtém o valor do atributo "int_mod"
    int_mod_value = component.get_attribute('dynamic_attributes', 'int_mod')

    # Renomeia o componente com o valor do atributo "int_mod"
    if int_mod_value
      component.name = int_mod_value.to_s
    end
  end

  # Verifica se há um componente selecionado
  def component_selected?
    selection = Sketchup.active_model.selection
    return selection.length == 1 && selection.first.is_a?(Sketchup::ComponentInstance)
  end

  # Pede ao usuário para inserir o valor do atributo "int_mod"
  def get_int_mod_value_from_user
    input = UI.inputbox(['Digite o nome do Módulo:'], [''], 'Digite o nome do Módulo')

    # Retorna nil se o usuário cancelar a operação
    return nil if !input

    return input[0].to_s
  end

  # Executa a lógica principal
  if component_selected?
    component = Sketchup.active_model.selection.first

    # Pede ao usuário para inserir o valor do atributo "int_mod"
    int_mod_value = get_int_mod_value_from_user

    # Adiciona o atributo e renomeia o componente se o valor do atributo não for nulo
    if int_mod_value
      adicionar_atributo(component, int_mod_value)
      renomear_component(component)
      puts "Atributo 'int_mod' adicionado e componente renomeado com sucesso!"
    else
      puts "Nenhum valor inserido. Nenhuma ação realizada."
    end
  else
    puts "Selecione exatamente um componente para adicionar o atributo 'int_mod'."
  end

  # Iterar sobre os componentes selecionados
  Sketchup.active_model.selection.grep(Sketchup::ComponentInstance).each do |component|
    # Redesenhe o componente
    $dc_observers.get_latest_class.redraw_with_undo(component)
  end
end

Consegui hshsh…

Feliz por cada evolução e por encontrar pessoas boas que se dispoem a ensinar e ajudar…

Bom a minha dúvida é como deixar o caminho do meu ícone dinâmico visto que nem sempre temos a mesma versão do SKP e nem mesmo o nome de “User” no Sistema \operacional idêntico.

Essa parte do Script queria entender como fazer !!!

    cmd.small_icon = "C:/Users/dougl/AppData/Roaming/SketchUp/SketchUp 2021/SketchUp/Plugins/IntProcess/img/icon_modulo.png"
    cmd.large_icon = "C:/Users/dougl/AppData/Roaming/SketchUp/SketchUp 2021/SketchUp/Plugins/IntProcess/img/icon_modulo.png"
    cmd.tooltip = "Clique para criar seu Módulo"
    cmd.status_bar_text = "Criar Módulo"
    toolbar = toolbar.add_item(cmd)

Try something like this:

PLUGIN_PATH = File.dirname(__FILE__)

When you have, “icon.png” in a folder named, “icons”, in the plugin folder.

cmd.small_icon = File.join(File.dirname(__FILE__), 'icons', 'icon.png')
1 Like

This works for me:
All my icons are in “icons” folder and icon names are:

  • iconname.svg (windows version)
  • iconname.pdf (mac version)
  • iconname_small.png (old versions)
  • iconname_large.png (old versions)

replace “icons” and “iconname” by yours…

IS_WIN = Sketchup.platform == :platform_win unless defined?(IS_WIN)
IS_OSX = Sketchup.platform == :platform_osx unless defined?(IS_OSX)

if IS_WIN
  replacer1 = replacer2 = ".svg"
elsif IS_OSX
  replacer1 = replacer2 = ".pdf"
else 
  replacer1 = "_small.png"
  replacer2 = "_large.png"
end

cmd.small_icon = File.join( __dir__, "./icons/iconname#{replacer1}" )
cmd.large_icon = File.join( __dir__, "./icons/iconname#{replacer2}" )
3 Likes

Hello Douglas, looks like you figured out the posting code part! :smiley: Ruby is fascinating and fun, I got started a couple of years ago now by accident lol, I just wanted a redraw button. The learning curve is steep and fast, but there are a lot of people here who are willing to help. This is how I was shown to handle the file path, icons, menus and toolbars dynamically:


# These were shown to me by the prolific and ever helpful coder @DanRathbun.
# Dynamic file path:

def plugins_fpath(filename) # File path to your extension folder.
  version = 'SketchUp 20' << Sketchup.version.split('.')[0]
  folder = '/SketchUp/Plugins/your_extension_folder/'
  if Sketchup.platform == :platform_osx
    return File.join(ENV['HOME'] + '/Library/Application Support/' + version + folder + filename)
  else
    return File.join('%AppData%/SketchUp/' + version + folder + filename)
  end
end

# Dynamic file path set for the icons:
def set_icon(key, cmd) # Assigns icons on extension load.
  icon = case key
  when :one       then 'one' # icon file is one_lg.png or one_sm.png
  when :two       then 'two'
  when :three     then 'three'
  end
  
  # Folder containing icon images is called 'icons'
  cmd.large_icon = File.join(__dir__,'icons',"#{icon}_lg.png")
  cmd.small_icon = File.join(__dir__,'icons',"#{icon}_sm.png")
end

# Make a hash of the commands:
CMNDS = Hash[
  :one, 'ONE',
  :two, 'TWO',
  :three, 'THREE'
]

# Make a hash of tool tips:
TIPS = Hash[
  :one, 'tooltip number 1',
  :two, 'tooltip number 2',
  :three, 'tooltip number 3'
]

# Create the toolbar and Menu commands:
CMNDS[:one]     = UI::Command.new('name_one') { cmd_one() }
CMNDS[:two]     = UI::Command.new('name_two') { cmd_two() }
CMNDS[:three]   = UI::Command.new('name_three') { cmd_three() }

# Create the extension menu and toolbar:
menu = UI.menu('Plugins') # SketchUp plugins menu
cmd_menu = menu.add_submenu(menu_name) # your extensions sub menu
@toolbar1 = UI::Toolbar.new(toolbar_name) # your toolbar

# Build the textension toolbar and populate submenu commands.
CMNDS.each { |key,cmd|
  set_icon(key,cmd) # set the icon path
  cmd_menu.add_item(cmd) # add command to menu
  cmd.tooltip = TIPS[key] # add tool tips
  @toolbar1.add_item(cmd) # add toolbar button
}

# Remember toolbar setting at last session, show or hide.
@toolbar1.get_last_state == -1 ? @toolbar1.show : @toolbar1.restore

Hope this helps! Happy coding…

1 Like

Obrigado, vou testar aqui esse código.

Obrigado, achei bem interessante, tudo aqui pe novo para mim mais estou com as horas de folga que tenho analisando e estudando cada linha nova para absorver o máximo.

Obrigado, achei bem interessante, tudo aqui pe novo para mim mais estou com as horas de folga que tenho analisando e estudando cada linha nova para absorver o máximo.