• Login
sketchucation logo sketchucation
  • Login
πŸ”Œ Quick Selection | Try Didier Bur's reworked classic extension that supercharges selections in SketchUp Download

Help requested for checking all nested instances

Scheduled Pinned Locked Moved Developers' Forum
11 Posts 2 Posters 1.1k Views 2 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.
  • B Offline
    Bobvandevoort
    last edited by 2 Dec 2014, 09:03

    Hey everybody I need some help with the following because I have a hard time figuring out how to program the following (mainly because I lack experience in programming with Ruby and ofcourse sketchup).

    I need to select all instances in the model and this means top-level components (parents) as well as the deepest nested components, I understood that you can do this with a definition list or something but that was a bit unclear to me.

    Than I need to make an array with all the components that have no nested components. This prevents double checking components and errors while using the intersect function (the solid tools function).

    What I'm trying to make is the following

    @unknownuser said:

    Hi everyone,

    So I haven't been able to find a plugin that checks something crucial in my opinion.
    If you are designing a 3D object with movable parts it can sometimes be very important to check if solids (or components) intersect (or maybe touch). This is especially important if you have a high number of parts or moving parts. An example I can give of this is something I'm working on, it is a puzzle box. A puzzle box is a box that has sliding components on different sides on the box, called sliders. If you move when one these sliders you want to be sure it doesn't get blocked by another part (aka intersecting), because if it's unintentionally blocked than you can't open the box.

    Something that would be even more usefull is if a part(component) could be moved (or rotated)along an axis until some part of it hits another component (this would make checking even easier).

    This can ofcourse be applied to much more cases, mostly mechanisms that need to be check if they having moving parts, a clock, a model engine, etc. To see if the device can actually operate.

    It would be even handier (also has a lot of other applications in building models) if you can move a component along the axes (either positive or negative) until it touches the next piece (component) and have it stop there. This easily shows if it can move along the intended path.
    It should check inner components touching and not just the surrounding (encompassing) parent component boxes.

    So what's on my to do list:

    1. Making the intersection test work for nested components.
      (add functionability to disable and enable a popup screen if an intersection is found and possible zoom in on it)
    2. Make a function (def) that add's a new scene.
    3. Make a function that can calculate the distance from a component(face) to the closest next component(face) in a certain direction (x,y,z axis and reverse directions). (I was thinking about a raytest, using a grid of lines based on my mininum feature size to do this per face of the component that is on the right side for the direction)
    4. Use this function to move the the component and everything included in the selection this much distance and that do another intersection test and give a warning if an intersection is found.
    5. If this all works combine it with the a moving animation plugin (maybe this one http://sketchucation.com/forums/viewtopic.php?t=17459 or another one that has the code visible so I can see what the def's are called)
    6. Make sure that this works all together (will only work for components though) add a small interface with options and buttons. 6 buttons for moving till hit, X_axis, -X_axis, Y_axis, etc. Will probably add a checkbox for no warning pop-ups (if it's not too hard) maybe a checkbox to just move and not creating a new scene with the saved position. Maybe adding a button just to check for intersection.
    7. Extra stuff that might happen in some real far feature automatic moving on click through check for possible paths and not going back where it came from, automatic animation export, adding group functionability and maybe more
    1 Reply Last reply Reply Quote 0
    • S Offline
      sdmitch
      last edited by 2 Dec 2014, 19:27

      Model definitions list with groups and images removed

      mod = Sketchup.active_model
      cds = mod.definitions.reject{|cd|cd.group?||cd.image?}
      
      

      Select all component instances

      cds.each{|cd| cd.instances.each{|ci|sel.add ci}}
      

      Array with all the components that have no nested components.

      noembed=[];
      cds.each{|cd|
       if cd.instances[0]
        embed=cd.entities.grep(Sketchup;;ComponentInstance)
        noembed << cd unless embed[0]
       end
      }
      
      

      Nothing is worthless, it can always be used as a bad example.

      http://sdmitch.blogspot.com/

      1 Reply Last reply Reply Quote 0
      • B Offline
        Bobvandevoort
        last edited by 3 Dec 2014, 12:02

        @sdmitch said:

        Model definitions list with groups and images removed

        mod = Sketchup.active_model
        > cds = mod.definitions.reject{|cd|cd.group?||cd.image?}
        > 
        

        Select all component instances

        cds.each{|cd| cd.instances.each{|ci|sel.add ci}}
        

        Array with all the components that have no nested components.

        noembed=[];
        > cds.each{|cd|
        >  if cd.instances[0]
        >   embed=cd.entities.grep(Sketchup;;ComponentInstance)
        >   noembed << cd unless embed[0]
        >  end
        > }
        > 
        

        Hey man Thank you very much πŸ˜„

        However I have 2 questions, the sel.add in the 2nd code block seems to be wrong or refer to something else, can somebody check that please?

        Also what does the << operator do in this case?

        1 Reply Last reply Reply Quote 0
        • S Offline
          sdmitch
          last edited by 3 Dec 2014, 14:01

          @bobvandevoort said:

          @sdmitch said:

          Model definitions list with groups and images removed

          mod = Sketchup.active_model
          > > cds = mod.definitions.reject{|cd|cd.group?||cd.image?}
          > > 
          

          Select all component instances

          sel = mod.selection
          > > cds.each{|cd| cd.instances.each{|ci|sel.add ci}}
          

          Array with all the components that have no nested components.

          noembed=[];
          > > cds.each{|cd|
          > >  if cd.instances[0]
          > >   embed=cd.entities.grep(Sketchup;;ComponentInstance)
          > >   noembed << cd unless embed[0]
          > >  end
          > > }
          > > 
          

          Hey man Thank you very much πŸ˜„

          However I have 2 questions, the sel.add in the 2nd code block seems to be wrong or refer to something else, can somebody check that please?

          Also what does the << operator do in this case?

          Sorry. I forgot to define sel, sel = mod.selection.

          Nothing is worthless, it can always be used as a bad example.

          http://sdmitch.blogspot.com/

          1 Reply Last reply Reply Quote 0
          • B Offline
            Bobvandevoort
            last edited by 4 Dec 2014, 13:03

            Ok yeah already thought it was something like that πŸ˜„

            anyway this is really helpful but for some reason when I do the following I get the wrong transformations

            noembed=[];
            cds.each{|cd|
             if cd.instances[0]
              embed=cd.entities.grep(Sketchup;;ComponentInstance)
              noembed << cd.instances unless embed[0]  #### storing the instances as I need those
             end
            }
            
            noembed.flatten! # making the array workable
            
            1 Reply Last reply Reply Quote 0
            • S Offline
              sdmitch
              last edited by 4 Dec 2014, 14:52

              @bobvandevoort said:

              Ok yeah already thought it was something like that πŸ˜„

              anyway this is really helpful but for some reason when I do the following I get the wrong transformations

              noembed=[];
              > cds.each{|cd|
              >  if cd.instances[0]
              >   embed=cd.entities.grep(Sketchup;;ComponentInstance)
              >   noembed << cd.instances unless embed[0]  #### storing the instances as I need those
              >  end
              > }
              > 
              > noembed.flatten! # making the array workable
              

              Please define "wrong".

              noembed will contain component instances that do not contain other component instances even though they are embedded themselves. In that case you might want the transformation of the parent as well.

              If you only want the top level components instances without embedded instances then

              noembed.flatten! # making the array workable
              noembed.each{|ci|
               next unless ci.parent==mod
               puts ci.definition.name,ci.transformation.to_a;
               sel.add ci
              }
              

              Nothing is worthless, it can always be used as a bad example.

              http://sdmitch.blogspot.com/

              1 Reply Last reply Reply Quote 0
              • B Offline
                Bobvandevoort
                last edited by 4 Dec 2014, 15:28

                Ahhhh
                of course that's what I forgot about.

                I want the components to have their original position in the skecthup model, so that means they probably need to be transformed by their own and all their parents transformations.

                1 Reply Last reply Reply Quote 0
                • B Offline
                  Bobvandevoort
                  last edited by 5 Dec 2014, 13:17

                  Would this work to get an array with all components of the level (aka no other nested components) that are in the same position as in the model?

                  		noembed=[];
                  		cds.each{|cd|
                  			if cd.instances[0]
                  				embed=cd.entities.grep(Sketchup;;ComponentInstance)
                  				trans_matrix=[]
                  				if not embed[0]
                  					cd.instances.each{|ci|
                  						next unless ci.parent==mod
                  						trans_matrix << ci.transformation;
                  					}
                  					trans_matrix.each{|tr| 
                  					cd.instances.transform! tr}
                  					noembed << cd.instances
                  				end				#### does this give the right transformation
                  			end
                  			}
                  
                  1 Reply Last reply Reply Quote 0
                  • S Offline
                    sdmitch
                    last edited by 5 Dec 2014, 14:20

                    @bobvandevoort said:

                    Would this work to get an array with all components of the level (aka no other nested components) that are in the same position as in the model?

                    		noembed=[];
                    > 		cds.each{|cd|
                    > 			if cd.instances[0]
                    > 				embed=cd.entities.grep(Sketchup;;ComponentInstance)
                    > 				trans_matrix=[]
                    > 				if not embed[0]
                    > 					cd.instances.each{|ci|
                    > 						next unless ci.parent==mod
                    > 						trans_matrix << ci.transformation;
                    > 					}
                    > 					trans_matrix.each{|tr| 
                    > 					cd.instances.transform! tr}
                    > 					noembed << cd.instances
                    > 				end				#### does this give the right transformation
                    > 			end
                    > 			}
                    

                    I think it would have to be

                    trans_matrix.each_with_index{|tr,i|
                     cd.instances[i].transform! tr}
                    

                    but that doesn't make much sense as that would only "double" the instances transformation and not all instance transformation might have been saved.

                    Maybe

                    cd.instances.each{|ci|
                     next unless ci.parent==mod
                     trans_matrix << ci.transformation
                     noembed << ci
                    }
                    

                    is what you were thinking?

                    Nothing is worthless, it can always be used as a bad example.

                    http://sdmitch.blogspot.com/

                    1 Reply Last reply Reply Quote 0
                    • B Offline
                      Bobvandevoort
                      last edited by 5 Dec 2014, 20:15

                      Ah I'll try to be a bit more specific.

                      Let's say I have a model with 3 components, comp1, comp2 and comp3.

                      comp1 has comp2 inside and comp3 is inside of comp2.
                      This then means (if I am correct) that comp1 has a transformation, called trans1, comp2 has one called trans2 and comp3 has one called trans3.
                      If I take comp3 and place it in the model with its own transformation, trans3, it will not be places at its original position in the model. To achieve that it needs to have its transformation multiplied by trans2 and trans1.

                      So now I want to create a matrix "noembed" that only has components that have no other components nested inside them (like comp3 here). However these components should still retain there original location/position in the model meaning their own transformation should be multiplied by all their parent's transformations.

                      In which case this code seem to do the trick

                      cd.instances.each{|ci|
                       next unless ci.parent==mod
                       trans_matrix << ci.transformation
                       noembed << ci
                      }
                      
                      1 Reply Last reply Reply Quote 0
                      • S Offline
                        sdmitch
                        last edited by 6 Dec 2014, 03:58

                        @bobvandevoort said:

                        Ah I'll try to be a bit more specific.

                        Let's say I have a model with 3 components, comp1, comp2 and comp3.

                        comp1 has comp2 inside and comp3 is inside of comp2.
                        This then means (if I am correct) that comp1 has a transformation, called trans1, comp2 has one called trans2 and comp3 has one called trans3.
                        If I take comp3 and place it in the model with its own transformation, trans3, it will not be places at its original position in the model. To achieve that it needs to have its transformation multiplied by trans2 and trans1.

                        So now I want to create a matrix "noembed" that only has components that have no other components nested inside them (like comp3 here). However these components should still retain there original location/position in the model meaning their own transformation should be multiplied by all their parent's transformations.

                        In which case this code seem to do the trick

                        cd.instances.each{|ci|
                        >  next unless ci.parent==mod
                        >  trans_matrix << ci.transformation
                        >  noembed << ci
                        > }
                        

                        You are correct that the transformation of comp3 not embedded will be the product of its' and the components instances transformations above it. The code above only would only save comp3's transformtion if it is at the model level.

                        It would be great if you could start at the instance and work up to the top but .parent returns a component definition which doesn't have a transformation associated with it. So you have to start at the top and drill down.

                        This code does that for two levels. Adds a comp3 at model level and erases the instance that it replaces.

                        mod = Sketchup.active_model
                        ent = mod.active_entities
                        sel = mod.selection
                        rmv = []
                        ci0 = ent.grep(Sketchup;;ComponentInstance);#parent is mod
                        ci0.each{|c0|
                         next if c0.definition.name=="comp3"
                         tr0 = c0.transformation
                         ci1 = c0.definition.entities.grep(Sketchup;;ComponentInstance);#parent is definition
                         ci1.each{|c1|
                          tr1 = c1.transformation
                          if c1.definition.name=="comp3"
                           tr = tr0*tr1
                           ent.add_instance(c1.definition,tr)
                           rmv << c1; break
                          else
                           ci2 = c1.definition.entities.grep(Sketchup;;ComponentInstance);#parent is definition
                           ci2.each{|c2|
                            tr2 =c2.transformation
                            if c2.definition.name=="comp3"
                             tr = tr0*tr1*tr2
                             ent.add_instance(c2.definition,tr)
                             rmv << c2; break
                            end
                           }
                          end
                         }
                        }
                        rmv.each{|ci| ci.erase! if ci.valid?}
                        
                        
                        

                        Nothing is worthless, it can always be used as a bad example.

                        http://sdmitch.blogspot.com/

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

                        Advertisement