Skip to content

Commit

Permalink
Merge pull request solvcon#449 from yungyuc/feature/gmsh-dialog3
Browse files Browse the repository at this point in the history
Enhance: Add a file dialog for loading Gmsh file
  • Loading branch information
yungyuc authored Jan 1, 2025
2 parents 8f7ad03 + 2d212b6 commit fa52b10
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 22 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/devbuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ jobs:
- name: dependency by pip
run: |
sudo pip3 install setuptools
sudo pip3 install numpy pytest flake8 jsonschema
sudo pip3 install numpy matplotlib pytest flake8 jsonschema
sudo pip3 install pyside6==$(qmake6 -query QT_VERSION)
- name: dependency by manual script
Expand Down Expand Up @@ -327,7 +327,7 @@ jobs:
# suppress the warning of pip because brew forces PEP668 since python3.12
python3 -m pip -v install --upgrade setuptools
python3 -m pip -v install --upgrade pip
python3 -m pip -v install --upgrade numpy pytest flake8 jsonschema
python3 -m pip -v install --upgrade numpy matplotlib pytest flake8 jsonschema
# For now (2024/10/22), pyside6 6.6.3 does not support Python 3.13.
# Use --ignore-requires-python to force installation.
python3 -m pip -v install --upgrade pyside6==$(qmake -query QT_VERSION) --ignore-requires-python
Expand Down Expand Up @@ -495,10 +495,10 @@ jobs:
uses: jurplel/install-qt-action@v4
with:
aqtversion: '==3.1.*'
version: '6.6.3'
version: '6.8.1'
host: 'windows'
target: 'desktop'
arch: 'win64_msvc2019_64'
arch: 'win64_msvc2022_64'
modules: 'qt3d'
cache: true

Expand All @@ -508,7 +508,7 @@ jobs:

- name: dependency by pip
run: |
pip3 install -U numpy pytest jsonschema flake8 pybind11 pyside6==$(qmake -query QT_VERSION)
pip3 install -U numpy matplotlib pytest jsonschema flake8 pybind11 pyside6==$(qmake -query QT_VERSION)
# Add PySide6 and Shiboken6 path into system path, that allow exe file can find
# dll during runtime
# If user needs to modified system path in github actions container
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ jobs:
- name: dependency by pip
run: |
sudo pip3 install setuptools
sudo pip3 install numpy pytest flake8 jsonschema pyside6==$(qmake6 -query QT_VERSION)
sudo pip3 install numpy matplotlib pytest flake8 jsonschema pyside6==$(qmake6 -query QT_VERSION)
- name: dependency (manual)
run: sudo ${GITHUB_WORKSPACE}/contrib/dependency/install.sh pybind11
Expand Down Expand Up @@ -236,7 +236,7 @@ jobs:
# suppress the warning of pip because brew forces PEP668 since python3.12
python3 -m pip -v install --upgrade setuptools --break-system-packages
python3 -m pip -v install --upgrade pip --break-system-packages
python3 -m pip -v install --upgrade numpy pytest flake8 jsonschema
python3 -m pip -v install --upgrade numpy matplotlib pytest flake8 jsonschema
# For now (2024/10/22), pyside6 6.6.3 does not support Python 3.13.
# Use --ignore-requires-python to force installation.
python3 -m pip -v install --upgrade pyside6==$(qmake -query QT_VERSION) --ignore-requires-python
Expand Down
13 changes: 7 additions & 6 deletions modmesh/pilot/_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@
enable = False
try:
from _modmesh import pilot as _vimpl # noqa: F401

enable = True
except ImportError:
pass

if enable:
from PySide6.QtGui import QAction

from . import _mesh

