Blender V4.3
grease_pencil_trace_util.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
7#include "BKE_attribute.hh"
8#include "BKE_curves.hh"
9#include "BLI_color.hh"
12#include "BLI_span.hh"
13#include "BLI_task.hh"
14
15#include "IMB_imbuf_types.hh"
16
17#ifdef WITH_POTRACE
18# include "potracelib.h"
19#endif
20
21namespace blender::bke {
22class CurvesGeometry;
23}
24
26
27#ifdef WITH_POTRACE
28using Bitmap = potrace_bitmap_t;
29using Trace = potrace_state_t;
30#else
31struct Bitmap;
32struct Trace;
33#endif
34
35Bitmap *create_bitmap(const int2 &size);
36void free_bitmap(Bitmap *bm);
37
44template<typename ThresholdFn> Bitmap *image_to_bitmap(const ImBuf &ibuf, ThresholdFn fn);
45ImBuf *bitmap_to_image(const Bitmap &bm);
46
47/* Policy for resolving ambiguity during decomposition of bitmaps into paths. */
48enum class TurnPolicy : int8_t {
49 /* Prefers to connect foreground pixels. */
50 Foreground = 0,
51 /* Prefers to connect background pixels. */
52 Background = 1,
53 /* Always take a left turn. */
54 Left = 2,
55 /* Always take a right turn. */
56 Right = 3,
57 /* Prefers to connect minority color in the neighborhood. */
58 Minority = 4,
59 /* Prefers to connect majority color in the neighborhood. */
60 Majority = 5,
61 /* Chose direction randomly. */
62 Random = 6,
63};
64
66 /* Area of the largest path to be ignored. */
68 /* Resolves ambiguous turns in path decomposition. */
70 /* Corner threshold. */
71 float alpha_max = 1.0f;
72 /* True to enable curve optimization. */
73 bool optimize_curves = true;
74 /* Curve optimization tolerance. */
75 float optimize_tolerance = 0.2f;
76};
77
81Trace *trace_bitmap(const TraceParams &params, Bitmap &bm);
82void free_trace(Trace *trace);
83
89 StringRef hole_attribute_id,
90 const float4x4 &transform);
96 StringRef hole_attribute_id,
97 FunctionRef<float3(const int2 &)> pixel_to_position);
98
99/* Inline functions. */
100
101template<typename ThresholdFn> Bitmap *image_to_bitmap(const ImBuf &ibuf, ThresholdFn fn)
102{
103#ifdef WITH_POTRACE
104 constexpr int BM_WORDSIZE = int(sizeof(potrace_word));
105 constexpr int BM_WORDBITS = 8 * BM_WORDSIZE;
106 constexpr potrace_word BM_HIBIT = potrace_word(1) << (BM_WORDBITS - 1);
107
108 potrace_bitmap_t *bm = create_bitmap({ibuf.x, ibuf.y});
109 const int num_words = bm->dy * bm->h;
110 const int words_per_scanline = bm->dy;
111 /* Note: bitmap stores one bit per pixel, but can't easily use a BitSpan, because the bit order
112 * is reversed in each word (most-significant bit is on the left). */
113 MutableSpan<potrace_word> words = {bm->map, num_words};
114
115 if (ibuf.float_buffer.data) {
116 const Span<ColorGeometry4f> colors = {
117 reinterpret_cast<ColorGeometry4f *>(ibuf.float_buffer.data), ibuf.x * ibuf.y};
118 threading::parallel_for(IndexRange(ibuf.y), 4096, [&](const IndexRange range) {
119 /* Use callback with the correct color conversion. */
120 constexpr bool is_float_color_fn =
121 std::is_invocable_r_v<void, ThresholdFn, const ColorGeometry4f &>;
122 for (const int y : range) {
123 MutableSpan<potrace_word> scanline_words = words.slice(
124 IndexRange(words_per_scanline * y, words_per_scanline));
125 const Span<ColorGeometry4f> scanline_colors = colors.slice(IndexRange(y * ibuf.x, ibuf.x));
126 for (int x = 0; x < ibuf.x; x++) {
127 potrace_word &word = scanline_words[x / BM_WORDBITS];
128 const potrace_word mask = BM_HIBIT >> (x & (BM_WORDBITS - 1));
129
130 const ColorGeometry4f &fcolor = scanline_colors[x];
131 bool is_foreground;
132 if constexpr (!is_float_color_fn) {
133 is_foreground = fn(
134 ColorGeometry4b(fcolor.r * 255, fcolor.g * 255, fcolor.b * 255, fcolor.a * 255));
135 }
136 else {
137 is_foreground = fn(fcolor);
138 }
139
140 if (is_foreground) {
141 word |= mask;
142 }
143 else {
144 word &= ~mask;
145 }
146 }
147 }
148 });
149 return bm;
150 }
151
152 const Span<ColorGeometry4b> colors = {reinterpret_cast<ColorGeometry4b *>(ibuf.byte_buffer.data),
153 ibuf.x * ibuf.y};
154 threading::parallel_for(IndexRange(ibuf.y), 4096, [&](const IndexRange range) {
155 /* Use callback with the correct color conversion. */
156 constexpr bool is_float_color_fn =
157 std::is_invocable_r_v<void, ThresholdFn, const ColorGeometry4f &>;
158 for (const int y : range) {
159 MutableSpan<potrace_word> scanline_words = words.slice(
160 IndexRange(words_per_scanline * y, words_per_scanline));
161 const Span<ColorGeometry4b> scanline_colors = colors.slice(IndexRange(y * ibuf.x, ibuf.x));
162 for (uint32_t x = 0; x < ibuf.x; x++) {
163 potrace_word &word = scanline_words[x / BM_WORDBITS];
164 const potrace_word mask = BM_HIBIT >> (x & (BM_WORDBITS - 1));
165
166 const ColorGeometry4b bcolor = scanline_colors[x];
167 bool is_foreground;
168 if constexpr (is_float_color_fn) {
169 is_foreground = fn(ColorGeometry4f(
170 bcolor.r / 255.0f, bcolor.r / 255.0f, bcolor.r / 255.0f, bcolor.r / 255.0f));
171 }
172 else {
173 is_foreground = fn(bcolor);
174 }
175
176 if (is_foreground) {
177 word |= mask;
178 }
179 else {
180 word &= ~mask;
181 }
182 }
183 }
184 });
185 return bm;
186#else
187 UNUSED_VARS(ibuf, fn);
188 return nullptr;
189#endif
190}
191
192} // namespace blender::ed::image_trace
Low-level operations for curves.
#define UNUSED_VARS(...)
Contains defines and structs used throughout the imbuf module.
ATTR_WARN_UNUSED_RESULT BMesh * bm
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void free_bitmap(Bitmap *bm)
Bitmap * create_bitmap(const int2 &size)
Bitmap * image_to_bitmap(const ImBuf &ibuf, ThresholdFn fn)
bke::CurvesGeometry trace_to_curves(const Trace &trace, StringRef hole_attribute_id, const float4x4 &transform)
void free_trace(Trace *trace)
Trace * trace_bitmap(const TraceParams &params, Bitmap &bm)
ImBuf * bitmap_to_image(const Bitmap &bm)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:95
VecBase< float, 3 > float3
signed char int8_t
Definition stdint.h:75
ImBufFloatBuffer float_buffer