Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/sculpt.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
| Show First 20 Lines • Show All 383 Lines • ▼ Show 20 Lines | switch (BKE_pbvh_type(ss->pbvh)) { | ||||
| case PBVH_BMESH: | case PBVH_BMESH: | ||||
| return true; | return true; | ||||
| case PBVH_GRIDS: | case PBVH_GRIDS: | ||||
| return true; | return true; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool SCULPT_vertex_all_face_sets_visible_get(SculptSession *ss, int index) | bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, int index) | ||||
| { | { | ||||
| switch (BKE_pbvh_type(ss->pbvh)) { | switch (BKE_pbvh_type(ss->pbvh)) { | ||||
| case PBVH_FACES: { | case PBVH_FACES: { | ||||
| MeshElemMap *vert_map = &ss->pmap[index]; | MeshElemMap *vert_map = &ss->pmap[index]; | ||||
| for (int j = 0; j < ss->pmap[index].count; j++) { | for (int j = 0; j < ss->pmap[index].count; j++) { | ||||
| if (ss->face_sets[vert_map->indices[j]] < 0) { | if (ss->face_sets[vert_map->indices[j]] < 0) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 382 Lines • ▼ Show 20 Lines | case PBVH_BMESH: | ||||
| sculpt_vertex_neighbors_get_bmesh(ss, index, iter); | sculpt_vertex_neighbors_get_bmesh(ss, index, iter); | ||||
| return; | return; | ||||
| case PBVH_GRIDS: | case PBVH_GRIDS: | ||||
| sculpt_vertex_neighbors_get_grids(ss, index, include_duplicates, iter); | sculpt_vertex_neighbors_get_grids(ss, index, include_duplicates, iter); | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| static bool sculpt_check_boundary_vertex_in_base_mesh(SculptSession *ss, const int index) | static bool sculpt_check_boundary_vertex_in_base_mesh(const SculptSession *ss, const int index) | ||||
| { | { | ||||
| const MeshElemMap *vert_map = &ss->pmap[index]; | BLI_assert(ss->vertex_info.boundary); | ||||
| if (vert_map->count <= 1) { | return BLI_BITMAP_TEST(ss->vertex_info.boundary, index); | ||||
| return true; | |||||
| } | |||||
| for (int i = 0; i < vert_map->count; i++) { | |||||
| const MPoly *p = &ss->mpoly[vert_map->indices[i]]; | |||||
| unsigned f_adj_v[2]; | |||||
| if (poly_get_adj_loops_from_vert(p, ss->mloop, index, f_adj_v) != -1) { | |||||
| int j; | |||||
| for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) { | |||||
| if (!(vert_map->count != 2 || ss->pmap[f_adj_v[j]].count <= 2)) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | } | ||||
| bool SCULPT_vertex_is_boundary(SculptSession *ss, const int index) | bool SCULPT_vertex_is_boundary(const SculptSession *ss, const int index) | ||||
| { | { | ||||
| switch (BKE_pbvh_type(ss->pbvh)) { | switch (BKE_pbvh_type(ss->pbvh)) { | ||||
| case PBVH_FACES: { | case PBVH_FACES: { | ||||
| if (!SCULPT_vertex_all_face_sets_visible_get(ss, index)) { | if (!SCULPT_vertex_all_face_sets_visible_get(ss, index)) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| return sculpt_check_boundary_vertex_in_base_mesh(ss, index); | return sculpt_check_boundary_vertex_in_base_mesh(ss, index); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 7,662 Lines • ▼ Show 20 Lines | if (ss->vertex_info.connected_component[i] == SCULPT_TOPOLOGY_ID_NONE) { | ||||
| data.next_id = next_id; | data.next_id = next_id; | ||||
| SCULPT_floodfill_execute(ss, &flood, SCULPT_connected_components_floodfill_cb, &data); | SCULPT_floodfill_execute(ss, &flood, SCULPT_connected_components_floodfill_cb, &data); | ||||
| SCULPT_floodfill_free(&flood); | SCULPT_floodfill_free(&flood); | ||||
| next_id++; | next_id++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void SCULPT_boundary_info_ensure(Object *object) | |||||
| { | |||||
| SculptSession *ss = object->sculpt; | |||||
| if (ss->vertex_info.boundary) { | |||||
| return; | |||||
| } | |||||
| Mesh *base_mesh = BKE_mesh_from_object(object); | |||||
| ss->vertex_info.boundary = BLI_BITMAP_NEW(base_mesh->totvert, "Boundary info"); | |||||
| int *adjacent_faces_edge_count = MEM_calloc_arrayN( | |||||
| base_mesh->totedge, sizeof(int), "Adjacent face edge count"); | |||||
| for (int p = 0; p < base_mesh->totpoly; p++) { | |||||
| MPoly *poly = &base_mesh->mpoly[p]; | |||||
| for (int l = 0; l < poly->totloop; l++) { | |||||
| MLoop *loop = &base_mesh->mloop[l + poly->loopstart]; | |||||
| adjacent_faces_edge_count[loop->e]++; | |||||
| } | |||||
| } | |||||
| for (int e = 0; e < base_mesh->totedge; e++) { | |||||
| if (adjacent_faces_edge_count[e] < 2) { | |||||
| MEdge *edge = &base_mesh->medge[e]; | |||||
| BLI_BITMAP_SET(ss->vertex_info.boundary, edge->v1, true); | |||||
| BLI_BITMAP_SET(ss->vertex_info.boundary, edge->v2, true); | |||||
| } | |||||
| } | |||||
| MEM_freeN(adjacent_faces_edge_count); | |||||
| } | |||||
| void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, const float max_dist) | void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, const float max_dist) | ||||
| { | { | ||||
| SculptSession *ss = ob->sculpt; | SculptSession *ss = ob->sculpt; | ||||
| const int totvert = SCULPT_vertex_count_get(ss); | const int totvert = SCULPT_vertex_count_get(ss); | ||||
| /* Fake neighbors were already initialized with the same distance, so no need to be recalculated. | /* Fake neighbors were already initialized with the same distance, so no need to be recalculated. | ||||
| */ | */ | ||||
| if (ss->fake_neighbors.fake_neighbor_index && | if (ss->fake_neighbors.fake_neighbor_index && | ||||
| ▲ Show 20 Lines • Show All 377 Lines • Show Last 20 Lines | |||||