Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
1d4aa8d
Add create named selection and get obejcts from named selections
gmalinve Jun 24, 2026
e70435e
chore: adding changelog file 7832.added.md [dependabot-skip]
pyansys-ci-bot Jun 24, 2026
ab68551
add tests to create and get objs in named selection
gmalinve Jun 24, 2026
bad335e
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jun 24, 2026
205c3d4
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jun 30, 2026
2af6278
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jun 30, 2026
904fbe7
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jul 1, 2026
d15e490
add new NamedSelection
gmalinve Jul 3, 2026
7523388
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jul 3, 2026
942c08b
chore: adding changelog file 7832.added.md [dependabot-skip]
pyansys-ci-bot Jul 3, 2026
37f068f
update tests
gmalinve Jul 3, 2026
056c1a7
Add example docstrings
gmalinve Jul 3, 2026
3c3da60
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jul 3, 2026
e7b1597
Add example docstrings
gmalinve Jul 3, 2026
7094dde
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jul 6, 2026
e8f3b6d
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jul 6, 2026
1ce50de
fix icepak tests
gmalinve Jul 6, 2026
de647ce
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jul 7, 2026
b2052d7
remove try/except
gmalinve Jul 7, 2026
02ffc72
remove try/except
gmalinve Jul 7, 2026
9128a29
add AEDT version check
gmalinve Jul 8, 2026
ecf8824
pragma no cover
gmalinve Jul 8, 2026
664ed24
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jul 20, 2026
06c412f
Merge branch 'main' into feat/create_get_named_selections
eblanco-ansys Jul 21, 2026
e481b48
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jul 21, 2026
1d649a6
add warning messages to List methods and update new named selections …
gmalinve Jul 22, 2026
edeb8ab
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jul 22, 2026
40a2b4d
add tests for named selection methods
gmalinve Jul 22, 2026
08e9c35
update docstring
gmalinve Jul 22, 2026
463bdde
update docstrings and logic
gmalinve Jul 22, 2026
2d3d2f8
updates in delete and rename
gmalinve Jul 23, 2026
2a9b2cf
update test
gmalinve Jul 23, 2026
0f37cd8
update implementation
gmalinve Jul 24, 2026
85e5796
updates for faces selection
gmalinve Jul 27, 2026
8b90d6a
updates for faces selection
gmalinve Jul 27, 2026
6ec5f91
Merge branch 'refs/heads/main' into feat/create_get_named_selections
gmalinve Jul 27, 2026
42c7d33
fix UT
gmalinve Jul 27, 2026
ddca879
Merge branch 'main' into feat/create_get_named_selections
gmalinve Jul 27, 2026
991f641
fix test
gmalinve Jul 27, 2026
2d4d2aa
fix test
gmalinve Jul 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/changelog.d/7832.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add new class for named selections
252 changes: 252 additions & 0 deletions src/ansys/aedt/core/modeler/cad/modeler.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

from __future__ import annotations

import warnings

from ansys.aedt.core.base import PyAedtBase
from ansys.aedt.core.generic.data_handlers import _dict2arg
from ansys.aedt.core.generic.file_utils import generate_unique_name
Expand All @@ -39,6 +41,7 @@
from ansys.aedt.core.generic.general_methods import settings
from ansys.aedt.core.generic.numbers_utils import _units_assignment
from ansys.aedt.core.generic.quaternion import Quaternion
from ansys.aedt.core.internal.errors import AEDTRuntimeError
from ansys.aedt.core.modeler.cad.elements_3d import EdgePrimitive
from ansys.aedt.core.modeler.cad.elements_3d import FacePrimitive
from ansys.aedt.core.modeler.cad.elements_3d import VertexPrimitive
Expand Down Expand Up @@ -1890,6 +1893,12 @@ class Lists(PropsManager, PyAedtBase):
"""

def __init__(self, modeler, props=None, name: str | None = None) -> None:
# Deprecated: Lists will be replaced by NamedSelections in future releases.
Comment thread
gmalinve marked this conversation as resolved.
Outdated
warnings.warn(
"`Lists` is deprecated and will be removed in future releases. Use `NamedSelections` instead.",
DeprecationWarning,
stacklevel=2,
)
self.auto_update = True
self._modeler = modeler
self.name = name
Expand Down Expand Up @@ -2072,6 +2081,249 @@ def _list_verification(self, object_list, list_type):
return object_list_new


class NamedSelections(PropsManager, PyAedtBase):
"""Manages Named Selections (replacement for `Lists`).

