(Breaking) Style: obsoleted style.CurveTessellationTol in favor of style.CurveTesselationMaxError.

cc #3127, #3664, #3665
This commit is contained in:
ocornut 2026-08-03 16:45:56 +02:00
parent b647af2100
commit fdc1152281
6 changed files with 53 additions and 29 deletions

View File

@ -41,6 +41,11 @@ HOW TO UPDATE?
Breaking Changes: Breaking Changes:
- Style: obsoleted `style.CurveTessellationTol (default 1.25)` which was in Pixels² unit in
favor of `style.CurveTesselationMaxError` (default 1.12)` which is in Pixels unit. It is
easier to tweak + this allows us to easily scale error threshold on high density screens.
- style.CurveTesselationMaxError == sqrf(style.CurveTessellationTol).
Other Changes: Other Changes:
- Fonts: - Fonts:

View File

@ -395,6 +395,8 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
You can read releases logs https://github.com/ocornut/imgui/releases for more details. You can read releases logs https://github.com/ocornut/imgui/releases for more details.
- 2026/08/03 (1.93.0) - Style: obsoleted `style.CurveTessellationTol (default 1.25)` which was in Pixels² unit in favor of `style.CurveTesselationMaxError` (default 1.12)` which is in Pixels unit.
- style.CurveTesselationMaxError == sqrf(style.CurveTessellationTol).
- 2026/07/20 (1.92.9) - DragXXX, SliderXXX, InputScalar: with `ImGuiItemFlags_LiveEditOnInputScalar` now defaulting to being disabled: - 2026/07/20 (1.92.9) - DragXXX, SliderXXX, InputScalar: with `ImGuiItemFlags_LiveEditOnInputScalar` now defaulting to being disabled:
inputting a value with the keyboard doesn't write intermediate values to backing variable. (#9476) inputting a value with the keyboard doesn't write intermediate values to backing variable. (#9476)
- Before: DragFloat() with user typing "123" --> write back 1, then 12, then 123. - Before: DragFloat() with user typing "123" --> write back 1, then 12, then 123.
@ -1570,10 +1572,12 @@ ImGuiStyle::ImGuiStyle()
DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows. DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows.
DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows.
MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
// Rendering & Tesselation
AntiAliasedLines = true; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. AntiAliasedLines = true; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU.
AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering).
AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.). AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.).
CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. CurveTessellationMaxError = 1.12f; // Maximum error (in pixels) when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
CircleTessellationMaxError = 0.30f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. CircleTessellationMaxError = 0.30f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
// Behaviors // Behaviors
@ -1586,6 +1590,9 @@ ImGuiStyle::ImGuiStyle()
// [Internal] // [Internal]
_MainScale = 1.0f; _MainScale = 1.0f;
_NextFrameFontSizeBase = 0.0f; _NextFrameFontSizeBase = 0.0f;
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
CurveTessellationTol = 0.0f; // Old CurveTessellationTol = CurveTessellationMaxError*CurveTessellationMaxError.
#endif
// Default theme // Default theme
ImGui::StyleColorsDark(this); ImGui::StyleColorsDark(this);
@ -2100,7 +2107,7 @@ ImVec2 ImBezierCubicClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec
} }
// Closely mimics PathBezierToCasteljau() in imgui_draw.cpp // Closely mimics PathBezierToCasteljau() in imgui_draw.cpp
static void ImBezierCubicClosestPointCasteljauStep(const ImVec2& p, ImVec2& p_closest, ImVec2& p_last, float& p_closest_dist2, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) static void ImBezierCubicClosestPointCasteljauStep(const ImVec2& p, ImVec2& p_closest, ImVec2& p_last, float& p_closest_dist2, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float max_error_sqr, int level)
{ {
float dx = x4 - x1; float dx = x4 - x1;
float dy = y4 - y1; float dy = y4 - y1;
@ -2108,7 +2115,7 @@ static void ImBezierCubicClosestPointCasteljauStep(const ImVec2& p, ImVec2& p_cl
float d3 = ((x3 - x4) * dy - (y3 - y4) * dx); float d3 = ((x3 - x4) * dy - (y3 - y4) * dx);
d2 = (d2 >= 0) ? d2 : -d2; d2 = (d2 >= 0) ? d2 : -d2;
d3 = (d3 >= 0) ? d3 : -d3; d3 = (d3 >= 0) ? d3 : -d3;
if ((d2 + d3) * (d2 + d3) < tess_tol * (dx * dx + dy * dy)) if ((d2 + d3) * (d2 + d3) < max_error_sqr * (dx * dx + dy * dy))
{ {
ImVec2 p_current(x4, y4); ImVec2 p_current(x4, y4);
ImVec2 p_line = ImLineClosestPoint(p_last, p_current, p); ImVec2 p_line = ImLineClosestPoint(p_last, p_current, p);
@ -2128,20 +2135,21 @@ static void ImBezierCubicClosestPointCasteljauStep(const ImVec2& p, ImVec2& p_cl
float x123 = (x12 + x23)*0.5f, y123 = (y12 + y23)*0.5f; float x123 = (x12 + x23)*0.5f, y123 = (y12 + y23)*0.5f;
float x234 = (x23 + x34)*0.5f, y234 = (y23 + y34)*0.5f; float x234 = (x23 + x34)*0.5f, y234 = (y23 + y34)*0.5f;
float x1234 = (x123 + x234)*0.5f, y1234 = (y123 + y234)*0.5f; float x1234 = (x123 + x234)*0.5f, y1234 = (y123 + y234)*0.5f;
ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1); ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, max_error_sqr, level + 1);
ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1); ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, max_error_sqr, level + 1);
} }
} }
// tess_tol is generally the same value you would find in ImGui::GetStyle().CurveTessellationTol // tess_tol is generally the same value you would find in ImGui::GetStyle().CurveTessellationMaxError
// Because those ImXXX functions are lower-level than ImGui:: we cannot access this value automatically. // Because those ImXXX functions are lower-level than ImGui:: we cannot access this value automatically.
ImVec2 ImBezierCubicClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol) ImVec2 ImBezierCubicClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float max_error)
{ {
IM_ASSERT(tess_tol > 0.0f); IM_ASSERT(max_error > 0.0f);
ImVec2 p_last = p1; ImVec2 p_last = p1;
ImVec2 p_closest; ImVec2 p_closest;
float p_closest_dist2 = FLT_MAX; float p_closest_dist2 = FLT_MAX;
ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, tess_tol, 0); float max_error_sqr = max_error * max_error;
ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, max_error_sqr, 0);
return p_closest; return p_closest;
} }
@ -5572,7 +5580,7 @@ static void SetupDrawListSharedData()
for (ImGuiViewportP* viewport : g.Viewports) for (ImGuiViewportP* viewport : g.Viewports)
virtual_space.Add(viewport->GetMainRect()); virtual_space.Add(viewport->GetMainRect());
g.DrawListSharedData.ClipRectFullscreen = virtual_space.ToVec4(); g.DrawListSharedData.ClipRectFullscreen = virtual_space.ToVec4();
g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol; g.DrawListSharedData.CurveTessellationMaxError = g.Style.CurveTessellationMaxError;
g.DrawListSharedData.SetCircleTessellationMaxError(g.Style.CircleTessellationMaxError); g.DrawListSharedData.SetCircleTessellationMaxError(g.Style.CircleTessellationMaxError);
g.DrawListSharedData.InitialFlags = ImDrawListFlags_None; g.DrawListSharedData.InitialFlags = ImDrawListFlags_None;
if (g.Style.AntiAliasedLines) if (g.Style.AntiAliasedLines)
@ -11098,7 +11106,7 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
IM_ASSERT((g.IO.DeltaTime > 0.0f || g.FrameCount == 0) && "Need a positive DeltaTime!"); IM_ASSERT((g.IO.DeltaTime > 0.0f || g.FrameCount == 0) && "Need a positive DeltaTime!");
IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?"); IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?");
IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value!"); IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value!");
IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting!"); IM_ASSERT(g.Style.CurveTessellationMaxError > 0.0f && "Invalid style setting!");
IM_ASSERT(g.Style.CircleTessellationMaxError > 0.0f && "Invalid style setting!"); IM_ASSERT(g.Style.CircleTessellationMaxError > 0.0f && "Invalid style setting!");
IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting!"); // Allows us to avoid a few clamps in color computations IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting!"); // Allows us to avoid a few clamps in color computations
IM_ASSERT(g.Style.WindowMinSize.x >= 1.0f && g.Style.WindowMinSize.y >= 1.0f && "Invalid style setting!"); IM_ASSERT(g.Style.WindowMinSize.x >= 1.0f && g.Style.WindowMinSize.y >= 1.0f && "Invalid style setting!");
@ -11138,6 +11146,11 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
g.PlatformIO.Platform_GetClipboardTextFn = [](ImGuiContext* ctx) { return ctx->IO.GetClipboardTextFn(ctx->IO.ClipboardUserData); }; g.PlatformIO.Platform_GetClipboardTextFn = [](ImGuiContext* ctx) { return ctx->IO.GetClipboardTextFn(ctx->IO.ClipboardUserData); };
if (g.IO.SetClipboardTextFn != NULL && (g.PlatformIO.Platform_SetClipboardTextFn == NULL || g.PlatformIO.Platform_SetClipboardTextFn == Platform_SetClipboardTextFn_DefaultImpl)) if (g.IO.SetClipboardTextFn != NULL && (g.PlatformIO.Platform_SetClipboardTextFn == NULL || g.PlatformIO.Platform_SetClipboardTextFn == Platform_SetClipboardTextFn_DefaultImpl))
g.PlatformIO.Platform_SetClipboardTextFn = [](ImGuiContext* ctx, const char* text) { return ctx->IO.SetClipboardTextFn(ctx->IO.ClipboardUserData, text); }; g.PlatformIO.Platform_SetClipboardTextFn = [](ImGuiContext* ctx, const char* text) { return ctx->IO.SetClipboardTextFn(ctx->IO.ClipboardUserData, text); };
// Remap legacy CurveTessellationTol into CurveTessellationMaxError (OBSOLETED in 1.93.0, August 2026)
if (g.Style.CurveTessellationTol != 0.0f)
g.Style.CurveTessellationMaxError = ImSqrt(g.Style.CurveTessellationTol);
g.Style.CurveTessellationTol = 0.0f;
#endif #endif
} }

