Merge branch 'blender-v2.90-release'
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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__);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
Reference in New Issue
Block a user