<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[[SOLVED]Reloading Component via DefinitionsList.load Problem]]></title><description><![CDATA[<p dir="auto">I have been having issues with DefinitionsList.load.  I am trying to reload an external component that has been updated externally via Ruby.</p>
<p dir="auto">I encounter the following behaviours:</p>
<pre><code>[ruby]model = Sketchup.active_model
# We have a single component in the model
old_definition = model.entities[0].definition
puts old_definition.path #=&gt; '/HD/Users/User/cylinder.skp'
puts model.definitions.count #=&gt; 1

# Note that the definition was saved to '/HD/Users/User/cylinder.skp', and 
# the file was then edited independently

# Attempt to reload the component
new_definition = model.definitions.load '/HD/Users/User/cylinder.skp'

puts old_definition.guid #=&gt; 1736b32a-8dd3-3040-bdfd-62a05e188985
puts new_definition.guid #=&gt; 1736b32a-8dd3-3040-bdfd-62a05e188985
#  The same GUID! The file was NOT loaded, as it has been edited since.

# And a new (renamed) defninition was not added to the definitions list;
puts model.definitions.count #=&gt; 1
if new_definition == old_definition
  puts "The definitions are the same!  This shouldn't happen, no?"
end

# However, loading a new component that does not share a path with another component works;
second_new_definition = model.definitions.load '/HD/Users/User/cube.skp'
puts model.definitions.count #=&gt;2

# Other things I have tried;
# - Renaming the old definition before load - same result;
old_definition.name= "new name"
new_definition = model.definitions.load '/HD/Users/User/cylinder.skp'
puts new_definition.name #=&gt; "new_name"[/ruby]
</code></pre>
<p dir="auto">It seems that Sketchup refuses to reload a component from a path if there is a component with that path in the model already.  This is driving me a bit mad.</p>
<p dir="auto">...Or is it just me?  Any suggestions for workarounds?</p>
]]></description><link>https://community.sketchucation.com/topic/148752/solved-reloading-component-via-definitionslist-load-problem</link><generator>RSS for Node</generator><lastBuildDate>Tue, 10 Mar 2026 13:08:43 GMT</lastBuildDate><atom:link href="https://community.sketchucation.com/topic/148752.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 08 Jan 2015 16:13:31 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Wed, 06 Feb 2019 05:24:35 GMT]]></title><description><![CDATA[<p dir="auto">Thanks for the quick reply!  I think I've done everything right, but I only get a new definition (loaded) when I use the write-to-dev-null trick (but it's painfully slow!).  When I use the add_cpoint() or add_group() trick my SKP file is ignored and I get the same GUID back.  Here's my full script, if you don't mind taking a look:</p>
<pre><code>
require "sketchup.rb"

module RefreshComponent
  def self.force_reload_component_definition!(model, definition)
    definition_path = definition.path
    definition_name = definition.name
    definition.name = definition.name + rand.to_s
##    definition.entities.add_cpoint(ORIGIN)     ## &lt;== this causes GUIDs to match (fail)
    definition.save_as("/dev/null")              ## &lt;== this causes new definition load (success)
    reloaded_definition = model.definitions.load(definition_path)
    puts "Old GUID; " + definition.guid
    puts "New GUID; " + reloaded_definition.guid
    reloaded_definition
  end

  def self.reconnect_component_instances!(model, old_definition, new_definition)
    model.start_operation("Remap instances")
    old_definition.instances.each { |instance| instance.definition = new_definition }
    model.commit_operation
  end

  def self.delete_component_definition!(model, definition)
    model.start_operation("Delete Definition")
    definition.entities.erase_entities(definition.entities.to_a)
    model.commit_operation
  end

  def self.refresh_component(model, definition)
    model.start_operation("Reload current component definition", true)
    reloaded_definition = force_reload_component_definition!(model, definition)
    reconnect_component_instances!(model, definition, reloaded_definition)
    delete_component_definition!(model, definition)
    model.commit_operation
  end

  def self.start
    model = Sketchup.active_model
    model.start_operation("Reload component definitions from file", true)
    model
      .selection
      .select { |entity| entity.is_a?(Sketchup;;ComponentInstance) }
      .map { |instance| instance.definition }
      .uniq
      .each { |definition| refresh_component(model, definition) }
    model.commit_operation
  end
