Plugin select only one instance + count instances
-
Hi guys,
I am new here and I was wondering if somebody could help me with my problem.
I have used Sketchup for some years, but I have just started working with Ruby.So here is my problem:
"select only one instance of each component"
I made a big model with many different components, some of them are more than once in the model and now I want to select the components and copy them next to the model to create a kind of library of all the different components, but I only want to select one of each component and I don't want to select every single one by hand.
Is there maybe an already existing plugin, that can select only one instance of each component? Or can anyone help me to write that in ruby?"text-tag: number of instances"
And after I copied the elements I would like to put a text tag next to them saying how many instances there are in total, of course minus the copy I just created and I don't want to do that by hand as well. So I want the entity info "solid component(65 in model)" for example as a text-tag. Is there maybe an existing plugin or can anyone help me to write that in ruby?
And it would also be great to do that by selecting all, so it will create a text tag with the number for every single element in the selection.I hope you can help me with that.
Thank you very much!Simon
-
To find components iterate the definitions...
require('sketchup.rb') module TIG def TIG.composer() model=Sketchup.active_model ents=model.entities ds=[] # component definitions model.definitions.each{|d| next if d.image? || d.group? next unless d.instances[0] ds << d } return unless ds[0] model.start_operation('Composer', true) pt=model.bounds.max pt.z=0 pt.offset!([120,0,0]) # first point to add instance 10' away adjust as desired ds.each{|d| n=d.name c=d.instances.length t=Geom;;Transformation.new(pt) i=ents.add_instance(d, t) pt.x=i.bounds.max.x+120 # point for next instance ents.add_text("#{n}\nInstances=#{c}", i.bounds.max, [6,6,12]) } model.commit_operation end end
Usage
TIG.composer
You can use this for the basis of many processes... -
Thank you so much. That helped a lot.
-
Hi TIG, so I have some more questions about the code.
"select only one instance of the components in selection"
The code runs for all the components in the model, right?
How can I run it for only the ones I select?
it would be good to have a code that only selects one instance of each component of my selection."text-tag: number of instances"
And the text tag which says how many instances there are, can I also use that separated from the copying, so that I can put a text-tag only on components that I select somewhere in my library or in the model?"order of components"
And another thing, what is the order the components come in? I don't find that in the code, do I?Sorry for all the questions, I would really like to understand the code and work on it, but I have just started doing this.
Thank you so much,
Simon
-
@sb1305 said:
Hi TIG, so I have some more questions about the code.
"select only one instance of the components in selection"
The code runs for all the components in the model, right?
How can I run it for only the ones I select?
it would be good to have a code that only selects one instance of each component of my selection."text-tag: number of instances"
And the text tag which says how many instances there are, can I also use that separated from the copying, so that I can put a text-tag only on components that I select somewhere in my library or in the model?"order of components"
And another thing, what is the order the components come in? I don't find that in the code, do I?Sorry for all the questions, I would really like to understand the code and work on it, but I have just started doing this.
Thank you so much,
Simon
Replace:ds=[] # component definitions model.definitions.each{|d| next if d.image? || d.group? next unless d.instances[0] ds << d }
with something to process the selection instead - a bit more convoluted!
ss=model.selection.grep(Sketchup;;ComponentInstance) ds=[] ss.each{|e| ds << e.definition } ds.uniq!
Now you have a 'list' of just the definitions relating to selected component-instances [.uniq! ensures there are no repeats]... Process that 'ds' 'array' as before...
To make a
text_adder()
create another method [def]... In it do something likept=model.bounds.max pt.z=0 pt.offset!([120,0,0]) (model.selection.grep(Sketchup;;ComponentInstance).uniq).each{|e| d=e.definition n=d.name c=d.instances.length t=Geom;;Transformation.new(pt) i=ents.add_instance(d, t) pt.x=i.bounds.max.x+120 # point for next instance ents.add_text("#{n}\nInstances=#{c}", i.bounds.max, [6,6,12]) }
If you want to not count the one you have in your 'Library' then change
c=d.instances.length
toc=d.instances.length-1
etc...
remember to wrap it in a namespace/module as the 'composer
' example, and use model_start_op...commit so it's one-step undo-able...The order of the components in the earlier post comes from the order in the definitions list, which is 'chronological', so if you made 'zebra' before 'aardvark' that's the order in which they are found.
The order in a selection is not easily possible to determine, you can try picking in the desired order [holding Ctrl to add to the selection...]...
If you want to get the results in sorted 'name' order, then you need to add in an extra step or two...The code outlined earlier...ss=model.selection.grep(Sketchup;;ComponentInstance) ds=[] ss.each{|e| ds << e.definition } ds.uniq!
needs to become something like ...
ss=model.selection.grep(Sketchup;;ComponentInstance) ns=[] ss.each{|e| ns << e.definition.name } ns.uniq.sort! ### sorted names... ds=[] ns.each{|n| ds << model.definitions[n] } ### NOW process 'ds' which is a list of definitions sorted by name...
You can make a similar change to the 'whole of the definitions' version too.
Ruby's 'sort' is 'case sensitive' - you can make it case 'insensitive' using a method [wrapped] like thisdef self.sort_by(a) return unless a.is_a?(Array) return a.sort_by{|w|[w.downcase, w]} end
You then replace the line
ns.uniq.sort!
with this:
ns.uniq! ns=self.sort_by(ns)
Advertisement