Counting visible copies of components

Hi guys,
I’ve been making a dynamic dining set for an event planner. I’m trying to make things as simple as possible as his team have no experience in 3d modelling and want to just drag and drop components. So I’ve made this dynamic component have all their standard options (height, size, #chairs, Type of chairs, table cloth, etc)
Now they’re also looking for a way to do a report to count all the components because sometimes they have 20-30 tables with different amount of chairs.
I’ve tried looking at Model Info and Generate report, however it counts each copy as 1 rather than give a total, and some hidden components (of the other chair types when not select) are included in the report. I’d like to avoid having them generate a report and then add a formula to count the repeats of names and exclude Hidden components.

In my screen shots, I’m showing my model with 8 Regular chairs, 5 Ghosts chairs, and 0 Napoleon chairs, yet the model info gives me the hidden ones too. Also, even the last number of the copies in the report are not accurate, I guess because I need to purge each time, otherwise if I have 10 chairs, delete and then copy another 10, the last chair # is 20.
Does anyone know of a way I can get a report with the total of visible components? Or any simpler solution to this.

1 Like

Not sure, but I will do some digging. This would be useful in some if my projects as well.

~Drew

For the programmers out there:
How hard would it be to code a script that allows you to first select a component, and then it’ll scan your model and return the amount of copies? It sounds simples, but I’m not sure if it’ll search based on identical edges/faces or name or both.

It’s actually quite easy. Here’s a bare-bones answer that deals with both outright hidden and placed on a hidden layer. I didn’t include any error checking, so be careful what you select!

require “sketchup”

def count_instances
sel=Sketchup.active_model.selection[0]
defn=sel.definition
count = 0
defn.instances.each do |inst|
count = count+1 if inst.visible? && inst.layer.visible?
end
count
end

1 Like

Hi @slbaumgartner Can you explain in more detail? I don’t know Ruby Script. Do I copy/paste this into the Ruby Console? Do I have to replace a certain text with the name of the component I want a unit count for? Thanks.

Hi,

Open the Ruby Console then cut-and-paste the Ruby into the input portion of the Console. Then select a ComponentInstance you want to count. Finally, type count_instances in the Ruby Console input area. You will see the count displayed in the output area of the Console. This relies on the selection, not on name or anything like that.

I did this in great haste just to show that it is very easy. A tool version would flesh this out to not need the Console and to handle errors. I didn’t look to see if anyone has ever published one

Cool, except what about nested components?
And I tried exploding my dining set after, but it still didn’t get the correct amount. Does it count differently towards actually copy/pasted components vs Copied through dynamic function? Thanks. And I’ll look around for a plugin, found nothing on a quick search

I’m not entirely sure what you mean about nested components. This snippet works from the selection. If a component is nested inside another, you have to open the outer one before you can select the nested one. But so far as I can see, the code counts instances that are nested as well as ones that are not. Perhaps there is something else going on in your dining set. Would you be willing to share the model?

Chair_Test_2.skp (2.2 MB)
I tried selecting from within the component, still didn’t give me the correct number. I’m also looking for a solution without having to enter each set, would it be possible to write a script that can look inside each component in a model? Thanks
Even outside of the component, I got 1 instead of two. Or does it not count the original?

Hmm…The problem is that the Dynamic Components technique you are using creates a new, distinct ComponentDefinition for each chair instance that it places, even though they are identical other than location. So, the table in your model has eight independent ComponentDefinitions, with names like 1_Regular#1, 1_Regular#2, etc. My snippet doesn’t see the chairs as instances of the same thing. To recognize them as such, it would indeed have to process the names. I’ll give that a shot.

But in the mean time, I wonder if the chairs really need to be DCs, since they differ only in location and orientation. Perhaps someone more expert in DCs than I can chime in and suggest a better way for you to generate your model.

I’m copying the component through the copy function. I figured it would be lighter for the model than to always have 12 copy/pasted components and just hide the ones I don’t need.
Anyone else have any input?

Thanks @slbaumgartner for checking it out.

The following should work with your model. Are you copying via a DC copy function? If so, it is making each copy into its own distinct definition, which isn’t doing what you wanted in terms of sharing. Again, I’m not much into DC’s, so I don’t know if this could be avoided.

def count_DC_instances
sel=Sketchup.active_model.selection[0]
if sel.nil?
puts “please select something first”
return
end
defn=sel.definition
if defn.nil?
puts “the selection isn’t a component”
return
end
name = defn.name
if name =~ /(\w*)#\d+/
basename = $1
puts “looking for definitions like #{basename}”
end
defs = Sketchup.active_model.definitions
count = 0
defs.each do |cdef|
defname=cdef.name
if defname.start_with? basename
cdef.instances.each do |inst|
count=count+1 if inst.visible? && inst.layer.visible?
end
end
end
puts “found #{count} instances like #{basename}”
end

(ugh! I need to learn how to format code in this board!)

Thanks, I’ll try it monday.

Do you think it’s better to have copied components (12 times in this time) or just one and use the DC Copy function?