In some cases, when conducting a boolean cut or union on two almost-identical shapes, OCC returns a null TopoDS_Shape, which produces a raise of a ValueError: Null TopoDS_Shape object. It's not clear what triggers it, but it seems to happen rarely, but reliably on the same shapes when it happens.
However, only the first operation on the two shapes fails. Subsequent identical operations on the same object work as originally expected.
#1503 seems related, but was closed after a workaround. It's not immediately clear to me if it's exactly the same or not.
#1452 also could be similar (but it's a union operation)
To Reproduce
Using the two attached very similar objects (these are real objects I tried to do a difference for in the KiCad 3D package library):
model.zip
import sys
from pathlib import Path
import cadquery as cq
def main(argv: list[str]) -> int:
if len(argv) != 3:
print(f"Usage: {argv[0]} <model1.step> <model2.step>")
return 2
old_path = Path(argv[1])
new_path = Path(argv[2])
old = cq.importers.importStep(str(old_path))
new = cq.importers.importStep(str(new_path))
old_volume = old.val().Volume()
new_volume = new.val().Volume()
print(f"{str(old_path)} volume: {old_volume:.4f} mm^3")
print(f"{str(new_path)} volume: {new_volume:.4f} mm^3")
i = 0
# Repeat n identical cut operations:
# Failure on the first attempt and success on subsequent attempts.
for i in range(1, 5):
print(f"\nCut attempt {i}....")
try:
added = new.cut(old)
except ValueError as exc:
print(f" Cut {i} raised {type(exc).__name__}: {exc}")
else:
added_volume = added.val().Volume()
print(f" Cut {i} succeeded. Added volume: {added_volume:.4f} mm^3")
if __name__ == "__main__":
sys.exit(main(sys.argv))
Output of the above script on these files:
./null_topods.py model1.step model2.step
model1.step volume: 281.1875 mm^3
model2.step volume: 281.8517 mm^3
Cut attempt 1....
Cut 1 raised ValueError: Null TopoDS_Shape object
Cut attempt 2....
Cut 2 succeeded. Added volume: 0.9051 mm^3
Cut attempt 3....
Cut 3 succeeded. Added volume: 0.9051 mm^3
Cut attempt 4....
Cut 4 succeeded. Added volume: 0.9051 mm^3
The same happens with the reverse order of model2.step model1.step.
The same happens if you change cut() to union().
Both models look like this, the differences are small:
Environment
OS: Arch Linux
Was CadQuery installed using Conda?: No, installed with pip. Python 3.11.16,
cadquery 2.6.1
cadquery-ocp 7.8.1.1.post1
I have seen these failures cropping up in diff attempts for at about year, but I don't have good records of what versions it was first seen in.
In some cases, when conducting a boolean cut or union on two almost-identical shapes, OCC returns a null
TopoDS_Shape, which produces a raise of aValueError: Null TopoDS_Shape object. It's not clear what triggers it, but it seems to happen rarely, but reliably on the same shapes when it happens.However, only the first operation on the two shapes fails. Subsequent identical operations on the same object work as originally expected.
#1503 seems related, but was closed after a workaround. It's not immediately clear to me if it's exactly the same or not.
#1452 also could be similar (but it's a union operation)
To Reproduce
Using the two attached very similar objects (these are real objects I tried to do a difference for in the KiCad 3D package library):
model.zip
Output of the above script on these files:
The same happens with the reverse order of
model2.step model1.step.The same happens if you change
cut()tounion().Both models look like this, the differences are small:
Environment
OS: Arch Linux
Was CadQuery installed using Conda?: No, installed with pip. Python 3.11.16,
I have seen these failures cropping up in diff attempts for at about year, but I don't have good records of what versions it was first seen in.