aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2024-09-14 10:18:18 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2024-09-14 10:28:53 +0300
commit66e260367ac774d563874203b260b0ed0e04c93d (patch)
treeeb4bc3df675c97f8fad0ef56ee272ae8549be9d7
parent47df7453282e2d3835d93fd3c4c24f9cbf8adca5 (diff)
downloadydb-66e260367ac774d563874203b260b0ed0e04c93d.tar.gz
Intermediate changes
commit_hash:ab55b3b972e940f79570e58af046841fae66b70c
-rw-r--r--contrib/python/Flask-Cors/py3/.dist-info/METADATA2
-rw-r--r--contrib/python/Flask-Cors/py3/flask_cors/core.py8
-rw-r--r--contrib/python/Flask-Cors/py3/flask_cors/extension.py16
-rw-r--r--contrib/python/Flask-Cors/py3/flask_cors/version.py2
-rw-r--r--contrib/python/Flask-Cors/py3/ya.make2
-rw-r--r--contrib/python/contourpy/.dist-info/METADATA12
-rw-r--r--contrib/python/contourpy/README.md4
-rw-r--r--contrib/python/contourpy/README_simple.md4
-rw-r--r--contrib/python/contourpy/contourpy/__init__.py38
-rw-r--r--contrib/python/contourpy/contourpy/_contourpy.pyi3
-rw-r--r--contrib/python/contourpy/contourpy/_version.py2
-rw-r--r--contrib/python/contourpy/contourpy/array.py2
-rw-r--r--contrib/python/contourpy/contourpy/convert.py83
-rw-r--r--contrib/python/contourpy/contourpy/dechunk.py79
-rw-r--r--contrib/python/contourpy/contourpy/util/bokeh_renderer.py17
-rw-r--r--contrib/python/contourpy/contourpy/util/data.py2
-rw-r--r--contrib/python/contourpy/contourpy/util/mpl_renderer.py12
-rw-r--r--contrib/python/contourpy/contourpy/util/renderer.py74
-rw-r--r--contrib/python/contourpy/src/base.h16
-rw-r--r--contrib/python/contourpy/src/base_impl.h120
-rw-r--r--contrib/python/contourpy/src/common.h1
-rw-r--r--contrib/python/contourpy/src/contour_generator.cpp79
-rw-r--r--contrib/python/contourpy/src/contour_generator.h13
-rw-r--r--contrib/python/contourpy/src/converter.cpp8
-rw-r--r--contrib/python/contourpy/src/mpl2005.cpp8
-rw-r--r--contrib/python/contourpy/src/mpl2005.h6
-rw-r--r--contrib/python/contourpy/src/mpl2014.cpp9
-rw-r--r--contrib/python/contourpy/src/mpl2014.h6
-rw-r--r--contrib/python/contourpy/src/util.cpp6
-rw-r--r--contrib/python/contourpy/src/util.h2
-rw-r--r--contrib/python/contourpy/src/wrap.cpp194
-rw-r--r--contrib/python/contourpy/ya.make3
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