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. */
51 /* Prefers to connect background pixels. */
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. */
59 /* Prefers to connect majority color in the neighborhood. */
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
105template<typename ThresholdFn> Bitmap *image_to_bitmap(const ImBuf &ibuf, ThresholdFn fn)
106{
107#ifdef WITH_POTRACE
108 constexpr int BM_WORDSIZE = int(sizeof(potrace_word));
109 constexpr int BM_WORDBITS = 8 * BM_WORDSIZE;
110 constexpr potrace_word BM_HIBIT = potrace_word(1) << (BM_WORDBITS - 1);
111
112 potrace_bitmap_t *bm = create_bitmap({ibuf.x, ibuf.y});
113 const int num_words = bm->dy * bm->h;
114 const int words_per_scanline = bm->dy;
115 /* Note: bitmap stores one bit per pixel, but can't easily use a BitSpan, because the bit order
116 * is reversed in each word (most-significant bit is on the left). */
117 MutableSpan<potrace_word> words = {bm->map, num_words};
118
119 if (ibuf.float_buffer.data) {
120 const Span<ColorGeometry4f> colors = {
121 reinterpret_cast<ColorGeometry4f *>(ibuf.float_buffer.data), ibuf.x * ibuf.y};
122 threading::parallel_for(IndexRange(ibuf.y), 4096, [&](const IndexRange range) {
123 /* Use callback with the correct color conversion. */
124 constexpr bool is_float_color_fn =
125 std::is_invocable_r_v<void, ThresholdFn, const ColorGeometry4f &>;
126 for (const int y : range) {
127 MutableSpan<potrace_word> scanline_words = words.slice(
128 IndexRange(words_per_scanline * y, words_per_scanline));
129 const Span<ColorGeometry4f> scanline_colors = colors.slice(IndexRange(y * ibuf.x, ibuf.x));
130 for (int x = 0; x < ibuf.x; x++) {
131 potrace_word &word = scanline_words[x / BM_WORDBITS];
132 const potrace_word mask = BM_HIBIT >> (x & (BM_WORDBITS - 1));
133
134 const ColorGeometry4f &fcolor = scanline_colors[x];
135 bool is_foreground;
136 if constexpr (!is_float_color_fn) {
137 is_foreground = fn(
138 ColorGeometry4b(fcolor.r * 255, fcolor.g * 255, fcolor.b * 255, fcolor.a * 255));
139 }
140 else {
141 is_foreground = fn(fcolor);
142 }
143
144 if (is_foreground) {
145 word |= mask;
146 }
147 else {
148 word &= ~mask;
149 }
150 }
151 }
152 });
153 return bm;
154 }
155
156 const Span<ColorGeometry4b> colors = {reinterpret_cast<ColorGeometry4b *>(ibuf.byte_buffer.data),
157 ibuf.x * ibuf.y};
158 threading::parallel_for(IndexRange(ibuf.y), 4096, [&](const IndexRange range) {
159 /* Use callback with the correct color conversion. */
160 constexpr bool is_float_color_fn =
161 std::is_invocable_r_v<void, ThresholdFn, const ColorGeometry4f &>;
162 for (const int y : range) {
163 MutableSpan<potrace_word> scanline_words = words.slice(
164 IndexRange(words_per_scanline * y, words_per_scanline));
165 const Span<ColorGeometry4b> scanline_colors = colors.slice(IndexRange(y * ibuf.x, ibuf.x));
166 for (uint32_t x = 0; x < ibuf.x; x++) {
167 potrace_word &word = scanline_words[x / BM_WORDBITS];
168 const potrace_word mask = BM_HIBIT >> (x & (BM_WORDBITS - 1));
169
170 const ColorGeometry4b bcolor = scanline_colors[x];
171 bool is_foreground;
172 if constexpr (is_float_color_fn) {
173 is_foreground = fn(ColorGeometry4f(
174 bcolor.r / 255.0f, bcolor.r / 255.0f, bcolor.r / 255.0f, bcolor.r / 255.0f));
175 }
176 else {
177 is_foreground = fn(bcolor);
178 }
179
180 if (is_foreground) {
181 word |= mask;
182 }
183 else {
184 word &= ~mask;
185 }
186 }
187 }
188 });
189 return bm;
190#else
191 UNUSED_VARS(ibuf, fn);
192 return nullptr;
193#endif
194}
195
196} // 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
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
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
MatBase< float, 4, 4 > float4x4
VecBase< int32_t, 2 > int2
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
Definition BLI_color.hh:337
VecBase< float, 3 > float3
ColorSceneLinearByteEncoded4b< eAlpha::Premultiplied > ColorGeometry4b
Definition BLI_color.hh:338
signed char int8_t
Definition stdint.h:75
ImBufFloatBuffer float_buffer