• Login
sketchucation logo sketchucation
  • Login
πŸ€‘ SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

How to add entities to a nested group?

Scheduled Pinned Locked Moved Developers' Forum
32 Posts 4 Posters 1.5k Views 4 Watching
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    draftomatic
    last edited by 12 Sept 2010, 18:57

    I want to have an Entities object which contains a face and its edges, and I want to group these entities, then add them to a different existing group which is nested 2 levels deep from Sketchup.active_model.entities. I tried this:
    # I already have the face (face), and the nested group (level2group) I want to add it to... ents = face.edges() ents.push(face) faceGroup = level2group.entities().add_group(ents)

    This doesn't work... faceGroup ends up without a parent, it seems. I attached a picture of what it looks like in the Outliner.

    also... the groups are locked, but should that make a difference? I tried unlocking them first and got the same result.


    The problem

    1 Reply Last reply Reply Quote 0
    • T Offline
      thomthom
      last edited by 12 Sept 2010, 19:51

      This face, are you creating it at some earlier point in your code?

      Thomas Thomassen β€” SketchUp Monkey & Coding addict
      List of my plugins and link to the CookieWare fund

      1 Reply Last reply Reply Quote 0
      • T Offline
        TIG Moderator
        last edited by 12 Sept 2010, 20:14

        You can't move entities between contexts.
        However, if you have two groups within the same context you can add both of these to a new group.
        Then you can explode one or both of these groups inside this new group - then you have a group containing both sets of entities etc...
        If you first get all of the first 'parent' group's details - [layer/material/name/properties/description/attributes] and then 'transfer them to this new group then you have effectively 'moved' the face-group [or its entities] into it, as for all intents and purposes it's become the same thing... [There's another recent thread about this...] πŸ€“

        TIG

        1 Reply Last reply Reply Quote 0
        • D Offline
          draftomatic
          last edited by 12 Sept 2010, 20:29

          @thomthom said:

          This face, are you creating it at some earlier point in your code?

          No, it's an existing face in the model.

          1 Reply Last reply Reply Quote 0
          • T Offline
            TIG Moderator
            last edited by 12 Sept 2010, 20:36

            For example, let's assume you have a group in the model 'group1' and a 'face' in the same 'context'...
            You use:
            grp=model.active_entities.add_group(group1, face)

            now get group1 details to transfer - e.g. name=group1.name

            group1.explode

            now rename/change details of grp to match group1 - e.g. grp.name=name

            group1=grp
            πŸ€“

            TIG

            1 Reply Last reply Reply Quote 0
            • D Offline
              draftomatic
              last edited by 13 Sept 2010, 15:09

              TIG, can you define "context?" Do you mean parent group?

              I want to nest this "faceGroup" 2 levels deep from model.entities... Does that mean I first have to do your trick to put it in level1group, then again to put it in level2group? This seems ridiculous! What if I wanted to nest faceGroup arbitrarily deep in a dynamic tree of groups? I'd have to write a recursive algorithm that copies all the group information over and over and over... All I'm really doing is changing faceGroup's parent group, right?

              Also... the face entities are both under model.entities, it's just that level2group is under level1group, which is under model.entities...

              1 Reply Last reply Reply Quote 0
              • T Offline
                TIG Moderator
                last edited by 13 Sept 2010, 16:38

                @draftomatic said:

                TIG, can you define "context?" Do you mean parent group?
                I want to nest this "faceGroup" 2 levels deep from model.entities... Does that mean I first have to do your trick to put it in level1group, then again to put it in level2group? This seems ridiculous! What if I wanted to nest faceGroup arbitrarily deep in a dynamic tree of groups? I'd have to write a recursive algorithm that copies all the group information over and over and over... All I'm really doing is changing faceGroup's parent group, right?
                Also... the face entities are both under model.entities, it's just that level2group is under level1group, which is under model.entities...

                The 'context' is the set of entities that the entity is in e.g. model.entities or group.entities or definition.entities - that is it's the entities of the parent of the entity!

                To add the faces 'face1' and 'face2' to a new group [group1] inside an existing group [group] that is in the same 'context' as the faces you first get that context...
                context=group.parent
                entities=context.entities
                group1=entities.add_group(face1,face2)
                group_temp=entities.add_group(group1,group)

                get all 'group' properties here...

                e.g. mat=group.material, layer=group.layer etc

                group.explode ### the entities are now back inside a group with another group next to them [group1]...
                group=group_temp ### group now refers back to the new container

                add the original group's properties to its new 'clone' - it's name is also referred to as 'group'...

                e.g. group.material=mat, group.layer=layer etc

                ...

                TIG

                1 Reply Last reply Reply Quote 0
                • D Offline
                  draftomatic
                  last edited by 15 Sept 2010, 16:32

                  This is only working for me to get the faceGroup nested one level deep from model.entities. After that, I get weird results. There exists rootGroup (under model.entities), which contains groupGroup, and I have a face, which should be grouped with its edges and placed inside of groupGroup:
                  ` # Make an array of the entities:
                  faceEntities = face.edges()
                  faceEntities.push(face)

                    # Get faceGroup inside of rootGroup:
                    faceGroup = @model.entities().add_group(faceEntities)
                    newRootGroup = @model.entities().add_group(rootGroup, faceGroup)
                    # Copy properties of rootGroup to newRootGroup here...
                    rootGroup.explode()
                    rootGroup = newRootGroup
                  
                    # Things seem to work up until here...
                    # Now nest it one level deeper:
                    newGroupGroup = rootGroup.entities().add_group(groupGroup, faceGroup)
                    # Copy properties of groupGroup to newGroupGroup here...
                    groupGroup.explode()
                    groupGroup = newGroupGroup`
                  

                  This line: newGroupGroup = rootGroup.entities().add_group(groupGroup, faceGroup) seems to copy my face/edges geometry and creates a new group... also, this crashes the program when I try to explode groupGroup (last line). What's going on?

                  After creating faceGroup under model.entities:
                  Group Bug before.JPG
                  Right before I explode groupGroup:
                  Group Bug after.JPG

                  1 Reply Last reply Reply Quote 0
                  • T Offline
                    TIG Moderator
                    last edited by 15 Sept 2010, 19:22

                    You cannot 'move' entities across 'contexts' when combining them into a new group.
                    That's what I tried to explain... how you need to find the common context level for the entities you are combining [even if that's back as the ' model.entities'], then combine the objects [or their parents, or copies of their parents in the same context - e.g. group.copy] into this new group... and then explode the sub-bits as needed...
                    Cross-threading entities is a sure recipe for a Bugsplat...
                    Also use model.active_entitiesIF you might be working initially NOT in model.entities - they can be the same if you are working 'in' the model... but 'entities' might refer to perhaps group.entities or definition.entities if you were to start in an 'edit' that is not the 'model'.
                    Note that faces[0]parent.entities will match the 'faces' entities context more safely...

                    You have a group and faces that you want to transfer into the group.
                    Make a new_group containing the group AND the faces.
                    Now get all of the properties of the group - name/description/layer/material etc etc
                    Repeat those on the new_group.
                    Explode the group inside the new_group.
                    For all intents and purposes 'new_group' IS 'group' AND it now contains the faces and its previous geometry/entities at the same context level inside it...

                    TIG

                    1 Reply Last reply Reply Quote 0
                    • D Offline
                      draftomatic
                      last edited by 15 Sept 2010, 19:40

                      @tig said:

                      You have a group and faces that you want to transfer into the group.
                      Make a new_group containing the group AND the faces.
                      Now get all of the properties of the group - name/description/layer/material etc etc
                      Repeat those on the new_group.
                      Explode the group inside the new_group.
                      For all intents and purposes 'new_group' IS 'group' AND it now contains the faces and its previous geometry/entities at the same context level inside it...

                      I'm sorry, but isn't that what I'm doing? I practically copied your code... Where am I "moving entities across contexts" ?????

                      faceGroup and groupGroup are in rootGroup - i.e., "same context." Then I create a newGroupGroup, containing faceGroup and groupGroup. I transfer properties of groupGroup to newGroupGroup, then explode groupGroup, and set groupGroup = newGroupGroup. Am I crazy or is this exactly what you're describing?

                      Also, I don't have multiple faces. I have a single face, and I want these entities grouped together, then placed under model.entities -> rootGroup -> groupGroup.

                      EDIT: "newRootGroup" -> "newGroupGroup" in 2nd paragraph...

                      1 Reply Last reply Reply Quote 0
                      • T Offline
                        TIG Moderator
                        last edited by 15 Sept 2010, 19:55

                        I must assume faceEntities is in the same context as the rest.
                        But in newGroupGroup = rootGroup.entities().add_group(groupGroup, faceGroup)
                        where did groupGroup suddenly come from ? It's not referred to in your example code...
                        and IT must be inside the rootGroup.entities - BUT where'd it come from...
                        THEN you explode this probbaly non-existent thing == Bugsplat ???

                        You seem to have overcomplicated it...

                        Also simply saying group2=group1 is changing a reference - it doesn't transfer 'properties' or 'attributes' - so you need to get the original group2 name and give that to the group2, and the same with layers, materials etc etc...

                        As I said tgroup=ents.add_group(extggroup,facebits)
                        'remember' extggroup details first, then
                        extggroup.explode
                        you have now got the entities that were in 'extggroup' AND 'facebits' inside the same group...
                        Now re-refer to tgroup as extggroup and add the 'remembered' extggroup details to []what is now 'called' extggroup ...

                        TIG

                        1 Reply Last reply Reply Quote 0
                        • D Offline
                          draftomatic
                          last edited by 15 Sept 2010, 21:48

                          @tig said:

                          I must assume faceEntities is in the same context as the rest.
                          But in newGroupGroup = rootGroup.entities().add_group(groupGroup, faceGroup)
                          where did groupGroup suddenly come from ? It's not referred to in your example code...
                          and IT must be inside the rootGroup.entities - BUT where'd it come from...
                          THEN you explode this probbaly non-existent thing == Bugsplat ???

                          faceEntities is under model.entities. rootGroup is under model.entities. groupGroup is already under rootGroup (look at the screenshots!). In fact, I created groupGroup with rootGroup.entities.add_group() (I'm 100% sure that groupGroup is correct; I can even find it by searching rootGroup.entities.each())

                          @tig said:

                          You seem to have overcomplicated it...

                          How?

                          @tig said:

                          Also simply saying group2=group1 is changing a reference - it doesn't transfer 'properties' or 'attributes' - so you need to get the original group2 name and give that to the group2, and the same with layers, materials etc etc...

                          I AM doing this. Look at the comments in the example code. The only purpose of groupGroup = newGroupGroup is to keep my variable names, since in the real code these are instance variables.

                          @tig said:

                          As I said tgroup=ents.add_group(extggroup,facebits)
                          'remember' extggroup details first, then
                          extggroup.explode
                          you have now got the entities that were in 'extggroup' AND 'facebits' inside the same group...
                          Now re-refer to tgroup as extggroup and add the 'remembered' extggroup details to []what is now 'called' extggroup ...

                          Why do I have to store these properties? Consider this:
                          ` newGroupGroup = rootGroup.entities().add_group(groupGroup, faceGroup)

                          Copy properties of groupGroup to newGroupGroup here...

                          groupGroup.explode()
                          groupGroup = newGroupGroup`

                          I don't see anything wrong with copying the properties directly before I explode groupGroup. The properties are going from groupGroup to newGroupGroup, so at one point they will have identical properties. Then I explode groupGroup. Seems okay to me...

                          1 Reply Last reply Reply Quote 0
                          • T Offline
                            TIG Moderator
                            last edited by 15 Sept 2010, 22:41

                            Last things first...
                            Assuming the next two objects mentioned are in the same 'context'...
                            A group variable ' group1' is named "mygroup1", it's on layer "XXXX" and has material "red" etc. This is the group we are adding to
                            A group variable ' group2' is named "mygroup2", it's on layer "AAAA" and has material "banana" etc. This is the group we want to add.
                            You add a temporary group thus:
                            newgroup=group1.parent.entities.add_group(group1,group2)
                            At this point variable ' newgroup' has name="", layer=nil and material=nil etc.
                            When you explode 'group1' all of it properties and attributes vanish with it [properties reside with the object NOT its variable]... UNLESS you save the properties/attributes BEFORE you do the explode thus:
                            name=group1.name layer=group1.layer mat=group1.material
                            etc
                            NOW you can explode group1, change its referring variable to the temporary group...
                            group1=newgroup group1.name=name group1.layer=layer group1.material=mat
                            etc
                            NOW for all intents and purposes the group is still group1 [its 'id' has changed but nothing else].
                            So you end up with a group variable ' group1' named etc exactly as before containing the same entities PLUS ' group2'...
                            You can also explode group2 if desired...

                            You say faceEntities is under model.entities. rootGroup is under model.entities. groupGroup is already under rootGroup...
                            BUT newGroupGroup = rootGroup.entities.add_group(groupGroup, faceGroup) [note the removed () after entities - not correct !!!] will add a group to rootGroup's entities, and remember that at this point in your code rootGroup is now a pointer to what was newRootGroup... which you have just made inside @model.entities from the original rootGroup and [ruby:1upcmdm6]faceGroup[/ruby:1upcmdm6].
                            You are therefore adding two things into this [ruby:1upcmdm6]newGroupGroup[/ruby:1upcmdm6] ... [ruby:1upcmdm6]faceGroup[/ruby:1upcmdm6] which IS in there as you have just added it AND the mysterious [ruby:1upcmdm6]groupGroup[/ruby:1upcmdm6] BUT newRootGroup [now referred to a rootGroup] was made from [ruby:1upcmdm6]faceGroup[/ruby:1upcmdm6] AND rootGroup which you then exploded after it was added - so unless [ruby:1upcmdm6]groupGroup[/ruby:1upcmdm6] was already inside that and is therefore now inside the now called rootGroup after the explosion, AND you had previously referred explicitly to it BEFORE all of this - which is NOT shown in any of your code πŸ˜’ - then it WILL fail - if you have made a reference to an 'object' that seems to have appeared from nowhere and therefore ==nil.
                            Do you have a handle to this 'object' set up before this code snippet ?
                            You are perhaps onfusing the groups' references [variables] and their actual names [which appear in the Outliner]... So it may be named 'groupGroup' but is there a variable called 'groupGroup' that is pointing at it ?? There's nothing in your code to show it...
                            Try tidyinh your syntax [remove unneeded () etc] and check that everything is properly 'referred to' by variables -
                            which can share the objetc's names but need to be called explicitly.
                            Also note that making a new group [unlike making a copy of it] defaults all of its properties/attributes - and you have to transfer them to its 'clone'...
                            πŸ˜’

                            TIG

                            1 Reply Last reply Reply Quote 0
                            • D Offline
                              draftomatic
                              last edited by 16 Sept 2010, 18:10

                              TIG, I really appreciate your help, but I still can't see that I'm doing anything wrong.

                              I've made a small example script that emulates my bug. Could you take a look please please? πŸ˜ƒ


                              test_group_bug.rb

                              1 Reply Last reply Reply Quote 0
                              • T Offline
                                TIG Moderator
                                last edited by 16 Sept 2010, 19:25

                                Try this...

                                # Testing group nesting
                                ### with TIG edits ###
                                  model = Sketchup.active_model
                                  entities = model.active_entities ### NOTE; 'active_'
                                  pts = []
                                  pts[0] = [0, 0, 0]
                                  pts[1] = [100, 0, 0]
                                  pts[2] = [100, 100, 0]
                                  pts[3] = [0, 100, 0]
                                  face = entities.add_face(pts)
                                  faceGroup = entities.add_group(face)
                                  faceGroup.name = "faceGroup"
                                  ### A GROUP REFERRED TO AS 'faceGroup', NAMED 'faceGroup'.
                                  ### IT CONTAINS THE FACE AND ITS EDGES - THEY ARE COPIED IT THEY ARE 
                                  ### STILL NEEDED IN THE ORIGINAL ENTITIES...
                                  rootGroup = entities.add_group()
                                  rootGroup.name = "rootGroup"
                                  ### A GROUP REFERRED TO AS 'rootGroup', NAMED 'rootGroup'.
                                  newGroup = rootGroup.entities.add_group(faceGroup)
                                  newGroup.name = rootGroup.name
                                  ### THERE'S NOW A GROUP REFERRED TO AS 'newGroup', BUT CALLED 'rootGroup'
                                  ### INSIDE IT IS A GROUP REFERRED/CALLED 'rootGroup'
                                  ### WHICH CONTAINS A GROUP REFERRED/NAMED 'faceGroup'
                                  ### WHICH CONTAINS THE 'face' ENTITIES...
                                  ### NOW DO WHAT YOU WANT...
                                ###
                                

                                TIG

                                1 Reply Last reply Reply Quote 0
                                • D Offline
                                  draftomatic
                                  last edited by 17 Sept 2010, 16:34

                                  @tig said:

                                  Try this...

                                  Try what? I did all of this in my code! I also want to nest faceGroup one level deeper, into "groupGroup."

                                  As I said, getting faceGroup inside of rootGroup isn't a problem. It works using your trick. But I need it to go one level deeper, into groupGroup, and it's not working!!!

                                  You stopped the code RIGHT BEFORE the point where I don't know what's wrong... And you took out the part with groupGroup, which is my entire problem!

                                  Your code does this:
                                  group_bug_tig.JPG

                                  Please TIG or someone else, can you tell me specifically in my code, i.e. what line and WHY, am I doing wrong? I posted the example which reproduces my bug. What am I doing wrong? This bug has been stopping me for a week now... it's getting ridiculous!

                                  1 Reply Last reply Reply Quote 0
                                  • T Offline
                                    TIG Moderator
                                    last edited by 17 Sept 2010, 17:43

                                    This 'groupGroup' must be inside the same context as 'faceGroup'... OR...

                                    You already have

                                    rootGroup** IN model.entities
                                    AND
                                    face IN faceGroup IN newGroup [also named 'rootGroup'** BUT it is a different group] IN model.entities

                                    so simply use:

                                    groupGroup=newGroup.entities.add_group(faceGroup)
                                    groupGroup.name="groupGroup"

                                    face IN faceGroup IN groupGroup IN newGroup [named 'rootGroup'**] IN model.entities

                                    OR you add another a group to model.entities

                                    groupGroup=entities.add_group(newGroup)
                                    groupGroup.name="rootGroup" ###***

                                    face IN faceGroup IN newGroup [named 'rootGroup'] IN groupGroup [named yet another 'rootGroup'*] IN model.entities

                                    You just have to decide which groups contain which.

                                    Naming groups with the same name is plain confusing - why do it ?
                                    Give them each a unique reference and at the end name them appropriately...

                                    TIG

                                    1 Reply Last reply Reply Quote 0
                                    • D Offline
                                      draftomatic
                                      last edited by 17 Sept 2010, 18:08

                                      Okay, you're just confusing me now, and what you're describing doesn't work for my situation. groupGroup already exists, and rootGroup already exists. I'm only creating them again in my example so that it can stand alone. So doing anything like groupGroup=newGroup.entities.add_group(faceGroup) isn't acceptable, because groupGroup is ALREADY THERE.

                                      Look TIG, can we get a bit simpler? Can you look quickly at test_group_bug.rb? I just simply don't understand why this line:
                                      LINE 49: newGroupGroup = rootGroup.entities().add_group(groupGroup, faceGroup)
                                      is breaking my code. As far as I can see, this is EXACTLY what you've told me to do. The contexts of groupGroup and faceGroup are identical (faceGroup.parent = rootGroup, and groupGroup.parent = rootGroup... I've checked).

                                      Moreover, the SAME CODE works several lines up, when I do the SAME THING, except in model.entities instead of in rootGroup. I'm very confused, and I need a straightforward answer. What EXACTLY is wrong about that line of code?

                                      1 Reply Last reply Reply Quote 0
                                      • T Offline
                                        TIG Moderator
                                        last edited by 17 Sept 2010, 19:24

                                        The 'groupGroup' group DOESN'T really exist... except that you have made an empty group [too early] with that reference.
                                        Adding that empty group so early on into the mix and then trying to 'move' it into another group only confuses things.
                                        IF you already have a non-empty group with that reference then it's OK... but if not only make it when you need it otherwise.

                                        If you still can't get your head around this then please post a simple before and after set of uniquely named objects with their hierarchy - e.g.

                                        modelEntities=model.active_entities

                                        CONTAINING [at least] groupX [an existing group that isn't empty] and face [a face]

                                        OR ANY OTHER entities set with common objects you are to 'group' ?

                                        groupX > modelEntities
                                        face > modelEntities

                                        WHICH BECOMES faceGroup = modelEntities.add_group(face)

                                        face > faceGroup > modelEntities

                                        THEN group1 = modelEntities.add_group(faceGroup, groupX)

                                        face > faceGroup > group1 > modelEntities
                                        groupX > group1 > modelEntities

                                        THEN group2 = group1.entities.add_group(faceGroup, groupX)

                                        face > faceGroup > group2 > group1 > modelEntities
                                        groupX > group2 > group1 > modelEntities

                                        THEN group3 = group2.entities.add_group(groupX)

                                        face > faceGroup > group2 > group1 > modelEntities [STILL THE SAME AS BEFORE]
                                        groupX > group3 > group2 > group1 > modelEntities

                                        TO SEPARATE THE ENTITIES INTO SEPARATE GROUPS ETC ETC...

                                        YOU CAN GO ON AND ON...

                                        This has no 'names' just references to groups etc - you can add those later...

                                        TIG

                                        1 Reply Last reply Reply Quote 0
                                        • D Offline
                                          draftomatic
                                          last edited by 17 Sept 2010, 19:57

                                          @tig said:

                                          The 'groupGroup' group DOESN'T really exist... except that you have made an empty group [too early] with that reference.
                                          Adding that empty group so early on into the mix and then trying to 'move' it into another group only confuses things.
                                          IF you already have a non-empty group with that reference then it's OK... but if not only make it when you need it otherwise.

                                          In my real code, there is already a CPoint inside "groupGroup." If you think it's a problem that groupGroup is empty, then fine, I just tried adding a CPoint to groupGroup in my example script. Still broken.

                                          @tig said:

                                          If you still can't get your head around this

                                          Sir, my head is wrapped around this problem about 9 times already. I feel like you think I don't understand, but I do. I understand every word you have written, and I keep telling you, "I'm doing that, I'm doing that. Look at my code, look at my code."

                                          @tig said:

                                          please post a simple before and after set of uniquely named objects with their hierarchy - e.g.

                                          I did this already. Look at my script!!! Look at my screenshots!!! I am creating rootGroup and groupGroup. That is my hierarchy.

                                          I'm going to repeat my question again. What is wrong with line 49 of my previous example script? I COMPLETELY understand EVERYTHING you're telling me, and I believe I'm doing it, but it's still broken, and I don't see why!!!!!!!!!!

                                          1 Reply Last reply Reply Quote 0
                                          • 1
                                          • 2
                                          • 1 / 2
                                          1 / 2
                                          • First post
                                            6/32
                                            Last post
                                          Buy SketchPlus
                                          Buy SUbD
                                          Buy WrapR
                                          Buy eBook
                                          Buy Modelur
                                          Buy Vertex Tools
                                          Buy SketchCuisine
                                          Buy FormFonts

                                          Advertisement