[Bf-blender-cvs] [98bdd08507b] temp-pbvh-split: Merge branch 'master' into temp-pbvh-split

Joseph Eagar noreply at git.blender.org
Sat Dec 31 06:38:10 CET 2022


Commit: 98bdd08507b95e2e0cb4b9bac4fd0d3b28cbd207
Author: Joseph Eagar
Date:   Fri Dec 30 21:38:01 2022 -0800
Branches: temp-pbvh-split
https://developer.blender.org/rB98bdd08507b95e2e0cb4b9bac4fd0d3b28cbd207

Merge branch 'master' into temp-pbvh-split

===================================================================



===================================================================

diff --cc source/blender/blenkernel/intern/pbvh.c
index b012cb7c098,a6a362b1daf..1239a29b353
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@@ -941,10 -1018,8 +1018,10 @@@ void BKE_pbvh_free(PBVH *pbvh
        if (node->bm_other_verts) {
          BLI_gset_free(node->bm_other_verts, NULL);
        }
 +    }
  
 +    if (node->flag & (PBVH_Leaf | PBVH_TexLeaf)) {
-       pbvh_pixels_free(node);
+       pbvh_node_pixels_free(node);
      }
    }
  
diff --cc source/blender/blenkernel/intern/pbvh_intern.h
index 34eb969adac,ee728a698dd..444a28d077c
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@@ -148,10 -148,9 +148,11 @@@ struct PBVH 
    int *prim_indices;
    int totprim;
    int totvert;
+   int faces_num; /* Do not use directly, use BKE_pbvh_num_faces. */
  
    int leaf_limit;
 +  int pixel_leaf_limit;
 +  int depth_limit;
  
    /* Mesh data */
    struct Mesh *mesh;
diff --cc source/blender/blenkernel/intern/pbvh_pixels.cc
index a0c796168ed,e21103c9f19..084d30b271f
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@@ -22,10 -20,15 +22,11 @@@
  #include "bmesh.h"
  
  #include "pbvh_intern.h"
