|
22 | 22 | """Provides tools for pulling geometry.""" |
23 | 23 |
|
24 | 24 | from enum import Enum, unique |
25 | | -from typing import TYPE_CHECKING, Union |
| 25 | +from typing import TYPE_CHECKING, Iterable, Union |
26 | 26 |
|
27 | 27 | from ansys.api.geometry.v0.commands_pb2 import ( |
28 | 28 | ChamferRequest, |
| 29 | + CombineIntersectBodiesRequest, |
| 30 | + CombineMergeBodiesRequest, |
29 | 31 | CreateCircularPatternRequest, |
30 | 32 | CreateFillPatternRequest, |
31 | 33 | CreateLinearPatternRequest, |
@@ -1138,3 +1140,130 @@ def split_body( |
1138 | 1140 | design._update_design_inplace() |
1139 | 1141 |
|
1140 | 1142 | return result.success |
| 1143 | + |
| 1144 | + def intersect_bodies( |
| 1145 | + self, |
| 1146 | + main_body: "Body", |
| 1147 | + other_bodies: Union["Body", Iterable["Body"]], |
| 1148 | + keep_other: bool = False, |
| 1149 | + ) -> bool: |
| 1150 | + """Intersect a body with other bodies. |
| 1151 | +
|
| 1152 | + Parameters |
| 1153 | + ---------- |
| 1154 | + main_body : Body |
| 1155 | + Main body to intersect with. |
| 1156 | + other_bodies : Body | list[Body] |
| 1157 | + Other bodies to intersect with. |
| 1158 | + keep_other : bool, default: False |
| 1159 | + Keep the other bodies if ``True``. |
| 1160 | +
|
| 1161 | + Returns |
| 1162 | + ------- |
| 1163 | + bool |
| 1164 | + ``True`` when successful, ``False`` when failed. |
| 1165 | + """ |
| 1166 | + self.__generic_boolean_command( |
| 1167 | + main_body, other_bodies, keep_other, "intersect", "Intersecting bodies failed." |
| 1168 | + ) |
| 1169 | + return True |
| 1170 | + |
| 1171 | + def subtract_bodies( |
| 1172 | + self, |
| 1173 | + main_body: "Body", |
| 1174 | + other_bodies: Union["Body", Iterable["Body"]], |
| 1175 | + keep_other: bool = False, |
| 1176 | + ) -> bool: |
| 1177 | + """Subtract a body from other bodies. |
| 1178 | +
|
| 1179 | + Parameters |
| 1180 | + ---------- |
| 1181 | + main_body : Body |
| 1182 | + Main body to subtract from. |
| 1183 | + other_bodies : Body | list[Body] |
| 1184 | + Other bodies to subtract. |
| 1185 | + keep_other : bool, default: False |
| 1186 | + Keep the other bodies if ``True``. |
| 1187 | +
|
| 1188 | + Returns |
| 1189 | + ------- |
| 1190 | + bool |
| 1191 | + ``True`` when successful. |
| 1192 | + """ |
| 1193 | + self.__generic_boolean_command( |
| 1194 | + main_body, other_bodies, keep_other, "subtract", "Subtracting bodies failed." |
| 1195 | + ) |
| 1196 | + return True |
| 1197 | + |
| 1198 | + def unite(self, main_body: "Body", other_bodies: Union["Body", Iterable["Body"]]) -> bool: |
| 1199 | + """Unite a body with other bodies. |
| 1200 | +
|
| 1201 | + Parameters |
| 1202 | + ---------- |
| 1203 | + main_body : Body |
| 1204 | + Main body to unite with. |
| 1205 | + other_bodies : Body | list[Body] |
| 1206 | + Other bodies to unite. |
| 1207 | +
|
| 1208 | + Returns |
| 1209 | + ------- |
| 1210 | + bool |
| 1211 | + ``True`` when successful. |
| 1212 | + """ |
| 1213 | + self.__generic_boolean_command( |
| 1214 | + main_body, other_bodies, False, "unite", "Uniting bodies failed." |
| 1215 | + ) |
| 1216 | + return True |
| 1217 | + |
| 1218 | + @protect_grpc |
| 1219 | + @min_backend_version(25, 2, 0) |
| 1220 | + def __generic_boolean_command( |
| 1221 | + self, |
| 1222 | + main: "Body", |
| 1223 | + other: Union["Body", Iterable["Body"]], |
| 1224 | + keep_other: bool, |
| 1225 | + type_bool_op: str, |
| 1226 | + err_bool_op: str, |
| 1227 | + ) -> None: |
| 1228 | + parent_design = get_design_from_body(main) |
| 1229 | + other_bodies = other if isinstance(other, Iterable) else [other] |
| 1230 | + if type_bool_op == "intersect": |
| 1231 | + body_ids = [body._grpc_id for body in other_bodies] |
| 1232 | + target_ids = [main._grpc_id] |
| 1233 | + request = CombineIntersectBodiesRequest( |
| 1234 | + target_selection=target_ids, |
| 1235 | + tool_selection=body_ids, |
| 1236 | + subtract_from_target=False, |
| 1237 | + keep_cutter=keep_other, |
| 1238 | + ) |
| 1239 | + response = self._commands_stub.CombineIntersectBodies(request) |
| 1240 | + elif type_bool_op == "subtract": |
| 1241 | + body_ids = [body._grpc_id for body in other_bodies] |
| 1242 | + target_ids = [main._grpc_id] |
| 1243 | + request = CombineIntersectBodiesRequest( |
| 1244 | + target_selection=target_ids, |
| 1245 | + tool_selection=body_ids, |
| 1246 | + subtract_from_target=True, |
| 1247 | + keep_cutter=keep_other, |
| 1248 | + ) |
| 1249 | + response = self._commands_stub.CombineIntersectBodies(request) |
| 1250 | + elif type_bool_op == "unite": |
| 1251 | + bodies = [main] |
| 1252 | + bodies.extend(other_bodies) |
| 1253 | + body_ids = [body._grpc_id for body in bodies] |
| 1254 | + request = CombineMergeBodiesRequest(target_selection=body_ids) |
| 1255 | + response = self._commands_stub.CombineMergeBodies(request) |
| 1256 | + else: |
| 1257 | + raise ValueError("Unknown operation requested") |
| 1258 | + |
| 1259 | + if not response.success: |
| 1260 | + raise ValueError( |
| 1261 | + f"Operation of type '{type_bool_op}' failed: {err_bool_op}.\n" |
| 1262 | + f"Involving bodies:{main}, {other_bodies}" |
| 1263 | + ) |
| 1264 | + |
| 1265 | + if not keep_other: |
| 1266 | + for b in other_bodies: |
| 1267 | + b.parent_component.delete_body(b) |
| 1268 | + |
| 1269 | + parent_design._update_design_inplace() |
0 commit comments