Skip to content

Commit

Permalink
Insert Layout component (#2968)
Browse files Browse the repository at this point in the history
* Read Layout component in User defined component class

* Insert Layout Component

* Add unittest

* Add example

* Fix bug

* Fix UT and codevoc

* Fix UT
  • Loading branch information
Samuelopez-ansys authored May 5, 2023
1 parent e187f8d commit 4b9d1a8
Show file tree
Hide file tree
Showing 7 changed files with 336 additions and 3 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ironpython.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ jobs:
Set-Item -Path env:ANSYSEM_FEATURE_SF159726_SCRIPTOBJECT_ENABLE -Value "1"
Set-Item -Path env:ANSYSEM_FEATURE_SF222134_CABLE_MODELING_ENHANCEMENTS_ENABLE -Value "1"
Set-Item -Path env:ANSYSEM_FEATURE_F395486_RIGID_FLEX_BENDING_ENABLE -Value "1"
Set-Item -Path env:ANSYSEM_FEATURE_S432616_LAYOUT_COMPONENT_IN_3D_ENABLE -Value "1"
$processA = start-process 'cmd' -ArgumentList '/c .\_unittest_ironpython\run_unittests_batchmode.cmd --test-filter test_0*.py' -PassThru
$processB = start-process 'cmd' -ArgumentList '/c .\_unittest_ironpython\run_unittests_batchmode.cmd --test-filter test_1*.py' -PassThru
$processC = start-process 'cmd' -ArgumentList '/c .\_unittest_ironpython\run_unittests_batchmode.cmd --test-filter test_2*.py' -PassThru
Expand Down
Binary file not shown.
28 changes: 28 additions & 0 deletions _unittest/test_08_Primitives3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
step = "input.stp"
component3d = "new.a3dcomp"
encrypted_cylinder = "encrypted_cylinder.a3dcomp"
layout_comp = "Layoutcomponent_231.aedbcomp"
test_subfolder = "T08"
if config["desktopVersion"] > "2022.2":
assembly = "assembly_231"
Expand Down Expand Up @@ -57,6 +58,7 @@ def setup_class(self):
self.flatten = BasisTest.add_app(self, project_name=components_flatten, subfolder=test_subfolder)
test_54b_project = os.path.join(local_path, "example_models", test_subfolder, polyline + ".aedt")
self.test_54b_project = self.local_scratch.copyfile(test_54b_project)
self.layout_component = os.path.join(local_path, "example_models", test_subfolder, layout_comp)

def teardown_class(self):
BasisTest.my_teardown(self)
Expand Down Expand Up @@ -1731,3 +1733,29 @@ def test_84_replace_3dcomponent(self):
object_list=[box2.name],
)
assert len(self.aedtapp.modeler.user_defined_components) == 2

@pytest.mark.skipif(
config["desktopVersion"] < "2023.1" or is_ironpython, reason="Method available in beta from 2023.1"
)
def test_85_insert_layoutcomponent(self):
self.aedtapp.insert_design("LayoutComponent")
self.aedtapp.solution_type = "Modal"
assert not self.aedtapp.modeler.insert_layout_component(
self.layout_component, name=None, parameter_mapping=False
)
self.aedtapp.solution_type = "Terminal"
comp = self.aedtapp.modeler.insert_layout_component(self.layout_component, name=None, parameter_mapping=False)
assert isinstance(comp, UserDefinedComponent)
assert len(self.aedtapp.modeler.modeler.user_defined_components[comp.name].parts) == 3
comp2 = self.aedtapp.modeler.insert_layout_component(
self.layout_component, name="new_layout", parameter_mapping=True
)
assert isinstance(comp2, UserDefinedComponent)
assert len(comp2.parameters) == 2
assert comp2.show_layout
comp2.show_layout = False
assert not comp2.show_layout
comp2.show_layout = True
assert comp2.fast_transformation
comp2.fast_transformation = False
assert not comp2.fast_transformation
1 change: 1 addition & 0 deletions pyaedt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
os.environ["ANSYSEM_FEATURE_SF159726_SCRIPTOBJECT_ENABLE"] = "1"
os.environ["ANSYSEM_FEATURE_SF222134_CABLE_MODELING_ENHANCEMENTS_ENABLE"] = "1"
os.environ["ANSYSEM_FEATURE_F395486_RIGID_FLEX_BENDING_ENABLE"] = "1"
os.environ["ANSYSEM_FEATURE_S432616_LAYOUT_COMPONENT_IN_3D_ENABLE"] = "1"