end 

unless file_loaded?("refresh_component.rb")
    UI.add_context_menu_handler do |context_menu|
      context_menu.add_item("Reload Current Component Definition") {
        RefreshComponent.start
      }
    end
   file_loaded("refresh_component.rb")
end

</code></pre>
]]></description><link>https://community.sketchucation.com/post/1556336</link><guid isPermaLink="true">https://community.sketchucation.com/post/1556336</guid><dc:creator><![CDATA[masp]]></dc:creator><pubDate>Wed, 06 Feb 2019 05:24:35 GMT</pubDate></item><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Tue, 05 Feb 2019 12:37:23 GMT]]></title><description><![CDATA[<p dir="auto">Your first block of code changes the selected instance's definition's entities, by adding the cpoint.<br />
At that point I'd also rename it e.g. <code> definition.name=definition.name+rnd.to_s</code></p>
<p dir="auto">This should then mean that a re-load of the original definition from the external SKP makes a new definition, auto-reusing its earlier name.</p>
<p dir="auto">Next you need to swap out any existing instances of the original definition, to use the new definition...<br />
<code> definition.instances.each{|i|i.definition=new_definition}</code></p>
<p dir="auto">Finally you can clear the entities of the original definition to remove it from the model's definitions list.<br />
<code> definition.entities.clear!</code><br />
Note that you need to have all of this code inside a <code> model.start_...commit_operation</code> block for it to take immediate effect...</p>
]]></description><link>https://community.sketchucation.com/post/1556227</link><guid isPermaLink="true">https://community.sketchucation.com/post/1556227</guid><dc:creator><![CDATA[TIG]]></dc:creator><pubDate>Tue, 05 Feb 2019 12:37:23 GMT</pubDate></item><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Tue, 05 Feb 2019 03:31:35 GMT]]></title><description><![CDATA[<p dir="auto">This is a very useful thread: I'm trying to apply this workaround (add_cpoint) but I'm still getting an identical GUID.  Would you mind posting the actual solution, so there's an explicit example I can refer to?  For what it's worth, this is my attempt (I'm trying to automate re-loading certain components from their .skp files):</p>
<pre><code>
    model = Sketchup.active_model
    selection_set = model.selection
    selection = selection_set[0]
    definition = selection.definition
    definition.entities.add_cpoint(ORIGIN)   # not sure if I'm applying this to the correct entity
    new_definition = model.definitions.load(definition.path)
    puts "Old GUID; " + definition.guid
    puts "New GUID; " + new_definition.guid

