• Login
sketchucation logo sketchucation
  • Login
๐Ÿค‘ 30% Off | Artisan 2 on sale until April 30th Buy Now

Why is my Group deleted while trying to add entities to it?

Scheduled Pinned Locked Moved Developers' Forum
20 Posts 6 Posters 616 Views
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.
  • T Offline
    tiktuk
    last edited by tiktuk 10 May 2012, 13:29

    Hi all,

    I am trying to create a script for creating struts for models of geodesic domes. I do this by iterating over all edges in a model of a geodome and create boxes along the edges. I have gotten all this to work, but for convenience I would like to add all my created boxes to a new group. This fails in the second iteration of the loop, with this message:

    Error; #<TypeError; reference to deleted Group>
    geodome_frame.rb;58;in `entities'
    geodome_frame.rb;58;in `create_frame'
    geodome_frame.rb;53;in `each'
    geodome_frame.rb;53;in `create_frame'
    geodome_frame.rb;115;in `main'
    geodome_frame.rb;84
    geodome_frame.rb;57;in `call'
    geodome_frame.rb;57
    
    

    The frame is created if I uncomment the code that adds all struts to a group.

    Here is the relevant code:

    <span class="syntaxdefault"></span><span class="syntaxcomment"># Create a strut (as a box in a group)<br /># along an edge, facing a center point.<br /></span><span class="syntaxdefault">def create_strut edge</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> center</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> size<br />    entities </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities<br />    width</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> depth </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> size<br />    <br />    vec_to_center </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">position</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">vector_to center<br />    plane_intersecting_with_center </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> Geom</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">fit_plane_to_points center</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">position</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">end</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">position<br />    <br />    </span><span class="syntaxcomment"># We need a vector in the plane of the top of the strut.<br /></span><span class="syntaxdefault">    </span><span class="syntaxcomment"># It is the same as the normal to the plane intersecting with the center<br /></span><span class="syntaxdefault">    </span><span class="syntaxcomment"># which is the same as the three first values in the plane we just calculated.<br /></span><span class="syntaxdefault">    width_vec </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Vector3d</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">new plane_intersecting_with_center</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">0..2</span><span class="syntaxkeyword">]<br /></span><span class="syntaxdefault">    width_vec</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> width </span><span class="syntaxkeyword">/</span><span class="syntaxdefault"> 2<br />    <br />    </span><span class="syntaxcomment"># We add half a strut-width to the end points<br /></span><span class="syntaxdefault">    </span><span class="syntaxcomment"># of the edge to get the corners of the top of the strut.<br /></span><span class="syntaxdefault">    e1 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">position </span><span class="syntaxkeyword">+</span><span class="syntaxdefault"> width_vec<br />    e2 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">position </span><span class="syntaxkeyword">-</span><span class="syntaxdefault"> width_vec<br />    e3 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">end</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">position </span><span class="syntaxkeyword">-</span><span class="syntaxdefault"> width_vec<br />    e4 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">end</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">position </span><span class="syntaxkeyword">+</span><span class="syntaxdefault"> width_vec<br />    <br />    </span><span class="syntaxcomment"># We add a group for the strut and create the strut top face<br /></span><span class="syntaxdefault">    strut_group </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_group<br />    strut_top_rect </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">[</span><span class="syntaxdefault">e1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> e2</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> e3</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> e4</span><span class="syntaxkeyword">]<br /></span><span class="syntaxdefault">    strut_top_face </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> strut_group</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_face strut_top_rect<br />    <br />    </span><span class="syntaxcomment"># Push pull the top face to create the final strut<br /></span><span class="syntaxdefault">    strut_top_face</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">pushpull </span><span class="syntaxkeyword">-</span><span class="syntaxdefault">depth<br />    <br />    return strut_group<br />end<br /><br /></span><span class="syntaxcomment"># Loop through all edges in the current selection and<br /># create struts. And add all the struts to a group.<br /></span><span class="syntaxdefault">def create_frame edges</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> center</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> size<br />    frame_group </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_group<br />    frame_group</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">name </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">'Geodome frame'<br /></span><span class="syntaxdefault">    for edge in edges<br />        puts frame_group</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">name<br />        puts frame_group<br />        strut </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> create_strut edge</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> center</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> size<br />        </span><span class="syntaxcomment"># strut.name = <br /></span><span class="syntaxdefault">        frame_group</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_group strut<br />    end<br />end</span>
    

    The entire script is here: https://bitbucket.org/tiktuk/geodome-frames-for-su/src/86808fce358a/geodome_frame.rb .

    If you would like to reproduce:

    1. Install the plugin as usual.
    2. Select some geometry including edges (doesn't have to be a geodome model) for this test.
    3. Choose Create geodome frame from the plugin menu.

    Any ideas..?

    1 Reply Last reply Reply Quote 0
    • T Offline
      thomthom
      last edited by 10 May 2012, 13:38

      Where in the script does the error occur?

      [off:1hcvswxb]Btw - you should wrap your plugin in a module in order to contain it to its own namespace.
      Read more: http://www.thomthom.net/thoughts/2012/01/golden-rules-of-sketchup-plugin-development/ [/off:1hcvswxb]

      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
        thomthom
        last edited by 10 May 2012, 13:41

        One thing to note when using the Ruby API:
        When grouping, add the group and add the entities directly to the new group.

        This is somewhat different from what you do when modelling where you make the faces/edge etc and then group it.

        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
          thomthom
          last edited by 10 May 2012, 13:43

          [off:1l6p55ob] Sketchup.active_model.start_operation 'Geodome frame'
          Set the second argument, disable_ui to true for speed improvements.
          https://developers.google.com/sketchup/docs/ourdoc/model#start_operation [/off:1l6p55ob]

          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
            thomthom
            last edited by 10 May 2012, 13:45

            [off:ujkahpgr]Instead of this: Sketchup.active_model.entities
            Use this: Sketchup.active_model.active_entities
            That way the geometry is added to the currently open group or component.[/off:ujkahpgr]

            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
              tiktuk
              last edited by 10 May 2012, 13:49

              @thomthom said:

              Where in the script does the error occur?

              I have updated the post to include the full error message.

              @unknownuser said:

              [off:56wfnlq5]Btw - you should wrap your plugin in a module in order to contain it to its own namespace.
              Read more: http://www.thomthom.net/thoughts/2012/01/golden-rules-of-sketchup-plugin-development/ [/off:56wfnlq5]

              Great, will look into that! And thanks for all your other tips as well ๐Ÿ˜„ .

              1 Reply Last reply Reply Quote 0
              • T Offline
                TIG Moderator
                last edited by 10 May 2012, 14:02

                Only ever use entities.add_group(ents) when 'entities' is the 'model.active_entities' and 'ents' are also in the 'model.active_entities'...
                Something like...
                frame_group = Sketchup.active_model.active_entities.add_group() for edge in edges frame_group.entities.add_group(self.create_strut(edge,center,size)) end
                might be better...

                TIG

                1 Reply Last reply Reply Quote 0
                • T Offline
                  thomthom
                  last edited by 10 May 2012, 14:02

                  Error line doesn't match anything in the BitBucket repository... โ“

                  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
                    thomthom
                    last edited by 10 May 2012, 14:08

                    I'm guessing it refer to line 58. I'm pretty sure it's because you make the containing group after you make the child entities. Refactor the code so you always create the container first - and then add the entities to the container.

                    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
                      tiktuk
                      last edited by 10 May 2012, 14:54

                      @thomthom said:

                      Error line doesn't match anything in the BitBucket repository... โ“

                      Sorry, the file was out of sync, yes. Corrected.

                      Looking into your suggestions now!

                      1 Reply Last reply Reply Quote 0
                      • T Offline
                        tiktuk
                        last edited by 10 May 2012, 15:37

                        @thomthom said:

                        I'm guessing it refer to line 58. I'm pretty sure it's because you make the containing group after you make the child entities. Refactor the code so you always create the container first - and then add the entities to the container.

                        strut = create_strut edge, center, size frame_group.entities.add_group strut

                        I think you are onto something there. I just noticed that I am creating an extra group in that line, that I don't want or need. create_strut is already returning a group and I have used add_group strut to add that group to my frame_group but while doing that I am creating another group.

                        How do I add an existing entity (a group in this instance), to an existing group? I can't find any methods for that.

                        1 Reply Last reply Reply Quote 0
                        • T Offline
                          tiktuk
                          last edited by 10 May 2012, 15:54

                          @tig said:

                          Only ever use entities.add_group(ents) when 'entities' is the 'model.active_entities' and 'ents' are also in the 'model.active_entities'...
                          Something like...
                          frame_group = Sketchup.active_model.active_entities.add_group() for edge in edges frame_group.entities.add_group(self.create_strut(edge,center,size)) end
                          might be better...

                          Thanks TIG. Did not solve this problem but learning about 'active_entities' was very useful. Was wondering why my struts were being created outside the active component before..

                          1 Reply Last reply Reply Quote 0
                          • D Offline
                            Dan Rathbun
                            last edited by 10 May 2012, 18:46

                            Above:

                            delete line 44

                            change line 42 to:
                            create_strut edge, center, size, frame_group

                            change line 3 to:
                            def create_strut edge, center, size, frame_group

                            change line 4 to:
                            entities = frame_group.entities

                            ๐Ÿ˜„

                            I'm not here much anymore.

                            1 Reply Last reply Reply Quote 0
                            • K Offline
                              kwalkerman
                              last edited by 10 May 2012, 23:13

                              @tiktuk said:

                              @thomthom said:

                              I'm guessing it refer to line 58. I'm pretty sure it's because you make the containing group after you make the child entities. Refactor the code so you always create the container first - and then add the entities to the container.

                              strut = create_strut edge, center, size frame_group.entities.add_group strut

                              I think you are onto something there. I just noticed that I am creating an extra group in that line, that I don't want or need. create_strut is already returning a group and I have used add_group strut to add that group to my frame_group but while doing that I am creating another group.

                              How do I add an existing entity (a group in this instance), to an existing group? I can't find any methods for that.

                              I'm not aware of any way to do this directly. If it's a group you want to add you can say:

                              new_group.entities.add_instance original_group.entities.parent
                              

                              (original_group.entities.parent will give you the original group's definition, so you add it like you're adding a component instance)

                              as far as adding individual items to a group, you can do it this way, but it's a little iffy:

                              entities_i_want_to_add = []   #array of entities you want to add to the new group
                              new_group = entities.add_group entities_i_want_to_add
                              

                              then I guess you could find the definition of this new group and add it to whatever entities collection you want, then explode the original

                              The most foolproof way to add entities to a group is to add the raw geometry using Entities.add_edges and Entities.add_face. You'd also need to copy the materials and any attributes you wanted to go along with them.

                              1 Reply Last reply Reply Quote 0
                              • T Offline
                                TIG Moderator
                                last edited by 11 May 2012, 08:47

                                As Karen said...
                                You can replicate the faces, edges etc inside a new group [erasing the originals if desired], but you ought to include all materials, layers, smoothed/softened/hidden-settings and attributes etc to make a perfect clone.
                                You can 'safely' use group=entities.add_group(array_of_stuff) BUT only if the new group and all of the elements in the array are in the same 'context' AND that is the model.active_entities... you can check for that, or if for example you are working on a preselection you know that it is the active_entities, so this will work...
                                new_group=model.active_entities.add_group(model.selection.to_a)

                                Then you could 'move' that into any other group/component's entities by getting a reference to its definition [components, groups and images are each instances of variations of a 'definition'].
                                Let's assume you have another group called 'receiver_group'...
                                tr=Geom::Transformation.new() new_group_clone=receiver_group.entities.add_instance(new_group.entities.parent, tr)
                                So the selection has been grouped, that group has been cloned inside another group.

                                To tidy up use new_group.erase! - you could also use new_group_clone.explode so the selection is loose inside the 'receiver_group'...

                                TIG

                                1 Reply Last reply Reply Quote 0
                                • T Offline
                                  tiktuk
                                  last edited by 14 May 2012, 13:59

                                  Thanks everybody, this forum is splendid, got it working thanks to your explanations ๐Ÿ‘ . Ended up just collecting the groups in an array an creating a group with that. Works perfectly.

                                  <span class="syntaxdefault">def&nbsp;create_frame&nbsp;edges</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">center</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">size<br />&nbsp;&nbsp;all_struts&nbsp;</span><span class="syntaxkeyword">=&nbsp;[]<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">edges</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_with_index&nbsp;</span><span class="syntaxkeyword">{&nbsp;|&nbsp;</span><span class="syntaxdefault">edge</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">index&nbsp;</span><span class="syntaxkeyword">|<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">strut&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">create_strut&nbsp;edge</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">center</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">size<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;props&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">strut_properties&nbsp;edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strut</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">name&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">props</span><span class="syntaxkeyword">[</span><span class="syntaxstring">"name"</span><span class="syntaxkeyword">]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">strut</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">material&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">props</span><span class="syntaxkeyword">[</span><span class="syntaxstring">"color"</span><span class="syntaxkeyword">]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">all_struts&nbsp;</span><span class="syntaxkeyword"><<&nbsp;</span><span class="syntaxdefault">strut<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">frame_group&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_group&nbsp;all_struts<br />&nbsp;&nbsp;&nbsp;&nbsp;frame_group</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">name&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxstring">"Geodome&nbsp;frame"<br /></span><span class="syntaxdefault">end</span>
                                  

                                  I see that your idea would work too, Dan, thanks!

                                  1 Reply Last reply Reply Quote 0
                                  • D Offline
                                    Dan Rathbun
                                    last edited by 14 May 2012, 14:14

                                    @tiktuk said:

                                    I see that your idea would work too, Dan, thanks!

                                    Your welcome.

                                    It is a normal way to pass the context into a method, that creates geometry, so that the method can create the geometry in any context (model or group or component.)

                                    It makes your methods more flexible, so that they can be reused for multiple commands and plugins.

                                    I'm not here much anymore.

                                    1 Reply Last reply Reply Quote 0
                                    • T Offline
                                      thomthom
                                      last edited by 14 May 2012, 14:17

                                      I second what Dan said.

                                      When you model in SketchUp you draw then group.

                                      When you use the API you make the group and then draw entities within that group. It's the clean and safe way of grouping. It's also faster, because you add the entities directly into the context where you want then. If you take existing geometry and group them it takes extra processing to move them.

                                      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
                                        thomthom
                                        last edited by 16 May 2012, 10:22

                                        @th3lurker said:

                                        Also, even if you don't use it, group.add_faces_from_mesh and group.fill_from_mesh seem to delete everything existent in that group.

                                        Only group.fill_from_mesh - as described in the API docs for the methods.

                                        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
                                          th3lurker
                                          last edited by 16 May 2012, 10:39

                                          Also, even if you don't use it, group.entities.add_faces_from_mesh and group.entities.fill_from_mesh seem to delete everything existent in that group.
                                          Edit: thomthom corrected me, sorry. Also, i wrote group.fill_from_mesh instead of group.ENTITIES.fill_from_mesh.
                                          I'm going to crawl back to my hole now, one post, two mistakes is quite embarrassing. ๐Ÿ˜ข

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

                                          Advertisement