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/converter.cpp | |
parent | dd6d20cadb65582270ac23f4b3b14ae189704b9d (diff) | |
download | ydb-77eb2d3fdcec5c978c64e025ced2764c57c00285.tar.gz |
KIKIMR-19287: add task_stats_drawing script
Diffstat (limited to 'contrib/python/contourpy/src/converter.cpp')
-rw-r--r-- | contrib/python/contourpy/src/converter.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/contrib/python/contourpy/src/converter.cpp b/contrib/python/contourpy/src/converter.cpp new file mode 100644 index 0000000000..1f693ceb1a --- /dev/null +++ b/contrib/python/contourpy/src/converter.cpp @@ -0,0 +1,155 @@ +#include "converter.h" +#include "mpl_kind_code.h" +#include <limits> + +namespace contourpy { + +void Converter::check_max_offset(count_t max_offset) +{ + if (max_offset > std::numeric_limits<OffsetArray::value_type>::max()) + throw std::range_error("Max offset too large to fit in np.uint32. Use smaller chunks."); +} + +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(cut_start != nullptr); + + index_t codes_shape = static_cast<index_t>(point_count); + CodeArray py_codes(codes_shape); + convert_codes(point_count, cut_count, cut_start, subtract, py_codes.mutable_data()); + return py_codes; +} + +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(cut_start != nullptr); + assert(codes != nullptr); + + std::fill(codes + 1, codes + point_count - 1, LINETO); + for (decltype(cut_count) i = 0; i < cut_count-1; ++i) { + codes[cut_start[i] - subtract] = MOVETO; + codes[cut_start[i+1] - 1 - subtract] = CLOSEPOLY; + } +} + +CodeArray Converter::convert_codes_check_closed( + count_t point_count, count_t cut_count, const offset_t* cut_start, const double* points) +{ + assert(point_count > 0 && cut_count > 0); + assert(cut_start != nullptr); + assert(points != nullptr); + + index_t codes_shape = static_cast<index_t>(point_count); + CodeArray codes(codes_shape); + convert_codes_check_closed(point_count, cut_count, cut_start, points, codes.mutable_data()); + return codes; +} + +void Converter::convert_codes_check_closed( + count_t point_count, count_t cut_count, const offset_t* cut_start, const double* points, + CodeArray::value_type* codes) +{ + assert(point_count > 0 && cut_count > 0); + assert(cut_start != nullptr); + assert(points != nullptr); + assert(codes != nullptr); + + std::fill(codes + 1, codes + point_count, LINETO); + for (decltype(cut_count) i = 0; i < cut_count-1; ++i) { + auto start = cut_start[i]; + auto end = cut_start[i+1]; + codes[start] = MOVETO; + bool closed = points[2*start] == points[2*end-2] && + points[2*start+1] == points[2*end-1]; + if (closed) + codes[end-1] = CLOSEPOLY; + } +} + +CodeArray Converter::convert_codes_check_closed_single( + count_t point_count, const double* points) +{ + assert(point_count > 0); + assert(points != nullptr); + + index_t codes_shape = static_cast<index_t>(point_count); + CodeArray py_codes(codes_shape); + convert_codes_check_closed_single(point_count, points, py_codes.mutable_data()); + return py_codes; +} + +void Converter::convert_codes_check_closed_single( + count_t point_count, const double* points, CodeArray::value_type* codes) +{ + assert(point_count > 0); + assert(points != nullptr); + assert(codes != nullptr); + + codes[0] = MOVETO; + auto start = points; + auto end = points + 2*point_count; + bool closed = *start == *(end-2) && *(start+1) == *(end-1); + if (closed) { + std::fill(codes + 1, codes + point_count - 1, LINETO); + codes[point_count-1] = CLOSEPOLY; + } + else + std::fill(codes + 1, codes + point_count, LINETO); +} + +OffsetArray Converter::convert_offsets( + count_t offset_count, const offset_t* start, offset_t subtract) +{ + assert(offset_count > 0 && subtract >= 0); + assert(start != nullptr); + + index_t offsets_shape = static_cast<index_t>(offset_count); + OffsetArray py_offsets(offsets_shape); + convert_offsets(offset_count, start, subtract, py_offsets.mutable_data()); + return py_offsets; +} + +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(start != nullptr); + assert(offsets != nullptr); + + check_max_offset(*(start + offset_count - 1) - subtract); + + if (subtract == 0) + std::copy(start, start + offset_count, offsets); + else { + for (decltype(offset_count) i = 0; i < offset_count; ++i) + *offsets++ = start[i] - subtract; + } +} + +PointArray Converter::convert_points(count_t point_count, const double* start) +{ + assert(point_count > 0); + assert(start != nullptr); + + index_t points_shape[2] = {static_cast<index_t>(point_count), 2}; + PointArray py_points(points_shape); + convert_points(point_count, start, py_points.mutable_data()); + return py_points; +} + +void Converter::convert_points(count_t point_count, const double* start, double* points) +{ + assert(point_count > 0); + assert(start != nullptr); + assert(points != nullptr); + + std::copy(start, start + 2*point_count, points); +} + +} // namespace contourpy |