SketchUcation Premium Membership

 

 

Volume of Multiple Groups

Volume of Multiple Groups

Postby Enzay » Tue Feb 28, 2012 5:20 am

Hi all,

Didn't find a plugin for my needs so I figured I'd try and make my own. We can get the volume of a solid group/component quite easily but it doesn't show us the volume of multiple groups when they're selected together. I tried making a pluggin but I'm not sure how to get all the selected groups. Maybe you guys can help me out?

Essentially I would like to select multiple groups/components and get the total volume.

The script is looking like this:
require 'sketchup.rb'

module KN_Volc

def KN_Volc.main
model = Sketchup.active_model
model.start_operation "VolumeCalcr"
sel = model.selection
ents = model.active_entities
voltot=0

sel.each do |e|
if e.is_a? Sketchup::Group
volumeinst = ent.volume
voltot = voltot + volumeinst
end
end
UI.messagebox"checkpoint"

Sketchup::set_status_text voltot
UI.messagebox " #{voltot} Total Volume "


model.commit_operation

end

end

plug_menu=UI.menu("Plugins")
plug_menu.add_item("Volume Calcr") { KN_Volc.main }


Thanks for your help,

Enzay.
Enzay
 
Posts: 7
Joined: Wed Jan 26, 2011 6:30 pm
Name: AuYaXuan

Re: Volume of Multiple Groups

Postby Dan Rathbun » Tue Feb 28, 2012 7:20 am

But it really should look like this...

Revised. Fixed output conversion for all units.

Code: Select all
require 'sketchup.rb'

module AuYaXuan; end

module AuYaXuan::MultiVolume

  #{# CONSTANTS
  #
    VERSION = '1.0.1'  # 2012-02-29
    TOPMENU = 'Plugins'
    SUBMENU = '' # This can point to a submenu object
                 # created by another script.
  #
  #}#
 
  #{# MODULE VARIABLES
  #
    @@topmenu = UI.menu(TOPMENU) unless defined?(@@topmenu)
   
    unless defined?(@@submenu)
      if SUBMENU.empty?
        @@submenu = @@topmenu
      elsif SUBMENU.is_a?(Sketchup::Menu)
        @@submenu = SUBMENU
      elsif SUBMENU.is_a?(String)
        @@submenu = @@topmenu.add_submenu(SUBMENU)
      end
    end
   
    @@subtot = 0 unless defined?(@@subtot)
  #
  #}#
 
  #{# PROXY CLASS
  #
  class << self
 
    private
   
    #{ find( array_of_entities )
    #
    #  Returns an array of only Groups and,
    #  Component Instances; or nil if none found.
    #
    def find(aoe)
      found = aoe.find_all do |e|
        e.is_a?(Sketchup::Group) ||
        e.is_a?(Sketchup::ComponentInstance)
      end
      return found
    end #}

    #{ iter( group_item_array )
    #
    #  Recursive method that drills down into
    #  nested Groups and Component Instances,
    #  finding their manifold volumes.
    #
    def iter(items)
      items.each do |e|
        if e.manifold?
          sum(e.volume)
        else
          if e.is_a?(Sketchup::Group)
            itp = find(e.entities)
            iter(itp) if itp
          elsif e.is_a?(Sketchup::ComponentInstance)
            itp = find(e.definition.entities)
            iter(itp) if itp
          end
        end
      end
    end #}

    #{ sum( number_to_add )
    #
    def sum(arg)
      (@@subtot = @@subtot + arg) if arg.is_a?(Numeric)
    end #}
   
    public

    #{ main()
    #
    #
    def main()
      @@subtot = 0
      mdl = Sketchup.active_model
      # get itp (items to process)
      itp = find(mdl.selection.to_a)
      if itp # nil test
        iter(itp)
        units = mdl.options['UnitsOptions']
        ui = units['LengthUnit']
        if ui>0 # unit index
          convert = ['to_inch','to_feet','to_mm','to_cm','to_m'][ui]
          @@subtot = eval( "@@subtot.#{convert}.#{convert}" )
        end
        #Sketchup::set_status_text @@subtot
        msg = " Total Volume: #{Sketchup.format_length(@@subtot)} (cubic)"
        puts(msg) unless $VERBOSE.nil?
        UI.messagebox("\n\n"<<msg+"      ",MB_MULTILINE,'  MultiVolume')
        #UI.messagebox(msg+"      ")
      else
        UI.messagebox("No Groups or Components in selection!      ")
        return nil
      end
    end #}
 
  end # PROXY CLASS
  #
  #}#

  #{# RUN ONCE
  #
  unless file_loaded?( File.basename(__FILE__) )
    #
    @@submenu.add_item("Volume Calcr") {
      if Sketchup.active_model.selection.empty?
        UI.messagebox("Selection is empty!      ")
      else
        main()
      end
    }
    #
    file_loaded( File.basename(__FILE__) )
    #
  end
  #
  #}#

