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

    [code] Calculate volume on manifold surface without grouping

    Scheduled Pinned Locked Moved Developers' Forum
    1 Posts 1 Posters 2.2k Views 1 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

      The question has been often raised on how to get the volume of manifold surface without temporarily grouping and then exploding it.

      With the release of SU2017 things got more difficult because the old references before the group and explode are no longer valid. (This happens because of persistant_id implementations in the SketchUp Core.)


      @TIG pointed me toward an old thread on SketchUcation (hiding in the "Plugins" forum) in which …
      @AdamB proposed a totally mathematical solution, without a temporary group.

      Following is my rendition of AdamB's "no temporary group" solution.

      Mine does not modify API class Geom::Point3d, but converts to an Array which already has a #dot method.

      Mine also uses #grep which is very fast when comparing class identity, ... instead of calling #is_a? on each and every object in the geometry collection on the Ruby-side, during each iteration.

      
      # calculate_volume(geometry)
      # Calculate volume on a set of faces without a temporary group.
      #
      # Based on an old SCF topic thread post by AdamB;
      # http://sketchucation.com/forums/viewtopic.php?p=14598#p14598
      #
      # @param geometry [Array<Drawingelement>] Array of collected geometry references.
      # @return [Float] the computed volume if successful, 0.0 if not.
      def calculate_volume(geometry)
        geometry.grep(Sketchup;;Face).map {|f|
          (2 * f.area * (f.vertices[0].position.to_a.dot(f.normal))) / 6      
        }.reduce(;+)
      rescue => e
        puts e.inspect
        return 0.0
      end
      
      

      If you are still using Ruby 1.8, you'll need to replace .reduce(:+) with .inject {|sum,n| sum+n } in the code above, like so ...

      
      # calculate_volume(geometry)
      # Calculate volume on a set of faces without a temporary group.
      #
      # Based on an old SCF topic thread post by AdamB;
      # http://sketchucation.com/forums/viewtopic.php?p=14598#p14598
      #
      # @param geometry [Array<Drawingelement>] Array of collected geometry references.
      # @return [Float] the computed volume if successful, 0.0 if not.
      def calculate_volume(geometry)
        geometry.grep(Sketchup;;Face).map {|f|
          (2 * f.area * (f.vertices[0].position.to_a.dot(f.normal))) / 6      
        }.inject {|sum,n| sum+n }
      rescue => e
        puts e.inspect
        return 0.0
      end
      
      

      Bonus method for a volume display string in model units:
      See: [code] format volume in model units

      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