</code></pre>
<p dir="auto">I'm not sure if I'm applying add_cpoint() to the right entity; also I'm not sure whether creating an empty group is a better workaround as suggested in the thread, or how to do that!).</p>
<p dir="auto">Finally, this is how I hope to replace the instances (based on someone else's example):</p>
<pre><code>
      definition.instances.each { |instance|
        instance.parent.entities.add_instance(new_definition, instance.transformation)
        instance.erase!
      }

</code></pre>
<p dir="auto">Many thanks, and hugely appreciated!</p>
<p dir="auto">Mike</p>
]]></description><link>https://community.sketchucation.com/post/1556207</link><guid isPermaLink="true">https://community.sketchucation.com/post/1556207</guid><dc:creator><![CDATA[masp]]></dc:creator><pubDate>Tue, 05 Feb 2019 03:31:35 GMT</pubDate></item><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Mon, 12 Jan 2015 11:19:46 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/jim" aria-label="Profile: jim">@<bdi>jim</bdi></a> said:</p>
<blockquote>
<p dir="auto">Hmm, if you add an empty Group instead of a CPoint it also works; and then you may need to worry less about cleaning up since the empty group will get swept away.</p>
</blockquote>
<p dir="auto">Good point. (No pun intended)</p>
<p dir="auto">I'll file up the issue internally so we'll look into it.</p>
]]></description><link>https://community.sketchucation.com/post/1469461</link><guid isPermaLink="true">https://community.sketchucation.com/post/1469461</guid><dc:creator><![CDATA[tt_su]]></dc:creator><pubDate>Mon, 12 Jan 2015 11:19:46 GMT</pubDate></item><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Sun, 11 Jan 2015 21:56:02 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/tt_su" aria-label="Profile: tt_su">@<bdi>tt_su</bdi></a> said:</p>
<blockquote>
<p dir="auto">Have you tried to "touch" the old definition first by making a small change like entities.add_cpoint(ORIGIN) then trying to load the new?</p>
</blockquote>
<p dir="auto">Yes, I did!  And it works.  Happy camper.</p>
]]></description><link>https://community.sketchucation.com/post/1469410</link><guid isPermaLink="true">https://community.sketchucation.com/post/1469410</guid><dc:creator><![CDATA[TommyK]]></dc:creator><pubDate>Sun, 11 Jan 2015 21:56:02 GMT</pubDate></item><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Fri, 09 Jan 2015 21:28:23 GMT]]></title><description><![CDATA[<p dir="auto">Hmm, if you add an empty Group instead of a CPoint it also works; and then you may need to worry less about cleaning up since the empty group will get swept away.</p>
]]></description><link>https://community.sketchucation.com/post/1469256</link><guid isPermaLink="true">https://community.sketchucation.com/post/1469256</guid><dc:creator><![CDATA[Jim]]></dc:creator><pubDate>Fri, 09 Jan 2015 21:28:23 GMT</pubDate></item><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Fri, 09 Jan 2015 11:36:23 GMT]]></title><description><![CDATA[<p dir="auto">Have you tried to "touch" the old definition first by making a small change like entities.add_cpoint(ORIGIN) then trying to load the new?</p>
]]></description><link>https://community.sketchucation.com/post/1469195</link><guid isPermaLink="true">https://community.sketchucation.com/post/1469195</guid><dc:creator><![CDATA[tt_su]]></dc:creator><pubDate>Fri, 09 Jan 2015 11:36:23 GMT</pubDate></item><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Fri, 09 Jan 2015 10:55:24 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/jim" aria-label="Profile: jim">@<bdi>jim</bdi></a> said:</p>
<blockquote>
<p dir="auto">Which is worse: CPU time or Disk I/O time?</p>
<p dir="auto">You will need to do your own testing, but here's another possible work-around..</p>
<p dir="auto">in Windows, save the definition as <code> "nul"</code> (or <code> "\\Device\\Null"</code>), and Mac as <code> "/dev/null/"</code></p>
<p dir="auto">These are special files that will not actually write to disk, but just throw away the data. But the definition path will be changed.</p>
<p dir="auto">It's not exactly what you are asking for, but maybe better than creating double files on disk.</p>
</blockquote>
<p dir="auto">Thank you for your suggestion, Jim.  I have made the test as you suggested:</p>
<pre><code>definition = Sketchup.active_model.entities[0].definition

n = 50
Benchmark.bm do |x|
  x.report("save to nul ") { for i in 1..n; definition.save_as("/dev/null"); end }
  x.report("save to desk") { for i in 1..n; definition.save_as("/Volumes/.../Desktop/cubes.skp"); end }
end

                    user     system      total        real
save to /dev/null   7.770000   0.440000   8.210000 (  8.380249)
save to desktop     8.180000   0.630000   8.810000 ( 10.576788)
</code></pre>
<p dir="auto">There is a marginal improvement.  I imagine it would be a greater improvement if the save_as path was a network drive, so well worth noting.</p>
<p dir="auto">Another lesson I learned in the process was understanding how fast the save_as method was. The component in the benchmark above was 3MB when saved.  This works out at 0.055 seconds/MB on my Mac Pro (2008).</p>
<p dir="auto">This contrasts markedly from the Definitions.load method, which guzzles a lot of CPU (it takes 6 times longer):</p>
<pre><code>model = Sketchup.active_model

