Bounds do not always give the same result

conponentInstance.definition.entities give a list of edge and face, but for the same component, the face size is not always the same
Its because of definition of component, but the component has been transformed
remorque latte bounds test.skp (4.5 MB)

class InfoSelectionObserver < Sketchup::SelectionObserver
    def onSelectionBulkChange(selection)
        putsInfoSelection(selection[0])
    end
end
Sketchup.active_model.selection.add_observer(InfoSelectionObserver.new)

def putsInfoSelection(entities)
    putsSizeEntity(entities)
    if(entities.is_a?(Sketchup::ComponentInstance))
        entity = entities.definition.entities
        #scale_group_definition(entity)
    elsif(entities.respond_to?(:each))
        entity = entities
    else 
        return
    end
    entity.each { | ent | 
        putsSizeEntity(ent)
    }
end
  
def putsSizeEntity(entity)
    if entity.respond_to?(:bounds)
        bb = entity.bounds  
        geom = {
            "d" => bb.depth.to_mm.round(),
            "h" => bb.height.to_mm.round(),
            "w" => bb.width.to_mm.round(),
        }
        puts "Size : #{entity.to_s} #{geom.to_s}"
    else
        puts "No size for : #{entity.to_s}"
    end
end

With this code, when i select the component, and display infoSelection i have not the same size for the face surrounded

If i right click on this component and click on “Scale the definition” and select the same component, the same face give the right size


there is certainly a principle that I did not understand with sketchup, but I wonder how to always see the correct size of the faces when I select a component

Is the component instance scaled ? If so, then the instance bounds will be scaled by the instance.transformation scaling factors.

Also, the bounding box for an object’s bounds is always aligned with the axes.

1 Like

Thank you Dan, I had indeed followed the path of transformation, but it is quite complex to understand, it’s normal because to understand it, you must know well the geometrics and mathematics and that’s not really my case.

To better understand the transformation on sketchup, I installed this excellent plugin written by Thomtom TransformationInspector.
I looked at the code very well documented, very detailed, and it is very educational to understand sketchup and coding with ruby. I highly recommend it
I slightly changed the code to use UI.HtmlDialog instead of UI.WebDialog, so I have access to devtools

While waiting to understand everything, I modified my code a little to find the right sizes. The most difficult was to find out where the transformations of scales are in the array given by transformation.to_a, the Thomthom plugin help me to find this values

the values given by transformation.to_a are very precise and sometimes a little too much, you have to round them because you can have values very close to zero (like 5.342948306008558e-16) when you did not do any transformation.

so I modified my function that displays the size of faces for simple volumes (it is for simple constructions in wood), and I got the right sizes of the faces of a component or a group

class InfoSelectionObserver < Sketchup::SelectionObserver
    def onSelectionBulkChange(selection)
        putsInfoSelection(selection[0])
    end
end
Sketchup.active_model.selection.add_observer(InfoSelectionObserver.new)

def putsInfoSelection(entities)
    instance = false
    putsSizeEntity("selection", entities)
    if(entities.is_a?(Sketchup::ComponentInstance))
        entity = entities.definition.entities
        instance = entities
    elsif(entities.respond_to?(:each))
        entity = entities
    else 
        return
    end
    entity.grep(Sketchup::Face).each { | ent | 
        putsSizeEntity("size", ent, instance)
    }
end
  
def putsSizeEntity(lib, entity, instance = false)
    if entity.respond_to?(:bounds)
        bb = entity.bounds  
        geom = {
            "bounds" => {
                "d" => bb.depth.to_mm.round(),      # depht
                "h" => bb.height.to_mm.round(),     # height
                "w" => bb.width.to_mm.round(),      # width
            }
        }
        if(instance != false)
            tr = instance.transformation
            tra = tr.to_a            
            # get the scale values in index 1 (xscale), 8 (yscale), 15 (zscale)
            geom['tr'] = {
                "d" => tra[8].round(6) != 0 ? tra[8].round(6).abs() : 1,
                "h" => tra[15].round(6) != 0 ? tra[15].round(6).abs() : 1,
                "w" => tra[1].round(6) != 0 ? tra[1].round(6).abs() : 1,
            }
            # compute the real size of the selected componant
            geom['scale'] = {
                "d" => (geom['bounds']['d'] * geom['tr']['d']).round(),
                "h" => (geom['bounds']['h'] * geom['tr']['h']).round(),
                "w" => (geom['bounds']['w'] * geom['tr']['w']).round()
            }
        end
        puts "#{lib} : #{entity.to_s} #{geom.to_s}"
    end
end