Volume differs between identical models


I'm loading models in either .step or .iges format.

However if I load the same model, the volume will differ by almost 100%, depending on whether I load it from a .step or a .iges file.

I'm using the python wrapper PyOCC, but' I havent seen any differences before.

The iges loads as a compound, with no solids, so I'm building the faces into a solid.

When I display the two solids, I can see they are completely identical.

# Load iges
shapes = read_iges_file('C:/Repos/model_analysis/test-assets/z-axis_mellemplade_SW.igs')

# Convert to solid
the_solid = TopoDS_Solid()
the_shell = TopoDS_Shell()
the_builder = BRep_Builder()
topo_expl = TopologyExplorer(shapes)
for face in topo_expl.faces():
    the_builder.Add(the_shell, face)
the_builder.Add(the_solid, the_shell)

# Calc colume
properties = GProp_GProps()
brepgprop_VolumeProperties(the_solid, properties)
shapeVolume = properties.Mass()

# load step
step_shp = read_step_file('C:/Repos/model_analysis/test-assets/z-axis_mellemplade_SW.step')

# Calc volume
brepgprop_VolumeProperties(step_shp, properties)
shapeVolume = properties.Mass()
Mikhail Sazonov's picture

IGES does not preserve sharing of edges by adjacent faces. Your solid will be invalid, as it has no tight shell. You can check it with BRepCheck_Analyzer.

In order to get the tight shell after reading IGES you need to sew faces using BRepBuilderAPI_Sewing.

Morten Hilligsoe's picture

[Edit: Still doesn't work properly]

Thanks, this seemed to work.

# Computes solid from iges compund using BRepBuilderAPI_Sewing
def iges_compound_to_solid(compound):
    builder_sewing = BRepBuilderAPI_Sewing()
    sewed_shape = builder_sewing.SewedShape()

    return sewed_shape
Morten Hilligsoe's picture

I was too quick, there are still issues.

The shape generated by BRepBuilderAPI_Sewing contains 51 shells, but no solids.
When calculating volume and dimensions from the sewed iges shape, there are still small differences compared to the solid loaded from the step model.

I tried to make a solid from the 51 shells, but the shape doesn't pass the validity check.

Any ideas what to do when sewing the iges shape results in 51 shells?


Mikhail Sazonov's picture

It is needed to look thoroughly at the IGES shape, analyze places where adjacent faces were not sewed. Usually such thing occurs when there is a considerable gap between faces. This can be healed by increasing sewing tolerance.

Mikhail Sazonov's picture

BTW, sewing never produces solids, shells are its result. You need to form solids from shells by yourself.

Morten Hilligsoe's picture

Thanks for the input.

I managed to build the shells into a solid, by setting the tolerance setting properly.

And it turns out that the differences in calculated dimensions has something to do with the Bnd_Box() function. If I manually check X, Y, and Z for all vertices, I get correct dimensions.
However if I use SolidWorks to import the .iges file and export to .step, then the .step will also show wrong dimensons when using Bnd_Box().
So something is happening when converting from .iges

There is also an issue where I get a negative volume from the brepgprop_VolumeProperties() function. Dont know why that is.

Mikhail Sazonov's picture

Negative volume means inversed cumulated orientation of faces.

Bnd box computed by the method BRepBndLib::Add is not the tight one. It contains all poles of b-splines, which can be much wider than the model shape. There is more precise method (and slow) BRepBndLib::AddOptimal.

Morten Hilligsoe's picture

Thanks for the help.

I clearly didn't understand how the Iges format works. I can see that all faces are converted into SurfaceOfRevolution and BSplineSurface.
It's nice to know that BRepBndLib::AddOptimal is needed to account for b-spline poles.