41 float3 barycentric = end_barycentric - start_barycentric;
42 return float2(barycentric.x, barycentric.y);
50 const float2 start_uv(
float(x) / image_buffer->
x,
float(y) / image_buffer->
y);
51 const float2 end_uv(
float(x + 1) / image_buffer->
x,
float(y) / image_buffer->
y);
62 const ImBuf *image_buffer,
64 const int uv_island_index,
65 const int uv_primitive_index,
73 for (
int y = miny; y < maxy; y++) {
74 bool start_detected =
false;
80 for (x = minx; x < maxx; x++) {
81 float2 uv((
float(x) + 0.5f) / image_buffer->
x, (
float(y) + 0.5f) / image_buffer->
y);
86 const bool is_masked = uv_mask.
is_masked(uv_island_index, uv + tile_offset);
87 if (!start_detected &&
is_inside && is_masked) {
88 start_detected =
true;
92 else if (start_detected && (!
is_inside || !is_masked)) {
97 if (!start_detected) {
134 uv_island.uv_primitives)
137 lookup[uv_primitive.primitive_i].append_as(
Entry(&uv_primitive, uv_island_index));
158 if (image_buffer ==
nullptr) {
166 for (
const int face : node.faces()) {
171 entry.uv_primitive->get_uv_vertex(mesh_data, 0)->uv - tile_offset,
172 entry.uv_primitive->get_uv_vertex(mesh_data, 1)->uv - tile_offset,
173 entry.uv_primitive->get_uv_vertex(mesh_data, 2)->uv - tile_offset,
175 const float minv =
clamp_f(
min_fff(uvs[0].y, uvs[1].y, uvs[2].y), 0.0f, 1.0f);
176 const int miny =
floor(minv * image_buffer->
y);
177 const float maxv =
clamp_f(
max_fff(uvs[0].y, uvs[1].y, uvs[2].y), 0.0f, 1.0f);
178 const int maxy =
min_ii(
ceil(maxv * image_buffer->
y), image_buffer->
y);
179 const float minu =
clamp_f(
min_fff(uvs[0].x, uvs[1].x, uvs[2].x), 0.0f, 1.0f);
180 const int minx =
floor(minu * image_buffer->
x);
181 const float maxu =
clamp_f(
max_fff(uvs[0].x, uvs[1].x, uvs[2].x), 0.0f, 1.0f);
182 const int maxx =
min_ii(
ceil(maxu * image_buffer->
x), image_buffer->
x);
191 image_buffer, uvs, minx, miny);
197 entry.uv_island_index,
214 node_data->
tiles.append(tile_data);
223 if (node.children_offset_ != 0) {
230 if (node_data !=
nullptr) {
259 if (nodes_to_update_len == 0) {
265 PBVHData *pbvh_data = MEM_new<PBVHData>(__func__);
273 r_nodes_to_update.
reserve(nodes_to_update_len);
279 r_nodes_to_update.
append(&node);
282 if (node.pixels_ ==
nullptr) {
283 NodeData *node_data = MEM_new<NodeData>(__func__);
284 node.pixels_ = node_data;
302 if (image_buffer ==
nullptr) {
311 if (tile_node_data ==
nullptr) {
316 int pixel_offset = pixel_row.start_image_coordinate.y * image_buffer->
x +
317 pixel_row.start_image_coordinate.x;
318 for (
int x = 0; x < pixel_row.num_pixels; x++) {
346 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
369 if (tile_buffer ==
nullptr) {
373 ushort2(tile_buffer->
x, tile_buffer->
y));
376 uv_masks.
add(mesh_data, islands);
377 uv_masks.
dilate(image.seam_margin);
379 islands.extract_borders();
380 islands.extend_borders(mesh_data, uv_masks);
386 for (const int i : range) {
388 mesh_data, uv_masks, uv_primitive_lookup, image, image_user, *nodes_to_update[i]);
399 for (
Node *node : nodes_to_update) {
400 NodeData *node_data =
static_cast<NodeData *
>(node->pixels_);
401 node_data->rebuild_undo_regions();
405 for (
Node *node : nodes_to_update) {
406 node->flag_ =
static_cast<PBVHNodeFlags>(node->flag_ & ~PBVH_RebuildPixels);
410 for (
Node &node : pbvh.nodes<MeshNode>()) {
417#ifdef DO_PRINT_STATISTICS
420 int compressed_data_len = 0;
422 for (
int n = 0; n < pbvh->totnode; n++) {
423 Node *node = &pbvh->nodes[n];
427 NodeData *node_data =
static_cast<NodeData *
>(node->pixels.node_data);
428 for (
const UDIMTilePixels &tile_data : node_data->
tiles) {
429 compressed_data_len += tile_data.encoded_pixels.size() *
sizeof(PackedPixelRow);
430 for (
const PackedPixelRow &encoded_pixels : tile_data.encoded_pixels) {
431 num_pixels += encoded_pixels.num_pixels;
435 printf(
"Encoded %lld pixels in %lld bytes (%f bytes per pixel)\n",
438 float(compressed_data_len) / num_pixels);
469 if (image_buffer ==
nullptr) {
473 node_data->
mark_region(image, image_tile, *image_buffer);
504 MEM_delete(node_data);
505 node->pixels_ =
nullptr;
511 MEM_delete(pbvh_data);
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_uchar(unsigned char r[4], unsigned char a)
MINLINE void copy_v4_fl(float r[4], float f)
Object is a sort of wrapper for general info.
constexpr int64_t size() const
constexpr bool is_empty() const
void append(const T &value)
IndexRange index_range() const
void reserve(const int64_t min_capacity)
Span< NodeT > nodes() const
pixels::PBVHData * pixels_
const Depsgraph * depsgraph
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
static bool is_inside(int x, int y, int cols, int rows)
ccl_gpu_kernel_postfix ccl_global KernelWorkTile * tiles
ccl_global const KernelWorkTile * tile
ccl_device_inline float2 floor(const float2 a)
ccl_device_inline float3 ceil(const float3 a)
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
unsigned __int64 uint64_t
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
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::@53 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
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)
Vector< UVIsland > islands