gumyr / build123d

A python CAD programming library
Apache License 2.0
386 stars 72 forks source link

project() creates broken/unusable Compound when called on a Solid #562

Open Windfisch opened 4 months ago

Windfisch commented 4 months ago

Hi,

the project function silently generates an unusable Compound when trying to project(some_solid).. When calling .faces(), .edges() or .vertices() on that Compound (or trying to show() it), an exception is raised.

That project does not work on a Solid is not the issue and is expected according to the documentation, which states: _"Parameters: objects (Union[Edge, Face, Wire, VectorLike, Vertex] or Iterable of) – objects or points to project"_

However, the behavior of the function should be more clear. I would expect a clear message like ValueError("project does not accept solids, try your_solid.faces()"), but not a broken object.

Steps to reproduce

from build123d import *
foo = project(extrude(Rectangle(20,20), 3), Plane.XY)
print(foo) # it's a Compound
foo.vertices()

Expected behaviour

The foo = project(...) line should throw a ValueError with a helpful error message

or: The foo = project(some_solid) call should behave the same as foo = project(some_solid.faces()).

Actual behavior

The foo.vertices() call raises the following exception:

Traceback (most recent call last):
  File "/home/flo/kruschkram/b3d-workspace/bugs/project.py", line 6, in <module>
    print(foo.vertices())
          ^^^^^^^^^^^^^^
  File "/home/flo/bin/cadquery/lib/python3.11/site-packages/build123d/topology.py", line 2117, in vertices
    [Vertex(downcast(i)) for i in self._entities(Vertex.__name__)]
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/flo/bin/cadquery/lib/python3.11/site-packages/build123d/topology.py", line 2082, in _entities
    explorer = TopExp_Explorer(self.wrapped, inverse_shape_LUT[topo_type])
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: __init__(): incompatible constructor arguments. The following argument types are supported:
    1. OCP.TopExp.TopExp_Explorer()
    2. OCP.TopExp.TopExp_Explorer(S: OCP.TopoDS.TopoDS_Shape, ToFind: OCP.TopAbs.TopAbs_ShapeEnum, ToAvoid: OCP.TopAbs.TopAbs_ShapeEnum = <TopAbs_ShapeEnum.TopAbs_SHAPE: 8>)

Invoked with: None, <TopAbs_ShapeEnum.TopAbs_VERTEX: 7>
gumyr commented 4 months ago

There isn't a lot of type checking on the inputs of the build123d API which can lead to these types of problems. However, catching these problems early can generate meaningful error messages which would help usability.