Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Dobarro <pablodp606@gmail.com>2020-08-05 00:34:55 +0300
committerPablo Dobarro <pablodp606@gmail.com>2020-08-05 00:34:55 +0300
commitdeb76548c108b3247a41ee273bad18de0f7d2ae1 (patch)
tree9f3ec253a31d5120bf4ecc3748656b13eed2e474
parentbf65820782a7b67c294587fa6f670bd9c7678b51 (diff)
parent3ebe97c06b67d1611dfeaa3919512155416b0378 (diff)
Merge branch 'blender-v2.90-release'
-rw-r--r--source/blender/blenkernel/BKE_paint.h4
-rw-r--r--source/blender/blenkernel/BKE_subdiv_ccg.h2
-rw-r--r--source/blender/blenkernel/intern/paint.c64
-rw-r--r--source/blender/blenkernel/intern/subdiv_ccg.c50
4 files changed, 117 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 382919147f8..e2b8a4d72e6 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -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 {
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h
index 5808f223f32..02b83a043b4 100644
--- a/source/blender/blenkernel/BKE_subdiv_ccg.h
+++ b/source/blender/blenkernel/BKE_subdiv_ccg.h
@@ -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
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index d4edcf88389..15d5b0cbf53 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -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,
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index 22649a2af07..bc1b79f62c5 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -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__);
+}
+
/** \} */