Entities.add_group(ents)
-
I know that entities.add_group is buggy when you pass an entity collection to it. It seems to work OK as long as the entities collection you are adding to is the active path, or model.entities.
Is there any way to add a group of already existing components to a group using code, and regardless of what entities collection is active in the model?
For example, in the outliner I have
Building_Geometry_Group
-->Exterior_Walls
-->Win1
-->Win2
-->Roof
-->FoundationNow I want to group the exterior walls and windows together into one group. I'd like to go:
walls_and_windows = Building_Geometry_Group.entities.add_group([Exterior_Walls, Win1, Win2])
But this adds walls_and_windows to model.entities, and messes up the transformation completely, often followed by a bugsplat. Is there any workaround for this?
Thanks,
--
Karen -
I've had a few PM's on this issue, so I'll post some clarifications:
I've tried adding things a few different ways. The only way I can properly add a group to a group.entities that is not the active entities is to add an empty group. Then, you need to add faces, by using entities.add_face. This means that you either have to manually copy all attributes, materials, etc, or you lose some of these attributes. It also seems like a very round-about way of doing things. If I say Building_Geometry_Group.entities.add_group(face), where face is an existing face, this creates some very strange results.
Try the following by using the ruby console:
- draw a cube, open the cube for editing (make sure the origin is NOT 0,0,0), and select a face
- in the ruby console:
s = Sketchup.active_model.entities
f = s[0] - now exit the group, and select the group, then in the ruby console
g = s[0] - now fur the fun
g2 = g.entities.add_group(f)
ok, so a group was added to model.entities, and in a strange location... Now double click your original group to edit it... the face moves!!
This is my conundrum.
--
Karen -
If they are components or groups you can get their definition and use
entities.add_instance
. That way you're safe from crashes. -
Thom,
I read your post on this method, from the 'change parent' thread, with much interest, hoping it would offer a solution. My issue is creating the group in the first place. Usually in SU, when a group is created of existing components, it is after the user has selected a bunch of components, and therfore model.active_entities is equal to any of the selected items parent.entities. Adding a sub-group to the component is easy. Just say parent.entities.add_group(entities), and everything works fine.
However, if your list of entities is not equal model.active_entities, even though all my entities have the same parent, and the group I am creating would have the same parent, when you do parent.entities.add_group(entities), the new group shows up in the outliner as existing within model.entities, and not parent.entities. Furthermore, more strange stuff happens when you edit the parent group.
Try my ruby console example.
I really appreciate the feedback too, by the way.
--
Karen -
@kwalkerman said:
- draw a cube, open the cube for editing (make sure the origin is NOT 0,0,0), and select a face
- in the ruby console:
s = Sketchup.active_model.entities
f = s[0] - now exit the group, and select the group, then in the ruby console
g = s[0] - now fur the fun
g2 = g.entities.add_group(f)
ok, so a group was added to model.entities, and in a strange location... Now double click your original group to edit it... the face moves!!
2:
Sketchup.active_model.entities
this does not refer to the current context - this will refer to the root entities in the model.Sketchup.active_model.active_entities
is what you need to use to refer to the current context.
Further more, s[0] is so assurance you are getting a face. And from your description you're trying to get the selected face - so you need to access the model's selectionSketchup.active_model.selection
The reason you're getting odd behaviour appear because you are not referencing the correct entities.
-
Thom,
Ok, sorry for wasting your time. I wrote that post late last night. It should read (and what I've been testing)
- draw a cube, open the cube for editing (make sure the origin is NOT 0,0,0), and select a face
- in the ruby console:
s = Sketchup.active_model.selection
f = s[0] - now exit the group, and select the group, then in the ruby console
g = s[0] - now for the fun
g2 = g.entities.add_group(f)
ok, so a group was added to model.entities, and in a strange location... Now double click your original group to edit it... the face moves!!
And, from this morning... I did mean Sketchup.active_model.active_entities.
I have run a few tests and it seems that if you try to create a group by passing in entities, the only time it works is when the parent entities collection equals the model.active_entities collection.
I could find a decent workaround if there was a way to change the active path of the model!!
--
Karen -
huh! that's a bizzare bug...
I've never really made groups from existing entities - partly because I've not needed it so face, and partly because of all the reports of crashes and oddities.The creation of the group in the wrong context is one thing - the jumping around is another. This method appear to be a can of worms.
@kwalkerman said:
I could find a decent workaround if there was a way to change the active path of the model!!
If only - it's an very annoying limitation.
-
In addition I got a nice BugSplat when I tried to make a new model...
-
Rather than try to find ways to break Sketchup when making groups let's concentrate on doing it the other way...
You gave a group 'g0' [containing some faces making a cube]
You have a similar group 'g1' etc.
You want to add them to a new group - we'll call it 'g2'.
The rule is that the new group and the entities that will be added to it must be in the same 'context' [entities-set].
To trap for this NOT being the case...
return nil if g0.parent.entities != g1.parent.entities
This ensures that the entities-set is suitable.
Assuming they match...
entities=g.parent.entities
Now add a new new group to it, with entities...
g2=entities.add_group(g,g1)
We now have a new group 'g2' containing 'g0' and 'g1'.
g2.entities.to_a
should list g0 and g1...
Any number of suitably 'contexted' entities can be added to new group as a list or an array - but not an entities-set - useentities.to_a
to add everything in the new-group-to-be's entities-set - otherwise the 'entities' will refer to a set including the new group itself and it'll get into a mega-twist... -
TIG,
I see what you're saying... but the issue is not that the parent entities are not the same, but that model.active_entities is not equal to parent.entities.
Try this:
create a simple model, draw a rectangle and pull it up.
in the ruby console:
model = Sketchup.active_model
s = model.selectionnow select the group.
in the ruby console:
g = s[0]now add a new group to g.entities, through the ruby console
new_g = g.entities.add_group(g.entities.to_a)
So... is this an official bug that needs to be logged with the SU team? How do I go about doing that?
Thanks!
--
Karen -
I think you can't do what you wrote!
You add the group then add the entities to it at that point the group itself is one of those entities!
This might work - it list the entities before the group is even thought about!
ents = g.entities.to_a new_g = g.entities.add_group(ents)
Make sure your new_group and lists of entities are in the 'context' AND that the list doesn't include the new_group itself...
It's an awkward area but it is possible to do it... -
TIG,
so let's back up for a minute.
What my code does, is look for certain existing items within a group (all items are within the same group), and creates sub-groups based on the items having certain characteristics, just like if you were editing a group, selected a few faces, right-clicked and said 'make group'. I want the user to be able to run the script on multiple groups at once, so the components to be grouped, will be part of active groups, but not part of model.active_entities when the script is run.
Am I making sense? Is this completely impossible? Is there some reason I'm overlooking that makes this unrealistic?
Thanks,
--
Karen -
model.active_entities
is just a shortcut to the context [entities] that you are in when you run a tool - the current edit's entities set.
It will point atmodel.entities
, ordefinition.entities
orgroup.entities
as is appropriate.
When you make a new group to contain some entities those entities AND the new group must be in the same context [entities]. The entities need NOT be the 'active_entities' which is a 'shorthand'.
You can compare each of theentities
usingentity.parent
to check they all have the same parent and therefore are in the same 'entities-set' [context] and if so thenentities_array=entities.to_a; entities[0].parent.entities.add_group(entities_array)
should work... -
TIG,
try my test sample. It doesn't work unless model.active_entities is equal to the entities to which you are adding a group. I know that model.active_entities is a shortcut.
try my test sample. Just try it.
--
Karen -
I can see what you mean.
If you are outside of the context you are working on, and try to add a group into a new 'sub-group' the database gets 'twisted'.
You therefore need to do this test -
if model.active_entities == group.parent.entities
if it'strue
you can do it as I described as the entities are 'active', if false you need to do it another way IF you are dealing with instances - although I find that 'raw' geometry etc seems to work OK...
A group is special kind of 'component instance' and therefore it has a 'definition' - only accessible through an obscure route - see below...
if model.active_entities != model.entities
you also need to find the group's transformation as you need that too...
So now instead of adding the group directly into the new sub-group [as you can with 'raw' geometry] you need to add an 'instance' of it instead, then match its transformation and erase the original-group...
ents = group.parent.entities defn = group.entities.parent tran = group.transformation sub_group = ents.add_group() ### initially made 'empty' new_group = sub_group.entities.add_instance(defn, tran) ### group 'cloned' group.erase! ### remove original group
This works for me... the group is effectively cloned into the new sub-group, keeping its transformation, the sub-group is made in the same context as the original group itself, and the original group is then erased... -
TIG,
Ahh, I tried something similar a few days ago, but I think yours has an extra twist or two that just might work!
I'll give it a try.
Thanks,
--
Karen -
... actually this works if you want to create a sub-group that includes all entities of the parent group, but not if you want to create a sub-group that includes only SOME of the entities of the parent group. For instance, I start with a box, and I create one group for all walls, another for all roofs, and another for the floors.
I guess I could create multiple sub-groups using your method, and then erase everything that I don't want out of each group. Aarg! This is much more calculation intensive that I want!
--
Karen
Advertisement