end # module AuYaXuan::MultiVolume

Last edited by Dan Rathbun on Wed Feb 29, 2012 3:50 pm, edited 2 times in total.
User avatar
Dan Rathbun
Top SketchUcator
 
Posts: 4069
Joined: Tue Oct 06, 2009 3:06 am
Location: Florida, USA
Name: Dan Rathbun
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: education
Level of SketchUp: Advanced

Re: Volume of Multiple Groups

Postby Dan Rathbun » Tue Feb 28, 2012 7:22 am

It works fine when model units are set to decimal inches.

I get crazy results when model units are decimal feet.
User avatar
Dan Rathbun
Top SketchUcator
 
Posts: 4069
Joined: Tue Oct 06, 2009 3:06 am
Location: Florida, USA
Name: Dan Rathbun
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: education
Level of SketchUp: Advanced

Re: Volume of Multiple Groups

Postby Dan Rathbun » Tue Feb 28, 2012 9:29 am


There was an old plugin by TIG,
that really was not very big...
the volumes it gave us,
did temporarily save us,
'til boolean groups also did.


Volume Calculator v2.1
User avatar
Dan Rathbun
Top SketchUcator
 
Posts: 4069
Joined: Tue Oct 06, 2009 3:06 am
Location: Florida, USA
Name: Dan Rathbun
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: education
Level of SketchUp: Advanced

Re: Volume of Multiple Groups

Postby Enzay » Wed Feb 29, 2012 6:54 am

Hi Dan,

Thanks foremost for such a great code and your use of comments; they're really useful for my learning.

I saw TIG volume calc but it didn't give me a total volume of multiple groups and added geometry to the model I didn't want. The purpose of this script is to help me get a quantity take off. I use to use SketchUp pro at work with CSV export but I don't have access to that anymore.

I also found that the units worked for inches but screwed up with SI units, which I'm using.

It seems that this part of code is what sums all the volumes from each group. Where does the "arg" come from? Is that a just a variable that's an array of groups?
Code: Select all
  def sum(arg)
      (@@subtot = @@subtot + arg) if arg.is_a?(Numeric)
    end #}


It seems that somewhere it would be useful to call the current units being used and set those to the volumes of the groups?
Enzay
 
Posts: 7
Joined: Wed Jan 26, 2011 6:30 pm
Name: AuYaXuan

Re: Volume of Multiple Groups

Postby TIG » Wed Feb 29, 2012 11:15 am

This one-liner
Code: Select all
v=0;Sketchup.active_model.selection.each{|e|v=v+e.volume if e.respond_to?(:volume)and e.volume>0};v
Copy/pasted into the Ruby Console + <enter> returns the volume of selected 'solid' objects in cu" [non-solid groups etc are ignored as their volume == -1].
You then need a converter to use other units...
So instead of the closing ;v use a conversion factor...
For cu'...
;v*0.000578703703703704
For cu.m...
;v*0.000016387064
etc...
It's easily incorporated into a method/class/module code-set, with a menu or toolbar etc as needed...
TIG
User avatar
TIG
Global Moderator
 
Posts: 13955
Joined: Mon Nov 12, 2007 7:24 pm
Location: Northumbria UK
Name: TIG
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: architecture
Level of SketchUp: Advanced

Re: Volume of Multiple Groups

Postby Dan Rathbun » Wed Feb 29, 2012 3:14 pm

However, TIG.. your cute one-liner, ignores groups that are not manifold, but DO contain nested manifold solids ?

2nd.. He clearly asked for a Plugin, not a one-liner-copy-and-paste-into-console-command ...
User avatar
Dan Rathbun
Top SketchUcator
 
Posts: 4069
Joined: Tue Oct 06, 2009 3:06 am
Location: Florida, USA
Name: Dan Rathbun
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: education
Level of SketchUp: Advanced

Re: Volume of Multiple Groups

Postby Dan Rathbun » Wed Feb 29, 2012 3:42 pm

Enzay wrote:Where does the "arg" come from? Is that a just a variable that's an array of groups?

That sum() is a private method, so it can only be called from inside the module.
It's called by the other methods, and they supply the arg.
See the iter() method, line 4, where it calls sum(e.volume)

Enzay wrote:It seems that somewhere it would be useful to call the current units being used and set those to the volumes of the groups?

Yup...

.. replace the line "#Sketchup::set_status_text @@subtot"

.. with:
units = mdl.options['UnitsOptions']
ui = units['LengthUnit']
if ui>0
convert = ['to_inch','to_feet','to_mm','to_cm','to_m'][ui]
@@subtot = eval( "@@subtot.#{convert}.#{convert}" )
end


nevermind I'll update the example...
User avatar
Dan Rathbun
Top SketchUcator
 
Posts: 4069
Joined: Tue Oct 06, 2009 3:06 am
Location: Florida, USA
Name: Dan Rathbun
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: education
Level of SketchUp: Advanced

Re: Volume of Multiple Groups

Postby TIG » Wed Feb 29, 2012 5:27 pm

Dan
I realize that he did ask for a 'plugin'; however, my 'one-liner' contains all of the basic elements he needs to make it himself. Your example of finding the units can of course be used to apply a conversion factor to the cu" volume - it might also be sensible to use sprintf to keep the d.p's in line if say it's to be 'outputted', rather that used in some later method as a float...
It does ignore non-manifold objects, and whilst a group or definition might contain one or more manifold solids that is not processed; and I don't think that is really what was asked for either ?
To burrow down into a group's entities, gets any nested groups/instances, see if they are manifold, get their volumes and apply any scaling transformations needed... is much more complex that the original question...
If he wants to find the volume of somethings inside a group he can always edit the group, select them and thereby get their volumes separately...
TIG
User avatar
TIG
Global Moderator
 
Posts: 13955
Joined: Mon Nov 12, 2007 7:24 pm
Location: Northumbria UK
Name: TIG
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: architecture
Level of SketchUp: Advanced

Re: Volume of Multiple Groups

Postby Dan Rathbun » Wed Feb 29, 2012 7:16 pm

TIG wrote:To burrow down into a group's entities, gets any nested groups/instances, see if they are manifold, get their volumes and apply any scaling transformations needed... is much more complex that the original question...

The volume() method appears to take any scaling into account.

So what do we do ? Ignore and throw out his example ? Should I erase the cleaned up working plugin example I posted above ?? (Did you even try it?)

Do we yank ourselves over to the TIG way of doing this ??

TIG wrote:If he wants to find the volume of somethings inside a group he can always edit the group, select them and thereby get their volumes separately...


Oh OK... sorry folks! TIG says ya'll have to do things the hard, slow way. :P

And.. don't need to use sprintf for now, as there's only 1 total volume value returned. (Maybe later if he writes a report generating method.)
User avatar
Dan Rathbun
Top SketchUcator
 
Posts: 4069
Joined: Tue Oct 06, 2009 3:06 am
Location: Florida, USA
Name: Dan Rathbun
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: education
Level of SketchUp: Advanced

Re: Volume of Multiple Groups

Postby Enzay » Wed Feb 29, 2012 7:31 pm

I see now how the inter gives the volume of the entity to the sum method which adds it to the total amount.

I suppose TIG's one-liner is adapt for someone familiar with quickly coding into the ruby console to get a result. I am, not so advanced and prefer to see a ruby script so that I can understand what is happening. Not to say that I specifically requested a ruby, but It does help significantly that the script recognizes nested groups which, as rubys are prone to do, saves time and effort.

I appreciate both your input to helping solve my problems. Thank you very much.
Enzay
 
Posts: 7
Joined: Wed Jan 26, 2011 6:30 pm
Name: AuYaXuan

Re: Volume of Multiple Groups

Postby TIG » Wed Feb 29, 2012 10:06 pm

I think the object.volume method does return the 'scaled-volume' of the object... but does it take into account the scaling of that volume's container[s] ?
I suspect not...

If you are happy with an #all bells and whistles# volumes getter, by delving into nested objects and getting all the right results, that's fine by me - my quick one-liner was simply to show how to get basic volumes without too much angst. It's no different to typing code into a 'method' in a script file - the script's carriage-returns are just shown as ';' instead...
TIG
User avatar
TIG
Global Moderator
 
Posts: 13955
Joined: Mon Nov 12, 2007 7:24 pm
Location: Northumbria UK
Name: TIG
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: architecture
Level of SketchUp: Advanced

SketchUcation One-Liner Adverts

by Ad Machine » 5 minutes ago

Are you a Premium Member? Get your freebies here. Are you not a Premium Member yet? Upgrade your account to grab these freebies instantly.

Ad Machine
Robot
 
Posts: 2012


Return to Developers' Forum

Who is online

Users browsing this forum: No registered users and 5 guests