Displaying the volume of an object instantaneously during scaling

You are welcome!


This version might be a little more “spectacular”… and can handle more solids at once.
Now there will be a “normal” menu under Extensions to toggle on-off the instant volumes: “Show Instant volumes” (When it is on there will be a checkmark.)

You need to put text label “vol” or “Vol” at the root of the model pointing to the solid(s) in question. There will be a warning if there are no such… These labels will show the volumes dynamically when you start to Show Instant volumes and e.g. scaling.

After 5 minutes there will be a warning (only once) to not forget to switch off…(otherwise it takes up resources constantly, not much but still…)
But will not switch off itself, unless you deleted the label(s) or the solid(s) which was taken into consideration when you activated.

If you switch off, the labels will remain to show the last volumes. So if you want to activate again you need to rename these labels to “Vol” again…

Dezmo_InstantVolumeB

.
.

Click here to see the code (B): No warranties! Use it at your own risk!

No warranties! Use it at your own risk!

Copy-paste the code below to Ruby Console and hit Return (Enter).

module Dezmo
module InstantVolumesB
  @@loaded = false unless defined?(@@loaded)
  @@runing = false unless defined?(@@runing)
  extend self
    
  def update_volume( texts )
    return if @@runing
    @@runing = true
    @note_timer = UI.start_timer(0.3, true){
      count = 0
      to_delete = []
      texts.each{|text, path|
        if path.last.valid? && text.valid?
          vol = calculate_volume( path )
          text.set_text( Sketchup.format_volume( vol ) )
          count += 1
        else
          to_delete<<text
        end
      }
      Sketchup.active_model.active_view.invalidate
      to_delete.each{ |k| texts.delete(k) }
      puts "Error finding label or solid!" if count == 0
      stop() if texts.empty?
    }
  end
  
  def stop()
    UI.stop_timer(@note_timer) if @note_timer
    @@runing = false
    puts "InstantVolumes stopped"
  end
  
  def start_stop()
    return stop() if @@runing
    texts = valid_labels()
    if texts.empty?
      UI.messagebox('Please label solids with "Vol" at root of the model.', MB_OK)
    else
      puts "InstantVolumes started"
      update_volume( texts )
      # Warning if run for 5 minutes:
      UI.start_timer(300, false){
        if @@runing
          UI.messagebox(
            'Please dont forget to turn off Showing Instant volumes.', 
            MB_OK
          )
        end
      }
    end
  end

  def instance?(e)
    e.is_a?(Sketchup::Group) || e.is_a?(Sketchup::ComponentInstance)
  end
  
  def valid_labels()
    texts = {}
    Sketchup.active_model.entities.select{|ent| 
      ent.is_a?( Sketchup::Text ) &&
      (ent.text == "Vol" || ent.text == "vol") &&
      ent.attached_to &&
      (ent.attached_to[0].to_a[-2].is_a?(Sketchup::Group) ||
       ent.attached_to[0].to_a[-2].is_a?(Sketchup::ComponentInstance) ) &&
      ent.attached_to[0].to_a[-2].manifold?
    }.each{|text| 
      texts[text] = text.attached_to[0].to_a[0..-2]
    }
    texts
  end
  
  ##############################
  ## Credit to Christina Eneroth
  #https://forums.sketchup.com/t/how-do-you-reliably-get-a-group-component-instances-volume/173349/4?u
  def calculate_volume(instance_path)
    leaf_instance = instance_path.to_a.last
    parents = instance_path.to_a[0..-2]
    parent_transformation = parents.map(&:transformation).inject(IDENTITY, :*)
    leaf_instance.volume * determinant(parent_transformation)
  end

  def determinant(transformation)
    xaxis(transformation) % (yaxis(transformation) * zaxis(transformation))
  end

  def xaxis(transformation)
    v = Geom::Vector3d.new(transformation.to_a.values_at(0..2))
    v.length /= transformation.to_a[15]
    v
  end

  def yaxis(transformation)
    v = Geom::Vector3d.new(transformation.to_a.values_at(4..6))
    v.length /= transformation.to_a[15]
    v
  end

  def zaxis(transformation)
    v = Geom::Vector3d.new(transformation.to_a.values_at(8..10))
    v.length /= transformation.to_a[15]
    v
  end
  ##############################

  unless @@loaded
    cmd1 = UI::Command.new("Show Instant volumes"){
      start_stop()
    }
    tip = 'Display the volume of the "Vol" labeled solid instances during modification'
    cmd1.tooltip = tip
    cmd1.status_bar_text = tip
    cmd1.set_validation_proc{
      @@runing ? MF_CHECKED : MF_UNCHECKED
    }
    UI.menu("Plugin").add_item cmd1
    @@loaded = true
  end
end# module Dezmo
end# module InstantVolume

.
That’s it for today. :innocent:

4 Likes