Hi all, I have tried to achieve this for a few days and had varied success.
Our business would benefit hugely from being able to create components, that when pulled from the component library into a SketchUp model arrive on pre-determined layers.
My problem is that if I create a component with the pencil tool in ‘Layer x’ and save the component into the library, it 9/10 reverts to ‘layer 0’ when inserted into another SketchUp model.
Make your Component.
Edit an instance of it and Select All.
Make a Group of the selected contents.
Assign a Layer to that Group.
Name the Group to match the Component - “xxx_group”
Assign a Material to that Group if desired.
Save the Component Definition as an external SKP.
Import that Component into a new Model.
It should arrive with its layer/name/material attached to the Group - making it capable of manipulation with the Layer Dialog.
The base-definition has no associated layer.
That is applied to its instances.
In the case outlined above you sidestep this by nesting a group using a fixed layer, which imports with the non-layered definition…
Thanks for your help!
The only problem with this approach is that the component and group combination seem to be split between layer Zero and my chosen layer.
Is there a way to have both on the same layer?
As I explained, component definitions have no layer assignment.
Only their placed instances can have layers.
A group is a special kind of component which does not appear in the Components Browser and its instance is always made unique, at least once it’s edited.
Because a group is a type of instance it can have a layer.
The placed component-instance is assigned to Layer0 [i.e. NO layer] by default, you can manually assign another layer later, or have the ‘current’ layer changed before you place it [remembering to swap back to Layer0 so that lines and faces you draw are kept with Layer0 assigned].
The layer of the group nested inside the component’s definition can be assigned to any layer you choose when creating it.
Switching OFF that layer should leave the compo’s contents hidden.
There is no way*** of setting a component-instance’s layer BEFORE it is manually placed, but you can set the layer of nested groups etc within its definition…
***You could use the Ruby API to do this… but it’s then dependent on all using having it set up !
Just thinking aloud @TIG, so if you make a nested component of the component and an edge the nestee can be assigned a specific layer, so that when you insert and explode the component you’ll be left with a bit of loose geometry and a component set to its chosen layer.
What is inside the wrapper may have a layer assigned to it. You can benefit from that. A wrapper itself will not have a layer assigned to it when bringing in. FAIK it gets the currently active layer (which should be Layer0) Once the wrapper is exploded you’ll benefit from the nested stuf that has different layers assigned to them. One layer per entity. You can wrap a component without other entities in a new extra wrapper.
You could do that, but the Component-Browser would clog up with these near duplicates, and picking the right-one might be a pain…
Here’s the idea… an instance of MyLovelyCompo with the desired Layer assigned to it, is added to a new similarly named component-definition !MyLovelyCompo - note how I added the ! to its name, so these ‘containers’ all sort together etc.
It might need a temporary entity [like a short line] together with the instance, so as to allow the manual creation of the ‘container’, but that can be erased afterwards - leaving just MyLovelyCompo inside !MyLovelyCompo
After the !MyLovelyCompo is added to a model it’s on Layer0 or the current-layer otherwise.
Exploding it leaves the MyLovelyCompo instance in place, using its originally assigned Layer [which will have been added to the model’s Layers list as it was imported].
However, now you have both MyLovelyCompo and !MyLovelyCompo listed in the model’s Components Browser, AND inserting another instance of MyLovelyCompo assigns it to Layer0 etc.
To keep its original layer it’s need to be Copied.
Also the earlier !MyLovelyCompo version might cause untold confusion later, and since it has no instances after it’s exploded any Purge removes it, leaving the MyLovelyCompo version which inserts on Layer0 - so one step forward, one step back !
I think ALL of the posited workarounds are too clunky for simple daily use…
Add a nested group [named ‘LayerHolder’] into the selected Component-Instance’s Definition’s entities, containing a tiny edge [1/1000" long] at the Component Definition’s origin [?], and assign it ‘LayerX’ - it’s easy done with some short Ruby code…
That code also sets up an Observer.
It checks for every Component Definition getting a new Instance added into the model, and then checks if that Definition’s entities contain a group named ‘LayerHolder’, if so it gets that groups layer and assigns it to the newly placed Instance !
All this is done seamlessly, BUT it does need the originator of the Component-Definition to assign the ‘LayerHolder’ to it, and for the end-user to have that Ruby loading to set the LayerX as it’s inserted - it could also be confusing since the user might have chosen LayerZ as current, and then gets his new Instance assigned to LayerX. Placed Instances can be reassigned other layers using Entity Info later on…
I’ll look at some outline code…
Add this to your Plugins folder…
TIG-LayerHolder.rb (4.1 KB)
And test it…
We could add an attribute to the definition - this should carry over to the external component SKP.
Then the test is for the attribute in the imported / inserted definition…
It’ll avoid the clutter of the nested groups in the Outliner etc…
I’ll look at that as an alternative…
Here’s a better solution using attributes attached to the definition, which persist into the component-SKP and then back into the definition imported into a new model.
The “LayerHolder” is an attribute - so no messy groups etc.
The user needs the RB file be loaded to ensure that all instances of that definition have the layer named in the attribute - that layer is added to the model if it doesn’t exist…
Here the alternative [better] script to go into your Plugins folder:
TIG-LayerHolder.rb (4.4 KB)
Here’s a slightly modified version of the tool.
It now also adds the command to the context-menu if you have at least one component-instance in the selection.
It now assigns the specified layer to the selected component-instance[s] as well as tagging the definition[s].
Now its dialog also only lists layer-names that are currently visible.
If the <NEW_LAYER> name is assigned and it already exists but it is currently hidden, then it is made visible.
When importing a component its instances are assigned the layer named in its definition’s tag.
If the layer doesn’t exist it is created and then assigned.
If the layer exists it is assigned, but if it is currently hidden it is also made visible.
TIG-LayerHolder.rb (4.8 KB)
I think that just about covers all of the bases…
As long as the ‘top’ level is a component, there is nothing wrong with assigning sublevel groups (instead of components) to different layers.
No exploding needed.(accept when importing in a file) you can even preset the visibilty.
Check this template with preassigned layers, and visibilty: