aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/contourpy/src/converter.cpp
diff options
context:
space:
mode:
authorshumkovnd <shumkovnd@yandex-team.com>2023-11-10 14:39:34 +0300
committershumkovnd <shumkovnd@yandex-team.com>2023-11-10 16:42:24 +0300
commit77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch)
treec51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/python/contourpy/src/converter.cpp
parentdd6d20cadb65582270ac23f4b3b14ae189704b9d (diff)
downloadydb-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.cpp155
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