Entities.add_group bug?
-
Reading the
@unknownuser said:
NOTE: calling add_group with entities in its parameters has been known to crash SketchUp before version 8.0. It is preferable to create an empty group and then add things to its Entities collection.
I'm asking if this is the bug case or is my mistake?
I have a group of 2 lines and want to group the first line.
I have put this in the ruby console:group1=Sketchup.active_model.selection[0] group1.entities.add_group(group1.entities[0])
The result is that the line is not in the subgroup ,but in the new group outside the group1.
If I delete it,it is also deleted in the group1.
I would expect to have 1 group(group1) , 1 subgroup with the line and 1 ungroupped line inside group1.Is it a bug?
-
No, you can't mix entities across different entities contexts. SO moving them is bad.
I'm surprised you didn't get a Bugsplat - that usually happens when you try it...
Just try running each line in turn in the Ruby Console...
group1=Sketchup.active_model.selection[0]
which returns the first item in the selection - this you say is a group of two lines. So thengroup1.entities.add_group(group1.entities[0])
might move a line into a group but as it means moving entities it will fail, if not crash.Why not add a group then add an edge to that group's entities and then add another group to the group's entities and add an edge to that second group's entities - you get what you want with no risks...
model=Sketchup.active_model group1=model.active_entities.add_group() group1.entities.add_line(p1,p2) group2group.entities.add_group() group2.entities.add_line(p3,p4)
You now have what you want.
If the group of two edges already exists and you have it selected then it's more difficult to split up and regroup.
BUT if it's one simple edge out of two then I'd simply clone it thus...
` group1=model.selection[0]
e0=group1.entities[0]although how are we to be sure it's the right edge?
group2=group1.entities.add_group()
group2.entities.add_line(e0.vertices)
e0.erase!`
The edge is 'moved' into group2 by making a clone and erasing the original... -
Thank you for the "line" example,I have try to "move" a face,but it is not working.
group1=model.selection[0] e0=group1.entities[0] # a face group2=group1.entities.add_group() group2.entities.add_face(e0.edges) e0.erase!
What's wrong?
The error is : Edge has different parent -
How do YOU know [magically?] that
e0=group1.entities[0]
is aface
?
I could just as easily be anedge
that makes the face!
To find a face inside the group you must do this...
` group1=model.selection[0]
face=nil
group1.entities.each{|e|face=e if e.class==Sketchup::Face}assumes only ONE face to find!
group2=group1.entities.add_group()
face2=group2.entities.add_face(face.vertices)
face.erase!It's more complex IF the face has more that one loop - i.e. a 'hole'. Then you use...
oloop=face.outer_loop
loops=face.loops-[oloop]
loops.each{|loop|group2.entities.add_face(loop.vertices)}
group2.entities.add_face(oloop.vertices)`THEN remove holes
faces2go=[] group2.entities.each{|e|faces2go << e if e.class==Sketchup::Face and e.outer_loop.edges[0].faces[1]}
faces[1] means it's a hole as it's outer edge abuts another face.
group2.entities.erase_entities(faces2go)
NOW you should have a clone of the original face with its holes
face2=nil group2.entities.each{|e|face2=e if e.class==Sketchup::Face}
IF face has materials, layer or attributes 'copy' them to the new face2
then
face.erase!
The face has been replicated inside a nested group.Nothings that easy
-
Uff,a lot of work for "moving" a face.And still needs the material and back material and soften edges...
Almost easier to wait the Sketchup team to repair the Entities.add_group(other_entities) function@tig said:
How do YOU know [magically?] that e0=group1.entities[0] is a face?
The ruby console confirmed it.It is only for testing. -
@tig said:
face=nil group1.entities.each{|e|face=e if e.class==Sketchup::Face}
Can be written as:
face = group1.entities.find{|e|e.class==Sketchup::Face}
-
TIG: It's safe to group entities as long as they are in the same context, right? To move the face, why not group it, get it's definition, then place a new instance in the destination context and erase the old.
Avoiding having to manually recreate the faces with its loops and UV mapping etc.... -
@thomthom said:
To move the face, why not group it, get it's definition, then place a new instance in the destination context and erase the old.
Can you give the code sample,please(how to group it).I would like to test it.
-
It's working!!
I cannot believe it.I have a theory that nothing can work without testing.You are breaking this theory -
I always get uneasy when a code is run the first time without any errors...
-
It's only 100% safe to make a group directly with
ents.add_group(an_entities_array)
[or(an_entity)
]
if the 'ents' is themodel.active_entities
OR the same 'entities context'
Doing it across a mix of 'entities contexts' can cause Bugsplats ???
So then you normally make an empty group
group=ents.add_group()
and then add the entities to itsgroup.entities
; either by cloning raw geometry etc; or if it's a component, by using
instance2=group.entities.add_instance(instance.definition, instance.transformation)
or if it's a group, by using
group2=group.entities.add_instance(group.entities.parent, group.transformation)
If you are not immediately erasing the original 'group' then rungroup2.make_unique
on the new group because, otherwise they as as if they are components - changing one changing one changes the other - behavior not expected in groups which ought to only ever have one instance of their definition. -
If making a temp group of the face in situ works for you and you can then add an instance of that into another context and explode it and then erase the original face-group then that's good ... but if it splats you need to do it by 'cloning'
-
@thomthom said:
I always get uneasy when a code is run the first time without any errors...
Reading your code, the line
group.erase
makes me curious because the erase should be with the !.
So I discover that it was only half the code working.
But the result is ok.
So the working code is:def move_face(face, destination_entities ) source_entities = face.parent.entities entities = face.edges << face # I think you need to include all the edges related to the face group = source_entities.add_group( entities ) end
So the untested code theory remains
I will test it more,because of the Bugsplat fear. -
You need to add the
###... definition = group.entities.parent transformation = Geom::Transformation.new # Adjust to place where you want it. copy = destination_entities.add_instance( definition, transformation ) copy.explode # Ungroup the copied face group.erase**!** # Erase the original temp group
otherwise all your code does is move the face into a group that is in the in the same context the face was. I thought your aim was to move the face into another group ?
The methodmove_face( face, destination_entities )
takes the two arguments 'face' - the face to move; and 'destination_entities' - where you want it to end up - e.g.group2.entities
...
Thomthom's clever face>group,add_instance,explode,delete_original idea should work in this set of circumstances, without recourse to cloning...Note that this method 'moves' the face, and leaves it un-grouped - just as it was originally but now within another entities-context - if you want to copy the face into a group then the code needs tweaking - instead of deleting the original face [that's been grouped] withgroup.erase!
you usegroup.explode
to return the original face to its un-grouped state. -
<span class="syntaxdefault"><br />def move_face</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> face</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> destination_entities </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> source_entities </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> face</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">parent</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities<br /> entities </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> face</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">edges </span><span class="syntaxkeyword"><<</span><span class="syntaxdefault"> face </span><span class="syntaxcomment"># I think you need to include all the edges related to the face<br /></span><span class="syntaxdefault"> group </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> source_entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_group</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> entities </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> definition </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> group</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">parent<br /> transformation </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Transformation</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">new </span><span class="syntaxcomment"># Adjust to place where you want it.<br /></span><span class="syntaxdefault"> copy </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> destination_entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_instance</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> definition</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> transformation </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> copy</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">explode </span><span class="syntaxcomment"># Ungroup the copied face<br /></span><span class="syntaxdefault"> group</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">erase</span><span class="syntaxkeyword">!</span><span class="syntaxdefault"> </span><span class="syntaxcomment"># Erase the original temp group<br /></span><span class="syntaxdefault">end<br /></span>
Note: completely un-tested. Just a theory
-
Grrr,it is only working if the group is edited (so in the same context).
Otherwise strange behaviour and Bugsplat anytime. -
As I suspected then...
Usingents.add_group(ent_array)
only works safely ifents==model.active_entities
So use my cloning tips...
Advertisement