Skip to content

User lists method #1167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 11, 2022
3 changes: 3 additions & 0 deletions _unittest/test_02_3D_modeler.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ def test_28_create_face_list(self):

def test_28B_create_object_list(self):
assert self.aedtapp.modeler.create_object_list(["Second_airbox"], "my_object_list")
assert self.aedtapp.modeler.create_object_list(["Core", "outer"])
self.aedtapp.modeler.user_lists[2].props["List"] = ["outer"]
assert self.aedtapp.modeler.user_lists[2].delete()

def test_29_create_outer_face_list(self):
assert self.aedtapp.modeler.create_outer_facelist(["Second_airbox"])
Expand Down
2 changes: 2 additions & 0 deletions _unittest/test_98_Icepak.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,11 @@ def test_13a_assign_openings(self):

def test_13b_assign_grille(self):
airfaces = [self.aedtapp.modeler["Region"].top_face_y.id]
self.aedtapp.modeler.user_lists[0].delete()
grille = self.aedtapp.assign_grille(airfaces)
grille.props["Free Area Ratio"] = 0.7
assert grille.update()
self.aedtapp.modeler.user_lists[0].delete()
airfaces = [self.aedtapp.modeler["Region"].bottom_face_x.id]
grille2 = self.aedtapp.assign_grille(
airfaces, free_loss_coeff=False, x_curve=["0", "3", "5"], y_curve=["0", "2", "3"]
Expand Down
300 changes: 275 additions & 25 deletions pyaedt/modeler/Modeler.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,30 @@ def _setitem_without_update(self, key, value):
OrderedDict.__setitem__(self, key, value)


class ListsProps(OrderedDict):
"""AEDT Lists Internal Parameters."""

def __setitem__(self, key, value):
OrderedDict.__setitem__(self, key, value)
if self._pyaedt_lists.auto_update:
res = self._pyaedt_lists.update()
if not res:
self._pyaedt_lists._app.logger.warning("Update of %s Failed. Check needed arguments", key)

def __init__(self, cs_object, props):
OrderedDict.__init__(self)
if props:
for key, value in props.items():
if isinstance(value, (dict, OrderedDict)):
OrderedDict.__setitem__(self, key, CsProps(cs_object, value))
else:
OrderedDict.__setitem__(self, key, value)
self._pyaedt_lists = cs_object

def _setitem_without_update(self, key, value):
OrderedDict.__setitem__(self, key, value)


class BaseCoordinateSystem(object):
"""Base methods common to FaceCoordinateSystem and CoordinateSystem.

Expand Down Expand Up @@ -168,6 +192,67 @@ def rename(self, newname):
return True


class BaseLists(object):
"""Base methods common to UserList.

Parameters
----------
modeler :
Inherited parent object.
props : dict, optional
Dictionary of properties. The default is ``None``.
name : optional
The default is ``None``.

"""

def __init__(self, modeler, name=None):
self.auto_update = True
self._modeler = modeler
self.name = name

@pyaedt_function_handler()
def delete(self):
"""Delete the List.

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

"""
self._modeler.oeditor.Delete(["NAME:Selections", "Selections:=", self.name])
self._modeler.user_lists.remove(self)
return True

@pyaedt_function_handler()
def rename(self, newname):
"""Rename the List.

Parameters
----------
newname : str
New name for the List.

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

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


class FaceCoordinateSystem(BaseCoordinateSystem, object):
"""Manages face coordinate system data and execution.

Expand Down Expand Up @@ -862,6 +947,130 @@ def _attributes(self):
return coordinateSystemAttributes


class Lists(BaseLists, object):
"""Manages Lists data and execution.

Parameters
----------
modeler :
Inherited parent object.
props : dict, optional
Dictionary of properties. The default is ``None``.
name : optional
The default is ``None``.

"""

def __init__(self, modeler, props=None, name=None):
BaseLists.__init__(self, modeler, name)
self.props = ListsProps(self, props)

@pyaedt_function_handler()
def update(self):
"""Update the List.

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

"""
# self._change_property(self.name, ["NAME:ChangedProps", ["NAME:Reference CS", "Value:=", self.ref_cs]])
object_list_new = self.list_verification(self.props["List"], self.props["Type"])

argument1 = ["NAME:Selections", "Selections:=", self.name]
argument2 = [
"NAME:GeometryEntityListParameters",
"EntityType:=",
self.props["Type"],
"EntityList:=",
object_list_new,
]
try:
self._modeler.oeditor.EditEntityList(argument1, argument2)
except: # pragma: no cover
raise ValueError("Input List not correct for the type " + self.props["Type"])

return True

@pyaedt_function_handler()
def create(
self,
object_list,
name=None,
type="Object",
):
"""Create a List.

Parameters
----------
object_list : list
List of ``["Obj1", "Obj2"]`` objects or face ID if type is "Face".
The default is ``None``, in which case all objects are selected.
name : list, str
List of names. The default is ``None``.
type : str, optional
List type. Options are ``"Object"``, ``"Face"``. The default is ``"Object"``.

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

"""

if type != "Object" and type != "Face":
raise ValueError("Specify the type = 'Object' or 'Face'")
if not name:
name = generate_unique_name(type + "List")

object_list_new = self.list_verification(object_list, type)

self.name = self._modeler.oeditor.CreateEntityList(
["NAME:GeometryEntityListParameters", "EntityType:=", type, "EntityList:=", object_list_new],
["NAME:Attributes", "Name:=", name],
)
props = {}
if type == "Object":
props["List"] = object_list
else:
props["List"] = object_list_new

props["ID"] = self._modeler.get_entitylist_id(self.name)
props["Type"] = type

self.props = ListsProps(self, props)
self._modeler.user_lists.append(self)
return True

def list_verification(self, object_list, list_type):
object_list = self._modeler.convert_to_selections(object_list, True)

if list_type == "Object":
object_list_new = ",".join(object_list)
elif list_type == "Face":
object_list_new = []
for element in object_list:
if isinstance(element, str):
if element.isnumeric():
object_list_new.append(int(element))
else:
if element in self._modeler.object_names:
obj_id = self._modeler.object_id_dict[element]
for sel in self._modeler.object_list:
if sel.id == obj_id:
for f in sel.faces:
object_list_new.append(f.id)
break
else:
raise ValueError(element + " is not defined")
else:
object_list_new.append(int(element))
else:
object_list_new = []
return object_list_new


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

Expand Down Expand Up @@ -929,6 +1138,7 @@ def __init__(self, app, is3d=True):
Modeler.__init__(self, app)
# TODO Refactor this as a dictionary with names as key
self.coordinate_systems = self._get_coordinates_data()
self.user_lists = self._get_lists_data()
self._is3d = is3d

@property
Expand Down Expand Up @@ -1109,6 +1319,29 @@ def _get_coordinates_data(self):
pass
return coord

def _get_lists_data(self):
"""Retrieve user object list data.

Returns
-------
[Dict with List information]
"""
design_lists = []
key1 = "GeometryOperations"
key2 = "GeometryEntityLists"
key3 = "GeometryEntityListOperation"
try:
for data in self._app.design_properties["ModelSetup"]["GeometryCore"][key1][key2][key3]:
props = {}
name = data["Attributes"]["Name"]
props["ID"] = data["ID"]
props["Type"] = data["GeometryEntityListParameters"]["EntityType"]
props["List"] = data["GeometryEntityListParameters"]["EntityList"]
design_lists.append(Lists(self, props, name))
except:
pass
return design_lists

def __get__(self, instance, owner):
self._app = instance
return self
Expand Down Expand Up @@ -3235,15 +3468,15 @@ def edit_region_dimensions(self, listvalues):
return True

@pyaedt_function_handler()
def create_face_list(self, fl, name):
"""Create a list of faces given a list of face names.
def create_face_list(self, face_list, name=None):
"""Create a list of faces given a list of face ID or a list of objects.

Parameters
----------
fl : list
List of face names.
face_list : list
List of face ID or list of objects

name : str
name : str, optional
Name of the new list.

Returns
Expand All @@ -3256,43 +3489,60 @@ def create_face_list(self, fl, name):

>>> oEditor.CreateEntityList
"""
fl = self.convert_to_selections(fl, True)
self.oeditor.CreateEntityList(
["NAME:GeometryEntityListParameters", "EntityType:=", "Face", "EntityList:=", fl],
["NAME:Attributes", "Name:=", name],
)
self.logger.info("Face List " + name + " created")
return True
if name:
list_names = [i.name for i in self.user_lists]
if name in list_names:
raise AttributeError("A List with the specified name already exists!")
face_list = self.convert_to_selections(face_list, True)
user_list = Lists(self)
list_type = "Face"
if user_list:
result = user_list.create(
object_list=face_list,
name=name,
type=list_type,
)
if result:
return result
return False

@pyaedt_function_handler()
def create_object_list(self, fl, name):
def create_object_list(self, object_list, name=None):
"""Create an object list given a list of object names.

Parameters
----------
fl : list
object_list : list
List of object names.
name : str
name : str, optional
Name of the new object list.

Returns
-------
int
ID of the new object list.
bool
``True`` when successful, ``False`` when failed.

References
----------

>>> oEditor.CreateEntityList
"""
listf = ",".join(fl)
self.oeditor.CreateEntityList(
["NAME:GeometryEntityListParameters", "EntityType:=", "Object", "EntityList:=", listf],
["NAME:Attributes", "Name:=", name],
)
self.logger.info("Object List " + name + " created")

return self.get_entitylist_id(name)
if name:
list_names = [i.name for i in self.user_lists]
if name in list_names:
raise AttributeError("A List with the specified name already exists!")
object_list = self.convert_to_selections(object_list, True)
user_list = Lists(self)
list_type = "Object"
if user_list:
result = user_list.create(
object_list=object_list,
name=name,
type=list_type,
)
if result:
return result
return False

@pyaedt_function_handler()
def generate_object_history(self, objectname):
Expand Down