Have you tried the TINVolumeCalculator from FME Hub?
Â
https://hub.safe.com/transformers/tinvolumecalculatorI'm not sure you can use this directly, but, if you edit it, it might give you some pointers on how to solve your particular solution.
Â
Hello @tobiasp
Â
To extrapolate off what @courtney_m stated.
Â
The TINVolumeCalculator should provide you with the tool to produce the volume. The transformer itself will calculate the volume of each individual triangle in the TIN down to a reference elevation. It then sums all the triangles together to get the total.
Â
You also have the option of using a boundary polygon which can be used in the Digital Terrain Model generation. This would allow you to use the same data(pile of dirt) and model changes over time.
Hello @tobiasp
Â
To extrapolate off what @courtney_m stated.
Â
The TINVolumeCalculator should provide you with the tool to produce the volume. The transformer itself will calculate the volume of each individual triangle in the TIN down to a reference elevation. It then sums all the triangles together to get the total.
Â
You also have the option of using a boundary polygon which can be used in the Digital Terrain Model generation. This would allow you to use the same data(pile of dirt) and model changes over time.
Thank´s for your answer! The TINVolumeCalculator sounded like exactly what I needed, but I wasn´t able to get it to work. I will give a new shot when I get back to office. I tried to use the bottom points of the pile (=ground level) to create the boundary polygon you´re mentioning but something went wrong I suppose.
Â
Â
Hello @tobiasp
Â
To extrapolate off what @courtney_m stated.
Â
The TINVolumeCalculator should provide you with the tool to produce the volume. The transformer itself will calculate the volume of each individual triangle in the TIN down to a reference elevation. It then sums all the triangles together to get the total.
Â
You also have the option of using a boundary polygon which can be used in the Digital Terrain Model generation. This would allow you to use the same data(pile of dirt) and model changes over time.
No, I still dont get it. What do I put into the TINVolumeCalculator? I cant find any good explanation. With my bottom-points and top-points I can get a nice TINSurface from the TINGenerator. This is exactly what I want; a 3D-model of my pile of dirt. How can it be so hard to measure the volume of this model? Please help me out in this seemingly easy-to-solve dilemma.
Â
Â
Hi @tobiasp, I looked at the TINVolumeCalculator. This transformer seems to always require a feature having a boundary area geometry from the Boundary_INPUT. If you already have a TIN surface and need to calculate its volume,Â
- create a footprint area of the TIN with a SurfaceFootprintReplacer,
- send the area to the Boundary_INPUT port,
- and send the TIN to the Breaklines_INPUT port.
The transformer should work with the setting above, but in my quick test, the resulting volume was wrong. The reason is that there are these fatal bugs in the implementation :-0
- The Index parameter in the CoordinateFetcher_3 is set to 1, but it should be set to 2.
- The procedure in the "Calculate volume of triangle" bookmark is wrong. Specifically, the expression in the ExpressionEvalluator_3 computes the volume of a trigonal pyramid, but the top-part of a diagonally cut triangular prism  is not always a trigonal pyramid.
I therefore would not recommend you to use the TINVolumeCalculator transformer. @trentatsafe, please check carefully the implementation of the TINVolumeCalculator.
This is a workaround using the BRepSolidBoundaryCreator.Beta (from FME Hub) to create a solid below (minimum z and above) the input TIN surface.
Alternatively, this small Python script can be used to directly compute the volume below the input Mesh surface (minimum z and above).Â
# PythonCaller Script Example
# Assume the input feature has a Mesh geometry (typically TIN).
import fmeobjects
def calculateMeshVolume(feature):
    mesh = feature.getGeometry()
    if isinstance(mesh, fmeobjects.FMEMesh):
        zmin = mesh.boundingCube()Â0]e2]
        pool = mesh.getVertices()
        volume = 0.0
        for part in mesh:
            a, h = 0.0, 0.0
            vertices = epoolhi] for i in part.getVertexIndices()]
            for i, (x0, y0, z0) in enumerate(verticesÂ:-1]):
                x1, y1, _ = verticesÂi+1]
                a += (x1 - x0) * (y0 + y1)
                h += (z0 - zmin)
            volume += abs(a) * 0.5 * (h / (len(vertices) - 1))
        feature.setAttribute('_volume', volume)