n = 50
Benchmark.bm do |x|
  x.report("load/save") {
    for i in 1..n
      definition = model.definitions.load("/Volumes/Storage/Users/Tommy/Desktop/Component.skp")
      definition.save_as("/dev/null")
    end
  }
  x.report("save to null ") { for i in 1..n; Sketchup.active_model.entities[0].definition.save_as("/dev/null"); end }
end
               user     system      total        real
load/save      59.010000   2.180000  61.190000 ( 61.211738)
save to null   8.720000   0.440000   9.160000 (  9.310672)
</code></pre>
<p dir="auto">So the way ahead is clear.  Save to change the path, then load only once.</p>
]]></description><link>https://community.sketchucation.com/post/1469181</link><guid isPermaLink="true">https://community.sketchucation.com/post/1469181</guid><dc:creator><![CDATA[TommyK]]></dc:creator><pubDate>Fri, 09 Jan 2015 10:55:24 GMT</pubDate></item><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Fri, 09 Jan 2015 00:05:33 GMT]]></title><description><![CDATA[<p dir="auto">Which is worse: CPU time or Disk I/O time?</p>
<p dir="auto">You will need to do your own testing, but here's another possible work-around..</p>
<p dir="auto">in Windows, save the definition as <code> "nul"</code> (or <code> "\\Device\\Null"</code>), and Mac as <code> "/dev/null/"</code></p>
<p dir="auto">These are special files that will not actually write to disk, but just throw away the data. But the definition path will be changed.</p>
<p dir="auto">It's not exactly what you are asking for, but maybe better than creating double files on disk.</p>
]]></description><link>https://community.sketchucation.com/post/1469130</link><guid isPermaLink="true">https://community.sketchucation.com/post/1469130</guid><dc:creator><![CDATA[Jim]]></dc:creator><pubDate>Fri, 09 Jan 2015 00:05:33 GMT</pubDate></item><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Thu, 08 Jan 2015 22:35:13 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/tig" aria-label="Profile: tig">@<bdi>tig</bdi></a> said:</p>
<blockquote>
<p dir="auto">How about this alternative...<br />
<code> definition1.name &gt;&gt;&gt; 'A' definition1.name = definitions.unique_name(definition1.name) ### e.g. A#1</code></p>
<p dir="auto">Now RE-load the component SKP ['A.skp'] and there is nothing in its way.<br />
Let's assume it's referenced as '<code> defintion2</code>'.<br />
It should arrive named 'A'.</p>
</blockquote>
<p dir="auto">Unfortunately, the component doesn't arrive named 'A'.  definitions.load path returns the existing definition if the path is identical.</p>
<p dir="auto">I have tried this:</p>
<p dir="auto">` model = Sketchup.active_model</p>
<h1>We have a single component in the model</h1>
<p dir="auto">old_definition = model.entities[0].definition<br />
puts old_definition.path #=&gt; '/HD/Users/User/cylinder.skp'</p>
<h1>Rename the component</h1>
<p dir="auto">old_definition.name = model.definitions.unique_name(old_definition.name)</p>
<h1>Attempt to reload the component</h1>
<p dir="auto">new_definition = model.definitions.load '/HD/Users/User/cylinder.skp'</p>
<p dir="auto">if new_definition == old_definition<br />
puts "The definitions are the same!  This shouldn't happen, no?"  #=&gt; ...but it does<br />
end`</p>
<p dir="auto">It appears that the problem is not the clash of definition names when a definition is loaded, but the clash of <strong>paths</strong> between the new and old components.  And you just can't change a definition path other than by loading it!  Quite an omission in the API methinks.</p>
<p dir="auto">In the meantime, my only other option is to temporarily rename the skp file from which the component is loaded using File.rename.  It's messy, but it should work ok.</p>
<p dir="auto">BTW - I am on Mac, Sketchup Pro 2015, and I experience this issue.  I would be interested if this is the case on other platforms.</p>
]]></description><link>https://community.sketchucation.com/post/1469117</link><guid isPermaLink="true">https://community.sketchucation.com/post/1469117</guid><dc:creator><![CDATA[TommyK]]></dc:creator><pubDate>Thu, 08 Jan 2015 22:35:13 GMT</pubDate></item><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Thu, 08 Jan 2015 19:11:53 GMT]]></title><description><![CDATA[<p dir="auto">How about this alternative...<br />
<code> definition1.name &gt;&gt;&gt; 'A' definition1.name = definitions.unique_name(definition1.name) ### e.g. A#1</code></p>
<p dir="auto">Now RE-load the component SKP ['A.skp'] and there is nothing in its way.<br />
Let's assume it's referenced as '<code> defintion2</code>'.<br />
It should arrive named 'A'.</p>
<p dir="auto">Now swap over <code> definition1.instances.each{|i| i.definition = definition2 }</code></p>
<p dir="auto">Next <code> definition1.entities.clear!</code></p>
<p dir="auto">If this whole operation is enclosed in a <code> model.start_operation... model.commit_operation</code> that now unused [an empty] '<code> definition1</code>' [temporarily named as A#1] is automatically removed from the definitions-list...<br />
<img src="https://community.sketchucation.com/assets/plugins/nodebb-plugin-emoji/emoji/android/1f913.png?v=e9183c1a0df" class="not-responsive emoji emoji-android emoji--nerd_face" style="height:23px;width:auto;vertical-align:middle" title=":nerd_face:" alt="🤓" /></p>
]]></description><link>https://community.sketchucation.com/post/1469091</link><guid isPermaLink="true">https://community.sketchucation.com/post/1469091</guid><dc:creator><![CDATA[TIG]]></dc:creator><pubDate>Thu, 08 Jan 2015 19:11:53 GMT</pubDate></item><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Thu, 08 Jan 2015 18:29:10 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/tig" aria-label="Profile: tig">@<bdi>tig</bdi></a> said:</p>
<blockquote>
<p dir="auto">Do a save_as on the current-component into a random-number-named SKP file in the user's Temp folder.<br />
It's stored path in the original model's definitions is then changed.<br />
Reload the externally changed component from its 'usual' external fixed-path, now it should overwrite in the model...<br />
Delete the randomly number-named SKP file in the user's Temp folder, using File.delete(full_path)...</p>
</blockquote>
<p dir="auto">I did think of this workaround as a worst case scenario.  It troubles me because of the (wasted) CPU time required to write the new file.  I have potentially tens of MB of Skp files I need to load at a time.  If I have to save an equivalent size of file every time, then, it potentially doubles the amount of CPU time.</p>
<p dir="auto">Another option is to rename the file to be loaded first, then change it back after the load, although in this case, the path the newly loaded component points to would then be wrong.</p>
<p dir="auto">We could really do with a new API function I think: ComponentDefinition.path=</p>
<p dir="auto">Any other suggestions would be welcome!</p>
]]></description><link>https://community.sketchucation.com/post/1469085</link><guid isPermaLink="true">https://community.sketchucation.com/post/1469085</guid><dc:creator><![CDATA[TommyK]]></dc:creator><pubDate>Thu, 08 Jan 2015 18:29:10 GMT</pubDate></item><item><title><![CDATA[Reply to [SOLVED]Reloading Component via DefinitionsList.load Problem on Thu, 08 Jan 2015 16:26:10 GMT]]></title><description><![CDATA[<p dir="auto">Do a save_as on the current-component into a random-number-named SKP file in the user's Temp folder.<br />
It's stored path in the original model's definitions is then changed.<br />
Reload the externally changed component from its 'usual' external fixed-path, now it should overwrite in the model...<br />
Delete the randomly number-named SKP file in the user's Temp folder, using File.delete(full_path)...</p>
]]></description><link>https://community.sketchucation.com/post/1469064</link><guid isPermaLink="true">https://community.sketchucation.com/post/1469064</guid><dc:creator><![CDATA[TIG]]></dc:creator><pubDate>Thu, 08 Jan 2015 16:26:10 GMT</pubDate></item></channel></rss>