Is there any way/extension that I can display the volume of a particular object instantaneously during resizing?
The object is solid and I can see its volume in the Entity Info panel when selecting the object after scaling (resizing) each time, but not DURING resizing. This object (let’s call A) is one of many components under object B. What I am looking for is the volume of object A when I change the size of its umbrella object (Object B).
I saw that Dimensions update instantaneously during scaling. Can the volume be displayed in the same way like that?
If the object is to be scaled uniformly about the three axis, you need first to calculate the volume scaling factor (VSF) using the actual volume (AV) and the final volume (FV) using this formula:
VSF = FV / AV
Then you can calculate the linear scale factor (LSF) by using the following formula:
LSF = Cube Root of VSF
Use the Scale Tool and scale uniformly, entering the LSF value obtained above.
For example, you have an object that is 50 cubic inches and you want to scale it to get 100 cubic inches.
Hello jean_lemire_1,
Thank you for the interesting information, but what I’m looking for is quite the other way around.
I would like to adjust the object’s size (maybe across 1,2, or 3 axes) by using mouse based on discussion and inputs from my team during a meeting. However, I would like the volume of the object to show in real time as I adjust the object. Is there any way to display the volume instantaneously as I drag my cursor to adjust the object?
I think the answer is No. When the object (group or component) is selected the volume is displayed. When you then select a face to Push/Pull the area of the face is displayed in Entity info. Push/Pull changes the same faces of identical named components in the same way.
If you select one of the identical components and apply “scale” only the scaled component changes.
I am not too familiar with components. I made a sample and tried various methods.
I’ll change my answer to No/ maybe.
Edit, I posted this at the same time VN2 posted his clarification.
I’m not aware of an extension that displays the volume as you scale an object, but there is Scale 2 Volume that will help you adjust the size of objects to match a particular volume. So if you and your colleagues have discussed making something a specific volume, this allows you to do that.
Of course, it is possible using Ruby (an extension). However, the concept snippets below is a bit kind of hacking and uncomfortable - need to be tuned more… but does the task, if I understood right…
After copy-paste the code below to Ruby console You can select one single, solid object to examine its volume during scaling itself or the containing object…
If you right click on a single, solid object and no other object selected there will be a context menu: “Show Instant volume”. You can start showing its volume “instantly” at a Status Bar by clicking on this menu.
(The format of the volume displayed is depends on a setting in Window>>Model Info>>Units )
Actually, the code is refreshing the value at every 0,3 sec, but if the curent Tool also displaying something at a Status Bar, then it will blink alternately… (That is one reason I call it "uncomfortable " and concept…)
You can stop showing this volume by right click on some object and select the context menu: “Stop showing Instant volume”, or it will stop after 5 minutes itself.
Then you can select an other single, solid object to examine its volume during scaling itself or the containing object…
Click here to see the code: 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 InstantVolumes
@@loaded = false unless defined?(@@loaded)
@@runing = false unless defined?(@@runing)
extend self
def update_volume( instance_path )
instance = instance_path.last
@@runing = true
@note_timer = UI.start_timer(0.3, true){
if instance.valid?
vol = calculate_volume( instance_path )
Sketchup.status_text = Sketchup.format_volume( vol )
else
stop()
end
}
end
def stop()
UI.stop_timer(@note_timer) if @note_timer
@@runing = false
puts "InstantVolumes stopped"
end
def start(instance_path)
puts "InstantVolumes started"
update_volume( instance_path )
# Limit to run for 5 minutes:
UI.start_timer(300, false){
stop()
}
end
def instance?(e)
e.is_a?(Sketchup::Group) || e.is_a?(Sketchup::ComponentInstance)
end
def valid_solid( sel = Sketchup.active_model.selection )
return false if sel.empty?
return false unless sel.single_object?
return false unless instance?( sel.first )
return false unless sel.first.manifold?
active_path = Sketchup.active_model.active_path
if active_path
return active_path.to_a<<sel.first
else
return [sel.first]
end
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 volume"){
start( valid_solid() )
}
cmd2 = UI::Command.new("Stop showing Instant volume"){
stop()
}
tip = "Display the volume of the selected solid instance during modification"
cmd1.tooltip = tip
cmd1.status_bar_text = tip
UI.add_context_menu_handler{|context_menu|
context_menu.add_item( cmd1 ) if valid_solid() && !@@runing
context_menu.add_item( cmd2 ) if @@runing
}
@@loaded = true
end
end# module Dezmo
end# module InstantVolume
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…
.
.
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