diff options
author | shumkovnd <shumkovnd@yandex-team.com> | 2023-11-10 14:39:34 +0300 |
---|---|---|
committer | shumkovnd <shumkovnd@yandex-team.com> | 2023-11-10 16:42:24 +0300 |
commit | 77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch) | |
tree | c51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/python/contourpy/src/base.h | |
parent | dd6d20cadb65582270ac23f4b3b14ae189704b9d (diff) | |
download | ydb-77eb2d3fdcec5c978c64e025ced2764c57c00285.tar.gz |
KIKIMR-19287: add task_stats_drawing script
Diffstat (limited to 'contrib/python/contourpy/src/base.h')
-rw-r--r-- | contrib/python/contourpy/src/base.h | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/contrib/python/contourpy/src/base.h b/contrib/python/contourpy/src/base.h new file mode 100644 index 0000000000..7faf9335ec --- /dev/null +++ b/contrib/python/contourpy/src/base.h @@ -0,0 +1,210 @@ +// BaseContourGenerator class provides functionality common to multiple contouring algorithms. +// Uses the Curiously Recurring Template Pattern idiom whereby classes derived from this are +// declared as +// class Derived : public BaseContourGenerator<Derived> +// +// It provides static polymorphism at compile-time rather than the more common dynamic polymorphism +// at run-time using virtual functions. Hence it avoids the runtime overhead of calling virtual +// functions. + +#ifndef CONTOURPY_BASE_H +#define CONTOURPY_BASE_H + +#include "chunk_local.h" +#include "contour_generator.h" +#include "fill_type.h" +#include "line_type.h" +#include "outer_or_hole.h" +#include "z_interp.h" +#include <vector> + +namespace contourpy { + +template <typename Derived> +class BaseContourGenerator : public ContourGenerator +{ +public: + ~BaseContourGenerator(); + + static FillType default_fill_type(); + static LineType default_line_type(); + + 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) + + bool get_corner_mask() const; + + FillType get_fill_type() const; + LineType get_line_type() const; + + bool get_quad_as_tri() const; + + ZInterp get_z_interp() const; + + py::sequence filled(double lower_level, double upper_level); + py::sequence lines(double level); + + static bool supports_fill_type(FillType fill_type); + static bool supports_line_type(LineType line_type); + + void write_cache() const; // For debug purposes only. + +protected: + BaseContourGenerator( + const CoordinateArray& x, const CoordinateArray& y, const CoordinateArray& z, + const MaskArray& mask, bool corner_mask, LineType line_type, FillType fill_type, + bool quad_as_tri, ZInterp z_interp, index_t x_chunk_size, index_t y_chunk_size); + + typedef uint32_t CacheItem; + typedef CacheItem ZLevel; + + // C++11 scoped enum for direction of movement from one quad to the next. + enum class Direction + { + Left = 1, + Straight = 0, + Right = -1 + }; + + struct Location + { + Location(index_t quad_, index_t forward_, index_t left_, bool is_upper_, bool on_boundary_) + : quad(quad_), forward(forward_), left(left_), is_upper(is_upper_), + on_boundary(on_boundary_) + {} + + friend std::ostream &operator<<(std::ostream &os, const Location& location) + { + os << "quad=" << location.quad << " forward=" << location.forward << " left=" + << location.left << " is_upper=" << location.is_upper << " on_boundary=" + << location.on_boundary; + return os; + } + + index_t quad, forward, left; + bool is_upper, on_boundary; + }; + + // Calculate, set and return z-level at middle of quad. + ZLevel calc_and_set_middle_z_level(index_t quad); + + // Calculate and return z at middle of quad. + double calc_middle_z(index_t quad) const; + + void closed_line(const Location& start_location, OuterOrHole outer_or_hole, ChunkLocal& local); + + void closed_line_wrapper( + const Location& start_location, OuterOrHole outer_or_hole, ChunkLocal& local); + + // If point/line/hole counts not consistent, throw runtime error. + void check_consistent_counts(const ChunkLocal& local) const; + + index_t find_look_S(index_t look_N_quad) const; + + // Return true if finished (i.e. back to start quad, direction and upper). + bool follow_boundary( + Location& location, const Location& start_location, ChunkLocal& local, + count_t& point_count); + + // Return true if finished (i.e. back to start quad, direction and upper). + bool follow_interior( + Location& location, const Location& start_location, ChunkLocal& local, + count_t& point_count); + + index_t get_boundary_start_point(const Location& location) const; + + // These are quad chunk limits, not point chunk limits. + // chunk is index in range 0.._n_chunks-1. + void get_chunk_limits(index_t chunk, ChunkLocal& local) const; + + index_t get_interior_start_left_point( + const Location& location, bool& start_corner_diagonal) const; + + double get_interp_fraction(double z0, double z1, double level) const; + + double get_middle_x(index_t quad) const; + double get_middle_y(index_t quad) const; + + index_t get_n_chunks() const; + + void get_point_xy(index_t point, double*& points) const; + + double get_point_x(index_t point) const; + double get_point_y(index_t point) const; + double get_point_z(index_t point) const; + + bool has_direct_line_offsets() const; + bool has_direct_outer_offsets() const; + bool has_direct_points() const; + + void init_cache_grid(const MaskArray& mask); + + // Either for a single chunk, or the whole domain (all chunks) if local == nullptr. + void init_cache_levels_and_starts(const ChunkLocal* local = nullptr); + + // Increments local.points twice. + void interp(index_t point0, index_t point1, bool is_upper, double*& points) const; + + // Increments local.points twice. + 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( + index_t quad, index_t istart, index_t iend, index_t jstart, index_t jend) const; + + bool is_quad_in_chunk(index_t quad, const ChunkLocal& local) const; + + void line(const Location& start_location, ChunkLocal& local); + + void march_chunk(ChunkLocal& local, std::vector<py::list>& return_lists); + + py::sequence march_wrapper(); + + void move_to_next_boundary_edge(index_t& quad, index_t& forward, index_t& left) const; + + void set_look_flags(index_t hole_start_quad); + + void write_cache_quad(index_t quad) const; + + ZLevel z_to_zlevel(double z_value) const; + + +private: + const CoordinateArray _x, _y, _z; + const double* _xptr; // For quick access to _x.data(). + const double* _yptr; + const double* _zptr; + const index_t _nx, _ny; // Number of points in each direction. + const index_t _n; // Total number of points (and quads). + const index_t _x_chunk_size, _y_chunk_size; + const index_t _nx_chunks, _ny_chunks; // Number of chunks in each direction. + const index_t _n_chunks; // Total number of chunks. + const bool _corner_mask; + const LineType _line_type; + const FillType _fill_type; + const bool _quad_as_tri; + const ZInterp _z_interp; + + CacheItem* _cache; + + // Current contouring operation. + bool _filled; + double _lower_level, _upper_level; + + // Current contouring operation, based on return type and filled or lines. + bool _identify_holes; + bool _output_chunked; // Implies empty chunks will have py::none(). + bool _direct_points; // Whether points array is written direct to Python. + bool _direct_line_offsets; // Whether line offsets array is written direct to Python. + bool _direct_outer_offsets; // Whether outer offsets array is written direct to Python. + bool _outer_offsets_into_points; // Otherwise into line offsets. Only used if _identify_holes. + unsigned int _return_list_count; +}; + +} // namespace contourpy + +#endif // CONTOURPY_BASE_H |