|
7 | 7 |
|
8 | 8 |
|
9 | 9 | class BooleanModifier(Modifier): |
10 | | - """Class representing a modifier that performs a boolean operation on a target geometry. |
| 10 | + """Perform boolean difference on the target element. |
11 | 11 |
|
12 | 12 | Parameters |
13 | 13 | ---------- |
| 14 | + source : :class:`compas.geometry.Brep` | :class:`compas.datastructures.Mesh` |
| 15 | + The geometry to be used as the modifier |
14 | 16 | name : str, optional |
15 | 17 | The name of the interaction. |
16 | 18 |
|
17 | 19 | """ |
18 | 20 |
|
19 | | - def apply(self, source: Union[Brep, Mesh], target: Union[Brep, Mesh]): |
| 21 | + @property |
| 22 | + def __data__(self): |
| 23 | + # type: () -> dict |
| 24 | + return {"name": self.name, "source": self.source} |
| 25 | + |
| 26 | + def __init__(self, source: Union[Brep, Mesh], name=None): |
| 27 | + # type: (Union[Brep, Mesh], str | None) -> None |
| 28 | + super(BooleanModifier, self).__init__(name=name) |
| 29 | + self.source = source |
| 30 | + |
| 31 | + def __repr__(self): |
| 32 | + return '{}(name="{}")'.format(self.__class__.__name__, self.name) |
| 33 | + |
| 34 | + def apply(self, target: Union[Brep, Mesh]): |
20 | 35 | """Apply the interaction to the affected geometry. |
| 36 | + NOTE: If the result is not a valid geometry, the original geometry is returned. |
21 | 37 |
|
22 | 38 | Parameters |
23 | 39 | ---------- |
24 | | - source : :class:`compas.geometry.Brep` | :class:`compas.datastructures.Mesh` |
25 | | - The source of the modification. |
26 | | - target : :class:`compas.geometry.Brep` | :class:`compas.datastructures.Mesh` |
27 | | - The target of the modification. |
28 | | -
|
| 40 | + targetgeometry : :class:`compas.geometry.Brep` | :class:`compas.datastructures.Mesh` |
| 41 | + The geometry to be affected iteratively. The same geometry can be modified multiple times. |
| 42 | + sourcegeometry : :class:`compas.geometry.Brep` | :class:`compas.datastructures.Mesh` |
| 43 | + The geometry to be used as the modifier. |
29 | 44 | """ |
30 | | - raise NotImplementedError |
| 45 | + # Local import is needed otherwise, remove contact interactions in algorithms module. |
| 46 | + if isinstance(target, Brep) and isinstance(self.source, Brep): |
| 47 | + try: |
| 48 | + return Brep.from_boolean_difference(target, self.source) |
| 49 | + except Exception: |
| 50 | + print("Boolean difference is not successful.") |
| 51 | + return target |
| 52 | + else: |
| 53 | + from compas_cgal.booleans import boolean_difference_mesh_mesh |
| 54 | + |
| 55 | + mesh0: Mesh = target.copy() if not isinstance(target, Brep) else Mesh.from_polygons(target.to_polygons()) |
| 56 | + mesh1: Mesh = self.source.copy() if not isinstance(self.source, Brep) else Mesh.from_polygons(self.source.to_polygons()) |
| 57 | + print(mesh0) |
| 58 | + print(mesh1) |
| 59 | + A = mesh0.to_vertices_and_faces(triangulated=True) |
| 60 | + B = mesh1.to_vertices_and_faces(triangulated=True) |
| 61 | + |
| 62 | + V, F = boolean_difference_mesh_mesh(A, B) |
| 63 | + mesh: Mesh = Mesh.from_vertices_and_faces(V, F) if len(V) > 0 and len(F) > 0 else mesh0 |
| 64 | + return mesh |
0 commit comments