diff --git a/doc/changelog.d/2129.added.md b/doc/changelog.d/2129.added.md new file mode 100644 index 0000000000..8a51f6866d --- /dev/null +++ b/doc/changelog.d/2129.added.md @@ -0,0 +1 @@ +Component operations - make_independent() and import_named_selections() \ No newline at end of file diff --git a/src/ansys/geometry/core/designer/component.py b/src/ansys/geometry/core/designer/component.py index 767672c757..31929a12a8 100644 --- a/src/ansys/geometry/core/designer/component.py +++ b/src/ansys/geometry/core/designer/component.py @@ -37,6 +37,8 @@ from ansys.api.geometry.v0.commands_pb2_grpc import CommandsStub from ansys.api.geometry.v0.components_pb2 import ( CreateRequest, + ImportGroupsRequest, + MakeIndependentRequest, SetPlacementRequest, SetSharedTopologyRequest, ) @@ -70,6 +72,7 @@ from ansys.geometry.core.math.matrix import Matrix44 from ansys.geometry.core.math.point import Point3D from ansys.geometry.core.math.vector import UnitVector3D, Vector3D +from ansys.geometry.core.misc.auxiliary import get_design_from_component from ansys.geometry.core.misc.checks import ( ensure_design_is_active, graphics_required, @@ -1876,3 +1879,43 @@ def build_parent_tree(comp: Component, parent_tree: str = "") -> str: lines.extend([f"|{'-' * (indent - 1)}(comp) {comp.name}" for comp in comps]) return lines if return_list else print("\n".join(lines)) + + @protect_grpc + @min_backend_version(26, 1, 0) + def import_named_selections(self) -> None: + """Import named selections of a component. + + When a design is inserted, it becomes a component. From 26R1 onwards, the named selections + of that component will be imported by default. If a file is opened that contains a + component that did not have its named selections imported, this method can be used to + import them. + + Warnings + -------- + This method is only available starting on Ansys release 26R1. + """ + self._component_stub.ImportGroups(ImportGroupsRequest(id=self._grpc_id)) + + design = get_design_from_component(self) + design._update_design_inplace() + + @protect_grpc + @min_backend_version(26, 1, 0) + def make_independent(self, others: list["Component"] = None) -> None: + """Make a component independent if it is an instance. + + If a component is an instance of another component, modifying one component modifies both. + When a component is made independent, it is no longer associated with other instances and + can be modified separately. + + Parameters + ---------- + others : list[Component], default: None + Optionally include multiple components to make them all independent. + + Warnings + -------- + This method is only available starting on Ansys release 26R1. + """ + ids = [self._grpc_id, *[o._grpc_id for o in others or []]] + self._component_stub.MakeIndependent(MakeIndependentRequest(ids=ids)) diff --git a/tests/integration/files/cars.scdocx b/tests/integration/files/cars.scdocx new file mode 100644 index 0000000000..fd406ea6a7 Binary files /dev/null and b/tests/integration/files/cars.scdocx differ diff --git a/tests/integration/files/import_component_groups.scdocx b/tests/integration/files/import_component_groups.scdocx new file mode 100644 index 0000000000..248c596401 Binary files /dev/null and b/tests/integration/files/import_component_groups.scdocx differ diff --git a/tests/integration/test_design.py b/tests/integration/test_design.py index d487f00399..b20a3c8357 100644 --- a/tests/integration/test_design.py +++ b/tests/integration/test_design.py @@ -3548,3 +3548,33 @@ def test_extrude_edges_missing_parameters(modeler: Modeler): from_point=None, direction=None, ) + + +def test_import_component_named_selections(modeler: Modeler): + """Test importing named selections from an inserted design component.""" + # This file had a component inserted into it that has named selections that we need to import + design = modeler.open_file(Path(FILES_DIR, "import_component_groups.scdocx")) + component = design.components[0] + + assert len(design.named_selections) == 0 + component.import_named_selections() + assert len(design.named_selections) == 3 + + +def test_component_make_independent(modeler: Modeler): + """Test making components independent.""" + + design = modeler.open_file(Path(FILES_DIR, "cars.scdocx")) + face = next((ns for ns in design.named_selections if ns.name == "to_pull"), None).faces[0] + comp = next( + (ns for ns in design.named_selections if ns.name == "make_independent"), None + ).components[0] + + comp.make_independent() + + assert Accuracy.length_is_equal(comp.bodies[0].volume.m, face.body.volume.m) + + modeler.geometry_commands.extrude_faces(face, 1) + comp = design.components[0].components[-1].components[-1] # stale from update-design-in-place + + assert not Accuracy.length_is_equal(comp.bodies[0].volume.m, face.body.volume.m)