Keeps create and delete behavior and provides an ``update`` method that wraps
the native ``oEditor.EditNamedSelection`` call.
"""

def __init__(self, modeler, props=None, name: str | None = None) -> None:
self.auto_update = True
self._modeler = modeler
self.name = name
# Reuse ListsProps for the simple properties structure
self.props = ListsProps(self, props)

@pyaedt_function_handler()
def create(
self, assignment: list | str | None = None, name: str | None = None, entity_type: str = "Object"
) -> bool:
"""Create a named selection.

Parameters
----------
assignment : list or str, optional
List of object names or face ids or a comma-separated string.
name : str, optional
Name of the named selection. If not provided a unique name is generated.
entity_type : str optional
Type of the selection: ``"Object"`` or ``"Face"``. Default is ``"Object"``.

Examples
--------
>>> from ansys.aedt.core.modeler.cad.modeler import NamedSelections
>>> m3d = Maxwell3d(version="2026.1")
>>> box1 = m3d.modeler.create_box([1, 1, 1], [5, 2, 5], name="box1")
Create a new instance of NamedSelections
>>> lst1 = NamedSelections(m3d.modeler)
Create a named selection by specifying assignment and entity type
>>> lst1.create(assignment=["box1"], name="my_list", entity_type="Object")
>>> m3d.release_desktop(False, False)

References
----------
>>> oEditor.CreateNamedSelection
"""
if not name:
name = generate_unique_name(entity_type + "NamedSelection")

user_list_names = [sel for sel in self._modeler.user_lists if sel.name == name]
if name in user_list_names:
raise ValueError(f"Named selection with name '{name}' already exists.")

# Normalize selection
if isinstance(assignment, (list, tuple)):
if all(isinstance(x, int) for x in assignment):
selection = assignment
sel_type = "Face"
else:
selection = ", ".join([str(x) for x in assignment])
sel_type = entity_type
elif isinstance(assignment, str):
selection = assignment
sel_type = entity_type
else:
selection = ""
sel_type = entity_type

params = ["NAME:NamedSelectionParameters", "Type:=", sel_type, "Selection:=", selection]
attr = ["NAME:Attributes", "Name:=", name, "UDM ID:=", -1]
try:
self._modeler.oeditor.CreateNamedSelection(params, attr)
except Exception:
raise AEDTRuntimeError("Failed to create named selection")

props = {}
props["Selection"] = selection
props["Type"] = sel_type
self.props = ListsProps(self, props)
# Keep compatibility with existing storage
try:
self._modeler.user_lists.append(self)
except Exception:
pass
self.name = name
return True

@pyaedt_function_handler()
def delete(self) -> bool:
"""Delete the named selection.

Examples
--------
>>> from ansys.aedt.core import Maxwell3d
>>> m3d = Maxwell3d(version="2026.1")
>>> box1 = m3d.modeler.create_box([1, 1, 1], [5, 2, 5], name="box1")
Create Objects list and delete it afterward
>>> lst = m3d.modeler.create_object_list(assignment=["box1"], name="my_list")
>>> lst.delete()
>>> m3d.release_desktop(False, False)

References
----------
>>> oEditor.Delete
"""
self._modeler.oeditor.Delete(["NAME:Selections", "Selections:=", self.name])
try:
self._modeler.user_lists.remove(self)
except Exception:
pass
return True

@pyaedt_function_handler()
def rename(self, name: str) -> bool:
"""Rename the named selection.

Parameters
----------
name : str
New name for the named selection.

