diff --git a/.github/workflows/testing_pr.yml b/.github/workflows/testing_pr.yml index 8221e4f..d416067 100644 --- a/.github/workflows/testing_pr.yml +++ b/.github/workflows/testing_pr.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: os: [windows-latest, macos-latest, ubuntu-latest] - python-version: [3.8, 3.9] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index b88f68a..4cc9c3b 100644 --- a/README.md +++ b/README.md @@ -46,10 +46,10 @@ See the [**Examples**](#examples) section below and the [**Tutorials**](tutorial ## Dependencies and installation **BladeX** requires `numpy`, `scipy`, `matplotlib`, `sphinx` (for the documentation), and `pytest` (for the local test). They can be easily installed using `pip`. -**BladeX** is compatible with Python 3.6. Moreover, some of the modules require `OCC` to be installed for the `.iges` or `.stl` CAD generation. This requirement cannot be satisfied through `pip`, but the precompiled binaries are available on `conda` using the command: +**BladeX** is compatible with Python>=3.9. Moreover, some of the modules require `OCC` to be installed for the `.iges` or `.stl` CAD generation. This requirement cannot be satisfied through `pip`, but the precompiled binaries are available on `conda` using the command: ```bash -> conda install -c conda-forge pythonocc-core=7.4.0 +> conda install -c conda-forge pythonocc-core ``` You can also refer to `pythonocc.org` or `github.com/tpaviot/pythonocc-core` for further instructions. diff --git a/bladex/__init__.py b/bladex/__init__.py index e527a59..d70f4de 100644 --- a/bladex/__init__.py +++ b/bladex/__init__.py @@ -1,9 +1,12 @@ """ BladeX init """ -__all__ = ['ProfileInterface', 'NacaProfile', 'CustomProfile', - 'ReversePropeller', 'Blade', 'Shaft', 'Propeller', 'Deformation', - 'ParamFile', 'RBF', 'reconstruct_f', 'scipy_bspline'] +__all__ = [ + 'ProfileInterface', 'NacaProfile', 'CustomProfile', + 'ReversePropeller', 'Blade', 'Shaft', 'CylinderShaft', + 'Propeller', 'Deformation', 'ParamFile', 'RBF', + 'reconstruct_f', 'scipy_bspline' +] from .meta import * from .profile import ProfileInterface @@ -16,3 +19,4 @@ from .params import ParamFile from .ndinterpolator import RBF, reconstruct_f, scipy_bspline from .reversepropeller import ReversePropeller +from .cylinder_shaft import CylinderShaft diff --git a/bladex/blade.py b/bladex/blade.py index 39f1a98..d91f256 100644 --- a/bladex/blade.py +++ b/bladex/blade.py @@ -960,7 +960,7 @@ def generate_solid(self, sewer.Perform() result_shell = sewer.SewedShape() solid_maker = BRepBuilderAPI_MakeSolid() - solid_maker.Add(OCC.Core.TopoDS.topods_Shell(result_shell)) + solid_maker.Add(OCC.Core.TopoDS.topods.Shell(result_shell)) if not solid_maker.IsDone(): raise RuntimeError('Unsuccessful assembling of solid blade') result_solid = solid_maker.Solid() diff --git a/bladex/cylinder_shaft.py b/bladex/cylinder_shaft.py new file mode 100644 index 0000000..f424366 --- /dev/null +++ b/bladex/cylinder_shaft.py @@ -0,0 +1,53 @@ +""" Cylinder Shaft """ +from OCC.Display.SimpleGui import init_display +from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeCylinder +from OCC.Core.gp import gp_Pnt, gp_Dir, gp_Ax2 + + +class CylinderShaft: + """ + Cylinder shaft construction. + + :param float radius: radius of the cylinder shaft. Defaults to 1.0. + :param float height: height of the cylinder shaft. Defaults to 1.0. + :param list orientation: orientation vector of the cylinder shaft. Defaults + to [1.0, 0.0, 0.0], so along X axis. + :param list origin: origin point of the cylinder shaft. Defaults to + [0.0, 0.0, 0.0]. + """ + + def __init__(self, radius=1.0, height=1.0, orientation=None, origin=None): + self.radius = radius + self.height = height + + if orientation is None: + self.orientation = [1.0, 0.0, 0.0] # default orientation along X + + if origin is None: + self.origin = [0.0, 0.0, 0.0] # default origin at (0,0,0) + + def generate_solid(self): + """ + Generate a cylindrical shaft using the BRepBuilderAPI_MakeCylinder + algorithm. This method requires PythonOCC to be installed. + + :return: solid shaft + :rtype: OCC.Core.TopoDS.TopoDS_Solid + """ + + origin = gp_Pnt(*self.origin) + orientation = gp_Dir(*self.orientation) + ax2 = gp_Ax2(origin, orientation) + + shape = BRepPrimAPI_MakeCylinder(ax2, self.radius, self.height).Shape() + + return shape + + def display(self): + """ + Display the shaft. + """ + shaft_solid = self.generate_solid() + display, start_display = init_display()[:2] + display.DisplayShape(shaft_solid, update=True) + start_display() diff --git a/bladex/shaft.py b/bladex/shaft.py index eeae8b0..2677f90 100644 --- a/bladex/shaft.py +++ b/bladex/shaft.py @@ -44,7 +44,7 @@ def generate_solid(self): sewer.Perform() result_sewed_shaft = sewer.SewedShape() shaft_solid_maker = BRepBuilderAPI_MakeSolid() - shaft_solid_maker.Add(OCC.Core.TopoDS.topods_Shell(result_sewed_shaft)) + shaft_solid_maker.Add(OCC.Core.TopoDS.topods.Shell(result_sewed_shaft)) if not shaft_solid_maker.IsDone(): raise RuntimeError('Unsuccessful assembling of solid shaft') shaft_solid = shaft_solid_maker.Solid() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..863e78c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,51 @@ +[build-system] +requires = ["setuptools>=61", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "BladeX" +version = "0.1.0" +description = "Python Blade Morphing" +readme = { file = "README.md", content-type = "text/markdown" } +requires-python = ">=3.9" +license = { text = "MIT" } +authors = [ + { name = "Marco Tezzele", email = "marcotez@gmail.com" }, + { name = "Mahmoud Gadalla", email = "gadalla.mah@gmail.com" } +] +keywords = ["blade-generation", "propeller", "iges", "procal"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering :: Mathematics" +] +dependencies = [ + "numpy", + "scipy", + "matplotlib", +] + +[project.optional-dependencies] +docs = [ + "Sphinx", + "sphinx_rtd_theme" +] +test = [ + "pytest", + "pytest-cov" +] + +[project.urls] +Homepage = "https://github.com/mathLab/BladeX" + +[tool.setuptools] +include-package-data = true + +[tool.setuptools.packages.find] +include = ["bladex*"] + diff --git a/setup.py b/setup.py deleted file mode 100644 index 2020cbe..0000000 --- a/setup.py +++ /dev/null @@ -1,61 +0,0 @@ -from setuptools import setup, find_packages - -meta = {} -with open("bladex/meta.py") as fp: - exec(fp.read(), meta) - -# Package meta-data. -NAME = meta['__title__'] -DESCRIPTION = 'Python Blade Morphing' -URL = 'https://github.com/mathLab/BladeX' -MAIL = meta['__mail__'] -AUTHOR = meta['__author__'] -VERSION = meta['__version__'] -KEYWORDS = 'blade-generation propeller iges procal' - -REQUIRED = [ - 'numpy', 'scipy', 'matplotlib', 'Sphinx', 'sphinx_rtd_theme', 'smithers' -] - -EXTRAS = { - 'docs': ['Sphinx==1.4', 'sphinx_rtd_theme'], - 'test': ['pytest', 'pytest-cov'], -} - -LDESCRIPTION = ( - "BladeX is a Python package for geometrical parametrization and bottom-up " - "construction of propeller blades. It allows to generate and deform a " - "blade based on the radial distribution of its parameters such as pitch, " - "rake, skew, and the sectional foils' parameters such as chord and " - "camber. The package is ideally suited for parametric simulations on " - "large number of blade deformations. It provides an automated procedure " - "for the CAD generation, hence reducing the time and effort required for " - "modelling. The main scope of BladeX is to deal with propeller blades, " - "however it can be flexible to be applied on further applications with " - "analogous geometrical structures such as aircraft wings, turbomachinery, " - "or wind turbine blades." -) - -setup( - name=NAME, - version=VERSION, - description=DESCRIPTION, - long_description=LDESCRIPTION, - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3.6', - 'Intended Audience :: Science/Research', - 'Topic :: Scientific/Engineering :: Mathematics' - ], - keywords=KEYWORDS, - url=URL, - author=AUTHOR, - author_email=MAIL, - license='MIT', - packages=find_packages(), - install_requires=REQUIRED, - extras_require=EXTRAS, - include_package_data=True, - zip_safe=False -) diff --git a/tests/test_cylinder_shaft.py b/tests/test_cylinder_shaft.py new file mode 100644 index 0000000..937283f --- /dev/null +++ b/tests/test_cylinder_shaft.py @@ -0,0 +1,9 @@ +from unittest import TestCase +from bladex import CylinderShaft +from OCC.Core.TopoDS import TopoDS_Solid + + +def test_generate_solid_01(): + sh = CylinderShaft() + shaft_solid = sh.generate_solid() + assert isinstance(shaft_solid, TopoDS_Solid) \ No newline at end of file