View File

@ -2373,10 +2373,12 @@ struct ImGuiStyle
ImVec2 DisplayWindowPadding; // Apply to regular windows: amount which we enforce to keep visible when moving near edges of your screen. ImVec2 DisplayWindowPadding; // Apply to regular windows: amount which we enforce to keep visible when moving near edges of your screen.
ImVec2 DisplaySafeAreaPadding; // Apply to every windows, menus, popups, tooltips: amount where we avoid displaying contents. Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured). ImVec2 DisplaySafeAreaPadding; // Apply to every windows, menus, popups, tooltips: amount where we avoid displaying contents. Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).
float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later. float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later.
// Rendering & Tesselation
bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). Latched at the beginning of the frame (copied to ImDrawList). bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). Latched at the beginning of the frame (copied to ImDrawList).
bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. float CurveTessellationMaxError; // Maximum error (in pixels) when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
float CircleTessellationMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. float CircleTessellationMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
// Colors // Colors
@ -2400,6 +2402,7 @@ struct ImGuiStyle
// Obsolete names // Obsolete names
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
float CurveTessellationTol; // [OBSOLETE] Old CurveTessellationTol = New CurveTessellationMaxError*CurveTessellationMaxError. // Changed in 1.93.0
// TabMinWidthForCloseButton = TabCloseButtonMinWidthUnselected // Renamed in 1.91.9. // TabMinWidthForCloseButton = TabCloseButtonMinWidthUnselected // Renamed in 1.91.9.
#endif #endif
}; };

