From cc987dcd9b8c7816866df5b3bc45e411aa9ff501 Mon Sep 17 00:00:00 2001 From: afernand Date: Thu, 5 Dec 2024 13:02:42 +0100 Subject: [PATCH 1/7] feat: Integrate geometry imports --- .../gallery/10_wheel_ground_contact_patch.py | 4 +- examples/gallery/12_import_from_pygeometry.py | 89 +++++++++++++++++++ src/ansys/meshing/prime/lucid/mesh_util.py | 41 +++++++++ 3 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 examples/gallery/12_import_from_pygeometry.py diff --git a/examples/gallery/10_wheel_ground_contact_patch.py b/examples/gallery/10_wheel_ground_contact_patch.py index e11002185a..b0bc991cd5 100644 --- a/examples/gallery/10_wheel_ground_contact_patch.py +++ b/examples/gallery/10_wheel_ground_contact_patch.py @@ -170,7 +170,7 @@ ############################################################################### # Wrap the fluid region -# ~~~~~~~~~~~~~~~~~~~~~ +# c # The largest internal region in this instance is the fluid region around the wheel. # Intersection loops are created to capture the features at the corners between the # patch, ground, and wheel. @@ -192,7 +192,7 @@ ######################### # Open a pyvistaqt window -# ======================= +# ~~~~~~~~~~~~~~~~~~~~~~~ # .. code-block:: python # # display = PrimePlotter() diff --git a/examples/gallery/12_import_from_pygeometry.py b/examples/gallery/12_import_from_pygeometry.py new file mode 100644 index 0000000000..62d2aa85c5 --- /dev/null +++ b/examples/gallery/12_import_from_pygeometry.py @@ -0,0 +1,89 @@ +# Copyright (C) 2024 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +""" +.. _ref_pygeometry_import: + +================================= +Import a geometry from PyGeometry +================================= + +**Summary**: This example demonstrates how to create a simple geometry using +PyGeometry and import it into PyPrimeMesh. + + + +Procedure +~~~~~~~~~ +#. Launch Ansys Prime Server. +#. Create a CAD geometry with PyGeometry. +#. Import the geometry into PyPrimeMesh. +#. Exit the PyPrimeMesh session. + +""" + +##################### +# Create the geometry +# ~~~~~~~~~~~~~~~~~~~ +# First we create a simple geometry using PyGeometry. The geometry is a plate +# with a hole in the center. +# .. code-block:: python +# from pint import Quantity +# +# from ansys.geometry.core import launch_modeler +# from ansys.geometry.core.math import Point2D +# from ansys.geometry.core.misc import UNITS +# from ansys.geometry.core.sketch import Sketch +# from ansys.geometry.core.math import Point2D +# sketch = Sketch() +# (sketch.segment(Point2D([-4, 5], unit=UNITS.m), Point2D([4, 5], unit=UNITS.m)) +# .segment_to_point(Point2D([4, -5], unit=UNITS.m)) +# .segment_to_point(Point2D([-4, -5], unit=UNITS.m)) +# .segment_to_point(Point2D([-4, 5], unit=UNITS.m)) +# .box(Point2D([0,0], unit=UNITS.m), Quantity(3, UNITS.m), Quantity(3, UNITS.m)) +# ) +# modeler = launch_modeler(hidden=True) +# design = modeler.create_design("ExtrudedPlateNoHoles") +# body = design.extrude_sketch(f"PlateLayer", sketch, Quantity(2, UNITS.m)) + +###################################### +# Import the geometry into PyPrimeMesh +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Once the geometry is created, we can pass the Design object to PyPrimeMesh to +# create a mesh. +# .. code-block:: python +# import ansys.meshing.prime as prime +# from ansys.meshing.prime.graphics.plotter import PrimePlotter +# prime_client = prime.launch_prime() +# model = prime_client.model +# mesh_util = prime.lucid.Mesh(model=model) + +################################## +# Mesh the geometry and display it +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# With the geometry imported, we can now mesh it and display the mesh. +# .. code-block:: python +# mesh_util.surface_mesh(min_size=0.1, max_size=0.5) +# display = PrimePlotter() +# display.plot(model) +# display.show() +# modeler.close() diff --git a/src/ansys/meshing/prime/lucid/mesh_util.py b/src/ansys/meshing/prime/lucid/mesh_util.py index 0788d0b042..0975d551bc 100644 --- a/src/ansys/meshing/prime/lucid/mesh_util.py +++ b/src/ansys/meshing/prime/lucid/mesh_util.py @@ -23,6 +23,7 @@ """Module for meshing utility functions.""" import enum import os +import tempfile from typing import Iterable, List import ansys.meshing.prime as prime @@ -31,6 +32,18 @@ from .utils import check_name_pattern +class ImportTypes(enum.Enum): + """Allowed geometry import types.""" + + PMDB = 0 + FMD = 1 + IGES = 2 + STEP = 3 + PARA_BIN = 4 + PARA_TEXT = 5 + SCDOCX = 6 + + class LabelToZoneMethod(enum.IntEnum): """Provides for creating zones from labels.""" @@ -69,6 +82,34 @@ def __init__(self, model: prime.Model): self._model = model self._logger = model.python_logger + def from_geometry( + self, design: "ansys.geometry.core.Design", import_type: ImportTypes = ImportTypes.FMD + ): + """Import geometry from an Ansys Design object. + + Parameters + ---------- + design : ansys.geometry.core.Design + Ansys Design object to import geometry from. + import_type : ImportTypes, optional + Type of import. The default is ImportTypes.FMD. + """ + with tempfile.TemporaryDirectory() as tmpdir: + file_path = os.path.join(tmpdir) + if import_type == ImportTypes.FMD: + design.export_to_fmd(file_path) + elif import_type == ImportTypes.IGES: + design.export_to_iges(file_path) + elif import_type == ImportTypes.STEP: + design.export_to_step(file_path) + elif import_type == ImportTypes.PARA_BIN: + design.export_to_parasolid_bin(file_path) + elif import_type == ImportTypes.PARA_TEXT: + design.export_to_parasolid_text(file_path) + elif import_type == ImportTypes.SCDOCX: + design.export_to_scdocx(file_path) + self.read(str(file_path)) + def read( self, file_name: str, append: bool = False, cad_reader_route: prime.CadReaderRoute = None ): From 43f255086ce86825b6785fb451c2971505785a15 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Thu, 5 Dec 2024 12:06:41 +0000 Subject: [PATCH 2/7] chore: adding changelog file 952.added.md [dependabot-skip] --- doc/changelog.d/952.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/952.added.md diff --git a/doc/changelog.d/952.added.md b/doc/changelog.d/952.added.md new file mode 100644 index 0000000000..b7e8642e75 --- /dev/null +++ b/doc/changelog.d/952.added.md @@ -0,0 +1 @@ +feat: Integrate geometry imports \ No newline at end of file From 0431528ab0108da6547e0956547353743a90cde9 Mon Sep 17 00:00:00 2001 From: afernand Date: Thu, 5 Dec 2024 13:09:03 +0100 Subject: [PATCH 3/7] fix: RST format --- examples/gallery/10_wheel_ground_contact_patch.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/gallery/10_wheel_ground_contact_patch.py b/examples/gallery/10_wheel_ground_contact_patch.py index b0bc991cd5..b7bf2cc429 100644 --- a/examples/gallery/10_wheel_ground_contact_patch.py +++ b/examples/gallery/10_wheel_ground_contact_patch.py @@ -100,7 +100,7 @@ ################### # Visualize results -# ================= +# ~~~~~~~~~~~~~~~~~ # .. code-block:: python # # display = PrimePlotter() @@ -168,9 +168,9 @@ # ) # display.show() -############################################################################### +####################### # Wrap the fluid region -# c +# ~~~~~~~~~~~~~~~~~~~~~ # The largest internal region in this instance is the fluid region around the wheel. # Intersection loops are created to capture the features at the corners between the # patch, ground, and wheel. From c5c07902a1f8ef2782ddb1c62d10f3f7949f0c8a Mon Sep 17 00:00:00 2001 From: afernand Date: Thu, 5 Dec 2024 13:16:12 +0100 Subject: [PATCH 4/7] fix: Add dependency to toml file --- pyproject.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 7aded0bf54..893fd55e14 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,13 @@ dependencies = [ graphics = [ "ansys-tools-visualization-interface>=0.4.7,<1", ] +pygeometry = [ + "ansys-geometry-core>=0.7.6,<1", +] +all = [ + "ansys-tools-visualization-interface>=0.4.7,<1", + "ansys-geometry-core>=0.7.6,<1", +] tests = [ "ansys-tools-visualization-interface==0.5.0", "pytest==8.3.3", From a457f295137db82873aedd1b71f77aca6f48db40 Mon Sep 17 00:00:00 2001 From: afernand Date: Thu, 5 Dec 2024 13:20:32 +0100 Subject: [PATCH 5/7] fix: Toml file --- pyproject.toml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 893fd55e14..444d98dbc0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,10 +34,6 @@ graphics = [ pygeometry = [ "ansys-geometry-core>=0.7.6,<1", ] -all = [ - "ansys-tools-visualization-interface>=0.4.7,<1", - "ansys-geometry-core>=0.7.6,<1", -] tests = [ "ansys-tools-visualization-interface==0.5.0", "pytest==8.3.3", @@ -62,6 +58,7 @@ doc = [ ] all = [ "ansys-tools-visualization-interface>=0.2.6,<1", + "ansys-geometry-core>=0.7.6,<1", ] [project.urls] From 051302d946939bef32f7c23deb94ffb919678fa6 Mon Sep 17 00:00:00 2001 From: afernand Date: Thu, 5 Dec 2024 15:42:29 +0100 Subject: [PATCH 6/7] fix: Proper code blocks --- .../gallery/10_wheel_ground_contact_patch.py | 6 +- examples/gallery/12_import_from_pygeometry.py | 101 ++++++++++-------- 2 files changed, 57 insertions(+), 50 deletions(-) diff --git a/examples/gallery/10_wheel_ground_contact_patch.py b/examples/gallery/10_wheel_ground_contact_patch.py index b7bf2cc429..d53f244184 100644 --- a/examples/gallery/10_wheel_ground_contact_patch.py +++ b/examples/gallery/10_wheel_ground_contact_patch.py @@ -106,7 +106,7 @@ # display = PrimePlotter() # display.plot(model, scope=prime.ScopeDefinition(model, label_expression="ground, wheel")) # display.show() - +# print(model) ############################################################################### @@ -167,7 +167,7 @@ # model, scope=prime.ScopeDefinition(model, label_expression="ground, patch*, wheel") # ) # display.show() - +# ####################### # Wrap the fluid region # ~~~~~~~~~~~~~~~~~~~~~ @@ -201,7 +201,7 @@ # scope=prime.ScopeDefinition(model, label_expression="ground, patch*, wheel"), update=True # ) # display.show() - +# print(model) ############################################################################### diff --git a/examples/gallery/12_import_from_pygeometry.py b/examples/gallery/12_import_from_pygeometry.py index 62d2aa85c5..6771c090a5 100644 --- a/examples/gallery/12_import_from_pygeometry.py +++ b/examples/gallery/12_import_from_pygeometry.py @@ -39,51 +39,58 @@ #. Import the geometry into PyPrimeMesh. #. Exit the PyPrimeMesh session. -""" -##################### -# Create the geometry -# ~~~~~~~~~~~~~~~~~~~ -# First we create a simple geometry using PyGeometry. The geometry is a plate -# with a hole in the center. -# .. code-block:: python -# from pint import Quantity -# -# from ansys.geometry.core import launch_modeler -# from ansys.geometry.core.math import Point2D -# from ansys.geometry.core.misc import UNITS -# from ansys.geometry.core.sketch import Sketch -# from ansys.geometry.core.math import Point2D -# sketch = Sketch() -# (sketch.segment(Point2D([-4, 5], unit=UNITS.m), Point2D([4, 5], unit=UNITS.m)) -# .segment_to_point(Point2D([4, -5], unit=UNITS.m)) -# .segment_to_point(Point2D([-4, -5], unit=UNITS.m)) -# .segment_to_point(Point2D([-4, 5], unit=UNITS.m)) -# .box(Point2D([0,0], unit=UNITS.m), Quantity(3, UNITS.m), Quantity(3, UNITS.m)) -# ) -# modeler = launch_modeler(hidden=True) -# design = modeler.create_design("ExtrudedPlateNoHoles") -# body = design.extrude_sketch(f"PlateLayer", sketch, Quantity(2, UNITS.m)) - -###################################### -# Import the geometry into PyPrimeMesh -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Once the geometry is created, we can pass the Design object to PyPrimeMesh to -# create a mesh. -# .. code-block:: python -# import ansys.meshing.prime as prime -# from ansys.meshing.prime.graphics.plotter import PrimePlotter -# prime_client = prime.launch_prime() -# model = prime_client.model -# mesh_util = prime.lucid.Mesh(model=model) - -################################## -# Mesh the geometry and display it -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# With the geometry imported, we can now mesh it and display the mesh. -# .. code-block:: python -# mesh_util.surface_mesh(min_size=0.1, max_size=0.5) -# display = PrimePlotter() -# display.plot(model) -# display.show() -# modeler.close() + +Create the geometry +~~~~~~~~~~~~~~~~~~~ +First we create a simple geometry using PyGeometry. The geometry is a plate +with a hole in the center: + +.. code-block:: python + + from pint import Quantity + + from ansys.geometry.core import launch_modeler + from ansys.geometry.core.math import Point2D + from ansys.geometry.core.misc import UNITS + from ansys.geometry.core.sketch import Sketch + from ansys.geometry.core.math import Point2D + + sketch = Sketch() + ( + sketch.segment(Point2D([-4, 5], unit=UNITS.m), Point2D([4, 5], unit=UNITS.m)) + .segment_to_point(Point2D([4, -5], unit=UNITS.m)) + .segment_to_point(Point2D([-4, -5], unit=UNITS.m)) + .segment_to_point(Point2D([-4, 5], unit=UNITS.m)) + .box(Point2D([0, 0], unit=UNITS.m), Quantity(3, UNITS.m), Quantity(3, UNITS.m)) + ) + modeler = launch_modeler(hidden=True) + design = modeler.create_design("ExtrudedPlateNoHoles") + body = design.extrude_sketch(f"PlateLayer", sketch, Quantity(2, UNITS.m)) + +Import the geometry into PyPrimeMesh +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Once the geometry is created, we can pass the Design object to PyPrimeMesh to +create a mesh: + +.. code-block:: python + + import ansys.meshing.prime as prime + from ansys.meshing.prime.graphics.plotter import PrimePlotter + + prime_client = prime.launch_prime() + model = prime_client.model + mesh_util = prime.lucid.Mesh(model=model) + +Mesh the geometry and display it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +With the geometry imported, we can now mesh it and display the mesh: + +.. code-block:: python + + mesh_util.surface_mesh(min_size=0.1, max_size=0.5) + display = PrimePlotter() + display.plot(model) + display.show() + modeler.close() +""" From 50b859560954c51435d3eb04f9ac3127eeadf47b Mon Sep 17 00:00:00 2001 From: afernand Date: Fri, 20 Dec 2024 16:15:49 +0100 Subject: [PATCH 7/7] fix: Missing line --- examples/gallery/12_import_from_pygeometry.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/gallery/12_import_from_pygeometry.py b/examples/gallery/12_import_from_pygeometry.py index 6771c090a5..ffb2c2d0b4 100644 --- a/examples/gallery/12_import_from_pygeometry.py +++ b/examples/gallery/12_import_from_pygeometry.py @@ -81,6 +81,8 @@ prime_client = prime.launch_prime() model = prime_client.model mesh_util = prime.lucid.Mesh(model=model) + mesh_util.from_geometry(design) + Mesh the geometry and display it ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~