+ #include "pbvh_uv_islands.hh"
  
 -namespace blender::bke::pbvh::pixels {
 +#include <atomic>
  
 -/**
 - * During debugging this check could be enabled.
 - * It will write to each image pixel that is covered by the PBVH.
 - */
 -constexpr bool USE_WATERTIGHT_CHECK = false;
 +namespace blender::bke::pbvh::pixels {
  
  /**
   * Calculate the delta of two neighbor UV coordinates in the given image buffer.
@@@ -53,317 -56,13 +54,322 @@@ static float2 calc_barycentric_delta_x(
    return calc_barycentric_delta(uvs, start_uv, end_uv);
  }
  
 +int count_node_pixels(PBVHNode &node)
 +{
 +  if (!node.pixels.node_data) {
 +    return 0;
 +  }
 +
 +  NodeData &data = BKE_pbvh_pixels_node_data_get(node);
 +
 +  int totpixel = 0;
 +
 +  for (UDIMTilePixels &tile : data.tiles) {
 +    for (PackedPixelRow &row : tile.pixel_rows) {
 +      totpixel += row.num_pixels;
 +    }
 +  }
 +
 +  return totpixel;
 +}
 +
 +struct SplitQueueData {
 +  ThreadQueue *new_nodes;
 +  TaskPool *pool;
 +
 +  PBVH *pbvh;
 +  Mesh *mesh;
 +  Image *image;
 +  ImageUser *image_user;
 +};
 +
 +struct SplitNodePair {
 +  SplitNodePair *parent;
 +  PBVHNode node;
 +  int children_offset = 0;
 +  int depth = 0;
 +  int source_index = -1;
 +  bool is_old = false;
 +  SplitQueueData *tdata;
 +
 +  SplitNodePair(SplitNodePair *node_parent = nullptr) : parent(node_parent)
 +  {
 +    memset(static_cast<void *>(&node), 0, sizeof(PBVHNode));
 +  }
 +};
 +
 +static void split_thread_job(TaskPool *__restrict pool, void *taskdata);
 +
 +static void split_pixel_node(PBVH *pbvh,
 +                             SplitNodePair *split,
 +                             Mesh *mesh,
 +                             Image *image,
 +                             ImageUser *image_user,
 +                             SplitQueueData *tdata)
 +{
 +  BB cb;
 +  PBVHNode *node = &split->node;
 +
 +  cb = node->vb;
 +
 +  if (count_node_pixels(*node) <= pbvh->pixel_leaf_limit || split->depth >= pbvh->depth_limit) {
 +    BKE_pbvh_pixels_node_data_get(split->node).rebuild_undo_regions();
 +    return;
 +  }
 +
 +  /* Find widest axis and its midpoint */
 +  const int axis = BB_widest_axis(&cb);
 +  const float mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
 +
 +  node->flag = (PBVHNodeFlags)((int)node->flag & (int)~PBVH_TexLeaf);
 +
 +  SplitNodePair *split1 = MEM_new<SplitNodePair>("split_pixel_node split1", split);
 +  SplitNodePair *split2 = MEM_new<SplitNodePair>("split_pixel_node split1", split);
 +
 +  split1->depth = split->depth + 1;
 +  split2->depth = split->depth + 1;
 +
 +  PBVHNode *child1 = &split1->node;
 +  PBVHNode *child2 = &split2->node;
 +
 +  child1->flag = PBVH_TexLeaf;
 +  child2->flag = PBVH_TexLeaf;
 +
 +  child1->vb = cb;
 +  child1->vb.bmax[axis] = mid;
 +
 +  child2->vb = cb;
 +  child2->vb.bmin[axis] = mid;
 +
 +  NodeData &data = BKE_pbvh_pixels_node_data_get(split->node);
 +
 +  NodeData *data1 = MEM_new<NodeData>(__func__);
 +  NodeData *data2 = MEM_new<NodeData>(__func__);
 +  child1->pixels.node_data = static_cast<void *>(data1);
 +  child2->pixels.node_data = static_cast<void *>(data2);
 +
-   data1->triangles = data.triangles;
-   data2->triangles = data.triangles;
++  data1->uv_primitives = data.uv_primitives;
++  data2->uv_primitives = data.uv_primitives;
 +
 +  data1->tiles.resize(data.tiles.size());
 +  data2->tiles.resize(data.tiles.size());
 +
 +  for (int i : IndexRange(data.tiles.size())) {
 +    UDIMTilePixels &tile = data.tiles[i];
 +    UDIMTilePixels &tile1 = data1->tiles[i];
 +    UDIMTilePixels &tile2 = data2->tiles[i];
 +
 +    tile1.tile_number = tile2.tile_number = tile.tile_number;
 +    tile1.flags.dirty = tile2.flags.dirty = 0;
 +  }
 +
 +  ImageUser image_user2 = *image_user;
 +
 +  for (int i : IndexRange(data.tiles.size())) {
 +    const UDIMTilePixels &tile = data.tiles[i];
 +
 +    image_user2.tile = tile.tile_number;
 +
 +    ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &image_user2, nullptr);
 +    if (image_buffer == nullptr) {
 +      continue;
 +    }
 +
 +    const MVert *mvert = BKE_pbvh_get_verts(pbvh);
++    PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(*pbvh);
 +
 +    for (const PackedPixelRow &row : tile.pixel_rows) {
 +      UDIMTilePixels *tile1 = &data1->tiles[i];
 +      UDIMTilePixels *tile2 = &data2->tiles[i];
 +
-       TrianglePaintInput &tri = data.triangles->paint_input[row.triangle_index];
++      UVPrimitivePaintInput &uv_prim = data.uv_primitives.paint_input[row.uv_primitive_index];
++      int3 tri = pbvh_data.geom_primitives.vert_indices[uv_prim.geometry_primitive_index];
 +
 +      float verts[3][3];
 +
-       copy_v3_v3(verts[0], mvert[tri.vert_indices[0]].co);
-       copy_v3_v3(verts[1], mvert[tri.vert_indices[1]].co);
-       copy_v3_v3(verts[2], mvert[tri.vert_indices[2]].co);
++      copy_v3_v3(verts[0], mvert[tri[0]].co);
++      copy_v3_v3(verts[1], mvert[tri[1]].co);
++      copy_v3_v3(verts[2], mvert[tri[2]].co);
 +
-       float2 delta = tri.delta_barycentric_coord_u;
++      float2 delta = uv_prim.delta_barycentric_coord_u;
 +      float2 uv1 = row.start_barycentric_coord;
 +      float2 uv2 = row.start_barycentric_coord + delta * (float)row.num_pixels;
 +
 +      float co1[3];
 +      float co2[3];
 +
 +      interp_barycentric_tri_v3(verts, uv1[0], uv1[1], co1);
 +      interp_barycentric_tri_v3(verts, uv2[0], uv2[1], co2);
 +
 +      /* Are we spanning the midpoint? */
 +      if ((co1[axis] <= mid) != (co2[axis] <= mid)) {
 +        PackedPixelRow row1 = row;
 +        float t;
 +
 +        if (mid < co1[axis]) {
 +          t = 1.0f - (mid - co2[axis]) / (co1[axis] - co2[axis]);
 +
 +          SWAP(UDIMTilePixels *, tile1, tile2);
 +        }
 +        else {
 +          t = (mid - co1[axis]) / (co2[axis] - co1[axis]);
 +        }
 +
 +        int num_pixels = (int)floorf((float)row.num_pixels * t);
 +
 +        if (num_pixels) {
 +          row1.num_pixels = num_pixels;
 +          tile1->pixel_rows.append(row1);
 +        }
 +
 +        if (num_pixels != row.num_pixels) {
 +          PackedPixelRow row2 = row;
 +
 +          row2.num_pixels = row.num_pixels - num_pixels;
 +
 +          row2.start_barycentric_coord = row.start_barycentric_coord +
-                                          tri.delta_barycentric_coord_u * (float)num_pixels;
++                                         uv_prim.delta_barycentric_coord_u * (float)num_pixels;
 +          row2.start_image_coordinate = row.start_image_coordinate;
 +          row2.start_image_coordinate[0] += num_pixels;
 +
 +          tile2->pixel_rows.append(row2);
 +        }
 +      }
 +      else if (co1[axis] <= mid && co2[axis] <= mid) {
 +        tile1->pixel_rows.append(row);
 +      }
 +      else {
 +        tile2->pixel_rows.append(row);
 +      }
 +    }
 +
 +    BKE_image_release_ibuf(image, image_buffer, nullptr);
 +  }
 +
 +  data.undo_regions.clear();
 +
 +  if (node->flag & PBVH_Leaf) {
 +    data.clear_data();
 +  }
 +  else {
-     pbvh_pixels_free(node);
++    pbvh_node_pixels_free(node);
 +  }
 +
 +  BLI_thread_queue_push(tdata->new_nodes, static_cast<void *>(split1));
 +  BLI_thread_queue_push(tdata->new_nodes, static_cast<void *>(split2));
 +
 +  BLI_task_pool_push(tdata->pool, split_thread_job, static_cast<void *>(split1), false, nullptr);
 +  BLI_task_pool_push(tdata->pool, split_thread_job, static_cast<void *>(split2), false, nullptr);
 +}
 +
 +static void split_flush_final_nodes(SplitQueueData *tdata)
 +{
 +  PBVH *pbvh = tdata->pbvh;
 +  Vector<SplitNodePair *> splits;
 +
 +  while (!BLI_thread_queue_is_empty(tdata->new_nodes)) {
 +    SplitNodePair *newsplit = static_cast<SplitNodePair *>(BLI_thread_queue_pop(tdata->new_nodes));
 +
 +    splits.append(newsplit);
 +
 +    if (newsplit->is_old) {
 +      continue;
 +    }
 +
 +    if (!newsplit->parent->children_offset) {
 +      newsplit->parent->children_offset = pbvh->totnode;
 +
 +      pbvh_grow_nodes(pbvh, pbvh->totnode + 2);
 +      newsplit->source_index = newsplit->parent->children_offset;
 +    }
 +    else {
 +      newsplit->source_index = newsplit->parent->children_offset + 1;
 +    }
 +  }
 +
 +  for (SplitNodePair *split : splits) {
 +    BLI_assert(split->source_index != -1);
 +
 +    split->node.children_offset = split->children_offset;
 +    pbvh->nodes[split->source_index] = split->node;
 +  }
 +
 +  for (SplitNodePair *split : splits) {
 +    MEM_delete<SplitNodePair>(split);
 +  }
 +}
 +
 +static void split_thread_job(TaskPool *__restrict pool, void *taskdata)
 +{
 +
 +  SplitQueueData *tdata = static_cast<SplitQueueData *>(BLI_task_pool_user_data(pool));
 +  SplitNodePair *split = static_cast<SplitNodePair *>(taskdata);
 +
 +  split_pixel_node(tdata->pbvh, split, tdata->mesh, tdata->image, tdata->image_user, tdata);
 +}
 +
 +static void split_pixel_nodes(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user)
 +{
 +  if (G.debug_value == 891) {
 +    return;
 +  }
 +
 +  if (!pbvh->depth_limit) {
 +    

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list