View File

@ -8828,8 +8828,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
Checkbox("Anti-aliased fill", &style.AntiAliasedFill); Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
PushItemWidth(GetFontSize() * 8); PushItemWidth(GetFontSize() * 8);
DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f"); DragFloat("Curve Tessellation Max Error", &style.CurveTessellationMaxError, 0.02f, 0.10f, 10.0f, "%.2f");
if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f; if (style.CurveTessellationMaxError < 0.10f)
style.CurveTessellationMaxError = 0.10f;
// When editing the "Circle Segment Max Error" value, draw a preview of its effect on auto-tessellated circles. // When editing the "Circle Segment Max Error" value, draw a preview of its effect on auto-tessellated circles.
DragFloat("Circle Tessellation Max Error", &style.CircleTessellationMaxError , 0.005f, 0.10f, 5.0f, "%.2f", ImGuiSliderFlags_AlwaysClamp); DragFloat("Circle Tessellation Max Error", &style.CircleTessellationMaxError , 0.005f, 0.10f, 5.0f, "%.2f", ImGuiSliderFlags_AlwaysClamp);

View File

@ -1370,7 +1370,7 @@ ImVec2 ImBezierQuadraticCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p
} }
// Closely mimics ImBezierCubicClosestPointCasteljau() in imgui.cpp // Closely mimics ImBezierCubicClosestPointCasteljau() in imgui.cpp
static void PathBezierCubicCurveToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) static void PathBezierCubicCurveToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float max_error_sqr, int level)
{ {
float dx = x4 - x1; float dx = x4 - x1;
float dy = y4 - y1; float dy = y4 - y1;
@ -1378,7 +1378,7 @@ static void PathBezierCubicCurveToCasteljau(ImVector<ImVec2>* path, float x1, fl
float d3 = (x3 - x4) * dy - (y3 - y4) * dx; float d3 = (x3 - x4) * dy - (y3 - y4) * dx;
d2 = (d2 >= 0) ? d2 : -d2; d2 = (d2 >= 0) ? d2 : -d2;
d3 = (d3 >= 0) ? d3 : -d3; d3 = (d3 >= 0) ? d3 : -d3;
if ((d2 + d3) * (d2 + d3) < tess_tol * (dx * dx + dy * dy)) if ((d2 + d3) * (d2 + d3) < max_error_sqr * (dx * dx + dy * dy))
{ {
path->push_back(ImVec2(x4, y4)); path->push_back(ImVec2(x4, y4));
} }
@ -1390,16 +1390,16 @@ static void PathBezierCubicCurveToCasteljau(ImVector<ImVec2>* path, float x1, fl
float x123 = (x12 + x23) * 0.5f, y123 = (y12 + y23) * 0.5f; float x123 = (x12 + x23) * 0.5f, y123 = (y12 + y23) * 0.5f;
float x234 = (x23 + x34) * 0.5f, y234 = (y23 + y34) * 0.5f; float x234 = (x23 + x34) * 0.5f, y234 = (y23 + y34) * 0.5f;
float x1234 = (x123 + x234) * 0.5f, y1234 = (y123 + y234) * 0.5f; float x1234 = (x123 + x234) * 0.5f, y1234 = (y123 + y234) * 0.5f;
PathBezierCubicCurveToCasteljau(path, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1); PathBezierCubicCurveToCasteljau(path, x1, y1, x12, y12, x123, y123, x1234, y1234, max_error_sqr, level + 1);
PathBezierCubicCurveToCasteljau(path, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1); PathBezierCubicCurveToCasteljau(path, x1234, y1234, x234, y234, x34, y34, x4, y4, max_error_sqr, level + 1);
} }
} }
static void PathBezierQuadraticCurveToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float tess_tol, int level) static void PathBezierQuadraticCurveToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float max_error_sqr, int level)
{ {
float dx = x3 - x1, dy = y3 - y1; float dx = x3 - x1, dy = y3 - y1;
float det = (x2 - x3) * dy - (y2 - y3) * dx; float det = (x2 - x3) * dy - (y2 - y3) * dx;
if (det * det * 4.0f < tess_tol * (dx * dx + dy * dy)) if (det * det * 4.0f < max_error_sqr * (dx * dx + dy * dy))
{ {
path->push_back(ImVec2(x3, y3)); path->push_back(ImVec2(x3, y3));
} }
@ -1408,8 +1408,8 @@ static void PathBezierQuadraticCurveToCasteljau(ImVector<ImVec2>* path, float x1
float x12 = (x1 + x2) * 0.5f, y12 = (y1 + y2) * 0.5f; float x12 = (x1 + x2) * 0.5f, y12 = (y1 + y2) * 0.5f;
float x23 = (x2 + x3) * 0.5f, y23 = (y2 + y3) * 0.5f; float x23 = (x2 + x3) * 0.5f, y23 = (y2 + y3) * 0.5f;
float x123 = (x12 + x23) * 0.5f, y123 = (y12 + y23) * 0.5f; float x123 = (x12 + x23) * 0.5f, y123 = (y12 + y23) * 0.5f;
PathBezierQuadraticCurveToCasteljau(path, x1, y1, x12, y12, x123, y123, tess_tol, level + 1); PathBezierQuadraticCurveToCasteljau(path, x1, y1, x12, y12, x123, y123, max_error_sqr, level + 1);
PathBezierQuadraticCurveToCasteljau(path, x123, y123, x23, y23, x3, y3, tess_tol, level + 1); PathBezierQuadraticCurveToCasteljau(path, x123, y123, x23, y23, x3, y3, max_error_sqr, level + 1);
} }
} }
@ -1418,8 +1418,9 @@ void ImDrawList::PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, cons
ImVec2 p1 = _Path.back(); ImVec2 p1 = _Path.back();
if (num_segments == 0) if (num_segments == 0)
{ {
IM_ASSERT(_Data->CurveTessellationTol > 0.0f); IM_ASSERT(_Data->CurveTessellationMaxError > 0.0f);
PathBezierCubicCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); // Auto-tessellated float max_error_sqr = _Data->CurveTessellationMaxError * _Data->CurveTessellationMaxError;
PathBezierCubicCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, max_error_sqr, 0); // Auto-tessellated
} }
else else
{ {
@ -1434,8 +1435,9 @@ void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3,
ImVec2 p1 = _Path.back(); ImVec2 p1 = _Path.back();
if (num_segments == 0) if (num_segments == 0)
{ {
IM_ASSERT(_Data->CurveTessellationTol > 0.0f); IM_ASSERT(_Data->CurveTessellationMaxError > 0.0f);
PathBezierQuadraticCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, _Data->CurveTessellationTol, 0);// Auto-tessellated float max_error_sqr = _Data->CurveTessellationMaxError * _Data->CurveTessellationMaxError;
PathBezierQuadraticCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, max_error_sqr, 0);// Auto-tessellated
} }
else else
{ {

View File

@ -550,7 +550,7 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
// Helpers: Geometry // Helpers: Geometry
IMGUI_API ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t); IMGUI_API ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t);
IMGUI_API ImVec2 ImBezierCubicClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments); // For curves with explicit number of segments IMGUI_API ImVec2 ImBezierCubicClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments); // For curves with explicit number of segments
IMGUI_API ImVec2 ImBezierCubicClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol);// For auto-tessellated curves you can use tess_tol = style.CurveTessellationTol IMGUI_API ImVec2 ImBezierCubicClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float max_error);// For auto-tessellated curves you can use max_error = style.CurveTessellationMaxError
IMGUI_API ImVec2 ImBezierQuadraticCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, float t); IMGUI_API ImVec2 ImBezierQuadraticCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, float t);
IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p); IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p);
IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
@ -895,7 +895,7 @@ struct IMGUI_API ImDrawListSharedData
ImFont* Font; // Current font (used for simplified AddText overload) ImFont* Font; // Current font (used for simplified AddText overload)
float FontSize; // Current font size (used for for simplified AddText overload) float FontSize; // Current font size (used for for simplified AddText overload)
float FontScale; // Current font scale (== FontSize / Font->FontSize) float FontScale; // Current font scale (== FontSize / Font->FontSize)
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() float CurveTessellationMaxError; // Tessellation tolerance when using PathBezierCurveTo()
float CircleTessellationMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc float CircleTessellationMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc
float InitialFringeScale; // Initial scale to apply to AA fringe float InitialFringeScale; // Initial scale to apply to AA fringe
ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards) ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards)