tpaviot / pythonocc-demos

Examples and demos for the pythonocc CAD package
216 stars 115 forks source link

Wrong BoundingBox dimension extraction #27

Closed mohamed0123 closed 3 years ago

mohamed0123 commented 3 years ago

I am trying to extract box dimensions from the STP file and it's worked for a some of the samples, but unfortunately, I got the wrong extraction for the other samples for example below zipped STP file

Test.zip

I got this results value for "x": 6.802000200000001 and the right one is 6.24, and so on for y and z values.

and here is my code

from __future__ import print_function

from OCC.Extend.DataExchange import read_step_file
from OCC.Core.IFSelect import IFSelect_RetDone
from OCC.Core.Bnd import Bnd_Box
from OCC.Core.BRepBndLib import brepbndlib_Add
from OCC.Core.BRepMesh import BRepMesh_IncrementalMesh
from OCC.Core.STEPControl import STEPControl_Reader

shapes = read_step_file('path/to/stpfile')

def read_stp_file(file_path):
    step_reader = STEPControl_Reader()
    status = step_reader.ReadFile(file_path)
    if status == IFSelect_RetDone:
        fails_only = False
        step_reader.TransferRoots()
        shape = step_reader.Shape(1)
        return shape
    else:
        print("Error: can't read file.")

bbox = Bnd_Box()
use_mesh = True
mesh = BRepMesh_IncrementalMesh()
mesh.SetParallelDefault(True)
mesh.SetShape(shapes)
mesh.Perform()
assert mesh.IsDone()
brepbndlib_Add(shapes, bbox, use_mesh)
xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get()
print('x value : >>>> ', xmax - xmin)
rainman110 commented 3 years ago

This is a limitation of the underlying OpenCASCADE framework. The boundary box is not exact as only the control points / the convex hull of the geometric objects are used to determine the bounding box due to computational performance:

https://dev.opencascade.org/doc/refman/html/class_b_rep_bnd_lib.html#a17355b3bd07e39f47b48f658c7f29b41

Cite: "The resulting bounding box may be somewhat larger than the object. "

rainman110 commented 3 years ago

Maybe use brepbndlib_AddOptimal, this should be more exact:

https://dev.opencascade.org/doc/refman/html/class_b_rep_bnd_lib.html#aad43f924ff3d1ff0963005c4c6cdeb90

mohamed0123 commented 3 years ago

@rainman110 Thanks for your replies. Unfortunately, I got the same wrong results using brepbndlib_AddOptimal, and I believe there is something wrong as the difference error is too large0.562

mohamed0123 commented 3 years ago

@rainman110 also, I used the IGES file for the same sample and I got the correct results values, so I believe there is something wrong for reading the STEP files

test_iges_sample.zip

from OCC.Core.IFSelect import IFSelect_RetDone
from OCC.Core.Bnd import Bnd_Box
from OCC.Core.BRepBndLib import brepbndlib_AddOptimal
from OCC.Core.BRepMesh import BRepMesh_IncrementalMesh
from OCC.Core.IGESControl import IGESControl_Reader

def read_igs_shap(file_path):
    step_reader = IGESControl_Reader()
    step_reader.SetReadVisible(False)
    status = step_reader.ReadFile(file_path)
    if status == IFSelect_RetDone:  # check status
        step_reader.TransferRoots()
        nbr = step_reader.NbRootsForTransfer()
        _nbs = step_reader.NbShapes()
        shape = step_reader.Shape(1)
        return shape
    else:
        print("Error: can't read file.")

shapes = read_igs_shap("path/to/iges")

bbox = Bnd_Box()

use_mesh = True
mesh = BRepMesh_IncrementalMesh()
mesh.SetParallelDefault(True)
mesh.SetShape(shapes)
mesh.Perform()
assert mesh.IsDone()
brepbndlib_AddOptimal(shapes, bbox, use_mesh)
xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get()
print('x value : >>>> ', xmax - xmin)