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 8,205 Lines • ▼ Show 20 Lines | |||||
| static void SCULPT_fake_neighbor_add(SculptSession *ss, int v_index_a, int v_index_b) | static void SCULPT_fake_neighbor_add(SculptSession *ss, int v_index_a, int v_index_b) | ||||
| { | { | ||||
| if (ss->fake_neighbors.fake_neighbor_index[v_index_a] == FAKE_NEIGHBOR_NONE) { | if (ss->fake_neighbors.fake_neighbor_index[v_index_a] == FAKE_NEIGHBOR_NONE) { | ||||
| ss->fake_neighbors.fake_neighbor_index[v_index_a] = v_index_b; | ss->fake_neighbors.fake_neighbor_index[v_index_a] = v_index_b; | ||||
| ss->fake_neighbors.fake_neighbor_index[v_index_b] = v_index_a; | ss->fake_neighbors.fake_neighbor_index[v_index_b] = v_index_a; | ||||
| } | } | ||||
| } | } | ||||
| static void SCULPT_fake_neighbor_remove(SculptSession *ss, int v_index) | |||||
| { | |||||
| if (ss->fake_neighbors.fake_neighbor_index[v_index] != FAKE_NEIGHBOR_NONE) { | |||||
| const int neighbor = ss->fake_neighbors.fake_neighbor_index[v_index]; | |||||
| ss->fake_neighbors.fake_neighbor_index[v_index] = FAKE_NEIGHBOR_NONE; | |||||
| ss->fake_neighbors.fake_neighbor_index[neighbor] = FAKE_NEIGHBOR_NONE; | |||||
| } | |||||
| } | |||||
| static void sculpt_pose_fake_neighbors_free(SculptSession *ss) | static void sculpt_pose_fake_neighbors_free(SculptSession *ss) | ||||
| { | { | ||||
| MEM_SAFE_FREE(ss->fake_neighbors.fake_neighbor_index); | MEM_SAFE_FREE(ss->fake_neighbors.fake_neighbor_index); | ||||
| } | } | ||||
| typedef struct NearestVertexFakeNeighborTLSData { | typedef struct NearestVertexFakeNeighborTLSData { | ||||
| int nearest_vertex_index; | int nearest_vertex_index; | ||||
| float nearest_vertex_distance_squared; | float nearest_vertex_distance_squared; | ||||
| ▲ Show 20 Lines • Show All 140 Lines • ▼ Show 20 Lines | void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, const float max_dist) | ||||
| if (ss->fake_neighbors.fake_neighbor_index && | if (ss->fake_neighbors.fake_neighbor_index && | ||||
| ss->fake_neighbors.current_max_distance == max_dist) { | ss->fake_neighbors.current_max_distance == max_dist) { | ||||
| return; | return; | ||||
| } | } | ||||
| SCULPT_connected_components_ensure(ob); | SCULPT_connected_components_ensure(ob); | ||||
| SCULPT_fake_neighbor_init(ss, max_dist); | SCULPT_fake_neighbor_init(ss, max_dist); | ||||
| float *fake_neighbor_distance = MEM_malloc_arrayN(totvert, sizeof(float), "neighbor distance"); | |||||
| for (int i = 0; i < totvert; i++) { | |||||
| fake_neighbor_distance[i] = FLT_MAX; | |||||
| } | |||||
| for (int i = 0; i < totvert; i++) { | for (int i = 0; i < totvert; i++) { | ||||
| const int from_v = i; | const int from_v = i; | ||||
| /* This vertex does not have a fake neighbor yet, seach one for it. */ | float max_dist_search = max_dist; | ||||
| if (ss->fake_neighbors.fake_neighbor_index[from_v] == FAKE_NEIGHBOR_NONE) { | if (ss->fake_neighbors.fake_neighbor_index[from_v] != FAKE_NEIGHBOR_NONE) { | ||||
| const int to_v = SCULPT_fake_neighbor_search(sd, ob, from_v, max_dist); | max_dist_search = sqrtf(fake_neighbor_distance[from_v]); | ||||
| } | |||||
| const int to_v = SCULPT_fake_neighbor_search(sd, ob, from_v, max_dist_search); | |||||
| if (to_v != -1) { | if (to_v != -1) { | ||||
| /* Add the fake neighbor if available. */ | const float *from_v_co = SCULPT_vertex_co_get(ss, from_v); | ||||
| const float *to_v_co = SCULPT_vertex_co_get(ss, to_v); | |||||
| const float dist = len_squared_v3v3(from_v_co, to_v_co); | |||||
| if (dist < fake_neighbor_distance[from_v] && dist < fake_neighbor_distance[to_v]) { | |||||
| /* Remove fake neigbors that could have been added in a previous iteration with a greater | |||||
| * distance before adding the new one. */ | |||||
| if (ss->fake_neighbors.fake_neighbor_index[from_v] != FAKE_NEIGHBOR_NONE) { | |||||
| fake_neighbor_distance[from_v] = FLT_MAX; | |||||
| fake_neighbor_distance[ss->fake_neighbors.fake_neighbor_index[from_v]] = FLT_MAX; | |||||
| SCULPT_fake_neighbor_remove(ss, from_v); | |||||
| } | |||||
| SCULPT_fake_neighbor_add(ss, from_v, to_v); | SCULPT_fake_neighbor_add(ss, from_v, to_v); | ||||
| fake_neighbor_distance[from_v] = dist; | |||||
| fake_neighbor_distance[to_v] = dist; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| MEM_freeN(fake_neighbor_distance); | |||||
| } | } | ||||
| void SCULPT_fake_neighbors_enable(Object *ob) | void SCULPT_fake_neighbors_enable(Object *ob) | ||||
| { | { | ||||
| SculptSession *ss = ob->sculpt; | SculptSession *ss = ob->sculpt; | ||||
| BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL); | BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL); | ||||
| ss->fake_neighbors.use_fake_neighbors = true; | ss->fake_neighbors.use_fake_neighbors = true; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 41 Lines • Show Last 20 Lines | |||||