Examples
--------
>>> from ansys.aedt.core import Maxwell3d
>>> m3d = Maxwell3d(version="2026.1")
>>> box1 = m3d.modeler.create_box([1, 1, 1], [5, 2, 5], name="box1")
Create Objects list and rename it afterward
>>> lst = m3d.modeler.create_object_list(assignment=["box1"], name="my_list")
>>> lst.rename(name="new_list")
>>> m3d.release_desktop(False, False)

Returns
-------
bool
``True`` when successful, ``False`` when failed.

References
----------
>>> oEditor.ChangeProperty
"""
argument = [
"NAME:AllTabs",
[
"NAME:Geometry3DListTab",
["NAME:PropServers", self.name],
["NAME:ChangedProps", ["NAME:Name", "Value:=", name]],
],
]
self._modeler.oeditor.ChangeProperty(argument)
self.name = name
return True

@pyaedt_function_handler()
def update(self, selection: list | str | None = None, entity_type: str = "Object", mode: str = "Reassign") -> bool:
"""Update an existing named selection.

This method mirrors the signature and semantics of :class:`Lists.update` for
backward compatibility. If ``selection`` is ``None``, the stored properties
in ``self.props`` are used.

Parameters
----------
selection : str or list, optional
Comma-separated string of object names or a list of names/ids. If
``None``, uses the selection stored in ``self.props["Selection"]``.
entity_type : str, optional
Type of selection, e.g. ``"Object"`` or ``"Face"``. Default ``"Object"``.
mode : str, optional
Edit mode for the named selection.
Options are: ``"Reassign"``, ``"Add"`,``"Remove"``.
The default value is ``"Reassign"``.

Examples
--------
>>> from ansys.aedt.core import Maxwell3d
>>> m3d = Maxwell3d(version="2026.1")
>>> box1 = m3d.modeler.create_box([1, 1, 1], [5, 2, 5], name="box1")
>>> box2 = m3d.modeler.create_box([2, 2, 2], [5, 2, 5], name="box2")
>>> box3 = m3d.modeler.create_box([3, 3, 3], [5, 2, 5], name="box3")
Create objects list
>>> lst = m3d.modeler.create_object_list(assignment=["box1"], name="my_list")
Add box2 in the NamedSelection "my_list"
>>> lst.update(selection=[m3d.modeler["box2"]], entity_type="Object", mode="Add")
Remove box2 in the NamedSelection "my_list"
>>> lst.update(selection=[m3d.modeler["box2"]], entity_type="Object", mode="Remove")
Reassign box2 in the NamedSelection "my_list"
>>> lst.update(selection=[m3d.modeler["box2"]], entity_type="Object", mode="Reassign")
>>> m3d.release_desktop(False, False)

References
----------
>>> oEditor.EditNamedSelection
"""
# If no selection provided, use stored properties
if selection is None:
selection = self.props.get("Selection", "")
entity_type = self.props.get("Type", entity_type)

# If caller provided a list, normalize using Lists._list_verification to keep
# behavior consistent with Lists.update
if isinstance(selection, (list, tuple)):
try:
object_list_new = Lists._list_verification(self, selection, entity_type)
except Exception:
# Fallback to simple string conversion if verification fails
selection = ", ".join([str(s) for s in selection])
else:
if entity_type == "Object":
selection = ", ".join(object_list_new)
else:
# For faces, keep a list of ints as EditNamedSelection accepts it
selection = object_list_new

# If selection is a string, leave it as-is

argument1 = ["NAME:Selections", "Selections:=", self.name]
argument2 = [
"NAME:NamedSelectionParameters",
"Type:=",
entity_type,
"Selection:=",
selection,
"Mode:=",
mode,
]
try:
self._modeler.oeditor.EditNamedSelection(argument1, argument2)
except Exception:
raise ValueError("Failed to update named selection")

# Update stored props to reflect the new selection/type when provided
try:
# self.props calls __setitem__ and internally calls update()
# auto_update needs to be disabled
previous_auto_update = self.auto_update
self.auto_update = False
self.props["Selection"] = selection
self.props["Type"] = entity_type
self.auto_update = previous_auto_update
except Exception:
pass

return True


class Modeler(PyAedtBase):
"""Provides the `Modeler` application class that other `Modeler` classes inherit.

Expand Down
Loading
Loading