You mean like the DC extension? An extension making an instance unique when interacting with it, instead of having a true DC system built-in the core of SketchUp.
Add or remove dynamic attributes affects all instances.
If the user chooses to modify only the selected instances, he must expect it to be made unique.
Youâre still right, making all instances of a piece of furniture unique will increase the volume of the file.
And the loading time can be very long, if there are many instances!
For this reason, making unique will only be applied in the cleaning method of the selection.
The method of cleaning all the project or all the furniture proposed by Click-Cuisine does not need to make unique! ( So no increase in the file size, no execution time. )
I understand that cleaning dynamic components in a selection may seem odd or unnecessary!
This method is under study to determine if it is more beneficial than harmful.
Cordially
David
eneroth3, I just noticed that your method selects sub-components for a single parent component.
Maybe this comes from the use of the âfirstâ method?
How can you select the sub-components of several parent components?
Thank you
David
David, I think itâs difficult for those who do not know the history and workings of your extensionsâŠ
as the files are huge, Iâll show some imageâŠ
the skp file is 46.9MB:
after a clean up itâs 1.3MB:
cc_test_file_1.skp (1.3 MB)
but it still has âdynamic attributesâ as well as some that should be purged before including in the extensionâŠ
and hereâs a gif of removed geometry [ anything with #BADA55
background ]
john
John, which weighs 46.9MB is not the models but the 700 IKEA materials, which are imported with the control panel.
Without these materials, Click-Cuisine could not offer the 5000 IKEA kitchen furniture.
Without taking into account the materials that will be purged:
The dynamic furniture with all these sub-components and attributes makes a weight of 1MB.
After cleaning the attributes as well as the hidden components the furniture makes a weight of 360KO.
I need help in the programming so if a person of experience can help me for my previous question, he would be very nice.
Thank you
David
as I said the other dayâŠ
then cleanup is a lot easierâŠ
I modified one of my âcommercialâ plugins to clean the model and generate that reportâŠ
did you inspect the âcleanedâ model?
you do not need to âselectâ them, you need to âcollectâ themâŠ
john
Touché!
This is the case for Click-Cuisine 2, which will soon be available.
Yes, and the job seems well done!
Ok I will collect!
Can you show me an example that collects all the entities of a selection and then removes the hidden entities?
Thank you
are you wanting to change the handles?
after âcollectingâ them in an array you can pass them to the âmodel.selectionâ and use âreplace selectedâ manuallyâŠ
but you would need to fix the insertion points and axis for all handle placements to matchâŠ
I just tacked this onto to my cleaner code to explain what I meanâŠ
in code you can do the same thing without ever adding to the âmodel.selectionââŠ
is handle replacement your end goal?
john
No it has been done for a long time on Click-Kitchen 2, with automatic positioning of the handles :
I am in the final straight or I want to propose a solution of cleanings of furniture proposed by Click-Kitchen 2.
To purge the components of the first level of nesting, I found hundreds of methods!
Here is a simple method that works:
mod = Sketchup.active_model
sel = mod.selection
sel.each{|s| s.definition.entities.grep(Sketchup::ComponentInstance).each{|e| e.erase! if e.hidden? }}
Cleaning the subcomponents of the child component is much more complicated!
It is on this subject that I need your help.
I do not lose hope!
David
Ps: If I find the only solution, I will come to post it to help all those who will find a day in my situation.
please read and try to understand what happens in this codeâŠ
ask questions when you donât follow the codeâŠ
I left in âcollectingâ the handles, but commented out the highlightingâŠ
# ClickCuisine::Cleaner (C) Copyright 2017 john@drivenupthewall.co.uk
#
#
require 'sketchup.rb'
# your namespace
module ClickCuisine
# your cleaner
module Cleaner
extend self
def target(ents)
ents.grep(Sketchup::Group).concat(ents.grep(Sketchup::ComponentInstance))
end
def kids?(entity)
entity.definition.entities rescue entity.entities
end
def hidden(e)
e.hidden?
end
def layer(e, ln)
e.layer.name =~ ln
end
def to_clean(entity)
#
kids = kids?(entity)
tents = target(kids)
lngth = tents.length
return unless lngth > 0
tents.each do |child|
# add any child we do not want, we can use known names to help...
if hidden(child) || layer(child, /VIGNETTES/) || child.definition.name == '00'
@to_go << child
# now we can remove dynamic attributes from the ones we want to keep
elsif child.definition.attribute_dictionaries
child.definition.attribute_dictionaries.delete('dynamic_attributes')
child.attribute_dictionaries.delete('dynamic_attributes') if child.attribute_dictionaries
end
# we can also 'collect' the handles here or you could have a separate ruby without @to_go[] code...
if child.parent != Sketchup.active_model
# again, we can use known names to help...
@handles << child if child.definition.name =~ /F.*POIGNEE/
end
# send it back to start like in 'Snakes and Ladders'
to_clean(child)
end # do
end # def
# we start and end here
def main
model = Sketchup.active_model
defs = model.definitions
ents = model.entities
lays = model.layers
mats = model.materials
sel = model.selection
# we create an array we can fill from outside this method
@to_go = []
# we can also 'collect' the handles
@handles = []
# we send the whole model to the cleaners
to_clean(model)
# create an operation before touching geometry
model.start_operation('cc_clean')
# to_clean(model) returns the array which we can erase
ents.erase_entities(@to_go)
# then we cleanup properly
[defs, lays, mats].each{|a| a.purge_unused}
# always close the operation
ensure model.commit_operation
# we can then do stuff with the handles in @ handles
# sel.add(@handles)
end
end
end
file = File.basename(__FILE__)
unless file_loaded?(file)
UI.menu('Plugins').add_item('Click Cuisine Cleaner') { ClickCuisine::Cleaner.main }
file_loaded(file)
end
# ClickCuisine::Cleaner.main
john
Wow, I was not asking as much!
Your code works wonderfully and purges all dynamic attributes and hidden components and much more.
I will take the time to analyze it and come back to ask my questions.
Thank you
Does your code purge all hidden sub-components and dynamic attributes in SketchUp or am I mistaken?
My goal is to purge the selected components:
Method 1 - Activate all Click-Kitchen 2 Dynamic Parent Components using the definitions names:
def method1
["IKEA","PLAN BAR SUR PIEDS","TABLE SUR PIED"].each{|name|
match = /#{name}/i
m=Sketchup.active_model;
s=m.selection;
m.definitions.each{|d|s.add d.instances if d.name =~ match }}
end
Method 2 - Purge all dynamic attributes and hidden components in the selection.
### It's code that I want to write. :-(
Thus, users of Click-Cuisine 2, will not affect other components that have nothing to do with the Plugin.
To purge all the hidden components and dynamic attributes of the SketchUp file, I know this solution:
def erase_hidden_components
Sketchup.active_model.definitions.each{|d|d.entities.grep(Sketchup::ComponentInstance).each{|e|e.erase! if e.hidden?}}
end
def purge_dynamic_attributes
m=Sketchup.active_model;m.definitions.each{|d|d.attribute_dictionaries.delete("dynamic_attributes")
d.instances.each{|i|i.attribute_dictionaries.delete("dynamic_attributes")}}
end
erase_hidden_components
purge_dynamic_attributes
But I do not want to do that!
Tomorrow I will study your code better, because it is certain that I have things to learn.
Thank you for your help John.
David
will cause the code to look 3 times over the same thingsâŠ
you can do them all at once if you recall the code from earlier posts at SCFâŠ
names = Regexp.union("IKEA","PLAN BAR SUR PIEDS","TABLE SUR PIED")
tents.each do |child|
next unless child.definition.name =~ names
EDIT: in the version of C_C I have, you would be better with a single filter methodâŠ
hereâs a cut and paste test snippetâŠ
model = Sketchup.active_model
sel = model.selection
def davids(child)
dicts = child.definition.attribute_dictionaries
'david B.' == dicts['GSU_ContributorsInfo']['NicknamesKey'].first
rescue
false
end
end
# to test select other items then run
davids(sel[0])
when combined into the cleaner, correctly, you will then only destroy âyourâ named DCâsâŠ
john
Good morning, John
I took an hour to analyze your code and I find it very surprising!
For example this excerpt:
if hidden(child)||layer(child,/VIGNETTES/)||child.definition.name=~/#{"00"}/
-
It allows you to delete all Hidden entities.
-
The models with the layer âVIGNETTESâ.
-
The definitions with â00â in their name.
I am surprised not to find the method that triggers the deletion, like âerase!â for example.
And yet the elements are removed!
I also enjoyed this excerpt:
[defs, lays, mats] .each {| a | a.purge_unused}
That allows to purge the definitions, layers and materials with a single purge_unused.
_
What is the purpose of opening and closing an operation like âmodel.start_operation (âcc_cleanâ)â?
Can cancel the operation immediately in SketchUp?
If yes, can the cleaning operation be memorized so that it can be canceled at any time with a method?
Here are my first questions and comments on your code.
Thank you
David
Should we replace lines of code:
By this in to_clean method ?
If Iâm wrong for can explain to me how to proceed?
_
Sorry but I donât understand how to use this example on your first code:
Thank you in advance for your help.
FIRSTLY: donât add spaces into the code, it will break the codeâŠ
/ # {"00"} / this is broken as ruby thinks it's a comment after the #
/00/ # is a regular expression, it doesn't need to be an escaped string /#{"00"}/
# you are just adding an extra un-needed step...
the ||
between each is another way of saying or
with stronger precedence [ some believe ]âŠ
e.g.
(1 || 2) == (1 or 2)
# will return true
so we are saying
if ( hidden(child) or layer(child, /Target Layername/) or child.definition.name =~ /Target Definition name/ )
# which works the same as separate lines
@to_go << hidden(child) # == @to_go.push(hidden(child))
@to_go << layer(child, /Target Layername/)
@to_go << child.definition.name =~ /Target Definition name/
itâs in the def main
and works on the collectionâŠ
# to_clean(model) returns the array which we can erase
ents.erase_entities(@to_go)
it still does three separate purges, but the code only needs one lineâŠ
click undo and youâll seeâŠ
no, it will miss any without those names that are inside your componentsâŠ
if everything you made had a namespace identifier then you could target them all without a list of namesâŠ
i.e. cc_CABINETS, cc_POIGNEE
that is what I was trying by using your âNicknamesKeyâ, but not all the content has those credits so get missed with a simple filterâŠ
john
open a model with a mixture of yours and other components >> select one >> paste the code and runâŠ
if itâs yours it will return âtrueâ, for others âfalseâ
to re-run, you only need the last lineâŠ
# to test select other item then run
davids(sel[0])
Sorry for my long absence!
I was able to analyze in depth the many methods you provided me on this forum and SketchUcation.
Thanks to that, I achieved all my goals and more.
Sorry john for the spaces in the code, I must be careful not to integrate the lines of codes in the language translator.
Thank you for your explanations and your example very detailed.
To solve the problem of deleting the dynamic attributes of all sub-components in a selection, I was inspired by a method provided by TIG in another example.
I used this same method to remove all hidden subcomponents.
To remove unnecessary components at the end of the project, I used john trick of naming components with a prefix.
To solve many other problems, I used the many methods provided by sdmitch in SketchUcation. ;-D
As promised here are some code examples that work:
def remove_all_sub_component_masks_in_the_selection(ents)
sel = Sketchup.active_model.selection
array = []
ents.grep(Sketchup::ComponentInstance).each{|e|
array << e
remove_all_sub_component_masks_in_the_selection(e.definition.entities)
}
array.each{|i|
i.erase! unless i.visible?
}
end
def remove_all_sub_component_masks_in_the_selection_end
mod = Sketchup.active_model
ent = mod.active_entities
sel = mod.selection
instances = sel.grep(Sketchup::ComponentInstance)
sel.clear
remove_all_sub_component_masks_in_the_selection(instances)
end
remove_all_sub_component_masks_in_the_selection_end
def remove_list_of_sub_components_with_prefix
["CLC2","0-DECO"].each{|name|
match = /#{name}/i
mod = Sketchup.active_model
sel = mod.selection
sel.grep(Sketchup::ComponentInstance).each{|s|s.definition.entities.grep(Sketchup::ComponentInstance).each{|e| e.erase! if e.definition.name =~ match }}}
end
remove_list_of_sub_components_with_prefix
This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.