_from_impl = [ # noqa: F822
'R3DWidget',
Expand All @@ -71,6 +73,9 @@ def _load():
del _load


_holder = {}


def populate_menu():
wm = _vimpl.RManager.instance

Expand All @@ -86,12 +91,8 @@ def _addAction(menu, text, tip, funcname):
act.triggered.connect(lambda *a: func())
menu.addAction(act)

_addAction(
menu=wm.fileMenu,
text="New file (dummy)",
tip="Create new file",
funcname=lambda: print("This is only a demo: Create new file!"),
)
_holder['gmsh_dialog'] = _mesh.GmshFileDialog(mgr=wm)
_holder['gmsh_dialog'].populate_menu()

if sys.platform != 'darwin':
_addAction(
Expand Down
123 changes: 123 additions & 0 deletions modmesh/pilot/_mesh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Copyright (c) 2021, Yung-Yu Chen <[email protected]>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# - Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.


"""
Show meshes.
"""

import os

from PySide6 import QtCore, QtWidgets, QtGui

from .. import core

__all__ = [ # noqa: F822
'GmshFileDialog',
]


def _add_menu_item(mainWindow, menu, text, tip, func):
act = QtGui.QAction(text, mainWindow)
act.setStatusTip(tip)
act.triggered.connect(func)
menu.addAction(act)


class GmshFileDialog(QtCore.QObject):
def __init__(self, *args, **kw):
self._mgr = kw.pop('mgr')
super(GmshFileDialog, self).__init__(*args, **kw)
self._diag = QtWidgets.QFileDialog()
self._diag.setFileMode(QtWidgets.QFileDialog.ExistingFile)
self._diag.setDirectory(self._get_initial_path())
self._diag.setWindowTitle('Open Gmsh file ...')

def run(self):
self._diag.open(self, QtCore.SLOT('on_finished()'))

def populate_menu(self):
_add_menu_item(
mainWindow=self._mgr.mainWindow,
menu=self._mgr.fileMenu,
text="Open Gmsh file",
tip="Open Gmsh file",
func=self.run,
)

@QtCore.Slot()
def on_finished(self):
filenames = []
for path in self._diag.selectedFiles():
filenames.append(path)
self._load_gmsh_file(filename=filenames[0])

@staticmethod
def _get_initial_path():
"""
Search for `tests/data/rectangle.msh` and return the directory holding
it. If not found, return an empty string.
:return: The holding directory in absolute path or empty string.
"""
found = ''
for dp in ('.', core.__file__):
dp = os.path.dirname(os.path.abspath(dp))
dp2 = os.path.dirname(dp)
while dp != dp2:
tp = os.path.join(dp, "tests", "data")
fp = os.path.join(tp, "rectangle.msh")
if os.path.exists(fp):
found = tp
break
dp = dp2
dp2 = os.path.dirname(dp)
if found:
break
return found

def _load_gmsh_file(self, filename):
if not os.path.exists(filename):
self._pycon.writeToHistory(f"{filename} does not exist\n")
return

with open(filename, 'rb') as fobj:
data = fobj.read()
self._pycon.writeToHistory(f"gmsh mesh file {filename} is read\n")
gmsh = core.Gmsh(data)
mh = gmsh.to_block()
self._pycon.writeToHistory("StaticMesh object created from gmsh\n")
# Open a sub window for triangles and quadrilaterals:
w = self._mgr.add3DWidget()
w.updateMesh(mh)
w.showMark()
self._pycon.writeToHistory(f"nedge: {mh.nedge}\n")

@property
def _pycon(self):
return self._mgr.pycon

# vim: set ff=unix fenc=utf8 et sw=4 ts=4 sts=4:
23 changes: 14 additions & 9 deletions tests/test_pilot.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,19 @@ class PilotCameraTB:

@classmethod
def setUpClass(cls):
widget = pilot.RManager.instance.setUp().add3DWidget()
if modmesh.HAS_PILOT:
widget = pilot.RManager.instance.setUp().add3DWidget()

if cls.camera_type is not None:
widget.setCameraType(cls.camera_type)
if cls.camera_type is not None:
widget.setCameraType(cls.camera_type)

cls.widget = widget
cls.camera = widget.camera
cls.widget = widget
cls.camera = widget.camera

@classmethod
def tearDownClass(cls):
cls.widget.close_and_destroy()
if modmesh.HAS_PILOT:
cls.widget.close_and_destroy()

def angle_axis(self, angle_deg, axis):
a = axis
Expand All @@ -104,7 +106,8 @@ def normalize(self, vec):
return vec / np.linalg.norm(vec)


@unittest.skipIf(GITHUB_ACTIONS, "GUI is not available in GitHub Actions")
@unittest.skipIf(GITHUB_ACTIONS or not modmesh.HAS_PILOT,
"GUI is not available in GitHub Actions")
class PilotCommonCameraTC(PilotCameraTB, unittest.TestCase):
def test_value_get_set(self):
c = self.camera
Expand Down Expand Up @@ -195,7 +198,8 @@ def test_translation(self):
self.assertEqual(c.view_center[2], new_view_center[2])


@unittest.skipIf(GITHUB_ACTIONS, "GUI is not available in GitHub Actions")
@unittest.skipIf(GITHUB_ACTIONS or not modmesh.HAS_PILOT,
"GUI is not available in GitHub Actions")
class PilotFPSCameraTC(PilotCameraTB, unittest.TestCase):
camera_type = "fps"

Expand Down Expand Up @@ -266,7 +270,8 @@ def test_rotation(self):
self.assertAlmostEqual(view_center[2], new_view_center[2], delta=1e-5)


@unittest.skipIf(GITHUB_ACTIONS, "GUI is not available in GitHub Actions")
@unittest.skipIf(GITHUB_ACTIONS or not modmesh.HAS_PILOT,
"GUI is not available in GitHub Actions")
class PilotOrbitCameraTC(PilotCameraTB, unittest.TestCase):
camera_type = "orbit"

Expand Down

0 comments on commit fa52b10

Please sign in to comment.