diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2024-09-14 10:18:18 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2024-09-14 10:28:53 +0300 |
commit | 66e260367ac774d563874203b260b0ed0e04c93d (patch) | |
tree | eb4bc3df675c97f8fad0ef56ee272ae8549be9d7 | |
parent | 47df7453282e2d3835d93fd3c4c24f9cbf8adca5 (diff) | |
download | ydb-66e260367ac774d563874203b260b0ed0e04c93d.tar.gz |
Intermediate changes
commit_hash:ab55b3b972e940f79570e58af046841fae66b70c
32 files changed, 597 insertions, 236 deletions
diff --git a/contrib/python/Flask-Cors/py3/.dist-info/METADATA b/contrib/python/Flask-Cors/py3/.dist-info/METADATA index 32d8407be9..34be16080b 100644 --- a/contrib/python/Flask-Cors/py3/.dist-info/METADATA +++ b/contrib/python/Flask-Cors/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Flask-Cors -Version: 4.0.1 +Version: 4.0.2 Summary: A Flask extension adding a decorator for CORS support Home-page: https://github.com/corydolphin/flask-cors Author: Cory Dolphin diff --git a/contrib/python/Flask-Cors/py3/flask_cors/core.py b/contrib/python/Flask-Cors/py3/flask_cors/core.py index 5358036c21..bd011f4d51 100644 --- a/contrib/python/Flask-Cors/py3/flask_cors/core.py +++ b/contrib/python/Flask-Cors/py3/flask_cors/core.py @@ -36,7 +36,7 @@ CONFIG_OPTIONS = ['CORS_ORIGINS', 'CORS_METHODS', 'CORS_ALLOW_HEADERS', 'CORS_MAX_AGE', 'CORS_SEND_WILDCARD', 'CORS_AUTOMATIC_OPTIONS', 'CORS_VARY_HEADER', 'CORS_RESOURCES', 'CORS_INTERCEPT_EXCEPTIONS', - 'CORS_ALWAYS_SEND'] + 'CORS_ALWAYS_SEND', 'CORS_ALLOW_PRIVATE_NETWORK'] # Attribute added to request object by decorator to indicate that CORS # was evaluated, in case the decorator and extension are both applied # to a view. @@ -56,7 +56,8 @@ DEFAULT_OPTIONS = dict(origins='*', vary_header=True, resources=r'/*', intercept_exceptions=True, - always_send=True) + always_send=True, + allow_private_network=True) def parse_resources(resources): @@ -186,7 +187,8 @@ def get_cors_headers(options, request_headers, request_method): if ACL_REQUEST_HEADER_PRIVATE_NETWORK in request_headers \ and request_headers.get(ACL_REQUEST_HEADER_PRIVATE_NETWORK) == 'true': - headers[ACL_RESPONSE_PRIVATE_NETWORK] = 'true' + allow_private_network = 'true' if options.get('allow_private_network') else 'false' + headers[ACL_RESPONSE_PRIVATE_NETWORK] = allow_private_network # This is a preflight request # http://www.w3.org/TR/cors/#resource-preflight-requests diff --git a/contrib/python/Flask-Cors/py3/flask_cors/extension.py b/contrib/python/Flask-Cors/py3/flask_cors/extension.py index 6361dccfd9..abf5cafe9c 100644 --- a/contrib/python/Flask-Cors/py3/flask_cors/extension.py +++ b/contrib/python/Flask-Cors/py3/flask_cors/extension.py @@ -138,6 +138,22 @@ class CORS(object): Default : True :type vary_header: bool + + :param allow_private_network: + If True, the response header `Access-Control-Allow-Private-Network` + will be set with the value 'true' whenever the request header + `Access-Control-Request-Private-Network` has a value 'true'. + + If False, the reponse header `Access-Control-Allow-Private-Network` + will be set with the value 'false' whenever the request header + `Access-Control-Request-Private-Network` has a value of 'true'. + + If the request header `Access-Control-Request-Private-Network` is + not present or has a value other than 'true', the response header + `Access-Control-Allow-Private-Network` will not be set. + + Default : True + :type allow_private_network: bool """ def __init__(self, app=None, **kwargs): diff --git a/contrib/python/Flask-Cors/py3/flask_cors/version.py b/contrib/python/Flask-Cors/py3/flask_cors/version.py index 1a3bef5327..4391764022 100644 --- a/contrib/python/Flask-Cors/py3/flask_cors/version.py +++ b/contrib/python/Flask-Cors/py3/flask_cors/version.py @@ -1 +1 @@ -__version__ = '4.0.1' +__version__ = '4.0.2' diff --git a/contrib/python/Flask-Cors/py3/ya.make b/contrib/python/Flask-Cors/py3/ya.make index 36ff4238c9..4906c474ad 100644 --- a/contrib/python/Flask-Cors/py3/ya.make +++ b/contrib/python/Flask-Cors/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(4.0.1) +VERSION(4.0.2) LICENSE(MIT) diff --git a/contrib/python/contourpy/.dist-info/METADATA b/contrib/python/contourpy/.dist-info/METADATA index 7078d82456..55e5c6d8e0 100644 --- a/contrib/python/contourpy/.dist-info/METADATA +++ b/contrib/python/contourpy/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: contourpy -Version: 1.2.1 +Version: 1.3.0 Summary: Python library for calculating contours of 2D quadrilateral grids Author-Email: Ian Thomas <ianthomas23@gmail.com> License: BSD 3-Clause License @@ -42,6 +42,7 @@ Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 Classifier: Topic :: Scientific/Engineering :: Information Analysis Classifier: Topic :: Scientific/Engineering :: Mathematics Classifier: Topic :: Scientific/Engineering :: Visualization @@ -50,7 +51,7 @@ Project-URL: Changelog, https://contourpy.readthedocs.io/en/latest/changelog.htm Project-URL: Documentation, https://contourpy.readthedocs.io Project-URL: Repository, https://github.com/contourpy/contourpy Requires-Python: >=3.9 -Requires-Dist: numpy>=1.20 +Requires-Dist: numpy>=1.23 Requires-Dist: furo; extra == "docs" Requires-Dist: sphinx>=7.2; extra == "docs" Requires-Dist: sphinx-copybutton; extra == "docs" @@ -58,13 +59,14 @@ Requires-Dist: bokeh; extra == "bokeh" Requires-Dist: selenium; extra == "bokeh" Requires-Dist: contourpy[bokeh,docs]; extra == "mypy" Requires-Dist: docutils-stubs; extra == "mypy" -Requires-Dist: mypy==1.8.0; extra == "mypy" +Requires-Dist: mypy==1.11.1; extra == "mypy" Requires-Dist: types-Pillow; extra == "mypy" Requires-Dist: contourpy[test-no-images]; extra == "test" Requires-Dist: matplotlib; extra == "test" Requires-Dist: Pillow; extra == "test" Requires-Dist: pytest; extra == "test-no-images" Requires-Dist: pytest-cov; extra == "test-no-images" +Requires-Dist: pytest-rerunfailures; extra == "test-no-images" Requires-Dist: pytest-xdist; extra == "test-no-images" Requires-Dist: wurlitzer; extra == "test-no-images" Provides-Extra: docs @@ -85,7 +87,7 @@ It contains the 2005 and 2014 algorithms used in Matplotlib as well as a newer a | | | | --- | --- | -| Latest release | [![PyPI version](https://img.shields.io/pypi/v/contourpy.svg?label=pypi&color=fdae61)](https://pypi.python.org/pypi/contourpy) [![conda-forge version](https://img.shields.io/conda/v/conda-forge/contourpy.svg?label=conda-forge&color=a6d96a)](https://anaconda.org/conda-forge/contourpy) [![anaconda version](https://img.shields.io/conda/v/anaconda/contourpy.svg?label=anaconda&color=1a9641)](https://anaconda.org/anaconda/contourpy) | -| Downloads | [![PyPi downloads](https://img.shields.io/pypi/dm/contourpy?label=pypi&style=flat&color=fdae61)](https://pepy.tech/project/contourpy) [![conda-forge downloads](https://raw.githubusercontent.com/contourpy/condabadges/main/cache/contourpy_conda-forge_monthly.svg)](https://anaconda.org/conda-forge/contourpy) [![anaconda downloads](https://raw.githubusercontent.com/contourpy/condabadges/main/cache/contourpy_anaconda_monthly.svg)](https://anaconda.org/anaconda/contourpy) | +| Latest release | [![PyPI version](https://img.shields.io/pypi/v/contourpy.svg?label=pypi&color=fdae61)](https://pypi.python.org/pypi/contourpy) [![conda-forge version](https://img.shields.io/conda/v/conda-forge/contourpy.svg?label=conda-forge&color=a6d96a)](https://anaconda.org/conda-forge/contourpy) | +| Downloads | [![PyPi downloads](https://img.shields.io/pypi/dm/contourpy?label=pypi&style=flat&color=fdae61)](https://pepy.tech/project/contourpy) | | Python version | [![Platforms](https://img.shields.io/pypi/pyversions/contourpy?color=fdae61)](https://pypi.org/project/contourpy/) | | Coverage | [![Codecov](https://img.shields.io/codecov/c/gh/contourpy/contourpy?color=fdae61&label=codecov)](https://app.codecov.io/gh/contourpy/contourpy) | diff --git a/contrib/python/contourpy/README.md b/contrib/python/contourpy/README.md index 27dad20093..b304b6a4ea 100644 --- a/contrib/python/contourpy/README.md +++ b/contrib/python/contourpy/README.md @@ -12,7 +12,7 @@ It contains the 2005 and 2014 algorithms used in Matplotlib as well as a newer a | | | | --- | --- | -| Latest release | [![PyPI version](https://img.shields.io/pypi/v/contourpy.svg?label=pypi&color=fdae61)](https://pypi.python.org/pypi/contourpy) [![conda-forge version](https://img.shields.io/conda/v/conda-forge/contourpy.svg?label=conda-forge&color=a6d96a)](https://anaconda.org/conda-forge/contourpy) [![anaconda version](https://img.shields.io/conda/v/anaconda/contourpy.svg?label=anaconda&color=1a9641)](https://anaconda.org/anaconda/contourpy) | -| Downloads | [![PyPi downloads](https://img.shields.io/pypi/dm/contourpy?label=pypi&style=flat&color=fdae61)](https://pepy.tech/project/contourpy) [![conda-forge downloads](https://raw.githubusercontent.com/contourpy/condabadges/main/cache/contourpy_conda-forge_monthly.svg)](https://anaconda.org/conda-forge/contourpy) [![anaconda downloads](https://raw.githubusercontent.com/contourpy/condabadges/main/cache/contourpy_anaconda_monthly.svg)](https://anaconda.org/anaconda/contourpy) | +| Latest release | [![PyPI version](https://img.shields.io/pypi/v/contourpy.svg?label=pypi&color=fdae61)](https://pypi.python.org/pypi/contourpy) [![conda-forge version](https://img.shields.io/conda/v/conda-forge/contourpy.svg?label=conda-forge&color=a6d96a)](https://anaconda.org/conda-forge/contourpy) | +| Downloads | [![PyPi downloads](https://img.shields.io/pypi/dm/contourpy?label=pypi&style=flat&color=fdae61)](https://pepy.tech/project/contourpy) | | Python version | [![Platforms](https://img.shields.io/pypi/pyversions/contourpy?color=fdae61)](https://pypi.org/project/contourpy/) | | Coverage | [![Codecov](https://img.shields.io/codecov/c/gh/contourpy/contourpy?color=fdae61&label=codecov)](https://app.codecov.io/gh/contourpy/contourpy) | diff --git a/contrib/python/contourpy/README_simple.md b/contrib/python/contourpy/README_simple.md index b8bc6939ab..d489ae4a80 100644 --- a/contrib/python/contourpy/README_simple.md +++ b/contrib/python/contourpy/README_simple.md @@ -9,7 +9,7 @@ It contains the 2005 and 2014 algorithms used in Matplotlib as well as a newer a | | | | --- | --- | -| Latest release | [![PyPI version](https://img.shields.io/pypi/v/contourpy.svg?label=pypi&color=fdae61)](https://pypi.python.org/pypi/contourpy) [![conda-forge version](https://img.shields.io/conda/v/conda-forge/contourpy.svg?label=conda-forge&color=a6d96a)](https://anaconda.org/conda-forge/contourpy) [![anaconda version](https://img.shields.io/conda/v/anaconda/contourpy.svg?label=anaconda&color=1a9641)](https://anaconda.org/anaconda/contourpy) | -| Downloads | [![PyPi downloads](https://img.shields.io/pypi/dm/contourpy?label=pypi&style=flat&color=fdae61)](https://pepy.tech/project/contourpy) [![conda-forge downloads](https://raw.githubusercontent.com/contourpy/condabadges/main/cache/contourpy_conda-forge_monthly.svg)](https://anaconda.org/conda-forge/contourpy) [![anaconda downloads](https://raw.githubusercontent.com/contourpy/condabadges/main/cache/contourpy_anaconda_monthly.svg)](https://anaconda.org/anaconda/contourpy) | +| Latest release | [![PyPI version](https://img.shields.io/pypi/v/contourpy.svg?label=pypi&color=fdae61)](https://pypi.python.org/pypi/contourpy) [![conda-forge version](https://img.shields.io/conda/v/conda-forge/contourpy.svg?label=conda-forge&color=a6d96a)](https://anaconda.org/conda-forge/contourpy) | +| Downloads | [![PyPi downloads](https://img.shields.io/pypi/dm/contourpy?label=pypi&style=flat&color=fdae61)](https://pepy.tech/project/contourpy) | | Python version | [![Platforms](https://img.shields.io/pypi/pyversions/contourpy?color=fdae61)](https://pypi.org/project/contourpy/) | | Coverage | [![Codecov](https://img.shields.io/codecov/c/gh/contourpy/contourpy?color=fdae61&label=codecov)](https://app.codecov.io/gh/contourpy/contourpy) | diff --git a/contrib/python/contourpy/contourpy/__init__.py b/contrib/python/contourpy/contourpy/__init__.py index aa6baf93d0..33c1f014b8 100644 --- a/contrib/python/contourpy/contourpy/__init__.py +++ b/contrib/python/contourpy/contourpy/__init__.py @@ -17,8 +17,18 @@ from contourpy._contourpy import ( ) from contourpy._version import __version__ from contourpy.chunk import calc_chunk_sizes -from contourpy.convert import convert_filled, convert_lines -from contourpy.dechunk import dechunk_filled, dechunk_lines +from contourpy.convert import ( + convert_filled, + convert_lines, + convert_multi_filled, + convert_multi_lines, +) +from contourpy.dechunk import ( + dechunk_filled, + dechunk_lines, + dechunk_multi_filled, + dechunk_multi_lines, +) from contourpy.enum_util import as_fill_type, as_line_type, as_z_interp if TYPE_CHECKING: @@ -33,8 +43,12 @@ __all__ = [ "contour_generator", "convert_filled", "convert_lines", + "convert_multi_filled", + "convert_multi_lines", "dechunk_filled", "dechunk_lines", + "dechunk_multi_filled", + "dechunk_multi_lines", "max_threads", "FillType", "LineType", @@ -87,10 +101,10 @@ def contour_generator( z_interp: ZInterp | str | None = ZInterp.Linear, thread_count: int = 0, ) -> ContourGenerator: - """Create and return a :class:`~contourpy._contourpy.ContourGenerator` object. + """Create and return a :class:`~.ContourGenerator` object. - The class and properties of the returned :class:`~contourpy._contourpy.ContourGenerator` are - determined by the function arguments, with sensible defaults. + The class and properties of the returned :class:`~.ContourGenerator` are determined by the + function arguments, with sensible defaults. Args: x (array-like of shape (ny, nx) or (nx,), optional): The x-coordinates of the ``z`` values. @@ -110,13 +124,17 @@ def contour_generator( out, other triangular corners comprising three unmasked points are contoured as usual. If not specified, uses the default provided by the algorithm ``name``. line_type (LineType or str, optional): The format of contour line data returned from calls - to :meth:`~contourpy.ContourGenerator.lines`, specified either as a - :class:`~contourpy.LineType` or its string equivalent such as ``"SeparateCode"``. + to :meth:`~.ContourGenerator.lines`, specified either as a :class:`~.LineType` or its + string equivalent such as ``"SeparateCode"``. If not specified, uses the default provided by the algorithm ``name``. + The relationship between the :class:`~.LineType` enum and the data format returned from + :meth:`~.ContourGenerator.lines` is explained at :ref:`line_type`. fill_type (FillType or str, optional): The format of filled contour data returned from calls - to :meth:`~contourpy.ContourGenerator.filled`, specified either as a - :class:`~contourpy.FillType` or its string equivalent such as ``"OuterOffset"``. + to :meth:`~.ContourGenerator.filled`, specified either as a :class:`~.FillType` or its + string equivalent such as ``"OuterOffset"``. If not specified, uses the default provided by the algorithm ``name``. + The relationship between the :class:`~.FillType` enum and the data format returned from + :meth:`~.ContourGenerator.filled` is explained at :ref:`fill_type`. chunk_size (int or tuple(int, int), optional): Chunk size in (y, x) directions, or the same size in both directions if only one value is specified. chunk_count (int or tuple(int, int), optional): Chunk count in (y, x) directions, or the @@ -140,7 +158,7 @@ def contour_generator( something other than ``"threaded"`` then the ``thread_count`` will be set to ``1``. Return: - :class:`~contourpy._contourpy.ContourGenerator`. + :class:`~.ContourGenerator`. Note: A maximum of one of ``chunk_size``, ``chunk_count`` and ``total_chunk_count`` may be diff --git a/contrib/python/contourpy/contourpy/_contourpy.pyi b/contrib/python/contourpy/contourpy/_contourpy.pyi index 077f5f9b59..c79cf8251a 100644 --- a/contrib/python/contourpy/contourpy/_contourpy.pyi +++ b/contrib/python/contourpy/contourpy/_contourpy.pyi @@ -9,6 +9,7 @@ import contourpy._contourpy as cpy # Input numpy array types, the same as in common.h CoordinateArray: TypeAlias = npt.NDArray[np.float64] MaskArray: TypeAlias = npt.NDArray[np.bool_] +LevelArray: TypeAlias = npt.ArrayLike # Output numpy array types, the same as in common.h PointArray: TypeAlias = npt.NDArray[np.float64] @@ -103,6 +104,8 @@ class ContourGenerator: def create_filled_contour(self, lower_level: float, upper_level: float) -> FillReturn: ... def filled(self, lower_level: float, upper_level: float) -> FillReturn: ... def lines(self, level: float) -> LineReturn: ... + def multi_filled(self, levels: LevelArray) -> list[FillReturn]: ... + def multi_lines(self, levels: LevelArray) -> list[LineReturn]: ... @staticmethod def supports_corner_mask() -> bool: ... @staticmethod diff --git a/contrib/python/contourpy/contourpy/_version.py b/contrib/python/contourpy/contourpy/_version.py index a955fdae12..67bc602abf 100644 --- a/contrib/python/contourpy/contourpy/_version.py +++ b/contrib/python/contourpy/contourpy/_version.py @@ -1 +1 @@ -__version__ = "1.2.1" +__version__ = "1.3.0" diff --git a/contrib/python/contourpy/contourpy/array.py b/contrib/python/contourpy/contourpy/array.py index fbc53d6c4c..5b41fb2589 100644 --- a/contrib/python/contourpy/contourpy/array.py +++ b/contrib/python/contourpy/contourpy/array.py @@ -257,5 +257,5 @@ def split_points_at_nan(points: cpy.PointArray) -> list[cpy.PointArray]: if len(nan_offsets) == 0: return [points] else: - nan_offsets = np.concatenate(([-1], nan_offsets, [len(points)])) # type: ignore[arg-type] + nan_offsets = np.concatenate(([-1], nan_offsets, [len(points)])) return [points[s+1:e] for s, e in zip(nan_offsets[:-1], nan_offsets[1:])] diff --git a/contrib/python/contourpy/contourpy/convert.py b/contrib/python/contourpy/contourpy/convert.py index 75a54b0863..92adbbb5b6 100644 --- a/contrib/python/contourpy/contourpy/convert.py +++ b/contrib/python/contourpy/contourpy/convert.py @@ -257,13 +257,14 @@ def convert_filled( fill_type_from: FillType | str, fill_type_to: FillType | str, ) -> cpy.FillReturn: - """Return the specified filled contours converted to a different :class:`~contourpy.FillType`. + """Convert filled contours from one :class:`~.FillType` to another. Args: - filled (sequence of arrays): Filled contour polygons to convert. - fill_type_from (FillType or str): :class:`~contourpy.FillType` to convert from as enum or + filled (sequence of arrays): Filled contour polygons to convert, such as those returned by + :meth:`.ContourGenerator.filled`. + fill_type_from (FillType or str): :class:`~.FillType` to convert from as enum or string equivalent. - fill_type_to (FillType or str): :class:`~contourpy.FillType` to convert to as enum or string + fill_type_to (FillType or str): :class:`~.FillType` to convert to as enum or string equivalent. Return: @@ -272,7 +273,7 @@ def convert_filled( When converting non-chunked fill types (``FillType.OuterCode`` or ``FillType.OuterOffset``) to chunked ones, all polygons are placed in the first chunk. When converting in the other direction, all chunk information is discarded. Converting a fill type that is not aware of the - relationship between outer boundaries and contained holes (``FillType.ChunkCombinedCode`` or) + relationship between outer boundaries and contained holes (``FillType.ChunkCombinedCode`` or ``FillType.ChunkCombinedOffset``) to one that is will raise a ``ValueError``. .. versionadded:: 1.2.0 @@ -507,13 +508,14 @@ def convert_lines( line_type_from: LineType | str, line_type_to: LineType | str, ) -> cpy.LineReturn: - """Return the specified contour lines converted to a different :class:`~contourpy.LineType`. + """Convert contour lines from one :class:`~.LineType` to another. Args: - lines (sequence of arrays): Contour lines to convert. - line_type_from (LineType or str): :class:`~contourpy.LineType` to convert from as enum or + lines (sequence of arrays): Contour lines to convert, such as those returned by + :meth:`.ContourGenerator.lines`. + line_type_from (LineType or str): :class:`~.LineType` to convert from as enum or string equivalent. - line_type_to (LineType or str): :class:`~contourpy.LineType` to convert to as enum or string + line_type_to (LineType or str): :class:`~.LineType` to convert to as enum or string equivalent. Return: @@ -553,3 +555,66 @@ def convert_lines( return _convert_lines_from_ChunkCombinedNan(lines, line_type_to) else: raise ValueError(f"Invalid LineType {line_type_from}") + + +def convert_multi_filled( + multi_filled: list[cpy.FillReturn], + fill_type_from: FillType | str, + fill_type_to: FillType | str, +) -> list[cpy.FillReturn]: + """Convert multiple sets of filled contours from one :class:`~.FillType` to another. + + Args: + multi_filled (nested sequence of arrays): Filled contour polygons to convert, such as those + returned by :meth:`.ContourGenerator.multi_filled`. + fill_type_from (FillType or str): :class:`~.FillType` to convert from as enum or + string equivalent. + fill_type_to (FillType or str): :class:`~.FillType` to convert to as enum or string + equivalent. + + Return: + Converted sets filled contour polygons. + + When converting non-chunked fill types (``FillType.OuterCode`` or ``FillType.OuterOffset``) to + chunked ones, all polygons are placed in the first chunk. When converting in the other + direction, all chunk information is discarded. Converting a fill type that is not aware of the + relationship between outer boundaries and contained holes (``FillType.ChunkCombinedCode`` or + ``FillType.ChunkCombinedOffset``) to one that is will raise a ``ValueError``. + + .. versionadded:: 1.3.0 + """ + fill_type_from = as_fill_type(fill_type_from) + fill_type_to = as_fill_type(fill_type_to) + + return [convert_filled(filled, fill_type_from, fill_type_to) for filled in multi_filled] + + +def convert_multi_lines( + multi_lines: list[cpy.LineReturn], + line_type_from: LineType | str, + line_type_to: LineType | str, +) -> list[cpy.LineReturn]: + """Convert multiple sets of contour lines from one :class:`~.LineType` to another. + + Args: + multi_lines (nested sequence of arrays): Contour lines to convert, such as those returned by + :meth:`.ContourGenerator.multi_lines`. + line_type_from (LineType or str): :class:`~.LineType` to convert from as enum or + string equivalent. + line_type_to (LineType or str): :class:`~.LineType` to convert to as enum or string + equivalent. + + Return: + Converted set of contour lines. + + When converting non-chunked line types (``LineType.Separate`` or ``LineType.SeparateCode``) to + chunked ones (``LineType.ChunkCombinedCode``, ``LineType.ChunkCombinedOffset`` or + ``LineType.ChunkCombinedNan``), all lines are placed in the first chunk. When converting in the + other direction, all chunk information is discarded. + + .. versionadded:: 1.3.0 + """ + line_type_from = as_line_type(line_type_from) + line_type_to = as_line_type(line_type_to) + + return [convert_lines(lines, line_type_from, line_type_to) for lines in multi_lines] diff --git a/contrib/python/contourpy/contourpy/dechunk.py b/contrib/python/contourpy/contourpy/dechunk.py index 622a1ceb7d..f571b4b5ff 100644 --- a/contrib/python/contourpy/contourpy/dechunk.py +++ b/contrib/python/contourpy/contourpy/dechunk.py @@ -17,16 +17,17 @@ if TYPE_CHECKING: def dechunk_filled(filled: cpy.FillReturn, fill_type: FillType | str) -> cpy.FillReturn: - """Return the specified filled contours with all chunked data moved into the first chunk. + """Return the specified filled contours with chunked data moved into the first chunk. Filled contours that are not chunked (``FillType.OuterCode`` and ``FillType.OuterOffset``) and those that are but only contain a single chunk are returned unmodified. Individual polygons are unchanged, they are not geometrically combined. Args: - filled (sequence of arrays): Filled contour data as returned by - :func:`~contourpy.ContourGenerator.filled`. - fill_type (FillType or str): Type of ``filled`` as enum or string equivalent. + filled (sequence of arrays): Filled contour data, such as returned by + :meth:`.ContourGenerator.filled`. + fill_type (FillType or str): Type of :meth:`~.ContourGenerator.filled` as enum or string + equivalent. Return: Filled contours in a single chunk. @@ -87,16 +88,17 @@ def dechunk_filled(filled: cpy.FillReturn, fill_type: FillType | str) -> cpy.Fil def dechunk_lines(lines: cpy.LineReturn, line_type: LineType | str) -> cpy.LineReturn: - """Return the specified contour lines with all chunked data moved into the first chunk. + """Return the specified contour lines with chunked data moved into the first chunk. Contour lines that are not chunked (``LineType.Separate`` and ``LineType.SeparateCode``) and those that are but only contain a single chunk are returned unmodified. Individual lines are unchanged, they are not geometrically combined. Args: - lines (sequence of arrays): Contour line data as returned by - :func:`~contourpy.ContourGenerator.lines`. - line_type (LineType or str): Type of ``lines`` as enum or string equivalent. + lines (sequence of arrays): Contour line data, such as returned by + :meth:`.ContourGenerator.lines`. + line_type (LineType or str): Type of :meth:`~.ContourGenerator.lines` as enum or string + equivalent. Return: Contour lines in a single chunk. @@ -104,6 +106,7 @@ def dechunk_lines(lines: cpy.LineReturn, line_type: LineType | str) -> cpy.LineR .. versionadded:: 1.2.0 """ line_type = as_line_type(line_type) + if line_type in (LineType.Separate, LineType.SeparateCode): # No-op if line_type is not chunked. return lines @@ -142,3 +145,63 @@ def dechunk_lines(lines: cpy.LineReturn, line_type: LineType | str) -> cpy.LineR return ret3 else: raise ValueError(f"Invalid LineType {line_type}") + + +def dechunk_multi_filled( + multi_filled: list[cpy.FillReturn], + fill_type: FillType | str, +) -> list[cpy.FillReturn]: + """Return multiple sets of filled contours with chunked data moved into the first chunks. + + Filled contours that are not chunked (``FillType.OuterCode`` and ``FillType.OuterOffset``) and + those that are but only contain a single chunk are returned unmodified. Individual polygons are + unchanged, they are not geometrically combined. + + Args: + multi_filled (nested sequence of arrays): Filled contour data, such as returned by + :meth:`.ContourGenerator.multi_filled`. + fill_type (FillType or str): Type of :meth:`~.ContourGenerator.filled` as enum or string + equivalent. + + Return: + Multiple sets of filled contours in a single chunk. + + .. versionadded:: 1.3.0 + """ + fill_type = as_fill_type(fill_type) + + if fill_type in (FillType.OuterCode, FillType.OuterOffset): + # No-op if fill_type is not chunked. + return multi_filled + + return [dechunk_filled(filled, fill_type) for filled in multi_filled] + + +def dechunk_multi_lines( + multi_lines: list[cpy.LineReturn], + line_type: LineType | str, +) -> list[cpy.LineReturn]: + """Return multiple sets of contour lines with all chunked data moved into the first chunks. + + Contour lines that are not chunked (``LineType.Separate`` and ``LineType.SeparateCode``) and + those that are but only contain a single chunk are returned unmodified. Individual lines are + unchanged, they are not geometrically combined. + + Args: + multi_lines (nested sequence of arrays): Contour line data, such as returned by + :meth:`.ContourGenerator.multi_lines`. + line_type (LineType or str): Type of :meth:`~.ContourGenerator.lines` as enum or string + equivalent. + + Return: + Multiple sets of contour lines in a single chunk. + + .. versionadded:: 1.3.0 + """ + line_type = as_line_type(line_type) + + if line_type in (LineType.Separate, LineType.SeparateCode): + # No-op if line_type is not chunked. + return multi_lines + + return [dechunk_lines(lines, line_type) for lines in multi_lines] diff --git a/contrib/python/contourpy/contourpy/util/bokeh_renderer.py b/contrib/python/contourpy/contourpy/util/bokeh_renderer.py index 85b0f8c40e..a8a10e8ad3 100644 --- a/contrib/python/contourpy/contourpy/util/bokeh_renderer.py +++ b/contrib/python/contourpy/contourpy/util/bokeh_renderer.py @@ -38,9 +38,8 @@ class BokehRenderer(Renderer): ``False``. Warning: - :class:`~contourpy.util.bokeh_renderer.BokehRenderer`, unlike - :class:`~contourpy.util.mpl_renderer.MplRenderer`, needs to be told in advance if output to - SVG format will be required later, otherwise it will assume PNG output. + :class:`~.BokehRenderer`, unlike :class:`~.MplRenderer`, needs to be told in advance if + output to SVG format will be required later, otherwise it will assume PNG output. """ _figures: list[figure] _layout: GridPlot @@ -99,9 +98,9 @@ class BokehRenderer(Renderer): Args: filled (sequence of arrays): Filled contour data as returned by - :func:`~contourpy.ContourGenerator.filled`. - fill_type (FillType or str): Type of ``filled`` data as returned by - :attr:`~contourpy.ContourGenerator.fill_type`, or a string equivalent. + :meth:`~.ContourGenerator.filled`. + fill_type (FillType or str): Type of :meth:`~.ContourGenerator.filled` data as returned + by :attr:`~.ContourGenerator.fill_type`, or a string equivalent. ax (int or Bokeh Figure, optional): Which plot to use, default ``0``. color (str, optional): Color to plot with. May be a string color or the letter ``"C"`` followed by an integer in the range ``"C0"`` to ``"C9"`` to use a color from the @@ -179,9 +178,9 @@ class BokehRenderer(Renderer): Args: lines (sequence of arrays): Contour line data as returned by - :func:`~contourpy.ContourGenerator.lines`. - line_type (LineType or str): Type of ``lines`` data as returned by - :attr:`~contourpy.ContourGenerator.line_type`, or a string equivalent. + :meth:`~.ContourGenerator.lines`. + line_type (LineType or str): Type of :meth:`~.ContourGenerator.lines` data as returned + by :attr:`~.ContourGenerator.line_type`, or a string equivalent. ax (int or Bokeh Figure, optional): Which plot to use, default ``0``. color (str, optional): Color to plot lines. May be a string color or the letter ``"C"`` followed by an integer in the range ``"C0"`` to ``"C9"`` to use a color from the diff --git a/contrib/python/contourpy/contourpy/util/data.py b/contrib/python/contourpy/contourpy/util/data.py index 5ab2617205..5fa7548695 100644 --- a/contrib/python/contourpy/contourpy/util/data.py +++ b/contrib/python/contourpy/contourpy/util/data.py @@ -51,7 +51,7 @@ def simple( def random( shape: tuple[int, int], seed: int = 2187, mask_fraction: float = 0.0, ) -> tuple[CoordinateArray, CoordinateArray, CoordinateArray | np.ma.MaskedArray[Any, Any]]: - """Return random test data. + """Return random test data in the range 0 to 1. Args: shape (tuple(int, int)): 2D shape of data to return. diff --git a/contrib/python/contourpy/contourpy/util/mpl_renderer.py b/contrib/python/contourpy/contourpy/util/mpl_renderer.py index c459e02a92..e078ca28f7 100644 --- a/contrib/python/contourpy/contourpy/util/mpl_renderer.py +++ b/contrib/python/contourpy/contourpy/util/mpl_renderer.py @@ -100,9 +100,9 @@ class MplRenderer(Renderer): Args: filled (sequence of arrays): Filled contour data as returned by - :func:`~contourpy.ContourGenerator.filled`. - fill_type (FillType or str): Type of ``filled`` data as returned by - :attr:`~contourpy.ContourGenerator.fill_type`, or string equivalent + :meth:`~.ContourGenerator.filled`. + fill_type (FillType or str): Type of :meth:`~.ContourGenerator.filled` data as returned + by :attr:`~.ContourGenerator.fill_type`, or string equivalent ax (int or Maplotlib Axes, optional): Which axes to plot on, default ``0``. color (str, optional): Color to plot with. May be a string color or the letter ``"C"`` followed by an integer in the range ``"C0"`` to ``"C9"`` to use a color from the @@ -177,9 +177,9 @@ class MplRenderer(Renderer): Args: lines (sequence of arrays): Contour line data as returned by - :func:`~contourpy.ContourGenerator.lines`. - line_type (LineType or str): Type of ``lines`` data as returned by - :attr:`~contourpy.ContourGenerator.line_type`, or string equivalent. + :meth:`~.ContourGenerator.lines`. + line_type (LineType or str): Type of :meth:`~.ContourGenerator.lines` data as returned + by :attr:`~.ContourGenerator.line_type`, or string equivalent. ax (int or Matplotlib Axes, optional): Which Axes to plot on, default ``0``. color (str, optional): Color to plot lines. May be a string color or the letter ``"C"`` followed by an integer in the range ``"C0"`` to ``"C9"`` to use a color from the diff --git a/contrib/python/contourpy/contourpy/util/renderer.py b/contrib/python/contourpy/contourpy/util/renderer.py index f4bdfdff9e..716569f776 100644 --- a/contrib/python/contourpy/contourpy/util/renderer.py +++ b/contrib/python/contourpy/contourpy/util/renderer.py @@ -14,7 +14,7 @@ if TYPE_CHECKING: class Renderer(ABC): - """Abstract base class for renderers, defining the interface that they must implement.""" + """Abstract base class for renderers.""" def _grid_as_2d(self, x: ArrayLike, y: ArrayLike) -> tuple[CoordinateArray, CoordinateArray]: x = np.asarray(x) @@ -23,12 +23,6 @@ class Renderer(ABC): x, y = np.meshgrid(x, y) return x, y - x = np.asarray(x) - y = np.asarray(y) - if x.ndim == 1: - x, y = np.meshgrid(x, y) - return x, y - @abstractmethod def filled( self, @@ -76,6 +70,72 @@ class Renderer(ABC): ) -> None: pass + def multi_filled( + self, + multi_filled: list[FillReturn], + fill_type: FillType | str, + ax: Any = 0, + color: str | None = None, + **kwargs: Any, + ) -> None: + """Plot multiple sets of filled contours on a single axes. + + Args: + multi_filled (list of filled contour arrays): Multiple filled contour sets as returned + by :meth:`.ContourGenerator.multi_filled`. + fill_type (FillType or str): Type of filled data as returned by + :attr:`~.ContourGenerator.fill_type`, or string equivalent. + ax (int or Renderer-specific axes or figure object, optional): Which axes to plot on, + default ``0``. + color (str or None, optional): If a string color then this same color is used for all + filled contours. If ``None``, the default, then the filled contour sets use colors + from the ``tab10`` colormap in order, wrapping around to the beginning if more than + 10 sets of filled contours are rendered. + kwargs: All other keyword argument are passed on to + :meth:`.Renderer.filled` unchanged. + + .. versionadded:: 1.3.0 + """ + if color is not None: + kwargs["color"] = color + for i, filled in enumerate(multi_filled): + if color is None: + kwargs["color"] = f"C{i % 10}" + self.filled(filled, fill_type, ax, **kwargs) + + def multi_lines( + self, + multi_lines: list[LineReturn], + line_type: LineType | str, + ax: Any = 0, + color: str | None = None, + **kwargs: Any, + ) -> None: + """Plot multiple sets of contour lines on a single axes. + + Args: + multi_lines (list of contour line arrays): Multiple contour line sets as returned by + :meth:`.ContourGenerator.multi_lines`. + line_type (LineType or str): Type of line data as returned by + :attr:`~.ContourGenerator.line_type`, or string equivalent. + ax (int or Renderer-specific axes or figure object, optional): Which axes to plot on, + default ``0``. + color (str or None, optional): If a string color then this same color is used for all + lines. If ``None``, the default, then the line sets use colors from the ``tab10`` + colormap in order, wrapping around to the beginning if more than 10 sets of lines + are rendered. + kwargs: All other keyword argument are passed on to + :meth:`Renderer.lines` unchanged. + + .. versionadded:: 1.3.0 + """ + if color is not None: + kwargs["color"] = color + for i, lines in enumerate(multi_lines): + if color is None: + kwargs["color"] = f"C{i % 10}" + self.lines(lines, line_type, ax, **kwargs) + @abstractmethod def save(self, filename: str, transparent: bool = False) -> None: pass diff --git a/contrib/python/contourpy/src/base.h b/contrib/python/contourpy/src/base.h index e626e99431..6b4d99d17e 100644 --- a/contrib/python/contourpy/src/base.h +++ b/contrib/python/contourpy/src/base.h @@ -24,11 +24,13 @@ template <typename Derived> class BaseContourGenerator : public ContourGenerator { public: - ~BaseContourGenerator(); + virtual ~BaseContourGenerator(); static FillType default_fill_type(); static LineType default_line_type(); + py::tuple filled(double lower_level, double upper_level) override; + py::tuple get_chunk_count() const; // Return (y_chunk_count, x_chunk_count) py::tuple get_chunk_size() const; // Return (y_chunk_size, x_chunk_size) @@ -41,8 +43,10 @@ public: ZInterp get_z_interp() const; - py::sequence filled(double lower_level, double upper_level); - py::sequence lines(double level); + py::sequence lines(double level) override; + + py::list multi_filled(const LevelArray levels) override; + py::list multi_lines(const LevelArray levels) override; static bool supports_fill_type(FillType fill_type); static bool supports_line_type(LineType line_type); @@ -149,8 +153,6 @@ protected: void interp( index_t point0, double x1, double y1, double z1, bool is_upper, double*& points) const; - bool is_filled() const; - bool is_point_in_chunk(index_t point, const ChunkLocal& local) const; bool is_quad_in_bounds( @@ -166,6 +168,10 @@ protected: void move_to_next_boundary_edge(index_t& quad, index_t& forward, index_t& left) const; + // Common initialisation for filled/multi_filled and lines/multi_lines calls. + void pre_filled(); + void pre_lines(); + void set_look_flags(index_t hole_start_quad); void write_cache_quad(index_t quad) const; diff --git a/contrib/python/contourpy/src/base_impl.h b/contrib/python/contourpy/src/base_impl.h index 6175ad5c56..80c9e51854 100644 --- a/contrib/python/contourpy/src/base_impl.h +++ b/contrib/python/contourpy/src/base_impl.h @@ -351,28 +351,13 @@ LineType BaseContourGenerator<Derived>::default_line_type() } template <typename Derived> -py::sequence BaseContourGenerator<Derived>::filled(double lower_level, double upper_level) +py::tuple BaseContourGenerator<Derived>::filled(double lower_level, double upper_level) { - if (lower_level >= upper_level) - throw std::invalid_argument("upper_level must be larger than lower_level"); + check_levels(lower_level, upper_level); + pre_filled(); - _filled = true; _lower_level = lower_level; _upper_level = upper_level; - - _identify_holes = !(_fill_type == FillType::ChunkCombinedCode || - _fill_type == FillType::ChunkCombinedOffset); - _output_chunked = !(_fill_type == FillType::OuterCode || _fill_type == FillType::OuterOffset); - _direct_points = _output_chunked; - _direct_line_offsets = (_fill_type == FillType::ChunkCombinedOffset|| - _fill_type == FillType::ChunkCombinedOffsetOffset); - _direct_outer_offsets = (_fill_type == FillType::ChunkCombinedCodeOffset || - _fill_type == FillType::ChunkCombinedOffsetOffset); - _outer_offsets_into_points = (_fill_type == FillType::ChunkCombinedCodeOffset); - _nan_separated = false; - _return_list_count = (_fill_type == FillType::ChunkCombinedCodeOffset || - _fill_type == FillType::ChunkCombinedOffsetOffset) ? 3 : 2; - return march_wrapper(); } @@ -1879,12 +1864,6 @@ void BaseContourGenerator<Derived>::interp( } template <typename Derived> -bool BaseContourGenerator<Derived>::is_filled() const -{ - return _filled; -} - -template <typename Derived> bool BaseContourGenerator<Derived>::is_point_in_chunk(index_t point, const ChunkLocal& local) const { return is_quad_in_bounds(point, local.istart-1, local.iend, local.jstart-1, local.jend); @@ -1942,22 +1921,9 @@ void BaseContourGenerator<Derived>::line(const Location& start_location, ChunkLo template <typename Derived> py::sequence BaseContourGenerator<Derived>::lines(double level) { - _filled = false; - _lower_level = _upper_level = level; - - _identify_holes = false; - _output_chunked = !(_line_type == LineType::Separate || _line_type == LineType::SeparateCode); - _direct_points = _output_chunked; - _direct_line_offsets = (_line_type == LineType::ChunkCombinedOffset); - _direct_outer_offsets = false; - _outer_offsets_into_points = false; - _return_list_count = (_line_type == LineType::Separate || - _line_type == LineType::ChunkCombinedNan) ? 1 : 2; - _nan_separated = (_line_type == LineType::ChunkCombinedNan); - - if (_nan_separated) - Util::ensure_nan_loaded(); + pre_lines(); + _lower_level = _upper_level = level; return march_wrapper(); } @@ -2358,6 +2324,82 @@ void BaseContourGenerator<Derived>::move_to_next_boundary_edge( } template <typename Derived> +py::list BaseContourGenerator<Derived>::multi_filled(const LevelArray levels) +{ + check_levels(levels, true); + pre_filled(); + + auto levels_proxy = levels.unchecked<1>(); + auto n = levels_proxy.size(); + + py::list ret(n-1); + _lower_level = levels_proxy[0]; + for (decltype(n) i = 0; i < n-1; i++) { + _upper_level = levels_proxy[i+1]; + ret[i] = march_wrapper(); + _lower_level = _upper_level; + } + + return ret; +} + +template <typename Derived> +py::list BaseContourGenerator<Derived>::multi_lines(const LevelArray levels) +{ + check_levels(levels, false); + pre_lines(); + + auto levels_proxy = levels.unchecked<1>(); + auto n = levels_proxy.size(); + + py::list ret(n); + for (decltype(n) i = 0; i < n; i++) { + _lower_level = _upper_level = levels_proxy[i]; + ret[i] = march_wrapper(); + } + + return ret; +} + +template <typename Derived> +void BaseContourGenerator<Derived>::pre_filled() +{ + _filled = true; + + _identify_holes = !(_fill_type == FillType::ChunkCombinedCode || + _fill_type == FillType::ChunkCombinedOffset); + _output_chunked = !(_fill_type == FillType::OuterCode || _fill_type == FillType::OuterOffset); + _direct_points = _output_chunked; + _direct_line_offsets = (_fill_type == FillType::ChunkCombinedOffset|| + _fill_type == FillType::ChunkCombinedOffsetOffset); + _direct_outer_offsets = (_fill_type == FillType::ChunkCombinedCodeOffset || + _fill_type == FillType::ChunkCombinedOffsetOffset); + _outer_offsets_into_points = (_fill_type == FillType::ChunkCombinedCodeOffset); + _nan_separated = false; + _return_list_count = (_fill_type == FillType::ChunkCombinedCodeOffset || + _fill_type == FillType::ChunkCombinedOffsetOffset) ? 3 : 2; +} + +template <typename Derived> +void BaseContourGenerator<Derived>::pre_lines() +{ + _filled = false; + + _identify_holes = false; + _output_chunked = !(_line_type == LineType::Separate || _line_type == LineType::SeparateCode); + _direct_points = _output_chunked; + _direct_line_offsets = (_line_type == LineType::ChunkCombinedOffset); + _direct_outer_offsets = false; + _outer_offsets_into_points = false; + _return_list_count = (_line_type == LineType::Separate || + _line_type == LineType::ChunkCombinedNan) ? 1 : 2; + _nan_separated = (_line_type == LineType::ChunkCombinedNan); + + if (_nan_separated) + Util::ensure_nan_loaded(); +} + +template <typename Derived> void BaseContourGenerator<Derived>::set_look_flags(index_t hole_start_quad) { assert(_identify_holes); diff --git a/contrib/python/contourpy/src/common.h b/contrib/python/contourpy/src/common.h index cc4bc851a0..68c522d1b6 100644 --- a/contrib/python/contourpy/src/common.h +++ b/contrib/python/contourpy/src/common.h @@ -21,6 +21,7 @@ typedef uint32_t offset_t; // Input numpy array classes. typedef py::array_t<double, py::array::c_style | py::array::forcecast> CoordinateArray; typedef py::array_t<bool, py::array::c_style | py::array::forcecast> MaskArray; +typedef py::array_t<double> LevelArray; // Doesn't have to be contiguous. // Output numpy array classes. typedef py::array_t<double> PointArray; diff --git a/contrib/python/contourpy/src/contour_generator.cpp b/contrib/python/contourpy/src/contour_generator.cpp new file mode 100644 index 0000000000..5ede6fa46e --- /dev/null +++ b/contrib/python/contourpy/src/contour_generator.cpp @@ -0,0 +1,79 @@ +#include "contour_generator.h" +#include "util.h" + +namespace contourpy { + +void ContourGenerator::check_levels(const LevelArray& levels, bool filled) const +{ + if (levels.ndim() != 1) { + throw std::domain_error( + "Levels array must be 1D not " + std::to_string(levels.ndim()) + "D"); + } + + if (filled) { + auto n = levels.size(); + if (n < 2) { + throw std::invalid_argument( + "Levels array must have at least 2 elements, not " + std::to_string(n)); + } + + auto levels_proxy = levels.unchecked<1>(); + + // Check levels are not NaN. + for (decltype(n) i = 0; i < n; i++) { + if (Util::is_nan(levels_proxy[i])) + throw std::invalid_argument("Levels must not contain any NaN"); + } + + // Check levels are increasing. + auto lower_level = levels_proxy[0]; + for (decltype(n) i = 0; i < n-1; i++) { + auto upper_level = levels_proxy[i+1]; + if (lower_level >= upper_level) + throw std::invalid_argument("Levels must be increasing"); + lower_level = upper_level; + } + } +} + +void ContourGenerator::check_levels(double lower_level, double upper_level) const +{ + if (Util::is_nan(lower_level) || Util::is_nan(upper_level)) + throw std::invalid_argument("lower_level and upper_level cannot be NaN"); + if (lower_level >= upper_level) + throw std::invalid_argument("upper_level must be larger than lower_level"); +} + +py::list ContourGenerator::multi_filled(const LevelArray levels) +{ + check_levels(levels, true); + + auto levels_proxy = levels.unchecked<1>(); + auto n = levels_proxy.size(); + + py::list ret(n-1); + auto lower_level = levels_proxy[0]; + for (decltype(n) i = 0; i < n-1; i++) { + auto upper_level = levels_proxy[i+1]; + ret[i] = filled(lower_level, upper_level); + lower_level = upper_level; + } + + return ret; +} + +py::list ContourGenerator::multi_lines(const LevelArray levels) +{ + check_levels(levels, false); + + auto levels_proxy = levels.unchecked<1>(); + auto n = levels_proxy.size(); + + py::list ret(n); + for (decltype(n) i = 0; i < n; i++) + ret[i] = lines(levels_proxy[i]); + + return ret; +} + +} // namespace contourpy diff --git a/contrib/python/contourpy/src/contour_generator.h b/contrib/python/contourpy/src/contour_generator.h index ce527b25f8..c437580023 100644 --- a/contrib/python/contourpy/src/contour_generator.h +++ b/contrib/python/contourpy/src/contour_generator.h @@ -14,8 +14,21 @@ public: ContourGenerator& operator=(const ContourGenerator& other) = delete; ContourGenerator& operator=(const ContourGenerator&& other) = delete; + virtual ~ContourGenerator() = default; + + virtual py::tuple filled(double lower_level, double upper_level) = 0; + + virtual py::sequence lines(double level) = 0; + + virtual py::list multi_filled(const LevelArray levels); + virtual py::list multi_lines(const LevelArray levels); + protected: ContourGenerator() = default; + + // Check levels are acceptable, throw exception if not. + void check_levels(const LevelArray& levels, bool filled) const; + void check_levels(double lower_level, double upper_level) const; }; } // namespace contourpy diff --git a/contrib/python/contourpy/src/converter.cpp b/contrib/python/contourpy/src/converter.cpp index 1f693ceb1a..6a800e2ec8 100644 --- a/contrib/python/contourpy/src/converter.cpp +++ b/contrib/python/contourpy/src/converter.cpp @@ -13,7 +13,7 @@ void Converter::check_max_offset(count_t max_offset) CodeArray Converter::convert_codes( count_t point_count, count_t cut_count, const offset_t* cut_start, offset_t subtract) { - assert(point_count > 0 && cut_count > 0 && subtract >= 0); + assert(point_count > 0 && cut_count > 0); assert(cut_start != nullptr); index_t codes_shape = static_cast<index_t>(point_count); @@ -26,7 +26,7 @@ void Converter::convert_codes( count_t point_count, count_t cut_count, const offset_t* cut_start, offset_t subtract, CodeArray::value_type* codes) { - assert(point_count > 0 && cut_count > 0 && subtract >= 0); + assert(point_count > 0 && cut_count > 0); assert(cut_start != nullptr); assert(codes != nullptr); @@ -105,7 +105,7 @@ void Converter::convert_codes_check_closed_single( OffsetArray Converter::convert_offsets( count_t offset_count, const offset_t* start, offset_t subtract) { - assert(offset_count > 0 && subtract >= 0); + assert(offset_count > 0); assert(start != nullptr); index_t offsets_shape = static_cast<index_t>(offset_count); @@ -118,7 +118,7 @@ void Converter::convert_offsets( count_t offset_count, const offset_t* start, offset_t subtract, OffsetArray::value_type* offsets) { - assert(offset_count > 0 && subtract >= 0); + assert(offset_count > 0); assert(start != nullptr); assert(offsets != nullptr); diff --git a/contrib/python/contourpy/src/mpl2005.cpp b/contrib/python/contourpy/src/mpl2005.cpp index a62d6e86ce..d94432a44f 100644 --- a/contrib/python/contourpy/src/mpl2005.cpp +++ b/contrib/python/contourpy/src/mpl2005.cpp @@ -46,11 +46,9 @@ Mpl2005ContourGenerator::~Mpl2005ContourGenerator() cntr_del(_site); } -py::tuple Mpl2005ContourGenerator::filled(const double& lower_level, const double& upper_level) +py::tuple Mpl2005ContourGenerator::filled(double lower_level, double upper_level) { - if (lower_level >= upper_level) - throw std::invalid_argument("upper_level must be larger than lower_level"); - + check_levels(lower_level, upper_level); double levels[2] = {lower_level, upper_level}; return cntr_trace(_site, levels, 2); } @@ -67,7 +65,7 @@ py::tuple Mpl2005ContourGenerator::get_chunk_size() const return py::make_tuple(_site->j_chunk_size, _site->i_chunk_size); } -py::tuple Mpl2005ContourGenerator::lines(const double& level) +py::sequence Mpl2005ContourGenerator::lines(double level) { double levels[2] = {level, 0.0}; return cntr_trace(_site, levels, 1); diff --git a/contrib/python/contourpy/src/mpl2005.h b/contrib/python/contourpy/src/mpl2005.h index e112880765..5801f5d17b 100644 --- a/contrib/python/contourpy/src/mpl2005.h +++ b/contrib/python/contourpy/src/mpl2005.h @@ -13,14 +13,14 @@ public: const CoordinateArray& x, const CoordinateArray& y, const CoordinateArray& z, const MaskArray& mask, index_t x_chunk_size, index_t y_chunk_size); - ~Mpl2005ContourGenerator(); + virtual ~Mpl2005ContourGenerator(); - py::tuple filled(const double& lower_level, const double& upper_level); + py::tuple filled(double lower_level, double upper_level) override; py::tuple get_chunk_count() const; // Return (y_chunk_count, x_chunk_count) py::tuple get_chunk_size() const; // Return (y_chunk_size, x_chunk_size) - py::tuple lines(const double& level); + py::sequence lines(double level) override; private: CoordinateArray _x, _y, _z; diff --git a/contrib/python/contourpy/src/mpl2014.cpp b/contrib/python/contourpy/src/mpl2014.cpp index a363fa8768..e1021572a7 100644 --- a/contrib/python/contourpy/src/mpl2014.cpp +++ b/contrib/python/contourpy/src/mpl2014.cpp @@ -483,16 +483,13 @@ void Mpl2014ContourGenerator::edge_interp( level, contour_line); } -py::tuple Mpl2014ContourGenerator::filled( - const double& lower_level, const double& upper_level) +py::tuple Mpl2014ContourGenerator::filled(double lower_level, double upper_level) { - if (lower_level >= upper_level) - throw std::invalid_argument("upper_level must be larger than lower_level"); + check_levels(lower_level, upper_level); init_cache_levels(lower_level, upper_level); Contour contour; - py::list vertices, codes; index_t ichunk, jchunk, istart, iend, jstart, jend; @@ -1218,7 +1215,7 @@ bool Mpl2014ContourGenerator::is_edge_a_boundary( } } -py::tuple Mpl2014ContourGenerator::lines(const double& level) +py::sequence Mpl2014ContourGenerator::lines(double level) { init_cache_levels(level, level); diff --git a/contrib/python/contourpy/src/mpl2014.h b/contrib/python/contourpy/src/mpl2014.h index 105ce23c1f..5872e8ddcf 100644 --- a/contrib/python/contourpy/src/mpl2014.h +++ b/contrib/python/contourpy/src/mpl2014.h @@ -270,11 +270,11 @@ public: const MaskArray& mask, bool corner_mask, index_t x_chunk_size, index_t y_chunk_size); // Destructor. - ~Mpl2014ContourGenerator(); + virtual ~Mpl2014ContourGenerator(); // Create and return polygons for a filled contour between the two // specified levels. - py::tuple filled(const double& lower_level, const double& upper_level); + py::tuple filled(double lower_level, double upper_level) override; py::tuple get_chunk_count() const; // Return (y_chunk_count, x_chunk_count) py::tuple get_chunk_size() const; // Return (y_chunk_size, x_chunk_size) @@ -283,7 +283,7 @@ public: // Create and return polygons for a line (i.e. non-filled) contour at the // specified level. - py::tuple lines(const double& level); + py::sequence lines(double level) override; private: // Typedef for following either a boundary of the domain or the interior; diff --git a/contrib/python/contourpy/src/util.cpp b/contrib/python/contourpy/src/util.cpp index 59b6e4da55..82c1cc21d9 100644 --- a/contrib/python/contourpy/src/util.cpp +++ b/contrib/python/contourpy/src/util.cpp @@ -1,4 +1,5 @@ #include "util.h" +#include <cmath> #include <thread> namespace contourpy { @@ -21,4 +22,9 @@ index_t Util::get_max_threads() return static_cast<index_t>(std::thread::hardware_concurrency()); } +bool Util::is_nan(double value) +{ + return std::isnan(value); +} + } // namespace contourpy diff --git a/contrib/python/contourpy/src/util.h b/contrib/python/contourpy/src/util.h index f4a1abda79..dcafd131c1 100644 --- a/contrib/python/contourpy/src/util.h +++ b/contrib/python/contourpy/src/util.h @@ -12,6 +12,8 @@ public: static index_t get_max_threads(); + static bool is_nan(double value); + // This is the NaN used internally and returned to calling functions. The value is taken from // numpy rather than the standard C++ approach so that it is guaranteed to work with // numpy.isnan(). The value is actually the same for many platforms, but this approach diff --git a/contrib/python/contourpy/src/wrap.cpp b/contrib/python/contourpy/src/wrap.cpp index b784f814a5..fede228095 100644 --- a/contrib/python/contourpy/src/wrap.cpp +++ b/contrib/python/contourpy/src/wrap.cpp @@ -13,18 +13,19 @@ #define MACRO_STRINGIFY(x) STRINGIFY(x) namespace py = pybind11; +using namespace pybind11::literals; static contourpy::LineType mpl20xx_line_type = contourpy::LineType::SeparateCode; static contourpy::FillType mpl20xx_fill_type = contourpy::FillType::OuterCode; -PYBIND11_MODULE(_contourpy, m) { +PYBIND11_MODULE(_contourpy, m, py::mod_gil_not_used()) { m.doc() = "C++11 extension module wrapped using `pybind11`_.\n\n" "It should not be necessary to access classes and functions in this extension module " - "directly. Instead, :func:`contourpy.contour_generator` should be used to create " - ":class:`~contourpy.ContourGenerator` objects, and the enums " - "(:class:`~contourpy.FillType`, :class:`~contourpy.LineType` and " - ":class:`~contourpy.ZInterp`) and :func:`contourpy.max_threads` function are all available " + "directly. Instead, :func:`~contourpy.contour_generator` should be used to create " + ":class:`~.ContourGenerator` objects, and the enums " + "(:class:`~.FillType`, :class:`~.LineType` and " + ":class:`~.ZInterp`) and :func:`.max_threads` function are all available " "in the :mod:`contourpy` module."; m.attr("__version__") = MACRO_STRINGIFY(CONTOURPY_VERSION); @@ -38,9 +39,9 @@ PYBIND11_MODULE(_contourpy, m) { #endif py::enum_<contourpy::FillType>(m, "FillType", - "Enum used for ``fill_type`` keyword argument in :func:`~contourpy.contour_generator`.\n\n" + "Enum used for ``fill_type`` keyword argument in :func:`~.contour_generator`.\n\n" "This controls the format of filled contour data returned from " - ":meth:`~contourpy.ContourGenerator.filled`.") + ":meth:`~.ContourGenerator.filled`.") .value("OuterCode", contourpy::FillType::OuterCode) .value("OuterOffset", contourpy::FillType::OuterOffset) .value("ChunkCombinedCode", contourpy::FillType::ChunkCombinedCode) @@ -50,9 +51,9 @@ PYBIND11_MODULE(_contourpy, m) { .export_values(); py::enum_<contourpy::LineType>(m, "LineType", - "Enum used for ``line_type`` keyword argument in :func:`~contourpy.contour_generator`.\n\n" + "Enum used for ``line_type`` keyword argument in :func:`~.contour_generator`.\n\n" "This controls the format of contour line data returned from " - ":meth:`~contourpy.ContourGenerator.lines`.\n\n" + ":meth:`~.ContourGenerator.lines`.\n\n" "``LineType.ChunkCombinedNan`` added in version 1.2.0") .value("Separate", contourpy::LineType::Separate) .value("SeparateCode", contourpy::LineType::SeparateCode) @@ -62,7 +63,7 @@ PYBIND11_MODULE(_contourpy, m) { .export_values(); py::enum_<contourpy::ZInterp>(m, "ZInterp", - "Enum used for ``z_interp`` keyword argument in :func:`~contourpy.contour_generator`\n\n" + "Enum used for ``z_interp`` keyword argument in :func:`~.contour_generator`\n\n" "This controls the interpolation used on ``z`` values to determine where contour lines " "intersect the edges of grid quads, and ``z`` values at quad centres.") .value("Linear", contourpy::ZInterp::Linear) @@ -73,47 +74,88 @@ PYBIND11_MODULE(_contourpy, m) { "Return the maximum number of threads, obtained from " "``std::thread::hardware_concurrency()``.\n\n" "This is the number of threads used by a multithreaded ContourGenerator if the kwarg " - "``threads=0`` is passed to :func:`~contourpy.contour_generator`."); + "``threads=0`` is passed to :func:`~.contour_generator`."); const char* chunk_count_doc = "Return tuple of (y, x) chunk counts."; const char* chunk_size_doc = "Return tuple of (y, x) chunk sizes."; const char* corner_mask_doc = "Return whether ``corner_mask`` is set or not."; const char* create_contour_doc = - "Synonym for :func:`~contourpy.ContourGenerator.lines` to provide backward compatibility " + "Synonym for :meth:`~.ContourGenerator.lines` to provide backward compatibility " "with Matplotlib."; const char* create_filled_contour_doc = - "Synonym for :func:`~contourpy.ContourGenerator.filled` to provide backward compatibility " + "Synonym for :meth:`~.ContourGenerator.filled` to provide backward compatibility " "with Matplotlib."; - const char* default_fill_type_doc = "Return the default ``FillType`` used by this algorithm."; - const char* default_line_type_doc = "Return the default ``LineType`` used by this algorithm."; - const char* fill_type_doc = "Return the ``FillType``."; + const char* default_fill_type_doc = + "Return the default :class:`~.FillType` used by this algorithm."; + const char* default_line_type_doc = + "Return the default :class:`~.LineType` used by this algorithm."; + const char* fill_type_doc = "Return the :class:`~.FillType`."; const char* filled_doc = "Calculate and return filled contours between two levels.\n\n" "Args:\n" - " lower_level (float): Lower z-level of the filled contours.\n" - " upper_level (float): Upper z-level of the filled contours.\n" + " lower_level (float): Lower z-level of the filled contours, cannot be ``np.nan``.\n" + " upper_level (float): Upper z-level of the filled contours, cannot be ``np.nan``.\n" "Return:\n" - " Filled contour polygons as one or more sequences of numpy arrays. The exact format is " - "determined by the ``fill_type`` used by the ``ContourGenerator``.\n\n" - "Raises a ``ValueError`` if ``lower_level >= upper_level``.\n\n" + " Filled contour polygons as nested sequences of numpy arrays. The exact format is " + "determined by the :attr:`~.ContourGenerator.fill_type` used by the ``ContourGenerator`` " + "and the options are explained at :ref:`fill_type`.\n\n" + "Raises a ``ValueError`` if ``lower_level >= upper_level`` or if\n" + "``lower_level`` or ``upper_level`` are ``np.nan``.\n\n" "To return filled contours below a ``level`` use ``filled(-np.inf, level)``.\n" "To return filled contours above a ``level`` use ``filled(level, np.inf)``"; - const char* line_type_doc = "Return the ``LineType``."; + const char* line_type_doc = "Return the :class:`~.LineType`."; const char* lines_doc = "Calculate and return contour lines at a particular level.\n\n" "Args:\n" " level (float): z-level to calculate contours at.\n\n" "Return:\n" - " Contour lines (open line strips and closed line loops) as one or more sequences of " - "numpy arrays. The exact format is determined by the ``line_type`` used by the " - "``ContourGenerator``."; + " Contour lines (open line strips and closed line loops) as nested sequences of " + "numpy arrays. The exact format is determined by the :attr:`~.ContourGenerator.line_type` " + "used by the ``ContourGenerator`` and the options are explained at :ref:`line_type`.\n\n" + "``level`` may be ``np.nan``, ``np.inf`` or ``-np.inf``; they all return the same result " + "which is an empty line set."; + const char* multi_filled_doc = + "Calculate and return filled contours between multiple pairs of adjacent levels.\n\n" + "Args:\n" + " levels (array-like of floats): z-levels to calculate filled contours between. " + "There must be at least 2 levels, they cannot be NaN, and each level must be larger than " + "the previous level.\n\n" + "Return:\n" + " List of filled contours, one per pair of levels. The length of the returned list is " + "one less than ``len(levels)``. The format of returned contours is determined by the " + "``fill_type`` used by the ``ContourGenerator`` and the options are explained at " + ":ref:`fill_type`.\n\n" + "Raises a ``ValueError`` if ``levels`` are not increasing, or contain a NaN, or there are " + "fewer than 2 ``levels``.\n\n" + "Calling:\n\n" + ".. code-block:: python\n\n" + " ret = cont_gen.multi_filled(levels)\n\n" + "is equivalent to:\n\n" + ".. code-block:: python\n\n" + " ret = [cont_gen.filled(lower, upper) for lower, upper in zip(levels[:-1], levels[1:])]\n\n" + ".. versionadded:: 1.3.0"; + const char* multi_lines_doc = + "Calculate and return contour lines at multiple levels.\n\n" + "Args:\n" + " levels (array-like of floats): z-levels to calculate contours at.\n\n" + "Return:\n" + " List of contour lines, one per level. The format of returned lines is determined by " + "the ``line_type`` used by the ``ContourGenerator`` and the options are explained at " + ":ref:`line_type`.\n\n" + "Calling:\n\n" + ".. code-block:: python\n\n" + " ret = cont_gen.multi_lines(levels)\n\n" + "is equivalent to:\n\n" + ".. code-block:: python\n\n" + " ret = [cont_gen.lines(level) for level in levels]\n\n" + ".. versionadded:: 1.3.0"; const char* quad_as_tri_doc = "Return whether ``quad_as_tri`` is set or not."; const char* supports_corner_mask_doc = "Return whether this algorithm supports ``corner_mask``."; const char* supports_fill_type_doc = - "Return whether this algorithm supports a particular ``FillType``."; + "Return whether this algorithm supports a particular :class:`~.FillType`."; const char* supports_line_type_doc = - "Return whether this algorithm supports a particular ``LineType``."; + "Return whether this algorithm supports a particular :class:`~.LineType`."; const char* supports_quad_as_tri_doc = "Return whether this algorithm supports ``quad_as_tri``."; const char* supports_threads_doc = @@ -127,18 +169,15 @@ PYBIND11_MODULE(_contourpy, m) { py::class_<contourpy::ContourGenerator>(m, "ContourGenerator", "Abstract base class for contour generator classes, defining the interface that they all " "implement.") - .def("create_contour", - [](py::object /* self */, double level) {return py::make_tuple();}, - py::arg("level"), create_contour_doc) - .def("create_filled_contour", - [](py::object /* self */, double lower_level, double upper_level) {return py::make_tuple();}, - py::arg("lower_level"), py::arg("upper_level"), create_filled_contour_doc) - .def("filled", - [](py::object /* self */, double lower_level, double upper_level) {return py::make_tuple();}, - py::arg("lower_level"), py::arg("upper_level"), filled_doc) - .def("lines", - [](py::object /* self */, double level) {return py::make_tuple();}, - py::arg("level"), lines_doc) + .def("create_contour", &contourpy::ContourGenerator::lines, create_contour_doc, "level"_a) + .def("create_filled_contour", &contourpy::ContourGenerator::filled, + create_filled_contour_doc, "lower_level"_a, "upper_level"_a) + .def("filled", &contourpy::ContourGenerator::filled, filled_doc, + "lower_level"_a, "upper_level"_a) + .def("lines", &contourpy::ContourGenerator::lines, lines_doc, "level"_a) + .def("multi_filled", &contourpy::ContourGenerator::multi_filled, multi_filled_doc, + "levels"_a) + .def("multi_lines", &contourpy::ContourGenerator::multi_lines, multi_lines_doc, "levels"_a) .def_property_readonly( "chunk_count", [](py::object /* self */) {return py::make_tuple(1, 1);}, chunk_count_doc) @@ -169,10 +208,10 @@ PYBIND11_MODULE(_contourpy, m) { .def_static("supports_corner_mask", []() {return false;}, supports_corner_mask_doc) .def_static( "supports_fill_type", [](contourpy::FillType /* fill_type */) {return false;}, - py::arg("fill_type"), supports_fill_type_doc) + "fill_type"_a, supports_fill_type_doc) .def_static( "supports_line_type", [](contourpy::LineType /* line_type */) {return false;}, - py::arg("line_type"), supports_line_type_doc) + "line_type"_a, supports_line_type_doc) .def_static("supports_quad_as_tri", []() {return false;}, supports_quad_as_tri_doc) .def_static("supports_threads", []() {return false;}, supports_threads_doc) .def_static("supports_z_interp", []() {return false;}, supports_z_interp_doc); @@ -193,18 +232,8 @@ PYBIND11_MODULE(_contourpy, m) { const contourpy::MaskArray&, contourpy::index_t, contourpy::index_t>(), - py::arg("x"), - py::arg("y"), - py::arg("z"), - py::arg("mask"), - py::kw_only(), - py::arg("x_chunk_size") = 0, - py::arg("y_chunk_size") = 0) - .def("create_contour", &contourpy::Mpl2005ContourGenerator::lines, create_contour_doc) - .def("create_filled_contour", &contourpy::Mpl2005ContourGenerator::filled, - create_filled_contour_doc) - .def("filled", &contourpy::Mpl2005ContourGenerator::filled, filled_doc) - .def("lines", &contourpy::Mpl2005ContourGenerator::lines, lines_doc) + "x"_a, "y"_a, "z"_a, "mask"_a, py::kw_only(), "x_chunk_size"_a = 0, + "y_chunk_size"_a = 0) .def_property_readonly( "chunk_count", &contourpy::Mpl2005ContourGenerator::get_chunk_count, chunk_count_doc) .def_property_readonly( @@ -247,20 +276,8 @@ PYBIND11_MODULE(_contourpy, m) { bool, contourpy::index_t, contourpy::index_t>(), - py::arg("x"), - py::arg("y"), - py::arg("z"), - py::arg("mask"), - py::kw_only(), - py::arg("corner_mask"), - py::arg("x_chunk_size") = 0, - py::arg("y_chunk_size") = 0) - .def("create_contour", &contourpy::mpl2014::Mpl2014ContourGenerator::lines, - create_contour_doc) - .def("create_filled_contour", &contourpy::mpl2014::Mpl2014ContourGenerator::filled, - create_filled_contour_doc) - .def("filled", &contourpy::mpl2014::Mpl2014ContourGenerator::filled, filled_doc) - .def("lines", &contourpy::mpl2014::Mpl2014ContourGenerator::lines, lines_doc) + "x"_a, "y"_a, "z"_a, "mask"_a, py::kw_only(), "corner_mask"_a, "x_chunk_size"_a = 0, + "y_chunk_size"_a = 0) .def_property_readonly( "chunk_count", &contourpy::mpl2014::Mpl2014ContourGenerator::get_chunk_count, chunk_count_doc) @@ -307,24 +324,10 @@ PYBIND11_MODULE(_contourpy, m) { contourpy::ZInterp, contourpy::index_t, contourpy::index_t>(), - py::arg("x"), - py::arg("y"), - py::arg("z"), - py::arg("mask"), - py::kw_only(), - py::arg("corner_mask"), - py::arg("line_type"), - py::arg("fill_type"), - py::arg("quad_as_tri"), - py::arg("z_interp"), - py::arg("x_chunk_size") = 0, - py::arg("y_chunk_size") = 0) + "x"_a, "y"_a, "z"_a, "mask"_a, py::kw_only(), "corner_mask"_a, "line_type"_a, + "fill_type"_a, "quad_as_tri"_a, "z_interp"_a, "x_chunk_size"_a = 0, + "y_chunk_size"_a = 0) .def("_write_cache", &contourpy::SerialContourGenerator::write_cache) - .def("create_contour", &contourpy::SerialContourGenerator::lines, create_contour_doc) - .def("create_filled_contour", &contourpy::SerialContourGenerator::filled, - create_filled_contour_doc) - .def("filled", &contourpy::SerialContourGenerator::filled, filled_doc) - .def("lines", &contourpy::SerialContourGenerator::lines, lines_doc) .def_property_readonly( "chunk_count", &contourpy::SerialContourGenerator::get_chunk_count, chunk_count_doc) .def_property_readonly( @@ -359,7 +362,7 @@ PYBIND11_MODULE(_contourpy, m) { py::class_<contourpy::ThreadedContourGenerator, contourpy::ContourGenerator>( m, "ThreadedContourGenerator", "ContourGenerator corresponding to ``name=\"threaded\"``, the multithreaded version of " - ":class:`~contourpy._contourpy.SerialContourGenerator`.\n\n" + ":class:`~.SerialContourGenerator`.\n\n" "Supports ``corner_mask``, ``quad_as_tri`` and ``z_interp`` and ``threads``. " "Supports all options for ``line_type`` and ``fill_type``.") .def(py::init<const contourpy::CoordinateArray&, @@ -374,25 +377,10 @@ PYBIND11_MODULE(_contourpy, m) { contourpy::index_t, contourpy::index_t, contourpy::index_t>(), - py::arg("x"), - py::arg("y"), - py::arg("z"), - py::arg("mask"), - py::kw_only(), - py::arg("corner_mask"), - py::arg("line_type"), - py::arg("fill_type"), - py::arg("quad_as_tri"), - py::arg("z_interp"), - py::arg("x_chunk_size") = 0, - py::arg("y_chunk_size") = 0, - py::arg("thread_count") = 0) + "x"_a, "y"_a, "z"_a, "mask"_a, py::kw_only(), "corner_mask"_a, "line_type"_a, + "fill_type"_a, "quad_as_tri"_a, "z_interp"_a, "x_chunk_size"_a = 0, + "y_chunk_size"_a = 0, "thread_count"_a = 0) .def("_write_cache", &contourpy::ThreadedContourGenerator::write_cache) - .def("create_contour", &contourpy::ThreadedContourGenerator::lines, create_contour_doc) - .def("create_filled_contour", &contourpy::ThreadedContourGenerator::filled, - create_filled_contour_doc) - .def("filled", &contourpy::ThreadedContourGenerator::filled, filled_doc) - .def("lines", &contourpy::ThreadedContourGenerator::lines, lines_doc) .def_property_readonly( "chunk_count", &contourpy::ThreadedContourGenerator::get_chunk_count, chunk_count_doc) .def_property_readonly( diff --git a/contrib/python/contourpy/ya.make b/contrib/python/contourpy/ya.make index 5c6203a16b..7c9cf3ac75 100644 --- a/contrib/python/contourpy/ya.make +++ b/contrib/python/contourpy/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(1.2.1) +VERSION(1.3.0) LICENSE(BSD-3-Clause) @@ -28,6 +28,7 @@ CFLAGS( SRCS( src/chunk_local.cpp + src/contour_generator.cpp src/converter.cpp src/fill_type.cpp src/line_type.cpp |