Replace a component with my DC,get old component lenx leny lenz to my DC lenx leny lenz,failed!

I 'm try to repalce my DC component to the old select component.
so i’m try to make a plugin ,but it got failed
as the code

require 'sketchup.rb'
require 'extensions.rb'

module MySketchupPlugin

#Hash table used to store component dimensions
@component_data = {}
@original_component = nil

#Create toolbar
toolbar = UI::Toolbar.new "My Plugin Toolbar"

#Define the first button (get component information)
Get_info_cmd=UI:: Command.new ("Get Component Information"){
model = Sketchup.active_model
selection = model.selection
if selection.length == 1 && selection[0].is_a? (Sketchup::ComponentInstance)
@original_component = selection[0]
bounds = @original_component.bounds
width = bounds.width
height = bounds.height
depth = bounds.depth
@component_data = { width: width,  height: height, depth: depth }
UI. messagebox ("Component information obtained \ nWidth: # {width} \ nHeight: # {height} \ nDeep: # {depth}")
else
UI. messagebox ("Please select a component")
end
}
Get_info_cmd.small_icon="get_info_icon. png" # small icon (custom icon path)
Get_info_cmd. large_icon="get_info_icon. png" # Large icon (custom icon path)
Get_info_cmd.tooltip="Get selected component information"
Get the length, width, and height information of the selected component
Get_info_cmd.menu_text="Get component information"
toolbar.add_item get_info_cmd

#Define the second button (replace component)
Replace_cmd=UI:: Command.new ("Replace required component"){
if @component_data.empty? || @original_component.nil?
UI. messagebox ("Please obtain component information first")
else
#Pop up the resource manager
File_cath=UI.oppanel ("Select Components", "SketchUp Files | *. skp | |")
if file_path
begin
model = Sketchup.active_model
entities = model.active_entities

#Start operation
Model. start_operation ('Replace Component', true)

#Load new component definition
definition = model.definitions.load(file_path, allow_newer: true)
Raise 'Unable to load component definition' if definition.nil?

#Obtain the position and rotation information of the original component
transformation = @original_component.transformation

#Delete the original component
entities.erase_entities(@original_component)

#Add a new component instance
new_component = entities.add_instance(definition, transformation)
Raise 'Unable to add new component instance' if new_component.nil?

#Ensure that the model update has been completed
model.commit_operation

#Refresh the view to ensure that new components are loaded correctly
model.active_view.refresh

#Get the dynamic properties of the new component
dynamic_attributes = new_component.attribute_dictionary('dynamic_attributes', true)
if dynamic_attributes
#Update dynamic attributes
dynamic_attributes['lenx'] = @component_data[:width]
dynamic_attributes['leny'] = @component_data[:depth]
dynamic_attributes['lenz'] = @component_data[:height]
else
UI. messagebox ("There is no 'dynamic_attributes' in the dynamic attribute dictionary of the new component")
end

#Ensure that the changes take effect
model.active_view.refresh

#Pop up a message box indicating successful replacement
UI. messagebox ("replacement successful")

#Clear cached data
@component_data.clear
@original_component = nil
rescue => e
UI. messagebox ("Component replacement failed: # {e.message}")
end
else
UI. messagebox ("No valid component file selected")
end
end
}
Replace_cmd.small_icon="replace_icon. png" # small icon (custom icon path)
Replace_cmd. large_icon="replace_icon. png" # Large icon (custom icon path)
Replace_cmd.tooltip="Replace selected component"
Replace_cmd. statis_bar_text="Replace the selected component and set the size of the new component"
Replace_cmd.menu_text="Replace required components"
toolbar.add_item replace_cmd

#Define the third button (get dynamic properties)
Get-dynamic _ attributies_cmd=UI:: Command.new ("Get dynamic properties"){
model = Sketchup.active_model
selection = model.selection
if selection.length == 1 && selection[0].is_a? (Sketchup::ComponentInstance)
component = selection[0]
dynamic_attributes = component.attribute_dictionary('dynamic_attributes', false)
if dynamic_attributes
attributes_text = dynamic_attributes.map { |key, value| "#{key}: #{value}" }.join("\n")
UI.messagebox(attributes_text)
else
UI. messagebox ("Selected component has no dynamic properties")
end
else
UI. messagebox ("Please select a component")
end
}
Get-dynamic _ attributies_cmd. small_icon="dynamic_attributies_icon. png" # small icon (custom icon path)
Get-dynamic _ attributies_cmd. large_icon="dynamic_attributies_icon. png" # Large icon (custom icon path)
Get the dynamic properties of the selected component from get-dynamic _ attributies_cmd. tooltip
Get all dynamic properties and their values of the selected component from get-dynamic _ attributies_cmd. statis_bar_text
Get_ dynamic_attributies_cmd.menu_text="Get dynamic properties"
toolbar.add_item get_dynamic_attributes_cmd

#Display toolbar
toolbar.show

end

but after finish the replace ,the new DC’s lenx leny lenz is not be changed ,how can i revise the code, thanks all

(a) You don’t need these in the main extension code file:

require 'sketchup.rb'
require 'extensions.rb'

… as they will already be loaded by any extension registrar file (or your extensions registrar file) before the main code file is loaded.

Also never use filetypes with require method calls.

You can also use conditionals to speed up loading by skipping the search through the $LOADED_FEATURES array:

require 'sketchup' unless defined?(LanguageHandler)
require 'extensions' unless defined?(SketchupExtension)

(1) Do not put a space between the method name and its argument list when you make method calls … or between the "::" scope operator and object references … or between "." and the method call.

(2) Please indent code correctly, so it is better readable.

(3) Your extension submodule should be wrapped inside a unique top-level namespace module.

(4) Your UI::Command blocks should have likely have a single statement that calls a method, so that you can tweak the code and reload the file during development. (Ie, command blocks cannot be redefined at runtime, but methods can.)
However, protect GUI object creation with a run once conditional block so that you don’t get duplicate GUI objects:

   if !defined?(@loaded)
    #
    # Define commands, menu items and toolbars here ...
    #
    @loaded = true
  end

(5) You should load definitions within a beginrescueend block:

  • raise needs to be lowercase if you use it. (It is global method from Kernel.)
    You have it capitalized repeatedly in your code.

  • If there are problems loading the definition, then exceptions will be raised and your code needs to handle the exceptions, not test for nil.

(6) Listing values may be better using the MB_MULTILINE messagebox type.

(7) You should usually not create a "dynamic_attributes" dictionary at the instance level. Let the DC extension do this when necessary. (Ie, there are other required attributes that should be in the instance dictionary.)
A component instance is dynamic if its’ definition has a "dynamic_attributes" dictionary, where all the default attribute values and formulae are. A dynamic instance only has a "dynamic_attributes" dictionary if its values differ from the defaults in the definition dictionary and will only have the attributes that are different.
A dynamic group must be nested inside a component and always has all dynamic attributes attached to the instance’s "dynamic_attributes" dictionary.
So, the standard practice is to check the instance for a "dynamic_attributes" dictionary first and if it does not exist or does not have the attribute you seek, then check the instance’s definition’s "dynamic_attributes" dictionary (if the instance is not a group.)

(8) If you properly modify dynamic attributes, then you must cause a redraw to happen upon the instance.

  $dc_observers.get_latest_class.redraw_with_undo(instance)
1 Like