Loading...
Searching...
No Matches
PointArraySegment.hpp
1#pragma once
2#include <Curve/Envelope.hpp>
3#include <Curve/Segment/CurveSegmentModel.hpp>
4
6#include <score/serialization/VisitorInterface.hpp>
7
8#include <ossia/detail/flat_map.hpp>
9
10#include <QPoint>
11#include <QVariant>
12#include <QVector>
13
14#include <memory>
15#include <span>
16#include <utility>
17#include <vector>
18#include <verdigris>
19
20class QObject;
21#include <score/model/Identifier.hpp>
22
23namespace Curve
24{
25class PointArraySegment;
26}
27
28CURVE_SEGMENT_METADATA(
29 SCORE_PLUGIN_CURVE_EXPORT, Curve::PointArraySegment,
30 "c598b840-db67-4c8f-937a-46cfac87cb59", "PointArray", "PointArray", "hidden")
31
32namespace Curve
33{
34class LinearSegment;
35struct SegmentData;
36class SegmentIdAllocator;
37
40using PointArraySamples = ossia::flat_map<double, double>;
41
44struct SCORE_PLUGIN_CURVE_EXPORT PointArraySegmentData
45{
46 double min_x{}, max_x{};
47 double min_y{}, max_y{};
48 std::shared_ptr<const PointArraySamples> points;
49
50 bool operator==(const PointArraySegmentData& other) const noexcept;
51};
52
56class SCORE_PLUGIN_CURVE_EXPORT PointArraySegment final : public SegmentModel
57{
58 W_OBJECT(PointArraySegment)
59public:
60 MODEL_METADATA_IMPL(PointArraySegment)
61
62 using data_type = PointArraySegmentData;
63 PointArraySegment(const Id<SegmentModel>& id, QObject* parent);
64 PointArraySegment(const SegmentData& dat, QObject* parent);
65
66 PointArraySegment(const PointArraySegment& other, const id_type& id, QObject* parent);
67
68 PointArraySegment(DataStream::Deserializer& vis, QObject* parent);
69 PointArraySegment(JSONObject::Deserializer& vis, QObject* parent);
70
71 ~PointArraySegment() override;
72
73 void on_startChanged() override;
74 void on_endChanged() override;
75
77 void updateData(int numInterp) const override;
78
81 void envelope(double x0, double x1, int columns, std::vector<QPointF>& out) const;
82
84 std::size_t samplesBetween(double x0, double x1) const noexcept;
85
88 void envelopeColumns(
89 double x0, double width, int columns, std::vector<QLineF>& out) const;
90 double valueAt(double x) const override;
91
92 void addPoint(double, double);
93 void addPointUnscaled(double, double);
94 void simplify(double ratio); // 10 is a good ratio
95 std::vector<SegmentData> toLinearSegments() const;
96 std::vector<SegmentData> toPowerSegments() const;
97
98 double min() { return min_y; }
99 double max() { return max_y; }
100
101 void setMinX(double y) { min_x = y; }
102 void setMinY(double y) { min_y = y; }
103 void setMaxX(double y) { max_x = y; }
104 void setMaxY(double y) { max_y = y; }
105
106 const PointArraySamples& points() const noexcept { return *m_points; }
107 void setData(const PointArraySegmentData& dat);
108 void setSpecificData(const QVariant& data) override;
109 bool specificDataEquals(const QVariant& data) const noexcept override;
110 void reserve(std::size_t p);
111
112 QVariant toSegmentSpecificData() const override;
113
114 ossia::curve_segment<double> makeDoubleFunction() const override;
115 ossia::curve_segment<float> makeFloatFunction() const override;
116 ossia::curve_segment<int> makeIntFunction() const override;
117 ossia::curve_segment<double>
118 makeScaledDoubleFunction(double offset, double factor) const override;
119 ossia::curve_segment<float>
120 makeScaledFloatFunction(double offset, double factor) const override;
121 ossia::curve_segment<int>
122 makeScaledIntFunction(double offset, double factor) const override;
123 void reset();
124
125public:
126 void minChanged(double arg_1) E_SIGNAL(SCORE_PLUGIN_CURVE_EXPORT, minChanged, arg_1)
127 void maxChanged(double arg_1) E_SIGNAL(SCORE_PLUGIN_CURVE_EXPORT, maxChanged, arg_1)
128
129private:
130 PointArraySamples& editPoints();
132 std::vector<QPointF> mappedPoints() const;
133
134 // Coordinates in {x, y}.
135 double min_x{}, max_x{};
136 double min_y{}, max_y{};
137
138 double m_lastX{-1};
139
140 std::shared_ptr<const PointArraySamples> m_points;
141 mutable int m_dataResolution{-1};
143 const MinMaxPyramid& pyramid() const;
144 mutable MinMaxPyramid m_pyramid;
145 // The samples it was built from: a weak_ptr is never equal to a later
146 // buffer, even one allocated at the same address. Reset on in-place edits.
147 mutable std::weak_ptr<const PointArraySamples> m_pyramidOf;
148};
149
152SCORE_PLUGIN_CURVE_EXPORT
153void setSegmentExtent(SegmentData& seg, QPointF start, QPointF end);
154
158SCORE_PLUGIN_CURVE_EXPORT
159std::vector<SegmentData>
160curveFromSamples(std::span<const float> values, std::size_t editable_max = 10000);
161
164SCORE_PLUGIN_CURVE_EXPORT
165std::vector<SegmentData> editableSegments(
166 const SegmentData& pointArray, double tolerance, SegmentIdAllocator& ids);
167}
168
169SCORE_SERIALIZE_DATASTREAM_DECLARE(
170 SCORE_PLUGIN_CURVE_EXPORT, Curve::PointArraySegmentData)
171Q_DECLARE_METATYPE(Curve::PointArraySegmentData)
172W_REGISTER_ARGTYPE(Curve::PointArraySegmentData)
Definition DataStreamVisitor.hpp:202
Definition JSONVisitor.hpp:423
The id_base_t class.
Definition Identifier.hpp:59
Utilities and base classes for 1D curves.
Definition FocusDispatcher.hpp:12
void envelope(std::size_t n, const X &x, const Y &y, const MinMaxPyramid &pyramid, std::size_t pyramid_offset, double x0, double x1, int columns, std::vector< QPointF > &out)
Definition score-plugin-curve/Curve/Envelope.hpp:81
void envelopeColumns(std::size_t n, const X &x, const Y &y, const MinMaxPyramid &pyramid, std::size_t pyramid_offset, double x0, double width, int columns, std::vector< QLineF > &out)
Definition score-plugin-curve/Curve/Envelope.hpp:138