sketchucation logo sketchucation
    • Login
    Oops, your profile's looking a bit empty! To help us tailor your experience, please fill in key details like your SketchUp version, skill level, operating system, and more. Update and save your info on your profile page today!
    ⚠️ Important | Libfredo 15.6b introduces important bugfixes for Fredo's Extensions Update

    [Code] Grepping entities

    Scheduled Pinned Locked Moved Developers' Forum
    19 Posts 6 Posters 2.6k Views 6 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.
    • Dan RathbunD Offline
      Dan Rathbun
      last edited by

      @thomthom said:

      @tig said:

      It would need to be something like:
      fs=Sketchup.active_model.entities.grep(Sketchup::Face).select{|f|f.material}
      to get an array of all faces that have a material assigned to them etc.

      But then you do a double iteration. I'd think it's be best to do this as:

      fs=Sketchup.active_model.entities.select{|f|f.is_a?(Sketchup::Face) && f.material}

      That's just one iteration.

      How about this ?

      fs=Sketchup.active_model.entities.grep(Sketchup::Face){|f| f.material ? f : nil }.compact

      compact removes the nil elements afterward.

      I'm not here much anymore.

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

        Again - a second iteration. Of the result, but none the less - an extra iteration.

        What's interesting here is what the performance is.

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

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

          I've looked st a couple of methods in Vertex Tools - where I refactored them to use grep in combo with hashes and I'm getting huge improvements! 😄

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

          1 Reply Last reply Reply Quote 0
          • dkendigD Offline
            dkendig
            last edited by

            Glad I got frustrated on Wednesday and started throwing stuff at the wall to see what stuck! Nice benchmarks Thomthom, hope my find can help some folks out!

            Devin Kendig
            Developer

            1 Reply Last reply Reply Quote 0
            • dkendigD Offline
              dkendig
              last edited by

              Dan, did you try benchmarking your pattern? It might not have much of a performance hit if you have the extra filtering criteria in the grep block:

              @unknownuser said:

              Don’t forget the extra processing — a map operation — comes “free” if you provide grep with a block

              Link Preview Image
              Enumerating Enumerable: Enumerable#grep : Global Nerdy

              Once again, it’s Enumerating Enumerable time! This is the latest in my series of articles where I set out to make better documentation for Ruby’s Enumerable module than Ruby-Doc.org’s. In this installment, I cover the grep method. In case you missed any of the previous articles, they’re listed and linked below: all? any? collect / […]

              favicon

              Global Nerdy (www.globalnerdy.com)

              Devin Kendig
              Developer

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

                @dkendig said:

                Dan, did you try benchmarking your pattern?

                No, but it can be added to TT's code above if your interested. (As TT said compact() needs to re-iterate the array to remove the nil elements. I tried using next but the block still returns a nil.)

                And BTW.. I checked the C source for compact() which uses dup() to create a new array, and then calls compact!(), ie %(#008080)[rb_compact_bang()] on the C-side, so to save time, this pattern might as well use the "bang" edition of the method, and save the time to create a new array.

                I'm deep into a Javascript mod for the forums, presently, and not doing much in Ruby.

                I'm not here much anymore.

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

                  Can you post your result data as well?

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

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

                    And what was the comparison code?

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

                    1 Reply Last reply Reply Quote 0
                    • dkendigD Offline
                      dkendig
                      last edited by

                      drawing_ele_test time: 0.00999999046325684, resulted in 1103 elements found
                      types_test time: 0.00999999046325684, resulted in 1103 elements found
                      magic_test time: 0.0420000553131104, resulted in 1103 elements found
                      loop_test time: 0.0190000534057617, resulted in 1103 elements found

                      that's my results from the huge one-liner that I copy and pasted for a scene with 13108 total entities. 10,000 edges, 1,000 component instances, 1,000 groups, 1,000 faces. The goal was to find anything that could have a material applied to it, so I wanted to filter out edges.

                      So actually it appears my test was flawed. I'm adding entities to a hash, and looping through the desired types in the "types_test" results. In the "drawing_ele_test" I am just doing a comparison to see if the type matches one of the types I am looking for. They both end up taking the same exact amount of time, so there's probably a cleaner way to write this, but under the hood both of those tests are essentially doing the same thing.

                      Devin Kendig
                      Developer

                      1 Reply Last reply Reply Quote 0
                      • dkendigD Offline
                        dkendig
                        last edited by

                        Just ran a benchmark in a scene with 10,000 edges, one component instance, one face, and one group. It appears that grepping specific classes you are interested in, is faster than doing a more general grep and then comparing within the block.

                        sample code soon to follow

                        Devin Kendig
                        Developer

                        1 Reply Last reply Reply Quote 0
                        • dkendigD Offline
                          dkendig
                          last edited by

                          actually, here's the benchmark code I ran

                          
                          class Magic;def initialize(&block)
                          	@block=block;end
                          	def ===(other)
                          		@block.call(other)
                          	end
                          end
                          
                          def GetVrayImportantArrayFromGrepDrawingelement(entities)
                          	return entities.grep(Sketchup;;Drawingelement){|ent| false == (ent.class == Sketchup;;Edge) ? ent ; nil}.compact
                          end
                          
                          def GetVrayImportantArrayOfTypesFromGrep(entities,typeHash)
                          	for curType in typeHash.keys()
                          		typeHash[curType] = entities.grep(curType )
                          	end
                          end
                          
                          def GetVrayImportantArrayFromGrepMagic(entities)
                          	return entities.grep(Magic.new {|ent| ent if(ent.class == Sketchup;;ComponentInstance or ent.class == Sketchup;;Group or ent.class == Sketchup;;Face)})
                          end
                          
                          def GetVrayImportantArrayFromLoop(entities)
                          	vrayImportant = Array.new()
                          	for ent in entities.to_a
                          		if ent.class == Sketchup;;Face or ent.class == Sketchup;;ComponentInstance or ent.class == Sketchup;;Group
                          			vrayImportant.push(ent)
                          		end
                          	end
                          	return vrayImportant
                          end
                          
                          def RunBenchmarkOnEntities(entities)
                          	testHash = Hash.new()
                          	testHash[Sketchup;;Face] = []
                          	testHash[Sketchup;;ComponentInstance] = []
                          	testHash[Sketchup;;Group] = []
                          	
                          	grep_drawing_ele_result = grep_magic_result = compare_loop_result = nil
                          	
                          	grep_drawing_ele_start_time = Time.now.to_f
                          	grep_drawing_ele_result = GetVrayImportantArrayFromGrepDrawingelement(entities)
                          	grep_drawing_ele_end_time = Time.now.to_f
                          	
                          	grep_types_start_time = Time.now.to_f
                          	grep_types_result = GetVrayImportantArrayOfTypesFromGrep(entities,testHash)
                          	grep_types_end_time = Time.now.to_f
                          	
                          	grep_magic_start_time = Time.now.to_f
                          	grep_magic_result = GetVrayImportantArrayFromGrepMagic(entities)
                          	grep_magic_end_time = Time.now.to_f 
                          	
                          	compare_loop_start_time = Time.now.to_f
                          	compare_loop_result = GetVrayImportantArrayFromLoop(entities)
                          	compare_loop_end_time = Time.now.to_f
                          	
                          	puts "drawing_ele_test time; #{grep_drawing_ele_end_time - grep_drawing_ele_start_time}, resulted in #{grep_drawing_ele_result.size} elements found"
                          	
                          	puts "types_test time; #{grep_types_end_time - grep_types_start_time}, resulted in #{testHash.values.flatten.size} elements found"
                          	
                          	puts "magic_test time; #{grep_magic_end_time - grep_magic_start_time}, resulted in #{compare_loop_result.size} elements found"
                          	
                          	puts "loop_test time; #{compare_loop_end_time - compare_loop_start_time}, resulted in #{compare_loop_result.size} elements found"
                          	
                          	return nil
                          end
                          
                          RunBenchmarkOnEntities(Sketchup.active_model.entities)
                          

                          Devin Kendig
                          Developer

                          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