39 float3 barycentric = end_barycentric - start_barycentric;
40 return float2(barycentric.x, barycentric.y);
48 const float2 start_uv(
float(
x) / image_buffer->
x,
float(
y) / image_buffer->
y);
49 const float2 end_uv(
float(
x + 1) / image_buffer->
x,
float(
y) / image_buffer->
y);
60 const ImBuf *image_buffer,
62 const int uv_island_index,
63 const int uv_primitive_index,
71 for (
int y = miny;
y < maxy;
y++) {
72 bool start_detected =
false;
78 for (
x = minx;
x < maxx;
x++) {
79 float2 uv((
float(
x) + 0.5f) / image_buffer->
x, (
float(
y) + 0.5f) / image_buffer->
y);
84 const bool is_masked = uv_mask.
is_masked(uv_island_index, uv + tile_offset);
85 if (!start_detected &&
is_inside && is_masked) {
86 start_detected =
true;
90 else if (start_detected && (!
is_inside || !is_masked)) {
95 if (!start_detected) {
152 if (image_buffer ==
nullptr) {
160 for (
const int face : node.
faces()) {
165 entry.uv_primitive->get_uv_vertex(mesh_data, 0)->uv - tile_offset,
166 entry.uv_primitive->get_uv_vertex(mesh_data, 1)->uv - tile_offset,
167 entry.uv_primitive->get_uv_vertex(mesh_data, 2)->uv - tile_offset,
170 const int miny =
floor(minv * image_buffer->
y);
172 const int maxy =
min_ii(
ceil(maxv * image_buffer->
y), image_buffer->
y);
174 const int minx =
floor(minu * image_buffer->
x);
176 const int maxx =
min_ii(
ceil(maxu * image_buffer->
x), image_buffer->
x);
185 image_buffer, uvs, minx, miny);
191 entry.uv_island_index,
208 node_data->
tiles.append(tile_data);
224 if (node_data !=
nullptr) {
253 if (nodes_to_update_len == 0) {
258 if (
pbvh.pixels_ ==
nullptr) {
259 PBVHData *pbvh_data = MEM_new<PBVHData>(__func__);
260 pbvh.pixels_ = pbvh_data;
267 r_nodes_to_update.
reserve(nodes_to_update_len);
273 r_nodes_to_update.
append(&node);
276 if (node.pixels_ ==
nullptr) {
277 NodeData *node_data = MEM_new<NodeData>(__func__);
278 node.pixels_ = node_data;
296 if (image_buffer ==
nullptr) {
305 if (tile_node_data ==
nullptr) {
318 dest[0] = dest[1] = dest[2] = dest[3] = 255;
340 const Mesh &
mesh = *
static_cast<const Mesh *
>(
object.data);
363 if (tile_buffer ==
nullptr) {
367 ushort2(tile_buffer->
x, tile_buffer->
y));
370 uv_masks.
add(mesh_data, islands);
380 for (const int i : range) {
382 mesh_data, uv_masks, uv_primitive_lookup, image, image_user, *nodes_to_update[i]);
393 for (
Node *node : nodes_to_update) {
394 NodeData *node_data =
static_cast<NodeData *
>(node->pixels_);
395 node_data->rebuild_undo_regions();
399 for (
Node *node : nodes_to_update) {
400 node->flag_ &=
~Node::RebuildPixels;
404 for (
Node &node : pbvh.nodes<MeshNode>()) {
411#ifdef DO_PRINT_STATISTICS
414 int compressed_data_len = 0;
416 for (
int n = 0; n < pbvh->totnode; n++) {
417 Node *node = &pbvh->nodes[n];
423 compressed_data_len += tile_data.encoded_pixels.size() *
sizeof(
PackedPixelRow);
424 for (
const PackedPixelRow &encoded_pixels : tile_data.encoded_pixels) {
425 num_pixels += encoded_pixels.num_pixels;
429 printf(
"Encoded %lld pixels in %lld bytes (%f bytes per pixel)\n",
432 float(compressed_data_len) / num_pixels);
463 if (image_buffer ==
nullptr) {
498 MEM_delete(node_data);
505 MEM_delete(pbvh_data);
506 pbvh->pixels_ =
nullptr;
CustomData interface, see also DNA_customdata_types.h.
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
void BKE_image_partial_update_mark_full_update(Image *image)
Mark the whole image to be updated.
A BVH for high poly meshes.
#define LISTBASE_FOREACH(type, var, list)
MINLINE float max_fff(float a, float b, float c)
MINLINE int min_ii(int a, int b)
MINLINE float clamp_f(float value, float min, float max)
MINLINE float min_fff(float a, float b, float c)
int barycentric_inside_triangle_v2(const float w[3])
void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
MINLINE void copy_v4_fl(float r[4], float f)
Object is a sort of wrapper for general info.
BMesh const char void * data
BPy_StructRNA * depsgraph
unsigned long long int uint64_t
constexpr bool is_empty() const
void append(const T &value)
IndexRange index_range() const
void reserve(const int64_t min_capacity)
GAttributeReader lookup(const StringRef attribute_id) const
pixels::NodeData * pixels_
static bool is_inside(int x, int y, int cols, int rows)
const ccl_global KernelWorkTile * tile
static bool barycentric_weights(const float v1[3], const float v2[3], const float v3[3], const float co[3], const float n[3], float w[3])
void vert_tris_from_corner_tris(Span< int > corner_verts, Span< int3 > corner_tris, MutableSpan< int3 > vert_tris)
IndexRange face_triangles_range(OffsetIndices< int > faces, int face_i)
pbvh::Tree * pbvh_get(Object &object)
NodeData & node_data_get(blender::bke::pbvh::Node &node)
static void update_geom_primitives(Tree &pbvh, const uv_islands::MeshData &mesh_data)
constexpr bool USE_WATERTIGHT_CHECK
static float2 calc_barycentric_delta(const float2 uvs[3], const float2 start_uv, const float2 end_uv)
void mark_image_dirty(blender::bke::pbvh::Node &node, Image &image, ImageUser &image_user)
static int count_nodes_to_update(Tree &pbvh)
static void apply_watertight_check(Tree &pbvh, Image &image, ImageUser &image_user)
void copy_update(blender::bke::pbvh::Tree &pbvh, Image &image, ImageUser &image_user, const uv_islands::MeshData &mesh_data)
static void do_encode_pixels(const uv_islands::MeshData &mesh_data, const uv_islands::UVIslandsMask &uv_masks, const UVPrimitiveLookup &uv_prim_lookup, Image &image, ImageUser &image_user, MeshNode &node)
static float2 calc_barycentric_delta_x(const ImBuf *image_buffer, const float2 uvs[3], const int x, const int y)
void collect_dirty_tiles(blender::bke::pbvh::Node &node, Vector< image::TileNumber > &r_dirty_tiles)
static bool should_pixels_be_updated(const Node &node)
static bool find_nodes_to_update(Tree &pbvh, Vector< MeshNode * > &r_nodes_to_update)
static void extract_barycentric_pixels(UDIMTilePixels &tile_data, const ImBuf *image_buffer, const uv_islands::UVIslandsMask &uv_mask, const int uv_island_index, const int uv_primitive_index, const float2 uvs[3], const float2 tile_offset, const int minx, const int miny, const int maxx, const int maxy)
static bool update_pixels(const Depsgraph &depsgraph, const Object &object, Tree &pbvh, Image &image, ImageUser &image_user)
PBVHData & data_get(blender::bke::pbvh::Tree &pbvh)
void node_pixels_free(blender::bke::pbvh::Node *node)
void pixels_free(blender::bke::pbvh::Tree *pbvh)
void build_pixels(const Depsgraph &depsgraph, Object &object, Image &image, ImageUser &image_user)
Span< float3 > vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< float, 2 > float2
VecBase< uint16_t, 2 > ushort2
VecBase< float, 3 > float3
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
int get_tile_y_offset() const
int get_tile_x_offset() const
TileNumber get_tile_number() const
int2 get_tile_offset() const
Span< int > faces() const
void mark_region(Image &image, const image::ImageTileWrapper &image_tile, ImBuf &image_buffer)
UDIMTilePixels * find_tile_data(const image::ImageTileWrapper &image_tile)
struct blender::bke::pbvh::pixels::NodeData::@126372137103364156366300331140353251345266233066 flags
Vector< UVPrimitivePaintInput > uv_primitives
void collect_dirty_tiles(Vector< image::TileNumber > &r_dirty_tiles)
Vector< UDIMTilePixels > tiles
ushort2 start_image_coordinate
ushort uv_primitive_index
float2 start_barycentric_coord
Vector< PackedPixelRow > pixel_rows
Entry(uv_islands::UVPrimitive *uv_primitive, uint64_t uv_island_index)
uv_islands::UVPrimitive * uv_primitive
Vector< Vector< Entry > > lookup
UVPrimitiveLookup(const uint64_t geom_primitive_len, uv_islands::UVIslands &uv_islands)
OffsetIndices< int > faces
VectorList< UVPrimitive > uv_primitives
void dilate(int max_iterations)
void add(const MeshData &mesh_data, const UVIslands &islands)
bool is_masked(const uint16_t island_index, const float2 uv) const
void add_tile(float2 udim_offset, ushort2 resolution)
void extend_borders(const MeshData &mesh_data, const UVIslandsMask &islands_mask)