Blender  V2.93
sculpt_automasking.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2020 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "BLI_blenlib.h"
27 #include "BLI_hash.h"
28 #include "BLI_math.h"
29 #include "BLI_task.h"
30 
31 #include "DNA_brush_types.h"
32 #include "DNA_mesh_types.h"
33 #include "DNA_meshdata_types.h"
34 
35 #include "BKE_brush.h"
36 #include "BKE_context.h"
37 #include "BKE_mesh.h"
38 #include "BKE_mesh_mapping.h"
39 #include "BKE_object.h"
40 #include "BKE_paint.h"
41 #include "BKE_pbvh.h"
42 #include "BKE_scene.h"
43 
44 #include "DEG_depsgraph.h"
45 
46 #include "WM_api.h"
47 #include "WM_message.h"
48 #include "WM_toolsystem.h"
49 #include "WM_types.h"
50 
51 #include "ED_object.h"
52 #include "ED_screen.h"
53 #include "ED_sculpt.h"
54 #include "paint_intern.h"
55 #include "sculpt_intern.h"
56 
57 #include "RNA_access.h"
58 #include "RNA_define.h"
59 
60 #include "bmesh.h"
61 
62 #include <math.h>
63 #include <stdlib.h>
64 
66 {
67  if (ss->cache) {
68  return ss->cache->automasking;
69  }
70  if (ss->filter_cache) {
71  return ss->filter_cache->automasking;
72  }
73  return NULL;
74 }
75 
77  const Brush *br,
78  const eAutomasking_flag mode)
79 {
80  if (br) {
81  return br->automasking_flags & mode || sd->automasking_flags & mode;
82  }
83  return sd->automasking_flags & mode;
84 }
85 
86 bool SCULPT_is_automasking_enabled(const Sculpt *sd, const SculptSession *ss, const Brush *br)
87 {
88  if (br && SCULPT_stroke_is_dynamic_topology(ss, br)) {
89  return false;
90  }
92  return true;
93  }
95  return true;
96  }
98  return true;
99  }
101  return true;
102  }
103  return false;
104 }
105 
106 static int sculpt_automasking_mode_effective_bits(const Sculpt *sculpt, const Brush *brush)
107 {
108  if (brush) {
109  return sculpt->automasking_flags | brush->automasking_flags;
110  }
111  return sculpt->automasking_flags;
112 }
113 
114 static bool SCULPT_automasking_needs_factors_cache(const Sculpt *sd, const Brush *brush)
115 {
116 
117  const int automasking_flags = sculpt_automasking_mode_effective_bits(sd, brush);
118  if (automasking_flags & BRUSH_AUTOMASKING_TOPOLOGY) {
119  return true;
120  }
121  if (automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES) {
122  return brush && brush->automasking_boundary_edges_propagation_steps != 1;
123  }
124  if (automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS) {
125  return brush && brush->automasking_boundary_edges_propagation_steps != 1;
126  }
127  return false;
128 }
129 
131 {
132  if (!automasking) {
133  return 1.0f;
134  }
135  /* If the cache is initialized with valid info, use the cache. This is used when the
136  * automasking information can't be computed in real time per vertex and needs to be
137  * initialized for the whole mesh when the stroke starts. */
138  if (automasking->factor) {
139  return automasking->factor[vert];
140  }
141 
142  if (automasking->settings.flags & BRUSH_AUTOMASKING_FACE_SETS) {
143  if (!SCULPT_vertex_has_face_set(ss, vert, automasking->settings.initial_face_set)) {
144  return 0.0f;
145  }
146  }
147 
148  if (automasking->settings.flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES) {
149  if (SCULPT_vertex_is_boundary(ss, vert)) {
150  return 0.0f;
151  }
152  }
153 
155  if (!SCULPT_vertex_has_unique_face_set(ss, vert)) {
156  return 0.0f;
157  }
158  }
159 
160  return 1.0f;
161 }
162 
164 {
165  if (!automasking) {
166  return;
167  }
168 
169  MEM_SAFE_FREE(automasking->factor);
170  MEM_SAFE_FREE(automasking);
171 }
172 
174 {
175  /* 2D falloff is not constrained by radius. */
177  return false;
178  }
179 
181  return true;
182  }
183  return false;
184 }
185 
186 typedef struct AutomaskFloodFillData {
188  float radius;
190  float location[3];
191  char symm;
193 
195  SculptSession *ss, int from_v, int to_v, bool UNUSED(is_duplicate), void *userdata)
196 {
197  AutomaskFloodFillData *data = userdata;
198 
199  data->automask_factor[to_v] = 1.0f;
200  data->automask_factor[from_v] = 1.0f;
201  return (!data->use_radius ||
203  SCULPT_vertex_co_get(ss, to_v), data->location, data->radius, data->symm));
204 }
205 
206 static float *SCULPT_topology_automasking_init(Sculpt *sd, Object *ob, float *automask_factor)
207 {
208  SculptSession *ss = ob->sculpt;
209  Brush *brush = BKE_paint_brush(&sd->paint);
210 
211  if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) {
212  BLI_assert(!"Topology masking: pmap missing");
213  return NULL;
214  }
215 
216  const int totvert = SCULPT_vertex_count_get(ss);
217  for (int i = 0; i < totvert; i++) {
218  automask_factor[i] = 0.0f;
219  }
220 
221  /* Flood fill automask to connected vertices. Limited to vertices inside
222  * the brush radius if the tool requires it. */
223  SculptFloodFill flood;
224  SCULPT_floodfill_init(ss, &flood);
225  const float radius = ss->cache ? ss->cache->radius : FLT_MAX;
226  SCULPT_floodfill_add_active(sd, ob, ss, &flood, radius);
227 
228  AutomaskFloodFillData fdata = {
229  .automask_factor = automask_factor,
230  .radius = radius,
231  .use_radius = ss->cache && sculpt_automasking_is_constrained_by_radius(brush),
232  .symm = SCULPT_mesh_symmetry_xyz_get(ob),
233  };
235  SCULPT_floodfill_execute(ss, &flood, automask_floodfill_cb, &fdata);
236  SCULPT_floodfill_free(&flood);
237 
238  return automask_factor;
239 }
240 
241 static float *sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob, float *automask_factor)
242 {
243  SculptSession *ss = ob->sculpt;
244  Brush *brush = BKE_paint_brush(&sd->paint);
245 
246  if (!SCULPT_is_automasking_enabled(sd, ss, brush)) {
247  return NULL;
248  }
249 
250  if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) {
251  BLI_assert(!"Face Sets automasking: pmap missing");
252  return NULL;
253  }
254 
255  int tot_vert = SCULPT_vertex_count_get(ss);
256  int active_face_set = SCULPT_active_face_set_get(ss);
257  for (int i = 0; i < tot_vert; i++) {
258  if (!SCULPT_vertex_has_face_set(ss, i, active_face_set)) {
259  automask_factor[i] *= 0.0f;
260  }
261  }
262 
263  return automask_factor;
264 }
265 
266 #define EDGE_DISTANCE_INF -1
267 
270  int propagation_steps,
271  float *automask_factor)
272 {
273  SculptSession *ss = ob->sculpt;
274 
275  if (!ss->pmap) {
276  BLI_assert(!"Boundary Edges masking: pmap missing");
277  return NULL;
278  }
279 
280  const int totvert = SCULPT_vertex_count_get(ss);
281  int *edge_distance = MEM_callocN(sizeof(int) * totvert, "automask_factor");
282 
283  for (int i = 0; i < totvert; i++) {
284  edge_distance[i] = EDGE_DISTANCE_INF;
285  switch (mode) {
287  if (SCULPT_vertex_is_boundary(ss, i)) {
288  edge_distance[i] = 0;
289  }
290  break;
292  if (!SCULPT_vertex_has_unique_face_set(ss, i)) {
293  edge_distance[i] = 0;
294  }
295  break;
296  }
297  }
298 
299  for (int propagation_it = 0; propagation_it < propagation_steps; propagation_it++) {
300  for (int i = 0; i < totvert; i++) {
301  if (edge_distance[i] != EDGE_DISTANCE_INF) {
302  continue;
303  }
306  if (edge_distance[ni.index] == propagation_it) {
307  edge_distance[i] = propagation_it + 1;
308  }
309  }
311  }
312  }
313 
314  for (int i = 0; i < totvert; i++) {
315  if (edge_distance[i] == EDGE_DISTANCE_INF) {
316  continue;
317  }
318  const float p = 1.0f - ((float)edge_distance[i] / (float)propagation_steps);
319  const float edge_boundary_automask = pow2f(p);
320  automask_factor[i] *= (1.0f - edge_boundary_automask);
321  }
322 
323  MEM_SAFE_FREE(edge_distance);
324  return automask_factor;
325 }
326 
328  SculptSession *ss,
329  Sculpt *sd,
330  Brush *brush)
331 {
332  automasking->settings.flags = sculpt_automasking_mode_effective_bits(sd, brush);
334 }
335 
337 {
338  SculptSession *ss = ob->sculpt;
339  const int totvert = SCULPT_vertex_count_get(ss);
340 
341  if (!SCULPT_is_automasking_enabled(sd, ss, brush)) {
342  return NULL;
343  }
344 
345  AutomaskingCache *automasking = MEM_callocN(sizeof(AutomaskingCache), "automasking cache");
346  SCULPT_automasking_cache_settings_update(automasking, ss, sd, brush);
348 
349  if (!SCULPT_automasking_needs_factors_cache(sd, brush)) {
350  return automasking;
351  }
352 
353  automasking->factor = MEM_malloc_arrayN(totvert, sizeof(float), "automask_factor");
354  for (int i = 0; i < totvert; i++) {
355  automasking->factor[i] = 1.0f;
356  }
357 
358  const int boundary_propagation_steps = brush ?
360  1;
361 
364  SCULPT_topology_automasking_init(sd, ob, automasking->factor);
365  }
368  sculpt_face_sets_automasking_init(sd, ob, automasking->factor);
369  }
370 
374  ob, AUTOMASK_INIT_BOUNDARY_EDGES, boundary_propagation_steps, automasking->factor);
375  }
379  ob, AUTOMASK_INIT_BOUNDARY_FACE_SETS, boundary_propagation_steps, automasking->factor);
380  }
381 
382  return automasking;
383 }
typedef float(TangentPoint)[2]
General operations, lookup, etc. for blender objects.
struct Brush * BKE_paint_brush(struct Paint *paint)
Definition: paint.c:604
A BVH for high poly meshes.
PBVHType BKE_pbvh_type(const PBVH *pbvh)
Definition: pbvh.c:1661
@ PBVH_FACES
Definition: BKE_pbvh.h:210
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE float pow2f(float x)
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define UNUSED(x)
#define ELEM(...)
eAutomasking_flag
@ BRUSH_AUTOMASKING_BOUNDARY_EDGES
@ BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS
@ BRUSH_AUTOMASKING_FACE_SETS
@ BRUSH_AUTOMASKING_TOPOLOGY
@ SCULPT_TOOL_THUMB
@ SCULPT_TOOL_GRAB
@ SCULPT_TOOL_ROTATE
@ PAINT_FALLOFF_SHAPE_TUBE
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
const float * SCULPT_vertex_co_get(SculptSession *ss, int index)
Definition: sculpt.c:134
int SCULPT_vertex_count_get(SculptSession *ss)
Definition: sculpt.c:120
void SCULPT_boundary_info_ensure(Object *object)
Definition: sculpt.c:9039
void SCULPT_floodfill_init(SculptSession *ss, SculptFloodFill *flood)
Definition: sculpt.c:1085
bool SCULPT_vertex_has_face_set(SculptSession *ss, int index, int face_set)
Definition: sculpt.c:539
bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, int index)
Definition: sculpt.c:669
const float * SCULPT_active_vertex_co_get(SculptSession *ss)
Definition: sculpt.c:285
void SCULPT_vertex_random_access_ensure(SculptSession *ss)
Definition: sculpt.c:112
bool SCULPT_stroke_is_dynamic_topology(const SculptSession *ss, const Brush *brush)
Definition: sculpt.c:1448
bool SCULPT_vertex_is_boundary(const SculptSession *ss, const int index)
Definition: sculpt.c:868
void SCULPT_floodfill_free(SculptFloodFill *flood)
Definition: sculpt.c:1188
char SCULPT_mesh_symmetry_xyz_get(Object *object)
Definition: sculpt.c:323
bool SCULPT_is_vertex_inside_brush_radius_symm(const float vertex[3], const float br_co[3], float radius, char symm)
Definition: sculpt.c:1048
void SCULPT_floodfill_add_active(Sculpt *sd, Object *ob, SculptSession *ss, SculptFloodFill *flood, float radius)
Definition: sculpt.c:1131
int SCULPT_active_face_set_get(SculptSession *ss)
Definition: sculpt.c:331
void SCULPT_floodfill_execute(SculptSession *ss, SculptFloodFill *flood, bool(*func)(SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata), void *userdata)
Definition: sculpt.c:1157
struct AutomaskFloodFillData AutomaskFloodFillData
static bool sculpt_automasking_is_constrained_by_radius(Brush *br)
float * SCULPT_boundary_automasking_init(Object *ob, eBoundaryAutomaskMode mode, int propagation_steps, float *automask_factor)
static float * sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob, float *automask_factor)
static int sculpt_automasking_mode_effective_bits(const Sculpt *sculpt, const Brush *brush)
static float * SCULPT_topology_automasking_init(Sculpt *sd, Object *ob, float *automask_factor)
void SCULPT_automasking_cache_free(AutomaskingCache *automasking)
static void SCULPT_automasking_cache_settings_update(AutomaskingCache *automasking, SculptSession *ss, Sculpt *sd, Brush *brush)
float SCULPT_automasking_factor_get(AutomaskingCache *automasking, SculptSession *ss, int vert)
bool SCULPT_is_automasking_mode_enabled(const Sculpt *sd, const Brush *br, const eAutomasking_flag mode)
#define EDGE_DISTANCE_INF
AutomaskingCache * SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object *ob)
static bool automask_floodfill_cb(SculptSession *ss, int from_v, int to_v, bool UNUSED(is_duplicate), void *userdata)
bool SCULPT_is_automasking_enabled(const Sculpt *sd, const SculptSession *ss, const Brush *br)
static bool SCULPT_automasking_needs_factors_cache(const Sculpt *sd, const Brush *brush)
AutomaskingCache * SCULPT_automasking_active_cache_get(SculptSession *ss)
#define SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN(ss, v_index, neighbor_iterator)
#define SCULPT_VERTEX_NEIGHBORS_ITER_END(neighbor_iterator)
eBoundaryAutomaskMode
@ AUTOMASK_INIT_BOUNDARY_EDGES
@ AUTOMASK_INIT_BOUNDARY_FACE_SETS
AutomaskingSettings settings
int automasking_flags
int automasking_boundary_edges_propagation_steps
char falloff_shape
char sculpt_tool
AutomaskingCache * automasking
struct SculptSession * sculpt
struct MeshElemMap * pmap
Definition: BKE_paint.h:474
struct StrokeCache * cache
Definition: BKE_paint.h:518
struct FilterCache * filter_cache
Definition: BKE_paint.h:519
struct PBVH * pbvh
Definition: BKE_paint.h:504
Paint paint
int automasking_flags
AutomaskingCache * automasking