|
30 | 30 | SherlockExportAllMountPoints, |
31 | 31 | SherlockExportAllTestFixtures, |
32 | 32 | SherlockExportAllTestPoints, |
| 33 | + SherlockUpdateModelingRegionError, |
33 | 34 | SherlockUpdateMountPointsByFileError, |
34 | 35 | SherlockUpdateTestFixturesByFileError, |
35 | 36 | SherlockUpdateTestPointsByFileError, |
@@ -997,7 +998,7 @@ def add_modeling_region( |
997 | 998 | } |
998 | 999 | } |
999 | 1000 | ] |
1000 | | - >>> result = sherlock.project.add_modeling_region("Tutorial Project", modeling_regions) |
| 1001 | + >>> result = sherlock.layer.add_modeling_region("Tutorial Project", modeling_regions) |
1001 | 1002 | """ |
1002 | 1003 | try: |
1003 | 1004 | if not project: |
@@ -1087,24 +1088,25 @@ def add_modeling_region( |
1087 | 1088 | polygonal_shape.rotation = shape.rotation |
1088 | 1089 | elif isinstance(shape, RectangularShape): |
1089 | 1090 | rectangular_shape = modeling_region.rectangularShape |
1090 | | - for point in shape.points: |
1091 | | - rectangular_point = rectangular_shape.points.add() |
1092 | | - rectangular_point.x = point[0] |
1093 | | - rectangular_point.y = point[1] |
| 1091 | + rectangular_shape.length = shape.length |
| 1092 | + rectangular_shape.width = shape.width |
| 1093 | + rectangular_shape.centerX = shape.centerX |
| 1094 | + rectangular_shape.centerY = shape.centerY |
1094 | 1095 | rectangular_shape.rotation = shape.rotation |
1095 | 1096 | elif isinstance(shape, SlotShape): |
1096 | 1097 | slot_shape = modeling_region.slotShape |
1097 | | - for point in shape.points: |
1098 | | - slot_point = slot_shape.points.add() |
1099 | | - slot_point.x = point[0] |
1100 | | - slot_point.y = point[1] |
| 1098 | + slot_shape.length = shape.length |
| 1099 | + slot_shape.width = shape.width |
| 1100 | + slot_shape.nodeCount = shape.nodeCount |
| 1101 | + slot_shape.centerX = shape.centerX |
| 1102 | + slot_shape.centerY = shape.centerY |
1101 | 1103 | slot_shape.rotation = shape.rotation |
1102 | 1104 | elif isinstance(shape, CircularShape): |
1103 | 1105 | circular_shape = modeling_region.circularShape |
1104 | | - for point in shape.points: |
1105 | | - circular_point = circular_shape.points.add() |
1106 | | - circular_point.x = point[0] |
1107 | | - circular_point.y = point[1] |
| 1106 | + circular_shape.diameter = shape.diameter |
| 1107 | + circular_shape.nodeCount = shape.nodeCount |
| 1108 | + circular_shape.centerX = shape.centerX |
| 1109 | + circular_shape.centerY = shape.centerY |
1108 | 1110 | circular_shape.rotation = shape.rotation |
1109 | 1111 | else: |
1110 | 1112 | raise SherlockAddModelingRegionError( |
@@ -1158,3 +1160,266 @@ def add_modeling_region( |
1158 | 1160 | except SherlockAddModelingRegionError as e: |
1159 | 1161 | LOG.error(str(e)) |
1160 | 1162 | raise e |
| 1163 | + |
| 1164 | + def update_modeling_region( |
| 1165 | + self, |
| 1166 | + project: str, |
| 1167 | + modeling_regions: List[Dict[str, Union[str, float, bool, dict]]], |
| 1168 | + ): |
| 1169 | + """ |
| 1170 | + Update one or more modeling regions in a specific project. |
| 1171 | +
|
| 1172 | + Parameters |
| 1173 | + ---------- |
| 1174 | + project : str |
| 1175 | + Name of the Sherlock project. |
| 1176 | + modeling_regions : list of dict |
| 1177 | + List of modeling regions to update. Each dictionary should contain: |
| 1178 | +
|
| 1179 | + - cca_name : str |
| 1180 | + Name of the CCA. |
| 1181 | + - region_id : str |
| 1182 | + Unique region ID of the modeling region. |
| 1183 | + - region_units : str |
| 1184 | + Units of the modeling region. |
| 1185 | + - model_mode : str |
| 1186 | + Mode that specifies how the region is used. Valid values are ``Enabled``, |
| 1187 | + ``Disabled`` and ``Excluded``. |
| 1188 | + - shape: PolygonalShape|RectangularShape|SlotShape|CircularShape|PCBShape |
| 1189 | + The shape of the modeling region. |
| 1190 | + - pcb_model_props : list |
| 1191 | + List of the PCB model parameters consisting of these properties: |
| 1192 | +
|
| 1193 | + - export_model_type : str |
| 1194 | + The type of model to be generated for a given modeling region. |
| 1195 | + Valid values are ``Default``, ``Sherlock``, ``Sweep`` and ``None``. |
| 1196 | + - elem_order: str |
| 1197 | + The type of 3D elements to be created for the PCB in the modeling region. |
| 1198 | + Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. |
| 1199 | + - max_mesh_size : float |
| 1200 | + The maximum size of the mesh to be used in the region. |
| 1201 | + - max_mesh_size_units : str |
| 1202 | + Units for the maximum mesh size. |
| 1203 | + - quads_preferred : bool |
| 1204 | + Whether to generate quad-shaped elements when creating the mesh if true. |
| 1205 | + - trace_model_props : list |
| 1206 | + List of the trace model parameters consisting of these properties: |
| 1207 | +
|
| 1208 | + - trace_model_type : str |
| 1209 | + The specification of whether trace modeling should be performed |
| 1210 | + within the region. Valid values are ``Default``, ``Enabled`` and |
| 1211 | + ``Disabled``. |
| 1212 | + - elem_order: str, optional |
| 1213 | + The type of 3D elements to be created for the PCB in the modeling region. |
| 1214 | + Valid values are ``First_Order``, ``Second_Order`` and ``Solid_Shell``. |
| 1215 | + - trace_mesh_size : float, optional |
| 1216 | + The maximum mesh size to be used in the region when trace modeling |
| 1217 | + is enabled. |
| 1218 | + - trace_mesh_size_units: str, optional |
| 1219 | + Units for the maximum mesh size when trace modeling is enabled. |
| 1220 | + - region_id_replacement : str, optional |
| 1221 | + Represents a unique region id that will replace the existing regionId value during |
| 1222 | + a modeling region update if a value exists. |
| 1223 | +
|
| 1224 | + Returns |
| 1225 | + ------- |
| 1226 | + int |
| 1227 | + Status code of the response. 0 for success. |
| 1228 | +
|
| 1229 | + Example |
| 1230 | + ------- |
| 1231 | + >>> from ansys.sherlock.core.launcher import launch_sherlock |
| 1232 | + >>> sherlock = launch_sherlock() |
| 1233 | + >>> sherlock.project.import_odb_archive( |
| 1234 | + "ODB++ Tutorial.tgz", |
| 1235 | + True, |
| 1236 | + True, |
| 1237 | + True, |
| 1238 | + True, |
| 1239 | + project="Tutorial Project", |
| 1240 | + cca_name="Card", |
| 1241 | + ) |
| 1242 | + >>> modeling_regions = [ |
| 1243 | + >>> { |
| 1244 | + >>> "cca_name": "Card", |
| 1245 | + >>> "region_id": "Region001", |
| 1246 | + >>> "region_units": "mm", |
| 1247 | + >>> "model_mode": "Enabled", |
| 1248 | + >>> "shape": PolygonalShape(points=[(0, 0), (1, 1)], rotation=0), |
| 1249 | + >>> "pcb_model_props": { |
| 1250 | + >>> "export_model_type": "Sherlock", |
| 1251 | + >>> "elem_order": "Second_Order", |
| 1252 | + >>> "max_mesh_size": 0.5, |
| 1253 | + >>> "max_mesh_size_units": "mm", |
| 1254 | + >>> "quads_preferred": True, |
| 1255 | + >>> }, |
| 1256 | + >>> "trace_model_props": { |
| 1257 | + >>> "trace_model_type": "Enabled", |
| 1258 | + >>> "elem_order": "Second_Order", |
| 1259 | + >>> "trace_mesh_size": 0.1, |
| 1260 | + >>> "trace_mesh_size_units": "mm", |
| 1261 | + >>> }, |
| 1262 | + >>> "region_id_replacement": "NewRegion001", |
| 1263 | + >>> } |
| 1264 | + >>> ] |
| 1265 | + >>> result = sherlock.layer.update_modeling_region("Tutorial Project", modeling_regions) |
| 1266 | + """ |
| 1267 | + try: |
| 1268 | + if not project: |
| 1269 | + raise SherlockUpdateModelingRegionError(message="Project name is invalid.") |
| 1270 | + |
| 1271 | + if not modeling_regions: |
| 1272 | + raise SherlockUpdateModelingRegionError(message="Modeling regions list is empty.") |
| 1273 | + |
| 1274 | + for region in modeling_regions: |
| 1275 | + if "cca_name" not in region: |
| 1276 | + raise SherlockUpdateModelingRegionError(message="CCA name is invalid.") |
| 1277 | + if "region_id" not in region: |
| 1278 | + raise SherlockUpdateModelingRegionError(message="Region ID is invalid.") |
| 1279 | + if "region_units" not in region: |
| 1280 | + raise SherlockUpdateModelingRegionError(message="Region units are invalid.") |
| 1281 | + if "shape" not in region: |
| 1282 | + raise SherlockUpdateModelingRegionError(message="Shape is missing.") |
| 1283 | + elif not isinstance( |
| 1284 | + region["shape"], |
| 1285 | + ( |
| 1286 | + PolygonalShape, |
| 1287 | + RectangularShape, |
| 1288 | + SlotShape, |
| 1289 | + CircularShape, |
| 1290 | + PCBShape, |
| 1291 | + ), |
| 1292 | + ): |
| 1293 | + raise SherlockUpdateModelingRegionError(message="Shape is not of a valid type.") |
| 1294 | + |
| 1295 | + pcb_model_props = region.get("pcb_model_props", {}) |
| 1296 | + if pcb_model_props: |
| 1297 | + if ( |
| 1298 | + "export_model_type" not in pcb_model_props |
| 1299 | + or pcb_model_props["export_model_type"] == "" |
| 1300 | + ): |
| 1301 | + raise SherlockUpdateModelingRegionError( |
| 1302 | + message="PCB model export type is invalid." |
| 1303 | + ) |
| 1304 | + if "elem_order" not in pcb_model_props or pcb_model_props["elem_order"] == "": |
| 1305 | + raise SherlockUpdateModelingRegionError( |
| 1306 | + message="PCB element order is invalid." |
| 1307 | + ) |
| 1308 | + if "max_mesh_size" not in pcb_model_props or not isinstance( |
| 1309 | + pcb_model_props["max_mesh_size"], float |
| 1310 | + ): |
| 1311 | + raise SherlockUpdateModelingRegionError( |
| 1312 | + message="PCB max mesh size is invalid." |
| 1313 | + ) |
| 1314 | + if "quads_preferred" not in pcb_model_props or not isinstance( |
| 1315 | + pcb_model_props["quads_preferred"], bool |
| 1316 | + ): |
| 1317 | + raise SherlockUpdateModelingRegionError( |
| 1318 | + message="PCB quads preferred is invalid." |
| 1319 | + ) |
| 1320 | + |
| 1321 | + trace_model_props = region.get("trace_model_props", {}) |
| 1322 | + if trace_model_props: |
| 1323 | + if ( |
| 1324 | + "trace_model_type" not in trace_model_props |
| 1325 | + or trace_model_props["trace_model_type"] == "" |
| 1326 | + ): |
| 1327 | + raise SherlockUpdateModelingRegionError( |
| 1328 | + message="Trace model type is invalid." |
| 1329 | + ) |
| 1330 | + |
| 1331 | + if not self._is_connection_up(): |
| 1332 | + LOG.error("There is no connection to a gRPC service.") |
| 1333 | + return |
| 1334 | + |
| 1335 | + update_modeling_region_request = SherlockLayerService_pb2.UpdateModelingRegionRequest() |
| 1336 | + update_modeling_region_request.project = project |
| 1337 | + |
| 1338 | + for region_request in modeling_regions: |
| 1339 | + modeling_region = update_modeling_region_request.modelingRegions.add() |
| 1340 | + modeling_region.ccaName = region_request["cca_name"] |
| 1341 | + modeling_region.regionId = region_request["region_id"] |
| 1342 | + modeling_region.regionUnits = region_request["region_units"] |
| 1343 | + modeling_region.modelMode = ModelingRegion.ModelingMode.Value( |
| 1344 | + region_request["model_mode"] |
| 1345 | + ) |
| 1346 | + |
| 1347 | + shape = region_request["shape"] |
| 1348 | + if isinstance(shape, PolygonalShape): |
| 1349 | + polygonal_shape = modeling_region.polygonalShape |
| 1350 | + for point in shape.points: |
| 1351 | + polygonal_point = polygonal_shape.points.add() |
| 1352 | + polygonal_point.x = point[0] |
| 1353 | + polygonal_point.y = point[1] |
| 1354 | + polygonal_shape.rotation = shape.rotation |
| 1355 | + elif isinstance(shape, RectangularShape): |
| 1356 | + rectangular_shape = modeling_region.rectangularShape |
| 1357 | + rectangular_shape.length = shape.length |
| 1358 | + rectangular_shape.width = shape.width |
| 1359 | + rectangular_shape.centerX = shape.center_x |
| 1360 | + rectangular_shape.centerY = shape.center_y |
| 1361 | + rectangular_shape.rotation = shape.rotation |
| 1362 | + elif isinstance(shape, SlotShape): |
| 1363 | + slot_shape = modeling_region.slotShape |
| 1364 | + slot_shape.length = shape.length |
| 1365 | + slot_shape.width = shape.width |
| 1366 | + slot_shape.nodeCount = shape.node_count |
| 1367 | + slot_shape.centerX = shape.center_x |
| 1368 | + slot_shape.centerY = shape.center_y |
| 1369 | + slot_shape.rotation = shape.rotation |
| 1370 | + elif isinstance(shape, CircularShape): |
| 1371 | + circular_shape = modeling_region.circularShape |
| 1372 | + circular_shape.diameter = shape.diameter |
| 1373 | + circular_shape.nodeCount = shape.node_count |
| 1374 | + circular_shape.centerX = shape.center_x |
| 1375 | + circular_shape.centerY = shape.center_y |
| 1376 | + circular_shape.rotation = shape.rotation |
| 1377 | + |
| 1378 | + ExportModelType = ModelingRegion.PCBModelingProperties.ExportModelType |
| 1379 | + pcb_model_props = region_request.get("pcb_model_props", {}) |
| 1380 | + modeling_region.pcbModelProps.exportModelType = getattr( |
| 1381 | + ExportModelType, |
| 1382 | + pcb_model_props["export_model_type"], |
| 1383 | + ) |
| 1384 | + modeling_region.pcbModelProps.elemOrder = getattr( |
| 1385 | + ModelingRegion.ElementOrder, |
| 1386 | + pcb_model_props["elem_order"], |
| 1387 | + ) |
| 1388 | + modeling_region.pcbModelProps.maxMeshSize = pcb_model_props["max_mesh_size"] |
| 1389 | + modeling_region.pcbModelProps.maxMeshSizeUnits = pcb_model_props[ |
| 1390 | + "max_mesh_size_units" |
| 1391 | + ] |
| 1392 | + modeling_region.pcbModelProps.quadsPreferred = pcb_model_props["quads_preferred"] |
| 1393 | + |
| 1394 | + TraceModelingType = ModelingRegion.TraceModelingProperties.TraceModelingType |
| 1395 | + trace_model_props = region_request.get("trace_model_props", {}) |
| 1396 | + modeling_region.traceModelProps.traceModelType = getattr( |
| 1397 | + TraceModelingType, |
| 1398 | + trace_model_props["trace_model_type"], |
| 1399 | + ) |
| 1400 | + if "elem_order" in trace_model_props: |
| 1401 | + modeling_region.traceModelProps.elemOrder = getattr( |
| 1402 | + ModelingRegion.ElementOrder, |
| 1403 | + trace_model_props["elem_order"], |
| 1404 | + ) |
| 1405 | + if "trace_mesh_size" in trace_model_props: |
| 1406 | + modeling_region.traceModelProps.traceMeshSize = trace_model_props[ |
| 1407 | + "trace_mesh_size" |
| 1408 | + ] |
| 1409 | + if "trace_mesh_size_units" in trace_model_props: |
| 1410 | + modeling_region.traceModelProps.traceMeshSizeUnits = trace_model_props[ |
| 1411 | + "trace_mesh_size_units" |
| 1412 | + ] |
| 1413 | + |
| 1414 | + if "region_id_replacement" in region_request: |
| 1415 | + modeling_region.regionIdReplacement = region_request["region_id_replacement"] |
| 1416 | + |
| 1417 | + return_code = self.stub.updateModelingRegion(update_modeling_region_request) |
| 1418 | + if return_code.value != 0: |
| 1419 | + raise SherlockUpdateModelingRegionError(message=return_code.message) |
| 1420 | + |
| 1421 | + return return_code.value |
| 1422 | + |
| 1423 | + except SherlockUpdateModelingRegionError as e: |
| 1424 | + LOG.error(str(e)) |
| 1425 | + raise e |
0 commit comments