Merge branch 'blender-v2.90-release'

This commit is contained in:
Pablo Dobarro 2020-08-04 23:34:55 +02:00
commit deb76548c1
4 changed files with 117 additions and 3 deletions

View File

@ -486,6 +486,10 @@ struct PBVH *BKE_sculpt_object_pbvh_ensure(struct Depsgraph *depsgraph, struct O
void BKE_sculpt_bvh_update_from_ccg(struct PBVH *pbvh, struct SubdivCCG *subdiv_ccg);
/* This ensure that all elements in the mesh (both vertices and grids) have their visibility
* updated according to the face sets. */
void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg);
bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct View3D *v3d);
enum {

View File

@ -338,6 +338,8 @@ SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const Subdi
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg);
const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG *subdiv_ccg);
void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index);
#ifdef __cplusplus
}
#endif

View File

@ -1824,6 +1824,64 @@ static bool check_sculpt_object_deformed(Object *object, const bool for_construc
return deformed;
}
static void sculpt_sync_face_sets_visibility_to_base_mesh(Mesh *mesh)
{
int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
if (!face_sets) {
return;
}
for (int i = 0; i < mesh->totvert; i++) {
mesh->mvert[i].flag |= ME_HIDE;
}
for (int i = 0; i < mesh->totpoly; i++) {
if (face_sets[i] >= 0) {
for (int l = 0; l < mesh->mpoly[i].totloop; l++) {
MLoop *loop = &mesh->mloop[mesh->mpoly[i].loopstart + l];
mesh->mvert[loop->v].flag &= ~ME_HIDE;
}
}
}
}
static void sculpt_sync_face_sets_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
{
int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
if (!face_sets) {
return;
}
if (!subdiv_ccg) {
return;
}
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
for (int i = 0; i < mesh->totloop; i++) {
const int face_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, i);
const bool is_hidden = (face_sets[face_index] < 0);
/* Avoid creating and modifying the grid_hidden bitmap if the base mesh face is visible and
* there is not bitmap for the grid. This is because missing grid_hidden implies grid is fully
* visible. */
if (is_hidden) {
BKE_subdiv_ccg_grid_hidden_ensure(subdiv_ccg, i);
}
BLI_bitmap *gh = subdiv_ccg->grid_hidden[i];
if (gh) {
BLI_bitmap_set_all(gh, is_hidden, key.grid_area);
}
}
}
void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg)
{
sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
sculpt_sync_face_sets_visibility_to_grids(mesh, subdiv_ccg);
}
static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
{
PBVH *pbvh = BKE_pbvh_new();
@ -1849,6 +1907,8 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
BKE_sculpt_sync_face_set_visibility(me, NULL);
BKE_pbvh_build_mesh(pbvh,
me,
me->mpoly,
@ -1881,6 +1941,10 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
PBVH *pbvh = BKE_pbvh_new();
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
Mesh *base_mesh = BKE_mesh_from_object(ob);
BKE_sculpt_sync_face_set_visibility(base_mesh, subdiv_ccg);
BKE_pbvh_build_grids(pbvh,
subdiv_ccg->grids,
subdiv_ccg->num_grids,

View File

@ -1618,6 +1618,18 @@ static int prev_adjacent_edge_point_index(const SubdivCCG *subdiv_ccg, const int
return point_index - 1;
}
/* When the point index corresponds to a grid corner, returs the point index which corresponds to
* the corner of the adjacent grid, as the adjacent edge has two separate points for each grid
* corner at the middle of the edge. */
static int adjacent_grid_corner_point_index_on_edge(const SubdivCCG *subdiv_ccg,
const int point_index)
{
if (point_index == subdiv_ccg->grid_size) {
return point_index - 1;
}
return point_index + 1;
}
/* Common implementation of neighbor calculation when input coordinate is at the edge between two
* coarse faces, but is not at the coarse vertex. */
static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
@ -1626,6 +1638,7 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
SubdivCCGNeighbors *r_neighbors)
{
const bool is_corner = is_corner_grid_coord(subdiv_ccg, coord);
const int adjacent_edge_index = adjacent_edge_index_from_coord(subdiv_ccg, coord);
BLI_assert(adjacent_edge_index >= 0);
BLI_assert(adjacent_edge_index < subdiv_ccg->num_adjacent_edges);
@ -1633,15 +1646,27 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
/* 2 neighbor points along the edge, plus one inner point per every adjacent grid. */
const int num_adjacent_faces = adjacent_edge->num_adjacent_faces;
subdiv_ccg_neighbors_init(
r_neighbors, num_adjacent_faces + 2, (include_duplicates) ? num_adjacent_faces - 1 : 0);
int num_duplicates = 0;
if (include_duplicates) {
num_duplicates += num_adjacent_faces - 1;
if (is_corner) {
/* When the coord is a grid corner, add an extra duplicate per adajacent grid in all adjacent
* faces to the edge. */
num_duplicates += num_adjacent_faces;
}
}
subdiv_ccg_neighbors_init(r_neighbors, num_adjacent_faces + 2, num_duplicates);
const int point_index = adjacent_edge_point_index_from_coord(
subdiv_ccg, coord, adjacent_edge_index);
const int point_index_duplicate = adjacent_grid_corner_point_index_on_edge(subdiv_ccg,
point_index);
const int next_point_index = next_adjacent_edge_point_index(subdiv_ccg, point_index);
const int prev_point_index = prev_adjacent_edge_point_index(subdiv_ccg, point_index);
for (int i = 0, duplicate_i = num_adjacent_faces; i < num_adjacent_faces; ++i) {
int duplicate_i = num_adjacent_faces;
for (int i = 0; i < num_adjacent_faces; ++i) {
SubdivCCGCoord *boundary_coords = adjacent_edge->boundary_coords[i];
/* One step into the grid from the edge for each adjacent face. */
SubdivCCGCoord grid_coord = boundary_coords[point_index];
@ -1657,7 +1682,15 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
r_neighbors->coords[duplicate_i + 2] = grid_coord;
duplicate_i++;
}
/* When it is a corner, add the duplicate of the adjacent grid in the same face. */
if (include_duplicates && is_corner) {
SubdivCCGCoord duplicate_corner_grid_coord = boundary_coords[point_index_duplicate];
r_neighbors->coords[duplicate_i + 2] = duplicate_corner_grid_coord;
duplicate_i++;
}
}
BLI_assert(duplicate_i - num_adjacent_faces == num_duplicates);
}
/* The corner is at the middle of edge between faces. */
@ -1889,4 +1922,15 @@ SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const Subdi
return SUBDIV_CCG_ADJACENT_NONE;
}
void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index)
{
if (subdiv_ccg->grid_hidden[grid_index] != NULL) {
return;
}
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
subdiv_ccg->grid_hidden[grid_index] = BLI_BITMAP_NEW(key.grid_area, __func__);
}
/** \} */