39 static const int directions[8][2];
40 static const int distances[8];
51 uint32_t value_to_store_;
63 const float uv_offset[2],
71 corner_edges_(corner_edges),
77 pixel_data_.resize(w_ * h_, 0xFFFFFFFF);
93 pixel_data_[
y * w_ +
x] = value;
102 return pixel_data_[
y * w_ +
x];
109 value_to_store_ = value;
111 write_mask_ = writemask;
117 void *map,
int x,
int y, [[maybe_unused]]
float u, [[maybe_unused]]
float v)
122 if (m->write_mask_) {
124 m->mask_[
y * m->w_ +
x] = 1;
131 if (m->mask_[
y * m->w_ +
x] != 0) {
146#define PackDijkstraPixel(dist, dir) (0x80000000 + ((dist) << 4) + (dir))
147#define DijkstraPixelGetDistance(dp) (((dp) ^ 0x80000000) >> 4)
148#define DijkstraPixelGetDirection(dp) ((dp) & 0xF)
149#define IsDijkstraPixel(dp) ((dp) & 0x80000000)
150#define DijkstraPixelIsUnset(dp) ((dp) == 0xFFFFFFFF)
158 class DijkstraActivePixel {
160 DijkstraActivePixel(
int dist,
int _x,
int _y) :
distance(dist),
x(_x),
y(_y) {}
164 auto cmp_dijkstrapixel_fun = [](DijkstraActivePixel
const &a1, DijkstraActivePixel
const &a2) {
165 return a1.distance > a2.distance;
169 for (
int y = 0;
y < h_;
y++) {
170 for (
int x = 0;
x < w_;
x++) {
172 for (
int i = 0;
i < 8;
i++) {
173 int xx =
x - directions[
i][0];
174 int yy =
y - directions[
i][1];
178 active_pixels.
append(DijkstraActivePixel(distances[
i],
x,
y));
188 std::make_heap(active_pixels.
begin(), active_pixels.
end(), cmp_dijkstrapixel_fun);
191 while (active_pixels.
size()) {
192 std::pop_heap(active_pixels.
begin(), active_pixels.
end(), cmp_dijkstrapixel_fun);
193 DijkstraActivePixel p = active_pixels.
pop_last();
195 int dist = p.distance;
197 if (dist < 2 * (margin + 1)) {
198 for (
int i = 0;
i < 8;
i++) {
199 int x = p.x + directions[
i][0];
200 int y = p.y + directions[
i][1];
206 active_pixels.
append(DijkstraActivePixel(dist + distances[
i],
x,
y));
207 std::push_heap(active_pixels.
begin(), active_pixels.
end(), cmp_dijkstrapixel_fun);
224 size_t pixel_index = 0;
225 for (
int y = 0;
y < h_;
y++) {
226 for (
int x = 0;
x < w_;
x++) {
227 uint32_t dp = pixel_data_[pixel_index];
237 xx -= directions[direction][0];
238 yy -= directions[direction][1];
240 dist -= distances[direction];
252 bool found_pixel_in_polygon =
false;
253 if (lookup_pixel_polygon_neighborhood(
x,
y, &face, &destX, &destY, &other_poly)) {
255 for (
int i = 0;
i < maxPolygonSteps;
i++) {
257 int nx = int(
round(destX));
258 int ny = int(
round(destY));
259 uint32_t polygon_from_map =
get_pixel(nx, ny);
260 if (other_poly == polygon_from_map) {
261 found_pixel_in_polygon =
true;
267 if (!lookup_pixel(nx, ny, other_poly, &destX, &destY, &other_poly, &dist_to_edge)) {
268 found_pixel_in_polygon =
false;
273 if (found_pixel_in_polygon) {
283 mask[pixel_index] = 1;
291 mask[pixel_index] = 1;
302 ret.x = (((uv_map[0] - uv_offset_[0]) * w_) - (0.5f + 0.001f));
303 ret.y = (((uv_map[1] - uv_offset_[1]) * h_) - (0.5f + 0.001f));
311 loop_adjacency_map_.
resize(corner_edges_.
size(), -1);
314 tmpmap.
resize(totedge_, -1);
317 int edge = corner_edges_[
i];
318 if (tmpmap[edge] == -1) {
319 loop_adjacency_map_[
i] = -1;
324 loop_adjacency_map_[
i] = tmpmap[edge];
325 loop_adjacency_map_[tmpmap[edge]] =
i;
336 bool lookup_pixel_polygon_neighborhood(
337 float x,
float y, uint32_t *r_start_poly,
float *r_destx,
float *r_desty,
int *r_other_poly)
340 if (lookup_pixel(
x,
y, *r_start_poly, r_destx, r_desty, r_other_poly, &found_dist)) {
344 int loopstart = faces_[*r_start_poly].start();
345 int totloop = faces_[*r_start_poly].size();
350 float mindist = -1.0f;
355 for (
int i = 0;
i < totloop;
i++) {
356 int otherloop = loop_adjacency_map_[
i + loopstart];
362 uint32_t face = loop_to_face_map_[otherloop];
364 if (lookup_pixel(
x,
y, face, &destx, &desty, &foundpoly, &found_dist)) {
365 if (mindist < 0.0f || found_dist < mindist) {
366 mindist = found_dist;
367 *r_other_poly = foundpoly;
370 *r_start_poly = face;
375 return mindist >= 0.0f;
384 bool lookup_pixel(
float x,
390 float *r_dist_to_edge)
394 *r_destx = *r_desty = 0;
397 float found_dist = -1;
402 for (
size_t i = 0;
i < faces_[src_poly].size();
i++) {
403 int l1 = faces_[src_poly].start() +
i;
405 if (l2 >= faces_[src_poly].start() + faces_[src_poly].
size()) {
406 l2 = faces_[src_poly].start();
409 float2 edgepoint1 = uv_to_xy(uv_map_[l1]);
410 float2 edgepoint2 = uv_to_xy(uv_map_[l2]);
413 float2 ab = edgepoint2 - edgepoint1;
414 float2 ap = point - edgepoint1;
421 float t = dotv / ablensq;
423 if (t >= 0.0 && t <= 1.0) {
426 float2 reflect_point = edgepoint1 + (t * ab);
428 float2 reflect_vec = reflect_point - point;
430 float reflectLen =
sqrt(reflect_vec[0] * reflect_vec[0] + reflect_vec[1] * reflect_vec[1]);
431 float cross = ab[0] * reflect_vec[1] - ab[1] * reflect_vec[0];
435 bool valid = (
cross > 0.0);
437 if (valid && (found_dist < 0 || reflectLen < found_dist)) {
439 found_dist = reflectLen;
441 found_edge =
i + faces_[src_poly].start();
446 if (found_edge < 0) {
450 *r_dist_to_edge = found_dist;
453 int other_edge = loop_adjacency_map_[found_edge];
455 if (other_edge < 0) {
459 int dst_poly = loop_to_face_map_[other_edge];
462 *r_other_poly = dst_poly;
465 int other_edge2 = other_edge + 1;
466 if (other_edge2 >= faces_[dst_poly].start() + faces_[dst_poly].
size()) {
467 other_edge2 = faces_[dst_poly].start();
470 float2 other_edgepoint1 = uv_to_xy(uv_map_[other_edge]);
471 float2 other_edgepoint2 = uv_to_xy(uv_map_[other_edge2]);
474 float2 other_ab = other_edgepoint1 - other_edgepoint2;
475 float2 other_reflect_point = other_edgepoint2 + (found_t * other_ab);
476 float2 perpendicular_other_ab;
477 perpendicular_other_ab.x = other_ab.
y;
478 perpendicular_other_ab.y = -other_ab.
x;
482 float2 new_point = other_reflect_point + (found_dist /
math::length(perpendicular_other_ab)) *
483 perpendicular_other_ab;
485 *r_destx = new_point.
x;
486 *r_desty = new_point.
y;
492const int TextureMarginMap::directions[8][2] = {
493 {-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}};
494const int TextureMarginMap::distances[8] = {2, 3, 2, 3, 2, 3, 2, 3};
505 const float uv_offset[2])
515 bool draw_new_mask =
false;
523 draw_new_mask =
true;
527 const int3 tri = corner_tris[
i];
530 for (
int a = 0; a < 3; a++) {
531 const float *uv = uv_map[tri[a]];
537 vec[a][0] = (uv[0] - uv_offset[0]) *
float(ibuf->
x) - (0.5f + 0.001f);
538 vec[a][1] = (uv[1] - uv_offset[1]) *
float(ibuf->
y) - (0.5f + 0.002f);
575 const float uv_offset[2])
587 mesh->vert_positions(),
590 mesh->corner_edges(),
591 mesh->corner_verts(),
CustomData interface, see also DNA_customdata_types.h.
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
MINLINE void copy_v2_v2(float r[2], const float a[2])
void IMB_filter_extend(ImBuf *ibuf, char *mask, int filter)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
IndexRange index_range() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void append(const T &value)
void resize(const int64_t new_size)
GAttributeReader lookup(const StringRef attribute_id) const
void rasterize_tri(float *v1, float *v2, float *v3, uint32_t value, char *mask, bool writemask)
void set_pixel(int x, int y, uint32_t value)
TextureMarginMap(size_t w, size_t h, const float uv_offset[2], const int totedge, const OffsetIndices< int > faces, const Span< int > corner_edges, const Span< float2 > uv_map)
void grow_dijkstra(int margin)
void lookup_pixels(ImBuf *ibuf, char *mask, int maxPolygonSteps)
static void zscan_store_pixel(void *map, int x, int y, float u, float v)
uint32_t get_pixel(int x, int y) const
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
float distance(VecOp< float, D >, VecOp< float, D >) RET
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void corner_tris_calc(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, MutableSpan< int3 > corner_tris)
Array< int > build_corner_to_face_map(OffsetIndices< int > faces)
void corner_tris_calc_face_indices(OffsetIndices< int > faces, MutableSpan< int > tri_faces)
uchar4 interpolate_bilinear_border_byte(const ImBuf *in, float u, float v)
float4 interpolate_bilinear_border_fl(const ImBuf *in, float u, float v)
T length_squared(const VecBase< T, Size > &a)
T length(const VecBase< T, Size > &a)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
static void generate_margin(ImBuf *ibuf, char *mask, const int margin, const Span< float3 > vert_positions, const int edges_num, const OffsetIndices< int > faces, const Span< int > corner_edges, const Span< int > corner_verts, const Span< float2 > uv_map, const float uv_offset[2])
blender::VecBase< uint8_t, 4 > uchar4
VecBase< float, 4 > float4
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
#define PackDijkstraPixel(dist, dir)
#define DijkstraPixelIsUnset(dp)
#define DijkstraPixelGetDistance(dp)
#define DijkstraPixelGetDirection(dp)
#define IsDijkstraPixel(dp)
void RE_generate_texturemargin_adjacentfaces(ImBuf *ibuf, char *mask, const int margin, const Mesh *mesh, blender::StringRef uv_layer, const float uv_offset[2])
void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *v3, void(*func)(void *, int, int, float, float))
void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty)
void zbuf_free_span(ZSpan *zspan)