mikedh / trimesh

Python library for loading and using triangular meshes.
https://trimesh.org
MIT License
3k stars 580 forks source link

Bug in trimesh.boolean check_volume variable propagation. #2253

Open sanyi opened 3 months ago

sanyi commented 3 months ago

In line https://github.com/mikedh/trimesh/blob/85b4bd1f410d8d8361009c6f27266719a3d2b97d/trimesh/boolean.py#L77

check_volume is not propagated, and might fail downstream. In my case is calling "boolean_manifold" . I observed the same behavior in other boolean operators. I would suggest a patch, but it is a question of taste how to solve such. I am also not sure by all the assumptions downstream.

mikedh commented 2 months ago

So the checks being run are:

Is there a combination of calls that misses checking is_volume on all the inputs?

sanyi commented 2 months ago

i am calling union_meshes(meshes, check_volume=False) and fails with:

Traceback (most recent call last):
  File "/home/a/cutters/cutter.py", line 107, in <module>
    create_cutter_from_shape(svg_to_shape('svg/ll1.svg'), 'll1.stl')
  File "/home/a/cutters/cutter.py", line 97, in create_cutter_from_shape
    union_meshes(meshes, check_volume=False).export(f'./output/{output_file}')
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/a/cutters/.venv/lib/python3.12/site-packages/trimesh/boolean.py", line 79, in union
    result = _engines[engine](meshes, operation="union", **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/a/cutters/.venv/lib/python3.12/site-packages/trimesh/boolean.py", line 138, in boolean_manifold
    raise ValueError("Not all meshes are volumes!")
ValueError: Not all meshes are volumes!

If I add kwargs["check_volume"] = check_volume into:

def union(
    meshes: Iterable, engine: Optional[str] = None, check_volume: bool = True, **kwargs
):
    """
    Compute the boolean union between a mesh an n other meshes.

    Parameters
    ----------
    meshes : list of trimesh.Trimesh
      Meshes to be processed
    engine : str
      Which backend to use, i.e. 'blender' or 'manifold'
    check_volume
      Raise an error if not all meshes are watertight
      positive volumes. Advanced users may want to ignore
      this check as it is expensive.
    kwargs
      Passed through to the `engine`.

    Returns
    ----------
    union
      A `Trimesh` that contains the union of all passed meshes.
    """
    if check_volume and not all(m.is_volume for m in meshes):
        raise ValueError("Not all meshes are volumes!")

    kwargs["check_volume"] = check_volume

    result = _engines[engine](meshes, operation="union", **kwargs)
    return result

Is happy.