Extract face area from component using generate report

Let me sketch the situation:

I have created a dynamic component which is basically a plate 1x1m with a selectable thickness from a list (LenX has predefined thicknesses, LenY and LenZ are not constrained). I then model using only this component. The plates can have arbitrary shapes but will always have a predefined thickness. Next I generate a report to have my Bill Of Materials. Importing in Excel gives me all the data I need except there’s no way to know the net surface area of non-rectangular plates.
What would be very useful to me is being able to export an attribute in the report which will give me the net surface area of the largest face in the component.
Any help would be greatly appreciated as I’ve been fiddling on this for hours to no avail!

1 Like

paint the area with a material concerned then use FACEAREA(“materialName”) on a named attribute

1 Like

If it’s a DC then FACEAREA("materialName") on a named attribute [say ‘Area’] will work for all faces that have been painted with "materialName", BUT if they are ‘unpainted’ faces inside a painted group/component-instance then you need to use FACEAREA("") on a named attribute - the empty string assumes ‘no-material’. Also remember that both back and front face areas are reported, so halve the result !

1 Like

Thanks, this is helpful but I’m not quite there.
Painting the said face is not very practical as the model can have hundreds of components.
The empty string returns the total area off all faces from that component which is not quite what I need. Is there a way to have it return only the single largest face? Or a list of all faces would be fine as well, then excel could do the rest…

1 Like

You’d have to write a custom Ruby that your DC would call as a function.
This could report all areas or largest area…
e.g. This adds functions =volume(), =all_areas() and =biggest_area()
If the faces are inside sub-components or groups, then you need to mine into those instance.definition.entities OR group.entities to find the faces for the area check…

if Sketchup.version.to_i <= 8
if defined?($dc_observers)
  # Open SketchUp's Dynamic Component Functions (V1) class.
  # only if DC extension is active
    class DCFunctionsV1
        # return volume of DC
        # Usage: =volume()
        if not DCFunctionsV1.method_defined?(:volume)
            def volume(a)
                return @source_entity.volume
        # return all areas of faces in DC
        # Usage: =all_areas()
        if not DCFunctionsV1.method_defined?(:all_areas)
            def all_areas(a)
                area = 0.0
                    area += face.area
                return area
        # return biggest_area of a face in DC
        # Usage: =biggest_area()
        if not DCFunctionsV1.method_defined?(:biggest_area)
            def biggest_area(a)
                area = 0.0
                    area = face.area if face.area > area
                return area
1 Like

Guess I’m out of my league here. It’s my first encounter with ruby… can’t seem to get it to work. The function evaluates as this:
#=biggest_area([undefined method ‘entities’ for #])

1 Like

Without some other code to see how you got there, then you assume we are psychic ?


I copy pasted the whole of your code into a .rb file and put it in the plugins folder. Then created a custom attribute in my DC and put =biggest_area() as the function. When I hit enter I get the above message.

I realize I’m lacking basic ruby knowledge so I went through some tutorials and got simpler code to work. I’m using SU2015.

Can you make a ZIP of the RB file and the SKP containing the DC, and attach it to a Private Message to me.
It’s all but impossible to debug at a distance like this…

1 Like

Thanks for the PM ZIP.
It was my mistake.
The example code was flawed - I assume it only applied to a nested Group.
It needs different coding to apply to either a Group or ComponentInstance.

The attached RB fixes this…
biggestfacearea.rb (1.4 KB)

1 Like

is it possible to consider the scale factor of the component?

scalefactor = o.scaled_size[0] / o.unscaled_size[0]
area += face.area * scalefactor

I am trying this approach but I don’t know what I am doing wrong.

Please post code correctly:

In your snippet, where does the reference "o" come from ?

… and where do you get the methods named “scaled_size” and “unscaled_size” ?
(A search of the API does not reveal methods by these names.)

1 Like