|
|
|
|
@@ -154,15 +154,15 @@ struct PBVHBatch {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const CustomData *get_cdata(eAttrDomain domain, const PBVH_GPU_Args *args)
|
|
|
|
|
static const CustomData *get_cdata(eAttrDomain domain, const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
switch (domain) {
|
|
|
|
|
case ATTR_DOMAIN_POINT:
|
|
|
|
|
return args->vert_data;
|
|
|
|
|
return args.vert_data;
|
|
|
|
|
case ATTR_DOMAIN_CORNER:
|
|
|
|
|
return args->loop_data;
|
|
|
|
|
return args.loop_data;
|
|
|
|
|
case ATTR_DOMAIN_FACE:
|
|
|
|
|
return args->face_data;
|
|
|
|
|
return args.face_data;
|
|
|
|
|
default:
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
@@ -185,16 +185,16 @@ struct PBVHBatches {
|
|
|
|
|
int coarse_level = 0; /* Coarse multires depth. */
|
|
|
|
|
int tris_count_coarse = 0, lines_count_coarse = 0;
|
|
|
|
|
|
|
|
|
|
int count_faces(PBVH_GPU_Args *args)
|
|
|
|
|
int count_faces(const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
|
|
switch (args->pbvh_type) {
|
|
|
|
|
switch (args.pbvh_type) {
|
|
|
|
|
case PBVH_FACES: {
|
|
|
|
|
for (const int looptri_i : args->prim_indices) {
|
|
|
|
|
const int face_i = args->looptri_faces[looptri_i];
|
|
|
|
|
for (const int looptri_i : args.prim_indices) {
|
|
|
|
|
const int face_i = args.looptri_faces[looptri_i];
|
|
|
|
|
|
|
|
|
|
if (args->hide_poly && args->hide_poly[face_i]) {
|
|
|
|
|
if (args.hide_poly && args.hide_poly[face_i]) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -203,16 +203,16 @@ struct PBVHBatches {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PBVH_GRIDS: {
|
|
|
|
|
count = BKE_pbvh_count_grid_quads((BLI_bitmap **)args->grid_hidden,
|
|
|
|
|
args->grid_indices.data(),
|
|
|
|
|
args->grid_indices.size(),
|
|
|
|
|
args->ccg_key.grid_size,
|
|
|
|
|
args->ccg_key.grid_size);
|
|
|
|
|
count = BKE_pbvh_count_grid_quads((BLI_bitmap **)args.grid_hidden,
|
|
|
|
|
args.grid_indices.data(),
|
|
|
|
|
args.grid_indices.size(),
|
|
|
|
|
args.ccg_key.grid_size,
|
|
|
|
|
args.ccg_key.grid_size);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PBVH_BMESH: {
|
|
|
|
|
GSET_FOREACH_BEGIN (BMFace *, f, args->bm_faces) {
|
|
|
|
|
GSET_FOREACH_BEGIN (BMFace *, f, args.bm_faces) {
|
|
|
|
|
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
@@ -224,11 +224,11 @@ struct PBVHBatches {
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PBVHBatches(PBVH_GPU_Args *args)
|
|
|
|
|
PBVHBatches(const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
faces_count = count_faces(args);
|
|
|
|
|
|
|
|
|
|
if (args->pbvh_type == PBVH_BMESH) {
|
|
|
|
|
if (args.pbvh_type == PBVH_BMESH) {
|
|
|
|
|
tris_count = faces_count;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -315,7 +315,7 @@ struct PBVHBatches {
|
|
|
|
|
|
|
|
|
|
PBVHBatch &ensure_batch(PBVHAttrReq *attrs,
|
|
|
|
|
int attrs_num,
|
|
|
|
|
PBVH_GPU_Args *args,
|
|
|
|
|
const PBVH_GPU_Args &args,
|
|
|
|
|
bool do_coarse_grids)
|
|
|
|
|
{
|
|
|
|
|
if (!has_batch(attrs, attrs_num, do_coarse_grids)) {
|
|
|
|
|
@@ -327,30 +327,30 @@ struct PBVHBatches {
|
|
|
|
|
|
|
|
|
|
void fill_vbo_normal_faces(
|
|
|
|
|
PBVHVbo & /*vbo*/,
|
|
|
|
|
PBVH_GPU_Args *args,
|
|
|
|
|
const PBVH_GPU_Args &args,
|
|
|
|
|
std::function<void(std::function<void(int, int, int, const int)> callback)> foreach_faces,
|
|
|
|
|
GPUVertBufRaw *access)
|
|
|
|
|
{
|
|
|
|
|
const bool *sharp_faces = static_cast<const bool *>(
|
|
|
|
|
CustomData_get_layer_named(args->face_data, CD_PROP_BOOL, "sharp_face"));
|
|
|
|
|
CustomData_get_layer_named(args.face_data, CD_PROP_BOOL, "sharp_face"));
|
|
|
|
|
short no[3];
|
|
|
|
|
int last_face = -1;
|
|
|
|
|
bool flat = false;
|
|
|
|
|
|
|
|
|
|
foreach_faces([&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const int looptri_i) {
|
|
|
|
|
const int face_i = args->looptri_faces[looptri_i];
|
|
|
|
|
const int face_i = args.looptri_faces[looptri_i];
|
|
|
|
|
if (face_i != last_face) {
|
|
|
|
|
last_face = face_i;
|
|
|
|
|
flat = sharp_faces && sharp_faces[face_i];
|
|
|
|
|
if (flat) {
|
|
|
|
|
const float3 fno = blender::bke::mesh::face_normal_calc(
|
|
|
|
|
args->vert_positions, args->corner_verts.slice(args->faces[face_i]));
|
|
|
|
|
args.vert_positions, args.corner_verts.slice(args.faces[face_i]));
|
|
|
|
|
normal_float_to_short_v3(no, fno);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!flat) {
|
|
|
|
|
normal_float_to_short_v3(no, args->vert_normals[vertex_i]);
|
|
|
|
|
normal_float_to_short_v3(no, args.vert_normals[vertex_i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*static_cast<short3 *>(GPU_vertbuf_raw_step(access)) = no;
|
|
|
|
|
@@ -359,13 +359,13 @@ struct PBVHBatches {
|
|
|
|
|
|
|
|
|
|
void fill_vbo_grids_intern(
|
|
|
|
|
PBVHVbo &vbo,
|
|
|
|
|
PBVH_GPU_Args *args,
|
|
|
|
|
const PBVH_GPU_Args &args,
|
|
|
|
|
std::function<
|
|
|
|
|
void(std::function<void(int x, int y, int grid_index, CCGElem *elems[4], int i)> func)>
|
|
|
|
|
foreach_grids)
|
|
|
|
|
{
|
|
|
|
|
uint vert_per_grid = square_i(args->ccg_key.grid_size - 1) * 4;
|
|
|
|
|
uint vert_count = args->grid_indices.size() * vert_per_grid;
|
|
|
|
|
uint vert_per_grid = square_i(args.ccg_key.grid_size - 1) * 4;
|
|
|
|
|
uint vert_count = args.grid_indices.size() * vert_per_grid;
|
|
|
|
|
|
|
|
|
|
int existing_num = GPU_vertbuf_get_vertex_len(vbo.vert_buf);
|
|
|
|
|
void *existing_data = GPU_vertbuf_get_data(vbo.vert_buf);
|
|
|
|
|
@@ -394,7 +394,7 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
case CD_PBVH_CO_TYPE:
|
|
|
|
|
foreach_grids([&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem *elems[4], int i) {
|
|
|
|
|
float *co = CCG_elem_co(&args->ccg_key, elems[i]);
|
|
|
|
|
float *co = CCG_elem_co(&args.ccg_key, elems[i]);
|
|
|
|
|
|
|
|
|
|
*static_cast<float3 *>(GPU_vertbuf_raw_step(&access)) = co;
|
|
|
|
|
});
|
|
|
|
|
@@ -404,17 +404,17 @@ struct PBVHBatches {
|
|
|
|
|
foreach_grids([&](int /*x*/, int /*y*/, int grid_index, CCGElem *elems[4], int /*i*/) {
|
|
|
|
|
float3 no(0.0f, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
|
|
const bool smooth = !args->grid_flag_mats[grid_index].sharp;
|
|
|
|
|
const bool smooth = !args.grid_flag_mats[grid_index].sharp;
|
|
|
|
|
|
|
|
|
|
if (smooth) {
|
|
|
|
|
no = CCG_elem_no(&args->ccg_key, elems[0]);
|
|
|
|
|
no = CCG_elem_no(&args.ccg_key, elems[0]);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
normal_quad_v3(no,
|
|
|
|
|
CCG_elem_co(&args->ccg_key, elems[3]),
|
|
|
|
|
CCG_elem_co(&args->ccg_key, elems[2]),
|
|
|
|
|
CCG_elem_co(&args->ccg_key, elems[1]),
|
|
|
|
|
CCG_elem_co(&args->ccg_key, elems[0]));
|
|
|
|
|
CCG_elem_co(&args.ccg_key, elems[3]),
|
|
|
|
|
CCG_elem_co(&args.ccg_key, elems[2]),
|
|
|
|
|
CCG_elem_co(&args.ccg_key, elems[1]),
|
|
|
|
|
CCG_elem_co(&args.ccg_key, elems[0]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
short sno[3];
|
|
|
|
|
@@ -426,9 +426,9 @@ struct PBVHBatches {
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case CD_PBVH_MASK_TYPE:
|
|
|
|
|
if (args->ccg_key.has_mask) {
|
|
|
|
|
if (args.ccg_key.has_mask) {
|
|
|
|
|
foreach_grids([&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem *elems[4], int i) {
|
|
|
|
|
float *mask = CCG_elem_mask(&args->ccg_key, elems[i]);
|
|
|
|
|
float *mask = CCG_elem_mask(&args.ccg_key, elems[i]);
|
|
|
|
|
|
|
|
|
|
*static_cast<uchar *>(GPU_vertbuf_raw_step(&access)) = uchar(*mask * 255.0f);
|
|
|
|
|
});
|
|
|
|
|
@@ -442,7 +442,7 @@ struct PBVHBatches {
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case CD_PBVH_FSET_TYPE: {
|
|
|
|
|
const int *face_sets = args->face_sets;
|
|
|
|
|
const int *face_sets = args.face_sets;
|
|
|
|
|
|
|
|
|
|
if (!face_sets) {
|
|
|
|
|
uchar white[3] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
|
|
|
|
|
@@ -458,14 +458,14 @@ struct PBVHBatches {
|
|
|
|
|
uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
|
|
|
|
|
|
|
|
|
|
if (face_sets) {
|
|
|
|
|
const int face_index = BKE_subdiv_ccg_grid_to_face_index(args->subdiv_ccg,
|
|
|
|
|
const int face_index = BKE_subdiv_ccg_grid_to_face_index(args.subdiv_ccg,
|
|
|
|
|
grid_index);
|
|
|
|
|
const int fset = face_sets[face_index];
|
|
|
|
|
|
|
|
|
|
/* Skip for the default color Face Set to render it white. */
|
|
|
|
|
if (fset != args->face_sets_color_default) {
|
|
|
|
|
if (fset != args.face_sets_color_default) {
|
|
|
|
|
BKE_paint_face_set_overlay_color_get(
|
|
|
|
|
fset, args->face_sets_color_seed, face_set_color);
|
|
|
|
|
fset, args.face_sets_color_seed, face_set_color);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -477,26 +477,26 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fill_vbo_grids(PBVHVbo &vbo, PBVH_GPU_Args *args)
|
|
|
|
|
void fill_vbo_grids(PBVHVbo &vbo, const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
int gridsize = args->ccg_key.grid_size;
|
|
|
|
|
int gridsize = args.ccg_key.grid_size;
|
|
|
|
|
|
|
|
|
|
uint totgrid = args->grid_indices.size();
|
|
|
|
|
uint totgrid = args.grid_indices.size();
|
|
|
|
|
|
|
|
|
|
auto foreach_solid =
|
|
|
|
|
[&](std::function<void(int x, int y, int grid_index, CCGElem *elems[4], int i)> func) {
|
|
|
|
|
for (int i = 0; i < totgrid; i++) {
|
|
|
|
|
const int grid_index = args->grid_indices[i];
|
|
|
|
|
const int grid_index = args.grid_indices[i];
|
|
|
|
|
|
|
|
|
|
CCGElem *grid = args->grids[grid_index];
|
|
|
|
|
CCGElem *grid = args.grids[grid_index];
|
|
|
|
|
|
|
|
|
|
for (int y = 0; y < gridsize - 1; y++) {
|
|
|
|
|
for (int x = 0; x < gridsize - 1; x++) {
|
|
|
|
|
CCGElem *elems[4] = {
|
|
|
|
|
CCG_grid_elem(&args->ccg_key, grid, x, y),
|
|
|
|
|
CCG_grid_elem(&args->ccg_key, grid, x + 1, y),
|
|
|
|
|
CCG_grid_elem(&args->ccg_key, grid, x + 1, y + 1),
|
|
|
|
|
CCG_grid_elem(&args->ccg_key, grid, x, y + 1),
|
|
|
|
|
CCG_grid_elem(&args.ccg_key, grid, x, y),
|
|
|
|
|
CCG_grid_elem(&args.ccg_key, grid, x + 1, y),
|
|
|
|
|
CCG_grid_elem(&args.ccg_key, grid, x + 1, y + 1),
|
|
|
|
|
CCG_grid_elem(&args.ccg_key, grid, x, y + 1),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
func(x, y, grid_index, elems, 0);
|
|
|
|
|
@@ -511,20 +511,20 @@ struct PBVHBatches {
|
|
|
|
|
auto foreach_indexed =
|
|
|
|
|
[&](std::function<void(int x, int y, int grid_index, CCGElem *elems[4], int i)> func) {
|
|
|
|
|
for (int i = 0; i < totgrid; i++) {
|
|
|
|
|
const int grid_index = args->grid_indices[i];
|
|
|
|
|
const int grid_index = args.grid_indices[i];
|
|
|
|
|
|
|
|
|
|
CCGElem *grid = args->grids[grid_index];
|
|
|
|
|
CCGElem *grid = args.grids[grid_index];
|
|
|
|
|
|
|
|
|
|
for (int y = 0; y < gridsize; y++) {
|
|
|
|
|
for (int x = 0; x < gridsize; x++) {
|
|
|
|
|
CCGElem *elems[4] = {
|
|
|
|
|
CCG_grid_elem(&args->ccg_key, grid, x, y),
|
|
|
|
|
CCG_grid_elem(&args->ccg_key, grid, min_ii(x + 1, gridsize - 1), y),
|
|
|
|
|
CCG_grid_elem(&args->ccg_key,
|
|
|
|
|
CCG_grid_elem(&args.ccg_key, grid, x, y),
|
|
|
|
|
CCG_grid_elem(&args.ccg_key, grid, min_ii(x + 1, gridsize - 1), y),
|
|
|
|
|
CCG_grid_elem(&args.ccg_key,
|
|
|
|
|
grid,
|
|
|
|
|
min_ii(x + 1, gridsize - 1),
|
|
|
|
|
min_ii(y + 1, gridsize - 1)),
|
|
|
|
|
CCG_grid_elem(&args->ccg_key, grid, x, min_ii(y + 1, gridsize - 1)),
|
|
|
|
|
CCG_grid_elem(&args.ccg_key, grid, x, min_ii(y + 1, gridsize - 1)),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
func(x, y, grid_index, elems, 0);
|
|
|
|
|
@@ -541,23 +541,23 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fill_vbo_faces(PBVHVbo &vbo, PBVH_GPU_Args *args)
|
|
|
|
|
void fill_vbo_faces(PBVHVbo &vbo, const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
const blender::Span<int> corner_verts = args->corner_verts;
|
|
|
|
|
const blender::Span<int> corner_verts = args.corner_verts;
|
|
|
|
|
auto foreach_faces =
|
|
|
|
|
[&](std::function<void(int buffer_i, int tri_i, int vertex_i, const int /*looptri_i*/)>
|
|
|
|
|
func) {
|
|
|
|
|
int buffer_i = 0;
|
|
|
|
|
|
|
|
|
|
for (const int looptri_i : args->prim_indices) {
|
|
|
|
|
const int face_i = args->looptri_faces[looptri_i];
|
|
|
|
|
for (const int looptri_i : args.prim_indices) {
|
|
|
|
|
const int face_i = args.looptri_faces[looptri_i];
|
|
|
|
|
|
|
|
|
|
if (args->hide_poly && args->hide_poly[face_i]) {
|
|
|
|
|
if (args.hide_poly && args.hide_poly[face_i]) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int j : IndexRange(3)) {
|
|
|
|
|
func(buffer_i, j, corner_verts[args->mlooptri[looptri_i].tri[j]], looptri_i);
|
|
|
|
|
func(buffer_i, j, corner_verts[args.mlooptri[looptri_i].tri[j]], looptri_i);
|
|
|
|
|
buffer_i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -580,7 +580,7 @@ struct PBVHBatches {
|
|
|
|
|
switch (vbo.type) {
|
|
|
|
|
case CD_PBVH_CO_TYPE:
|
|
|
|
|
foreach_faces([&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const int /*looptri_i*/) {
|
|
|
|
|
*static_cast<float3 *>(GPU_vertbuf_raw_step(&access)) = args->vert_positions[vertex_i];
|
|
|
|
|
*static_cast<float3 *>(GPU_vertbuf_raw_step(&access)) = args.vert_positions[vertex_i];
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case CD_PBVH_NO_TYPE:
|
|
|
|
|
@@ -588,7 +588,7 @@ struct PBVHBatches {
|
|
|
|
|
break;
|
|
|
|
|
case CD_PBVH_MASK_TYPE: {
|
|
|
|
|
const float *mask = static_cast<const float *>(
|
|
|
|
|
CustomData_get_layer(args->vert_data, CD_PAINT_MASK));
|
|
|
|
|
CustomData_get_layer(args.vert_data, CD_PAINT_MASK));
|
|
|
|
|
|
|
|
|
|
if (mask) {
|
|
|
|
|
foreach_faces(
|
|
|
|
|
@@ -607,7 +607,7 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
case CD_PBVH_FSET_TYPE: {
|
|
|
|
|
const int *face_sets = static_cast<const int *>(
|
|
|
|
|
CustomData_get_layer_named(args->face_data, CD_PROP_INT32, ".sculpt_face_set"));
|
|
|
|
|
CustomData_get_layer_named(args.face_data, CD_PROP_INT32, ".sculpt_face_set"));
|
|
|
|
|
|
|
|
|
|
if (face_sets) {
|
|
|
|
|
int last_face = -1;
|
|
|
|
|
@@ -615,15 +615,15 @@ struct PBVHBatches {
|
|
|
|
|
|
|
|
|
|
foreach_faces(
|
|
|
|
|
[&](int /*buffer_i*/, int /*tri_i*/, int /*vertex_i*/, const int looptri_i) {
|
|
|
|
|
const int face_i = args->looptri_faces[looptri_i];
|
|
|
|
|
const int face_i = args.looptri_faces[looptri_i];
|
|
|
|
|
if (last_face != face_i) {
|
|
|
|
|
last_face = face_i;
|
|
|
|
|
|
|
|
|
|
const int fset = face_sets[face_i];
|
|
|
|
|
|
|
|
|
|
if (fset != args->face_sets_color_default) {
|
|
|
|
|
if (fset != args.face_sets_color_default) {
|
|
|
|
|
BKE_paint_face_set_overlay_color_get(
|
|
|
|
|
fset, args->face_sets_color_seed, fset_color);
|
|
|
|
|
fset, args.face_sets_color_seed, fset_color);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Skip for the default color face set to render it white. */
|
|
|
|
|
@@ -648,7 +648,7 @@ struct PBVHBatches {
|
|
|
|
|
case CD_PROP_COLOR:
|
|
|
|
|
if (vbo.domain == ATTR_DOMAIN_POINT) {
|
|
|
|
|
const MPropCol *mpropcol = static_cast<const MPropCol *>(
|
|
|
|
|
CustomData_get_layer_named(args->vert_data, CD_PROP_COLOR, vbo.name.c_str()));
|
|
|
|
|
CustomData_get_layer_named(args.vert_data, CD_PROP_COLOR, vbo.name.c_str()));
|
|
|
|
|
|
|
|
|
|
foreach_faces(
|
|
|
|
|
[&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const int /*looptri_i*/) {
|
|
|
|
|
@@ -665,11 +665,11 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
else if (vbo.domain == ATTR_DOMAIN_CORNER) {
|
|
|
|
|
const MPropCol *mpropcol = static_cast<const MPropCol *>(
|
|
|
|
|
CustomData_get_layer_named(args->loop_data, CD_PROP_COLOR, vbo.name.c_str()));
|
|
|
|
|
CustomData_get_layer_named(args.loop_data, CD_PROP_COLOR, vbo.name.c_str()));
|
|
|
|
|
|
|
|
|
|
foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const int looptri_i) {
|
|
|
|
|
ushort color[4];
|
|
|
|
|
const MPropCol *col = mpropcol + args->mlooptri[looptri_i].tri[tri_i];
|
|
|
|
|
const MPropCol *col = mpropcol + args.mlooptri[looptri_i].tri[tri_i];
|
|
|
|
|
|
|
|
|
|
color[0] = unit_float_to_ushort_clamp(col->color[0]);
|
|
|
|
|
color[1] = unit_float_to_ushort_clamp(col->color[1]);
|
|
|
|
|
@@ -683,7 +683,7 @@ struct PBVHBatches {
|
|
|
|
|
case CD_PROP_BYTE_COLOR:
|
|
|
|
|
if (vbo.domain == ATTR_DOMAIN_POINT) {
|
|
|
|
|
const MLoopCol *mbytecol = static_cast<const MLoopCol *>(
|
|
|
|
|
CustomData_get_layer_named(args->vert_data, CD_PROP_BYTE_COLOR, vbo.name.c_str()));
|
|
|
|
|
CustomData_get_layer_named(args.vert_data, CD_PROP_BYTE_COLOR, vbo.name.c_str()));
|
|
|
|
|
|
|
|
|
|
foreach_faces(
|
|
|
|
|
[&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const int /*looptri_i*/) {
|
|
|
|
|
@@ -700,11 +700,11 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
else if (vbo.domain == ATTR_DOMAIN_CORNER) {
|
|
|
|
|
const MLoopCol *mbytecol = static_cast<const MLoopCol *>(
|
|
|
|
|
CustomData_get_layer_named(args->loop_data, CD_PROP_BYTE_COLOR, vbo.name.c_str()));
|
|
|
|
|
CustomData_get_layer_named(args.loop_data, CD_PROP_BYTE_COLOR, vbo.name.c_str()));
|
|
|
|
|
|
|
|
|
|
foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const int looptri_i) {
|
|
|
|
|
ushort color[4];
|
|
|
|
|
const MLoopCol *col = mbytecol + args->mlooptri[looptri_i].tri[tri_i];
|
|
|
|
|
const MLoopCol *col = mbytecol + args.mlooptri[looptri_i].tri[tri_i];
|
|
|
|
|
|
|
|
|
|
color[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->r]);
|
|
|
|
|
color[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->g]);
|
|
|
|
|
@@ -717,11 +717,11 @@ struct PBVHBatches {
|
|
|
|
|
break;
|
|
|
|
|
case CD_PROP_FLOAT2: {
|
|
|
|
|
const float2 *mloopuv = static_cast<const float2 *>(
|
|
|
|
|
CustomData_get_layer_named(args->loop_data, CD_PROP_FLOAT2, vbo.name.c_str()));
|
|
|
|
|
CustomData_get_layer_named(args.loop_data, CD_PROP_FLOAT2, vbo.name.c_str()));
|
|
|
|
|
|
|
|
|
|
foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const int looptri_i) {
|
|
|
|
|
*static_cast<float2 *>(
|
|
|
|
|
GPU_vertbuf_raw_step(&access)) = mloopuv[args->mlooptri[looptri_i].tri[tri_i]];
|
|
|
|
|
GPU_vertbuf_raw_step(&access)) = mloopuv[args.mlooptri[looptri_i].tri[tri_i]];
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -737,7 +737,7 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void update(PBVH_GPU_Args *args)
|
|
|
|
|
void update(const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
check_index_buffers(args);
|
|
|
|
|
|
|
|
|
|
@@ -746,10 +746,10 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fill_vbo_bmesh(PBVHVbo &vbo, PBVH_GPU_Args *args)
|
|
|
|
|
void fill_vbo_bmesh(PBVHVbo &vbo, const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
auto foreach_bmesh = [&](std::function<void(BMLoop * l)> callback) {
|
|
|
|
|
GSET_FOREACH_BEGIN (BMFace *, f, args->bm_faces) {
|
|
|
|
|
GSET_FOREACH_BEGIN (BMFace *, f, args.bm_faces) {
|
|
|
|
|
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
@@ -811,7 +811,7 @@ struct PBVHBatches {
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case CD_PBVH_MASK_TYPE: {
|
|
|
|
|
int cd_mask = args->cd_mask_layer;
|
|
|
|
|
int cd_mask = args.cd_mask_layer;
|
|
|
|
|
|
|
|
|
|
if (cd_mask == -1) {
|
|
|
|
|
foreach_bmesh(
|
|
|
|
|
@@ -836,9 +836,9 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fill_vbo(PBVHVbo &vbo, PBVH_GPU_Args *args)
|
|
|
|
|
void fill_vbo(PBVHVbo &vbo, const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
switch (args->pbvh_type) {
|
|
|
|
|
switch (args.pbvh_type) {
|
|
|
|
|
case PBVH_FACES:
|
|
|
|
|
fill_vbo_faces(vbo, args);
|
|
|
|
|
break;
|
|
|
|
|
@@ -851,7 +851,7 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void create_vbo(eAttrDomain domain, const uint32_t type, string name, PBVH_GPU_Args *args)
|
|
|
|
|
void create_vbo(eAttrDomain domain, const uint32_t type, string name, const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
PBVHVbo vbo(domain, type, name);
|
|
|
|
|
GPUVertFormat format;
|
|
|
|
|
@@ -912,8 +912,8 @@ struct PBVHBatches {
|
|
|
|
|
|
|
|
|
|
if (ELEM(type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
|
|
|
|
|
prefix = "c";
|
|
|
|
|
is_active = blender::StringRef(args->active_color) == layer->name;
|
|
|
|
|
is_render = blender::StringRef(args->render_color) == layer->name;
|
|
|
|
|
is_active = blender::StringRef(args.active_color) == layer->name;
|
|
|
|
|
is_render = blender::StringRef(args.render_color) == layer->name;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
switch (type) {
|
|
|
|
|
@@ -945,9 +945,9 @@ struct PBVHBatches {
|
|
|
|
|
vbos.append(vbo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void update_pre(PBVH_GPU_Args *args)
|
|
|
|
|
void update_pre(const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
if (args->pbvh_type == PBVH_BMESH) {
|
|
|
|
|
if (args.pbvh_type == PBVH_BMESH) {
|
|
|
|
|
int count = count_faces(args);
|
|
|
|
|
|
|
|
|
|
if (faces_count != count) {
|
|
|
|
|
@@ -966,31 +966,31 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void create_index_faces(PBVH_GPU_Args *args)
|
|
|
|
|
void create_index_faces(const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
const int *mat_index = static_cast<const int *>(
|
|
|
|
|
CustomData_get_layer_named(args->face_data, CD_PROP_INT32, "material_index"));
|
|
|
|
|
CustomData_get_layer_named(args.face_data, CD_PROP_INT32, "material_index"));
|
|
|
|
|
|
|
|
|
|
if (mat_index && !args->prim_indices.is_empty()) {
|
|
|
|
|
const int looptri_i = args->prim_indices[0];
|
|
|
|
|
const int face_i = args->looptri_faces[looptri_i];
|
|
|
|
|
if (mat_index && !args.prim_indices.is_empty()) {
|
|
|
|
|
const int looptri_i = args.prim_indices[0];
|
|
|
|
|
const int face_i = args.looptri_faces[looptri_i];
|
|
|
|
|
material_index = mat_index[face_i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const blender::Span<blender::int2> edges = args->me->edges();
|
|
|
|
|
const blender::Span<blender::int2> edges = args.me->edges();
|
|
|
|
|
|
|
|
|
|
/* Calculate number of edges. */
|
|
|
|
|
int edge_count = 0;
|
|
|
|
|
for (const int looptri_i : args->prim_indices) {
|
|
|
|
|
const int face_i = args->looptri_faces[looptri_i];
|
|
|
|
|
if (args->hide_poly && args->hide_poly[face_i]) {
|
|
|
|
|
for (const int looptri_i : args.prim_indices) {
|
|
|
|
|
const int face_i = args.looptri_faces[looptri_i];
|
|
|
|
|
if (args.hide_poly && args.hide_poly[face_i]) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const MLoopTri *lt = &args->mlooptri[looptri_i];
|
|
|
|
|
const MLoopTri *lt = &args.mlooptri[looptri_i];
|
|
|
|
|
int r_edges[3];
|
|
|
|
|
BKE_mesh_looptri_get_real_edges(
|
|
|
|
|
edges.data(), args->corner_verts.data(), args->corner_edges.data(), lt, r_edges);
|
|
|
|
|
edges.data(), args.corner_verts.data(), args.corner_edges.data(), lt, r_edges);
|
|
|
|
|
|
|
|
|
|
if (r_edges[0] != -1) {
|
|
|
|
|
edge_count++;
|
|
|
|
|
@@ -1007,16 +1007,16 @@ struct PBVHBatches {
|
|
|
|
|
GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, edge_count * 2, INT_MAX);
|
|
|
|
|
|
|
|
|
|
int vertex_i = 0;
|
|
|
|
|
for (const int looptri_i : args->prim_indices) {
|
|
|
|
|
const int face_i = args->looptri_faces[looptri_i];
|
|
|
|
|
if (args->hide_poly && args->hide_poly[face_i]) {
|
|
|
|
|
for (const int looptri_i : args.prim_indices) {
|
|
|
|
|
const int face_i = args.looptri_faces[looptri_i];
|
|
|
|
|
if (args.hide_poly && args.hide_poly[face_i]) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const MLoopTri *lt = &args->mlooptri[looptri_i];
|
|
|
|
|
const MLoopTri *lt = &args.mlooptri[looptri_i];
|
|
|
|
|
int r_edges[3];
|
|
|
|
|
BKE_mesh_looptri_get_real_edges(
|
|
|
|
|
edges.data(), args->corner_verts.data(), args->corner_edges.data(), lt, r_edges);
|
|
|
|
|
edges.data(), args.corner_verts.data(), args.corner_edges.data(), lt, r_edges);
|
|
|
|
|
|
|
|
|
|
if (r_edges[0] != -1) {
|
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, vertex_i, vertex_i + 1);
|
|
|
|
|
@@ -1034,7 +1034,7 @@ struct PBVHBatches {
|
|
|
|
|
lines_index = GPU_indexbuf_build(&elb_lines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void create_index_bmesh(PBVH_GPU_Args *args)
|
|
|
|
|
void create_index_bmesh(const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
GPUIndexBufBuilder elb_lines;
|
|
|
|
|
GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tris_count * 3 * 2, INT_MAX);
|
|
|
|
|
@@ -1042,7 +1042,7 @@ struct PBVHBatches {
|
|
|
|
|
int v_index = 0;
|
|
|
|
|
lines_count = 0;
|
|
|
|
|
|
|
|
|
|
GSET_FOREACH_BEGIN (BMFace *, f, args->bm_faces) {
|
|
|
|
|
GSET_FOREACH_BEGIN (BMFace *, f, args.bm_faces) {
|
|
|
|
|
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
@@ -1059,32 +1059,32 @@ struct PBVHBatches {
|
|
|
|
|
lines_index = GPU_indexbuf_build(&elb_lines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void create_index_grids(PBVH_GPU_Args *args, bool do_coarse)
|
|
|
|
|
void create_index_grids(const PBVH_GPU_Args &args, bool do_coarse)
|
|
|
|
|
{
|
|
|
|
|
const int *mat_index = static_cast<const int *>(
|
|
|
|
|
CustomData_get_layer_named(args->face_data, CD_PROP_INT32, "material_index"));
|
|
|
|
|
CustomData_get_layer_named(args.face_data, CD_PROP_INT32, "material_index"));
|
|
|
|
|
|
|
|
|
|
if (mat_index && !args->grid_indices.is_empty()) {
|
|
|
|
|
int face_i = BKE_subdiv_ccg_grid_to_face_index(args->subdiv_ccg, args->grid_indices[0]);
|
|
|
|
|
if (mat_index && !args.grid_indices.is_empty()) {
|
|
|
|
|
int face_i = BKE_subdiv_ccg_grid_to_face_index(args.subdiv_ccg, args.grid_indices[0]);
|
|
|
|
|
material_index = mat_index[face_i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
needs_tri_index = true;
|
|
|
|
|
int gridsize = args->ccg_key.grid_size;
|
|
|
|
|
int gridsize = args.ccg_key.grid_size;
|
|
|
|
|
int display_gridsize = gridsize;
|
|
|
|
|
int totgrid = args->grid_indices.size();
|
|
|
|
|
int totgrid = args.grid_indices.size();
|
|
|
|
|
int skip = 1;
|
|
|
|
|
|
|
|
|
|
const int display_level = do_coarse ? coarse_level : args->ccg_key.level;
|
|
|
|
|
const int display_level = do_coarse ? coarse_level : args.ccg_key.level;
|
|
|
|
|
|
|
|
|
|
if (display_level < args->ccg_key.level) {
|
|
|
|
|
if (display_level < args.ccg_key.level) {
|
|
|
|
|
display_gridsize = (1 << display_level) + 1;
|
|
|
|
|
skip = 1 << (args->ccg_key.level - display_level - 1);
|
|
|
|
|
skip = 1 << (args.ccg_key.level - display_level - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const int grid_index : args->grid_indices) {
|
|
|
|
|
bool smooth = !args->grid_flag_mats[grid_index].sharp;
|
|
|
|
|
BLI_bitmap *gh = args->grid_hidden[grid_index];
|
|
|
|
|
for (const int grid_index : args.grid_indices) {
|
|
|
|
|
bool smooth = !args.grid_flag_mats[grid_index].sharp;
|
|
|
|
|
BLI_bitmap *gh = args.grid_hidden[grid_index];
|
|
|
|
|
|
|
|
|
|
for (int y = 0; y < gridsize - 1; y += skip) {
|
|
|
|
|
for (int x = 0; x < gridsize - 1; x += skip) {
|
|
|
|
|
@@ -1106,10 +1106,10 @@ struct PBVHBatches {
|
|
|
|
|
|
|
|
|
|
GPUIndexBufBuilder elb, elb_lines;
|
|
|
|
|
|
|
|
|
|
CCGKey *key = &args->ccg_key;
|
|
|
|
|
const CCGKey *key = &args.ccg_key;
|
|
|
|
|
|
|
|
|
|
uint visible_quad_len = BKE_pbvh_count_grid_quads((BLI_bitmap **)args->grid_hidden,
|
|
|
|
|
args->grid_indices.data(),
|
|
|
|
|
uint visible_quad_len = BKE_pbvh_count_grid_quads((BLI_bitmap **)args.grid_hidden,
|
|
|
|
|
args.grid_indices.data(),
|
|
|
|
|
totgrid,
|
|
|
|
|
key->grid_size,
|
|
|
|
|
display_gridsize);
|
|
|
|
|
@@ -1127,7 +1127,7 @@ struct PBVHBatches {
|
|
|
|
|
uint v0, v1, v2, v3;
|
|
|
|
|
bool grid_visible = false;
|
|
|
|
|
|
|
|
|
|
BLI_bitmap *gh = args->grid_hidden[args->grid_indices[i]];
|
|
|
|
|
BLI_bitmap *gh = args.grid_hidden[args.grid_indices[i]];
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < gridsize - skip; j += skip) {
|
|
|
|
|
for (int k = 0; k < gridsize - skip; k += skip) {
|
|
|
|
|
@@ -1165,7 +1165,7 @@ struct PBVHBatches {
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < totgrid; i++, offset += grid_vert_len) {
|
|
|
|
|
bool grid_visible = false;
|
|
|
|
|
BLI_bitmap *gh = args->grid_hidden[args->grid_indices[i]];
|
|
|
|
|
BLI_bitmap *gh = args.grid_hidden[args.grid_indices[i]];
|
|
|
|
|
|
|
|
|
|
uint v0, v1, v2, v3;
|
|
|
|
|
for (int j = 0; j < gridsize - skip; j += skip) {
|
|
|
|
|
@@ -1226,9 +1226,9 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void create_index(PBVH_GPU_Args *args)
|
|
|
|
|
void create_index(const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
switch (args->pbvh_type) {
|
|
|
|
|
switch (args.pbvh_type) {
|
|
|
|
|
case PBVH_FACES:
|
|
|
|
|
create_index_faces(args);
|
|
|
|
|
break;
|
|
|
|
|
@@ -1238,7 +1238,7 @@ struct PBVHBatches {
|
|
|
|
|
case PBVH_GRIDS:
|
|
|
|
|
create_index_grids(args, false);
|
|
|
|
|
|
|
|
|
|
if (args->ccg_key.level > coarse_level) {
|
|
|
|
|
if (args.ccg_key.level > coarse_level) {
|
|
|
|
|
create_index_grids(args, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1260,14 +1260,17 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void check_index_buffers(PBVH_GPU_Args *args)
|
|
|
|
|
void check_index_buffers(const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
if (!lines_index) {
|
|
|
|
|
create_index(args);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void create_batch(PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args, bool do_coarse_grids)
|
|
|
|
|
void create_batch(PBVHAttrReq *attrs,
|
|
|
|
|
int attrs_num,
|
|
|
|
|
const PBVH_GPU_Args &args,
|
|
|
|
|
bool do_coarse_grids)
|
|
|
|
|
{
|
|
|
|
|
check_index_buffers(args);
|
|
|
|
|
|
|
|
|
|
@@ -1313,7 +1316,7 @@ struct PBVHBatches {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void DRW_pbvh_node_update(PBVHBatches *batches, PBVH_GPU_Args *args)
|
|
|
|
|
void DRW_pbvh_node_update(PBVHBatches *batches, const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
batches->update(args);
|
|
|
|
|
}
|
|
|
|
|
@@ -1323,7 +1326,7 @@ void DRW_pbvh_node_gpu_flush(PBVHBatches *batches)
|
|
|
|
|
batches->gpu_flush();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PBVHBatches *DRW_pbvh_node_create(PBVH_GPU_Args *args)
|
|
|
|
|
PBVHBatches *DRW_pbvh_node_create(const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
PBVHBatches *batches = new PBVHBatches(args);
|
|
|
|
|
return batches;
|
|
|
|
|
@@ -1337,11 +1340,11 @@ void DRW_pbvh_node_free(PBVHBatches *batches)
|
|
|
|
|
GPUBatch *DRW_pbvh_tris_get(PBVHBatches *batches,
|
|
|
|
|
PBVHAttrReq *attrs,
|
|
|
|
|
int attrs_num,
|
|
|
|
|
PBVH_GPU_Args *args,
|
|
|
|
|
const PBVH_GPU_Args &args,
|
|
|
|
|
int *r_prim_count,
|
|
|
|
|
bool do_coarse_grids)
|
|
|
|
|
{
|
|
|
|
|
do_coarse_grids &= args->pbvh_type == PBVH_GRIDS;
|
|
|
|
|
do_coarse_grids &= args.pbvh_type == PBVH_GRIDS;
|
|
|
|
|
|
|
|
|
|
PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args, do_coarse_grids);
|
|
|
|
|
|
|
|
|
|
@@ -1353,11 +1356,11 @@ GPUBatch *DRW_pbvh_tris_get(PBVHBatches *batches,
|
|
|
|
|
GPUBatch *DRW_pbvh_lines_get(PBVHBatches *batches,
|
|
|
|
|
PBVHAttrReq *attrs,
|
|
|
|
|
int attrs_num,
|
|
|
|
|
PBVH_GPU_Args *args,
|
|
|
|
|
const PBVH_GPU_Args &args,
|
|
|
|
|
int *r_prim_count,
|
|
|
|
|
bool do_coarse_grids)
|
|
|
|
|
{
|
|
|
|
|
do_coarse_grids &= args->pbvh_type == PBVH_GRIDS;
|
|
|
|
|
do_coarse_grids &= args.pbvh_type == PBVH_GRIDS;
|
|
|
|
|
|
|
|
|
|
PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args, do_coarse_grids);
|
|
|
|
|
|
|
|
|
|
@@ -1366,7 +1369,7 @@ GPUBatch *DRW_pbvh_lines_get(PBVHBatches *batches,
|
|
|
|
|
return batch.lines;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DRW_pbvh_update_pre(PBVHBatches *batches, PBVH_GPU_Args *args)
|
|
|
|
|
void DRW_pbvh_update_pre(PBVHBatches *batches, const PBVH_GPU_Args &args)
|
|
|
|
|
{
|
|
|
|
|
batches->update_pre(args);
|
|
|
|
|
}
|
|
|
|
|
|