MeshLib
 
Loading...
Searching...
No Matches
MRImGuiMeasurementIndicators.h
Go to the documentation of this file.
1#pragma once
2
4#include "MRViewer/exports.h"
6
7#include <imgui.h>
8
9#include <optional>
10#include <span>
11
13{
14
15struct Params
16{
17 ImDrawList* list = ImGui::GetBackgroundDrawList();
22
23 float pointDiameter = 6;
24
25 float width = 1.5f;
26 float smallWidth = 0.75f;
27 float outlineWidth = 1.5f;
28 float textOutlineWidth = 4.f;
30
31 float arrowLen = 12;
32 float arrowHalfWidth = 4;
33 // The arrow tip is moved back for this amount of pixels,
34 // to compensate for the outline that otherwise makes the tip look longer than it actually is.
35 // This only applies if the tip doesn't continue into a line.
37
38 // The spacing box around the text is extended by this amount.
39 ImVec2 textToLineSpacingA = ImVec2( 0, 0 ); // Top-left corner.
40 ImVec2 textToLineSpacingB = ImVec2( 0, 2 ); // Bottom-right corner.
41 // Further, the lines around the text are shortened by this amount.
43
44 // For a distance, when the total length is less than this, an alternative rendering method is used.
45 // If the text is added, its size can make the actual threshold larger.
47
48 // When drawing inverted (short) distances, the line is extended by this amount on both sides.
49 float invertedOverhang = 24;
50
51 // The length of the leader lines (short lines attaching text to other things).
52 float leaderLineLen = 20;
53
54 // A small perpendicular line at the end of some arrows.
55 float notchHalfLen = 8;
56
57 // This picks the colors based on the current color theme.
58 MRVIEWER_API Params();
59};
60
61enum class Element
62{
63 main = 1 << 0,
64 outline = 1 << 1,
65 both = main | outline, // Use this by default.
66};
68
69// Draws a point.
70MRVIEWER_API void point( Element elem, float menuScaling, const Params& params, ImVec2 point );
71
72enum class StringIcon
73{
74 none,
76};
77
78// A string with an optional custom icon inserted in the middle.
80{
82 std::size_t iconPos = 0;
83
84 std::string string;
85
87
88 // Need a bunch of constructors to allow implicit conversions when this is used as a function parameter.
89 StringWithIcon( const char* string ) : string( string ) {}
90 StringWithIcon( std::string string ) : string( std::move( string ) ) {}
91
92 StringWithIcon( StringIcon icon, std::size_t iconPos, std::string string )
93 : icon( icon ), iconPos( iconPos ), string( std::move( string ) )
94 {}
95
96 [[nodiscard]] bool isEmpty() const { return icon == StringIcon::none && string.empty(); }
97
98 // Returns the icon width, already scaled to the current scale.
99 [[nodiscard]] MRVIEWER_API float getIconWidth() const;
100 // Calculates the text size with the icon, using the current font.
101 [[nodiscard]] MRVIEWER_API ImVec2 calcTextSize() const;
102 // Draws the text with an icon to the specified draw list.
103 MRVIEWER_API void draw( ImDrawList& list, float menuScaling, ImVec2 pos, ImU32 color );
104};
105
106// Draws a floating text bubble.
107// If `push` is specified, it's normalized and the text is pushed in that direction,
108// by the amount necessarily to clear a perpendicular going through the center point.
109// If `pivot` is specified, the bubble is positioned according to its size (like in ImGui::SetNextWindowPos):
110// { 0, 0 } for top left corner, { 0.5f, 0.5f } for center (default), { 1, 1 } for bottom right corner.
111MRVIEWER_API void text( Element elem, float menuScaling, const Params& params, ImVec2 pos, StringWithIcon string,
112 ImVec2 push = {}, ImVec2 pivot = { 0.5f, 0.5f } );
113
114// Draws a triangle from an arrow.
115MRVIEWER_API void arrowTriangle( Element elem, float menuScaling, const Params& params, ImVec2 point, ImVec2 dir );
116
118{
119 enum class Decoration
120 {
121 none,
122 arrow,
123 };
125
127};
128
129enum class LineFlags
130{
131 narrow = 1 << 0,
132 noBackwardArrowTipOffset = 1 << 1, // Overrides `params.arrowTipBackwardOffset` to zero.
133};
135
137{
138 LineFlags flags{};
139
140 LineCap capA{};
141 LineCap capB{};
142
143 std::span<const ImVec2> midPoints;
144};
145
146// Draws a line or an arrow.
147MRVIEWER_API void line( Element elem, float menuScaling, const Params& params, ImVec2 a, ImVec2 b, const LineParams& lineParams = {} );
148
150{
151 // If this is set, the text is moved from the middle of the line to one of the line ends (false = A, true = B).
152 std::optional<bool> moveTextToLineEndIndex;
153};
154
155// Draws a distance arrow between two points, automatically selecting the best visual style.
156// The `string` is optional.
157MRVIEWER_API void distance( Element elem, float menuScaling, const Params& params, ImVec2 a, ImVec2 b, StringWithIcon string, const DistanceParams& distanceParams = {} );
158
160{
161 // How many times can be subdivide a curve (resuling in up to 2^depth segments).
163 // A curve is always subdivided at least this many times.
165 // If a curve segment is longer than this, it gets divided in two.
166 // You probably don't want to multiply this by `menuScaling`, and we don't do it automatically.
168};
169
171{
172 ImVec2 a; // The first point.
173 ImVec2 b; // The last point.
174
175 [[nodiscard]] ImVec2 endPoint( bool second ) const { return second ? b : a; }
176
177 std::span<ImVec2> midPoints; // All the points in between.
178};
179
180// Calculates points for a custom curve, from a function you provide. You can then draw this curve as a `line()`.
181// The points are appended into `pointBuffer` (and for convenience the new points are also returned as `.midPoints`;
182// the first and the last point are not inserted into the vector and are not included in `.midPoints`, they sit in `.a` and `.b`).
183// You should reuse `pointBuffer` between calls for better performance (and `.clear()` it each time you finish drawing the resulting curve,
184// which conveniently preserves vector capacity). Or, if you don't care, just pass an empty vector, and keep it alive as long as you need the curve.
185// `stateA` and `stateB` can have any type, they describe the beginning and the end of the curve respectively. They might often be `0.f` and `1.f`.
186// Let `S` be the type of `stateA`/`stateB` (more on that belw).
187// `stateToPoint` is a lambda `(const S &s) -> ImVec2`. It converts a state into a curve point coordinates.
188// `bisectState` is a lambda `(const S &a, const S &b, int depth) -> S`. Given two states, it produces the state between them. `depth` starts at `0`.
189// `onInsertPoint`, if specified, is a lambda `(ImVec2 point, const S &state) -> void`. It's called right before a point is added into the list.
190// It's actually possible to have multiple state types instead of a single `S`, and template your functions (e.g. to track bisection depth in the type system, etc).
191// Example usage:
192// prepareCurve( params, buf, 0, PI*2, [](float x){return std::sin(x);}, [](float a, float b, int /*depth*/){return (a+b)/2;} )
193template <typename A, typename B, typename F, typename G, typename H = std::nullptr_t>
194[[nodiscard]] PreparedCurve prepareCurve( const CurveParams& curveParams, std::vector<ImVec2>& pointBuffer, const A& stateA, const B& stateB,
195 F&& stateToPoint, G&& bisectState, H&& onInsertPoint = nullptr
196)
197{
198 const float pixelStepSq = curveParams.subdivisionStepPixels * curveParams.subdivisionStepPixels;
199
200 std::size_t firstIndex = pointBuffer.size();
201
202 auto makeCurve = [&]( auto makeCurve, int depth, const auto& stateA, const auto& stateB, ImVec2 pointA, ImVec2 pointB ) -> void
203 {
204 // Check if we need to subdivide.
205 if ( depth < curveParams.maxSubdivisionDepth && ( depth < curveParams.minSubdivisionDepth || ImGuiMath::lengthSq( pointB - pointA ) > pixelStepSq ) )
206 {
207 // Do subdivide.
208
209 auto midState = bisectState( stateA, stateB, int( depth ) ); // A cast to prevent modification.
210 ImVec2 midPoint = stateToPoint( midState );
211
212 makeCurve( makeCurve, depth + 1, stateA, midState, pointA, midPoint );
213 makeCurve( makeCurve, depth + 1, midState, stateB, midPoint, pointB );
214 }
215 else
216 {
217 // No subdivide.
218
219 onInsertPoint( pointB, stateB );
220 pointBuffer.push_back( pointB );
221 }
222
223 };
224 ImVec2 firstPoint = stateToPoint( stateA );
225 makeCurve( makeCurve, 0, stateA, stateB, firstPoint, stateToPoint( stateB ) );
226
227 PreparedCurve ret{ .a = firstPoint, .b = pointBuffer.back() };
228 pointBuffer.pop_back();
229 ret.midPoints = { pointBuffer.data() + firstIndex, pointBuffer.data() + pointBuffer.size() };
230 return ret;
231}
232
233} // namespace MR::ImGuiMeasurementIndicators
#define MR_MAKE_FLAG_OPERATORS(T)
Definition MRFlagOperators.h:6
auto depth(const Box< V > &box)
returns size along z axis
Definition MRMesh/MRBox.h:244
constexpr auto lengthSq(A a)
Definition MRImGuiVectorOperators.h:131
Definition MRImGuiMeasurementIndicators.h:13
MRVIEWER_API void text(Element elem, float menuScaling, const Params &params, ImVec2 pos, StringWithIcon string, ImVec2 push={}, ImVec2 pivot={ 0.5f, 0.5f })
MRVIEWER_API void point(Element elem, float menuScaling, const Params &params, ImVec2 point)
StringIcon
Definition MRImGuiMeasurementIndicators.h:73
MRVIEWER_API void line(Element elem, float menuScaling, const Params &params, ImVec2 a, ImVec2 b, const LineParams &lineParams={})
MRVIEWER_API void arrowTriangle(Element elem, float menuScaling, const Params &params, ImVec2 point, ImVec2 dir)
PreparedCurve prepareCurve(const CurveParams &curveParams, std::vector< ImVec2 > &pointBuffer, const A &stateA, const B &stateB, F &&stateToPoint, G &&bisectState, H &&onInsertPoint=nullptr)
Definition MRImGuiMeasurementIndicators.h:194
LineFlags
Definition MRImGuiMeasurementIndicators.h:130
Element
Definition MRImGuiMeasurementIndicators.h:62
MRVIEWER_API void distance(Element elem, float menuScaling, const Params &params, ImVec2 a, ImVec2 b, StringWithIcon string, const DistanceParams &distanceParams={})
Definition MRColor.h:9
Definition MRImGuiMeasurementIndicators.h:160
int maxSubdivisionDepth
Definition MRImGuiMeasurementIndicators.h:162
float subdivisionStepPixels
Definition MRImGuiMeasurementIndicators.h:167
int minSubdivisionDepth
Definition MRImGuiMeasurementIndicators.h:164
Definition MRImGuiMeasurementIndicators.h:150
std::optional< bool > moveTextToLineEndIndex
Definition MRImGuiMeasurementIndicators.h:152
Definition MRImGuiMeasurementIndicators.h:118
StringWithIcon text
Definition MRImGuiMeasurementIndicators.h:126
Decoration decoration
Definition MRImGuiMeasurementIndicators.h:124
Decoration
Definition MRImGuiMeasurementIndicators.h:120
Definition MRImGuiMeasurementIndicators.h:137
std::span< const ImVec2 > midPoints
Definition MRImGuiMeasurementIndicators.h:143
Definition MRImGuiMeasurementIndicators.h:16
float width
Definition MRImGuiMeasurementIndicators.h:25
float smallWidth
Definition MRImGuiMeasurementIndicators.h:26
float totalLenThreshold
Definition MRImGuiMeasurementIndicators.h:46
float arrowHalfWidth
Definition MRImGuiMeasurementIndicators.h:32
float arrowLen
Definition MRImGuiMeasurementIndicators.h:31
float textToLineSpacingRadius
Definition MRImGuiMeasurementIndicators.h:42
float notchHalfLen
Definition MRImGuiMeasurementIndicators.h:55
float textOutlineWidth
Definition MRImGuiMeasurementIndicators.h:28
float leaderLineLen
Definition MRImGuiMeasurementIndicators.h:52
Color colorOutline
Definition MRImGuiMeasurementIndicators.h:19
float arrowTipBackwardOffset
Definition MRImGuiMeasurementIndicators.h:36
Color colorMain
Definition MRImGuiMeasurementIndicators.h:18
Color colorTextOutline
Definition MRImGuiMeasurementIndicators.h:21
ImVec2 textToLineSpacingB
Definition MRImGuiMeasurementIndicators.h:40
float pointDiameter
Definition MRImGuiMeasurementIndicators.h:23
ImDrawList * list
Definition MRImGuiMeasurementIndicators.h:17
Color colorText
Definition MRImGuiMeasurementIndicators.h:20
ImVec2 textToLineSpacingA
Definition MRImGuiMeasurementIndicators.h:39
float outlineWidth
Definition MRImGuiMeasurementIndicators.h:27
float invertedOverhang
Definition MRImGuiMeasurementIndicators.h:49
float textOutlineRounding
Definition MRImGuiMeasurementIndicators.h:29
Definition MRImGuiMeasurementIndicators.h:171
ImVec2 a
Definition MRImGuiMeasurementIndicators.h:172
ImVec2 b
Definition MRImGuiMeasurementIndicators.h:173
std::span< ImVec2 > midPoints
Definition MRImGuiMeasurementIndicators.h:177
ImVec2 endPoint(bool second) const
Definition MRImGuiMeasurementIndicators.h:175
Definition MRImGuiMeasurementIndicators.h:80
MRVIEWER_API void draw(ImDrawList &list, float menuScaling, ImVec2 pos, ImU32 color)
StringWithIcon(const char *string)
Definition MRImGuiMeasurementIndicators.h:89
StringWithIcon(std::string string)
Definition MRImGuiMeasurementIndicators.h:90
StringIcon icon
Definition MRImGuiMeasurementIndicators.h:81
StringWithIcon()
Definition MRImGuiMeasurementIndicators.h:86
bool isEmpty() const
Definition MRImGuiMeasurementIndicators.h:96
std::size_t iconPos
Definition MRImGuiMeasurementIndicators.h:82
std::string string
Definition MRImGuiMeasurementIndicators.h:84
MRVIEWER_API ImVec2 calcTextSize() const
StringWithIcon(StringIcon icon, std::size_t iconPos, std::string string)
Definition MRImGuiMeasurementIndicators.h:92