sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Modifying geometry in freshly copied Groups (not unique)

    Scheduled Pinned Locked Moved Developers' Forum
    8 Posts 4 Posters 572 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.
    • fredo6F Offline
      fredo6
      last edited by

      I spent some time exploring the implications of non-unique groups from the Ruby perspective and found that it may be the source of numerous nasty crashes and issues in scripts.

      1) Background

      When you create a copy of a Group in a model, whether by Copy / Paste or by the Move tool in copy mode, the new created group does not duplicate its geometry. Instead, the new and old groups share the same Definition, a little bit like Components. You can check in the Entity Info panel that the Groups are indicated with “Group (2 in model)”.

      In the Sketchup viewport, you will however make a group Unique whenever you double-click on it and edit it.

      In Ruby, the situation is different when you access directly the entities of the group. Many scripts just work on geometry at the top level, but there are a few scripts that have to change the geometry within groups. And for these scripts, the situation of duplicated groups may be quite frequent, because, for safety reasons, the user would naturally make a copy of the geometry s/he works on before launching the script modifying this geometry.

      2) The Problem for Ruby scripts

      From a Ruby standpoint, duplicated groups:

      • Have 2 different entities objects: g1.entities != g2.entities
      • However, their list of entities (edges, faces, …) are strictly identical: g1.entities.to_a == g2.entities.to_a
      • which is because they share a common Definition: g1.entities.parent == g2.entities.parent

      As a result, if you modify an element in one of the group by methods such as transform_by_vector, transform_entities, erase_entities, erase!, material =, … you may likely get a wrong behavior:

      • Either the change may apply to the other group (for instance when you transform). These methods seem however to make the group unique
      • Or it will apply to both groups (for instance with erase!, material=). In addition this does not make the group unique.

      The real problem occurs when groups become de-duplicated (i.e. unique), because each group has now its own set of entities. So the references to edges, vertices and faces you previously had will now point to the entities of one of the group. And by chance, it may not be the group you are working on.

      This situation is likely to provoke SU crashes and ‘reference to deleted entity’ errors, especially if you do these modifications repeatedly. Not mentioning that when you perform Undo (or model.abort_operation) you can get very nasty bugsplats.

      3) How to detect whether a group <g> is unique or not

      The test is (g.entities.parent.count_instances == 1)

      4) How to make a group unique by Ruby

      I noticed a few things:

      • The method make_unique for groups does the job, but display a warning message about its obsolescence
      • Changing the name of one of the group (new name or same name) does NOT work. If you do this, you will surely see in the Entity Info box that each group is a single instance, BUT under the hood, you still have the commonality of entities ( g1.entities.to_a == g2.entities.to_a)
      • Creating a group and deleting it seems to make the groups unique, so a one-liner such as g1.entities.add_group.erase! would work. The benefit of this method is that you don’t get any warning message in the Ruby console.

      5) How to solve the problem of reference to entities

      Once a group is made unique, the references to edges, faces vertices and other elements that you previously computed when exploring the group entities, are NO LONGER valid. Actually, they may be valid SU objects, but belong to another group.

      One way to circumvent this problem is to build a mapping of entities for the group before it is made unique in order to retrieve them after. The method is based on two properties that seem to be respected:

      • when a group is made unique, the list of entities keeps the same order before and after.
      • object_id method is valid for old edges or faces before and after the ‘make unique’ operation

      This means that for instance g.entities[i] refers to the same edge or face before and after the ‘make unique’ operation, even if the reference it contains is different.

      A suggested code is therefore as follows:

      Let’s say that you explored the group and found a list of edges and faces that you want to operate onto: < selected_edges_and_faces >

      First you save the index of each entity in the group

      
      hmapid = {}
      g.entities.each_with_index { |e, i| hmapid[e.object_id] = i  }
      
      

      Then you make the group unique. At this stage, the list <selected_edges_and_faces> does not contain valid references anymore.

      Then to recompute the corresponding valid references , you need to use the mapping:

      
      gent = g.entities
      selected_edges_and_faces = selected_edges_and_faces.collect { |e| gent[hmapid[e.object_id] }
      
      

      Note that if you had references to vertices, you need to recomput them from the new edges or faces references.

      6) Conclusions

      • The optimization brought by keeping the same definition for freshly copied groups is a real pain for Ruby scripts. Of course it is faster for the user in the viewport and it saves space.

      • The make_unique method is not at all to be deprecated, whatever the SU development team thinks. The workaround g.entities.add_group.erase! is not necessarily a good, performing solution.

      • It is advised to perform the ‘make unique’ operation on groups as a true Operation, that is, within a start_operation and a commit_operation. This avoids that undo or abort_operation generate crashes, as apparently the undoing is not well managed in those particular situations. Of course, this makes the flow of operations more complex.

      • Personally, I would expect the Sketchup development team to find a built-in solution, either by disabling this optimization feature of duplicated groups or by making sure that any modification on entities are applicable to the referred groups (which is then made unique).

      Any comment and feedback welcome.

      Fredo

      1 Reply Last reply Reply Quote 0
      • jolranJ Offline
        jolran
        last edited by

        Thank you for this. Very useful information indeed. Will use these methods for sure.

        @4) So renaming the group doesent make it uniq, huh? To bad. 😞

        1 Reply Last reply Reply Quote 0
        • thomthomT Offline
          thomthom
          last edited by

          @jolran said:

          @4) So renaming the group doesent make it uniq, huh? To bad. 😞

          Because it works just like component instances - you can name each instance differently.

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

          1 Reply Last reply Reply Quote 0
          • jolranJ Offline
            jolran
            last edited by

            @unknownuser said:

            Because it works just like component instances - you can name each instance differently

            Yeah. So there exist some consistency in the API after all ? 😄

            Seriously though, my vote for this post is to be made sticky or something similar.
            Otherwise there is a risk it gets lost on page 4 or so 2 weeks.

            1 Reply Last reply Reply Quote 0
            • thomthomT Offline
              thomthom
              last edited by

              @jolran said:

              Yeah. So there exist some consistency in the API after all ? 😄

              http://www.thomthom.net/thoughts/2012/02/definitions-and-instances-in-sketchup/

              @jolran said:

              Seriously though, my vote for this post is to be made sticky or something similar.
              Otherwise there is a risk it gets lost on page 4 or so 2 weeks.

              Could add it to the existing sticky with list of link ?

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

              1 Reply Last reply Reply Quote 0
              • Dan RathbunD Offline
                Dan Rathbun
                last edited by

                @jolran said:

                @unknownuser said:

                Seriously though, my vote for this post is to be made sticky or something similar.

                You can have your OWN set of bookmarked topics.

                The "Bookmark topic" link is at the bottom of each topic page.

                You access your bookmarks thru the User Control Panel.

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • jolranJ Offline
                  jolran
                  last edited by

                  @unknownuser said:

                  You can have your OWN set of bookmarked topics.

                  Dan. I've must admit never ever fiddled with preferences. Thats a good tip.
                  However I was thinking more as a benefit to others, keeping this info visible.

                  Thomthom I've read your post but was thinking more about that old topic I started:
                  (which I find higly relative to this topic)

                  http://sketchucation.com/forums/viewtopic.php?f=180&t=51263

                  Now Fredo seams to have a better solution and that makes me very happy.

                  1 Reply Last reply Reply Quote 0
                  • Dan RathbunD Offline
                    Dan Rathbun
                    last edited by

                    @jolran said:

                    However I was thinking more as a benefit to others, keeping this info visible.

                    I added this topic to my manual list of Snippets.

                    See Groups: [Code Snippets] by Subject

                    I'm not here much anymore.

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

                    Advertisement