Hi @tobiasp, I looked at the TINVolumeCalculator. This transformer seems to always require a feature having a boundary area geometry from the Boundary_INPUT. If you already have a TIN surface and need to calculate its volume,Â
- create a footprint area of the TIN with a SurfaceFootprintReplacer,
- send the area to the Boundary_INPUT port,
- and send the TIN to the Breaklines_INPUT port.
The transformer should work with the setting above, but in my quick test, the resulting volume was wrong. The reason is that there are these fatal bugs in the implementation :-0
- The Index parameter in the CoordinateFetcher_3 is set to 1, but it should be set to 2.
- The procedure in the "Calculate volume of triangle" bookmark is wrong. Specifically, the expression in the ExpressionEvalluator_3 computes the volume of a trigonal pyramid, but the top-part of a diagonally cut triangular prism  is not always a trigonal pyramid.
I therefore would not recommend you to use the TINVolumeCalculator transformer. @trentatsafe, please check carefully the implementation of the TINVolumeCalculator.
This is a workaround using the BRepSolidBoundaryCreator.Beta (from FME Hub) to create a solid below (minimum z and above) the input TIN surface.
Alternatively, this small Python script can be used to directly compute the volume below the input Mesh surface (minimum z and above).Â
# PythonCaller Script Example
# Assume the input feature has a Mesh geometry (typically TIN).
import fmeobjects
def calculateMeshVolume(feature):
    mesh = feature.getGeometry()
    if isinstance(mesh, fmeobjects.FMEMesh):
        zmin = mesh.boundingCube()Â0]e2]
        pool = mesh.getVertices()
        volume = 0.0
        for part in mesh:
            a, h = 0.0, 0.0
            vertices = epoolhi] for i in part.getVertexIndices()]
            for i, (x0, y0, z0) in enumerate(verticesÂ:-1]):
                x1, y1, _ = verticesÂi+1]
                a += (x1 - x0) * (y0 + y1)
                h += (z0 - zmin)
            volume += abs(a) * 0.5 * (h / (len(vertices) - 1))
        feature.setAttribute('_volume', volume)
Thanks for your effort! I tried to copy your workbench and I am almost following how it works. Thing is; I finally got some values out of the TINVolumeCalculator but theese volumes are based on a "base elevation" that I have to estimate from an average of the surronding base points. With your method the volume is calculated based on the lowest Z value of the base points, right? This will result in a larger volume than the real one, especially if the ground is sloping, right?Â
Â
Hi @tobiasp, I looked at the TINVolumeCalculator. This transformer seems to always require a feature having a boundary area geometry from the Boundary_INPUT. If you already have a TIN surface and need to calculate its volume,Â
- create a footprint area of the TIN with a SurfaceFootprintReplacer,
- send the area to the Boundary_INPUT port,
- and send the TIN to the Breaklines_INPUT port.
The transformer should work with the setting above, but in my quick test, the resulting volume was wrong. The reason is that there are these fatal bugs in the implementation :-0
- The Index parameter in the CoordinateFetcher_3 is set to 1, but it should be set to 2.
- The procedure in the "Calculate volume of triangle" bookmark is wrong. Specifically, the expression in the ExpressionEvalluator_3 computes the volume of a trigonal pyramid, but the top-part of a diagonally cut triangular prism  is not always a trigonal pyramid.
I therefore would not recommend you to use the TINVolumeCalculator transformer. @trentatsafe, please check carefully the implementation of the TINVolumeCalculator.
This is a workaround using the BRepSolidBoundaryCreator.Beta (from FME Hub) to create a solid below (minimum z and above) the input TIN surface.
Alternatively, this small Python script can be used to directly compute the volume below the input Mesh surface (minimum z and above).Â
# PythonCaller Script Example
# Assume the input feature has a Mesh geometry (typically TIN).
import fmeobjects
def calculateMeshVolume(feature):
    mesh = feature.getGeometry()
    if isinstance(mesh, fmeobjects.FMEMesh):
        zmin = mesh.boundingCube()Â0]e2]
        pool = mesh.getVertices()
        volume = 0.0
        for part in mesh:
            a, h = 0.0, 0.0
            vertices = epoolhi] for i in part.getVertexIndices()]
            for i, (x0, y0, z0) in enumerate(verticesÂ:-1]):
                x1, y1, _ = verticesÂi+1]
                a += (x1 - x0) * (y0 + y1)
                h += (z0 - zmin)
            volume += abs(a) * 0.5 * (h / (len(vertices) - 1))
        feature.setAttribute('_volume', volume)
You are right. The method I suggested calculates the volume of a solid whose base is a plane of the lowest z.
Â
If you can choose only base points on the boundary of the TIN, (the volume of the TIN created from all the points - the volume of the TIN created from only the base points) would be your desired volume, I think.
Â
Â