pyaedt_path = os.path.dirname(__file__)

Expand Down
1 change: 1 addition & 0 deletions pyaedt/generic/general_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -1745,6 +1745,7 @@ def __init__(self):
"ANSYSEM_FEATURE_SF159726_SCRIPTOBJECT_ENABLE": "1",
"ANSYSEM_FEATURE_SF222134_CABLE_MODELING_ENHANCEMENTS_ENABLE": "1",
"ANSYSEM_FEATURE_F395486_RIGID_FLEX_BENDING_ENABLE": "1",
"ANSYSEM_FEATURE_S432616_LAYOUT_COMPONENT_IN_3D_ENABLE": "1",
}
if is_linux:
self._aedt_environment_variables["ANS_NODEPCHECK"] = "1"
Expand Down
236 changes: 236 additions & 0 deletions pyaedt/modeler/cad/Primitives3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from math import tan
import os

from pyaedt import Edb
from pyaedt import Icepak
from pyaedt.generic import LoadAEDTFile
from pyaedt.generic.general_methods import _retry_ntimes
Expand Down Expand Up @@ -1426,6 +1427,241 @@ def insert_3d_component(
else:
return udm_obj

@pyaedt_function_handler()
def insert_layout_component(
self,
comp_file,
coordinate_system="Global",
name=None,
parameter_mapping=False,
):
"""Insert a new layout component.
Parameters
----------
comp_file : str
Path of the component file. Either ``".aedb"`` and ``".aedbcomp"`` are allowed.
coordinate_system : str, optional
Target coordinate system. The default is ``"Global"``.
name : str, optional
3D component name. The default is ``None``.
parameter_mapping : bool, optional
Map the layout parameters in the target HFSS design. The default is ``False``.
Returns
-------
:class:`pyaedt.modeler.components_3d.UserDefinedComponent`
User defined component object.
References
----------
>>> oEditor.InsertNativeComponent
Examples
--------
>>> from pyaedt import Hfss
>>> app = Hfss()
>>> layout_component = "path/to/layout_component/component.aedbcomp"
>>> comp = app.modeler.insert_layout_component(layout_component)
"""
if self._app.solution_type != "Terminal" and self._app.solution_type != "TransientAPhiFormulation":
self.logger.warning("Solution type must be terminal in HFSS or APhi in Maxwell")
return False

component_name = os.path.splitext(os.path.basename(comp_file))[0]
aedt_component_name = component_name
if component_name not in self._app.o_component_manager.GetNames():
compInfo = ["NAME:" + str(component_name), "Info:=", []]

compInfo.extend(
[
"CircuitEnv:=",
0,
"Refbase:=",
"U",
"NumParts:=",
1,
"ModSinceLib:=",
True,
"Terminal:=",
[],
"CompExtID:=",
9,
"ModelEDBFilePath:=",
comp_file,
"EDBCompPassword:=",
"",
]
)

aedt_component_name = self._app.o_component_manager.Add(compInfo)

if not name or name in self.modeler.user_defined_component_names:
name = generate_unique_name("LC")

# Open Layout component and get information
aedb_component_path = comp_file
if os.path.splitext(os.path.basename(comp_file))[1] == ".aedbcomp":
aedb_project_path = os.path.join(self._app.project_path, self._app.project_name + ".aedb")
aedb_component_path = os.path.join(
aedb_project_path, "LayoutComponents", aedt_component_name, aedt_component_name + ".aedb"
)
aedb_component_path = aedb_component_path.replace("/", "\\")

component_obj = Edb(
edbpath=aedb_component_path,
isreadonly=True,
edbversion=self._app._aedt_version,
student_version=self._app.student_version,
)

# Extract and map parameters
parameters = {}
for param in component_obj.design_variables:
parameters[param] = [param + "_" + name, component_obj.design_variables[param].value_string]
if parameter_mapping:
self._app[param + "_" + name] = component_obj.design_variables[param].value_string

# Get coordinate systems
component_cs = list(component_obj.components.components.keys())
component_obj.close_edb()

vArg1 = ["NAME:InsertNativeComponentData"]
vArg1.append("TargetCS:=")
vArg1.append(coordinate_system)
vArg1.append("SubmodelDefinitionName:=")
vArg1.append("LC")
varg2 = ["NAME:ComponentPriorityLists"]
vArg1.append(varg2)
vArg1.append("NextUniqueID:=")
vArg1.append(0)
vArg1.append("MoveBackwards:=")
vArg1.append(False)
vArg1.append("DatasetType:=")
vArg1.append("ComponentDatasetType")
varg3 = ["NAME:DatasetDefinitions"]
vArg1.append(varg3)
varg4 = [
"NAME:BasicComponentInfo",
"ComponentName:=",
"LC",
"Company:=",
"",
"Company URL:=",
"",
"Model Number:=",
"",
"Help URL:=",
"",
"Version:=",
"1.0",
"Notes:=",
"",
"IconTypeL:=",
"Layout Component",
]
vArg1.append(varg4)
varg5 = [
"NAME:GeometryDefinitionParameters",
]
if parameters and parameter_mapping:
for param in parameters:
varg5.append("VariableProp:=")
varg5.append([parameters[param][0], "D", "", parameters[param][1]])

varg5.append(["NAME:VariableOrders"])
vArg1.append(varg5)

varg6 = ["NAME:DesignDefinitionParameters", ["NAME:VariableOrders"]]
vArg1.append(varg6)

varg7 = ["NAME:MaterialDefinitionParameters", ["NAME:VariableOrders"]]
vArg1.append(varg7)

vArg1.append("DefReferenceCSID:=")
vArg1.append(1)
vArg1.append("MapInstanceParameters:=")
vArg1.append("DesignVariable")
vArg1.append("UniqueDefinitionIdentifier:=")
vArg1.append("")
vArg1.append("OriginFilePath:=")
vArg1.append("")
vArg1.append("IsLocal:=")
vArg1.append(False)
vArg1.append("ChecksumString:=")
vArg1.append("")
vArg1.append("ChecksumHistory:=")
vArg1.append([])
vArg1.append("VersionHistory:=")
vArg1.append([])

varg8 = ["NAME:VariableMap"]

for param in parameters:
varg8.append(param + ":=")
if parameter_mapping:
varg8.append(parameters[param][0])
else:
varg8.append(parameters[param][1])

varg9 = [
"NAME:NativeComponentDefinitionProvider",
"Type:=",
"Layout Component",
"Unit:=",
"mm",
"Version:=",
1.1,
"EDBDefinition:=",
aedt_component_name,
varg8,
"ReferenceCS:=",
"Global",
"CSToImport:=",
]

if component_cs:
varg10 = component_cs
varg10.append("Global")
else:
varg10 = ["Global"]
varg9.append(varg10)
vArg1.append(varg9)

varg11 = ["NAME:InstanceParameters"]
varg11.append("GeometryParameters:=")

if parameters and parameter_mapping:
varg12 = ""
for param in parameters:
varg12 += " {0}='{1}'".format(parameters[param][0], parameters[param][0])
else:
varg12 = ""
varg11.append(varg12[1:])

varg11.append("MaterialParameters:=")
varg11.append("")
varg11.append("DesignParameters:=")
varg11.append("")
vArg1.append(varg11)

try:
new_object_name = self.oeditor.InsertNativeComponent(vArg1)
udm_obj = False
if new_object_name:
obj_list = list(self.oeditor.Get3DComponentPartNames(new_object_name))
for new_name in obj_list:
self._create_object(new_name)

udm_obj = self._create_user_defined_component(new_object_name)
if name:
udm_obj.name = name
except Exception: # pragma: no cover
udm_obj = False
return udm_obj

@pyaedt_function_handler()
def get_3d_component_object_list(self, componentname):
"""Retrieve all objects belonging to a 3D component.
Expand Down
Loading

0 comments on commit 4b9d1a8

Please sign in to comment.