• Login
sketchucation logo sketchucation
  • Login
🤑 SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

Can't regroup an exploded ComponentInstance

Scheduled Pinned Locked Moved Developers' Forum
10 Posts 4 Posters 1.7k 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.
  • G Offline
    Grays42
    last edited by 24 Aug 2013, 19:10

    Problem Background/Context: Here's an example gallery of what I'm working with: http://imgur.com/a/Vfhjn

    I need to perform an extremely complicated set of functions on a number of ComponentInstances that only correctly work when a piece I'm working with is flat in the X-Y plane. (They are pieces of wood I'm going to cut out.) However, the components have other axes, and in order to perform the operation I have to explode the component and re-group it. I cannot quickly rewrite the process to correctly adapt to different axes. I need to use explode/group as a workaround until I have more time to rewrite everything.

    Problem: I am unable to use the existing functions to correctly explode/group. I need to be able to explode the ComponentInstance, then take all of the resulting entities and put them into a group, which I will then use with the functions I've written and delete the whole thing when I'm done.

    Here's a sample of what happens if I have a single ComponentInstance selected and try to perform the operation in the command line (trimming irrelevant output).

    ci = Sketchup.active_model.selection[0] #<Sketchup::ComponentInstance:0xbc75758> ents = ci.explode g = Sketchup.active_model.entities.add_group(ents) Error: #<ArgumentError: (eval):0:inadd_group': All Entities must have a common parent>`

    However, I can verify that all of the exploded entities do indeed have the correct parent:
    parents = {} ents.each {|ent| p = ent.parent; parents[p] = 0 unless parents.keys.include?(p); parents[p] += 1} puts parents #<Sketchup::Model:0xbca10d8>5711

    That means that of 5711 entities, all of them share a parent, but I can't get it to regroup correctly.

    The problem gets worse if I actually try to do the above within my plugin instead of just the command line: not only can I not group them because they "don't all share a parent", but if I check the parent immediately after exploding, it is not showing that the parent is a Model object; the parent of the exploded entities is the ComponentDefinition!

    So, I'm completely stuck. I'd have to rewrite a significant bit of my code to hack it to work with just open ungrouped faces, and that would completely destroy my future plans at scaling up the capabilities of the code to work with ComponentInstances and more complicated objects. Any suggestions on how I get this particular function to work?

    1 Reply Last reply Reply Quote 0
    • G Offline
      Grays42
      last edited by 24 Aug 2013, 20:05

      Here is what I'm trying to do in the plugin itself:
      Sketchup.active_model.start_operation "Gcode Clones" selection.each do |s| if s.class == Sketchup::ComponentInstance then temp_instance = Sketchup.active_model.entities.add_instance(s.definition,s.transformation) loose_entities = temp_instance.explode parent = loose_entities[0].parent new_group = parent.entities.add_group(loose_entities) @workpiece_groups << new_group @workpieces << Workpiece.new(@environment,new_group) end end Sketchup.active_model.commit_operation

      Workpiece accepts a group and does all of my complicated logic.

      [edit:] Since that formatting is incredibly hard to read, here's pretty formatting of that snippet: http://i.imgur.com/Zuf2dGf.png

      1 Reply Last reply Reply Quote 0
      • D Offline
        driven
        last edited by 24 Aug 2013, 21:55

        not about your plugin… you can use a code block in you posts for better formatting

        Sketchup.active_model.start_operation "Gcode Clones"
        selection.each do |s|
        if s.class == Sketchup;;ComponentInstance then
        temp_instance = Sketchup.active_model.entities.add_instance(s.definition,s.transformation)
        loose_entities = temp_instance.explode
        parent = loose_entities[0].parent
        new_group = parent.entities.add_group(loose_entities)
        @workpiece_groups << new_group
        @workpieces << Workpiece.new(@environment,new_group)
        end
        end
        Sketchup.active_model.commit_operation
        

        john

        learn from the mistakes of others, you may not live long enough to make them all yourself...

        1 Reply Last reply Reply Quote 0
        • C Offline
          Chris Fullmer
          last edited by 24 Aug 2013, 22:15

          Could you upload a component that is giving this error for us to play with?

          When you explode groups/components, sometimes you get a bunch of unexpected things back. So it might require poking around to see what is being returned.

          Lately you've been tan, suspicious for the winter.
          All my Plugins I've written

          1 Reply Last reply Reply Quote 0
          • C Offline
            Chris Fullmer
            last edited by 24 Aug 2013, 22:28

            Quick example, if you explode the "Derrick" component that is used in some of the templates, these are the classes of objects that you get back form him:

            Sketchup::AttributeDictionaries
            Sketchup::AttributeDictionary
            Sketchup::ComponentInstance
            Sketchup::Curve
            Sketchup::Edge
            Sketchup::EdgeUse
            Sketchup::Face
            Sketchup::Loop
            Sketchup::Vertex

            Many of those are not entities that can be added to a group. So try being careful to just add edges, faces, construction geometry, instances, groups, and....anything else?

            Lately you've been tan, suspicious for the winter.
            All my Plugins I've written

            1 Reply Last reply Reply Quote 0
            • G Offline
              Grays42
              last edited by 24 Aug 2013, 22:46

              Agh. Does that mean that in order to re-group the exploded ComponentInstance, I've got to pull construction information from every single bit of geometry and completely re-add them using the .add_face, .add_curve, etc. functions? That's quite a headache--are you sure there's no other way to drop them in?

              The problem occurs on every single ComponentInstance; I can make a component out of two lines, and the same errors occur from the code I posted above.

              I'm currently working on a workaround for now, but it would still be very useful to know how to quickly re-group; currently my workaround consists of exploding the clone and storing all of the exploded entities indefinitely until the logic is complete, then executing a cleanup routine afterward. The only problem with this approach is that I'm holding 50,000+ entities in some variables and calling .erase! on them after the whole thing is done is locking up the client for two minutes while Sketchup processes thousands of .erase! calls.

              1 Reply Last reply Reply Quote 0
              • C Offline
                Chris Fullmer
                last edited by 25 Aug 2013, 01:33

                Hmm, I know its doable. Can you group the entities inside the group first, and then explode the outer group? Does that do what you need?

                Lately you've been tan, suspicious for the winter.
                All my Plugins I've written

                1 Reply Last reply Reply Quote 0
                • TIGT Online
                  TIG Moderator
                  last edited by 25 Aug 2013, 10:58

                  A shorter version could be:
                  a=(Sketchup.active_model.selection[0].explode.find_all{|e|e if e.respond_to?(:bounds)}).uniq
                  Then later you can regroup the array a...
                  Sketchup.active_model.entities.add_group(a)BUT remember that you must have the selection in the active model and the new group in the same entities collect - or else it will splat!
                  Also there is a risk that some of the entities in a might be erased in the meantime - all depending on what you are doing... To protect you for this trip-hazard try something like this:
                  a=a.dup.find_all{|e|e.valid?}
                  before making the new group...

                  TIG

                  1 Reply Last reply Reply Quote 0
                  • G Offline
                    Grays42
                    last edited by 25 Aug 2013, 17:18

                    Thank you both! I'm working on the code more later tonight, I'll try implementing that. It sounds like exactly what I was after.

                    1 Reply Last reply Reply Quote 0
                    • C Offline
                      Chris Fullmer
                      last edited by 25 Aug 2013, 19:50

                      This snippet works for me, and I think its fairly safe? (We'll let one of the other Ruby folk weigh in on that if they feel they need to 😄 ).

                      random_classes = []
                      ents_to_regroup = []
                      
                      a = Sketchup.active_model.selection[0].explode
                      
                      a.each do |e|
                        random_classes << e.class
                      end
                      
                      random_classes.uniq!
                      
                      random_classes.each do |e|
                        single_class_objects = a.grep(e)
                        if single_class_objects[0].respond_to?(;bounds)
                          then ents_to_regroup << single_class_objects
                        end
                      end
                      
                      ents_to_regroup.flatten!
                      Sketchup.active_model.entities.add_group(ents_to_regroup)
                      

                      This will take the selected component and explode it. It then looks at the class of every object that was returned and decides if that class can be added to a group by testing to see if an object from that class responds to the bounds method, (which is in the Drawingelement class and inherited by all valid SU geometry entities). So if an object from the given class does respond to the bounds method, then it is safe to try to add those objects back into a group. If they do not respond to that method, then they get skipped.

                      Hopefully the logic makes sense. That snippet worked fine for me. You do have to have an object selected to test that piece of code.

                      Chris

                      Lately you've been tan, suspicious for the winter.
                      All my Plugins I've written

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

                      Advertisement