Blender  V3.3
sculpt_ops.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2006 by Nicholas Bishop. All rights reserved. */
3 
9 #include "MEM_guardedalloc.h"
10 
11 #include "BLI_array.h"
12 #include "BLI_blenlib.h"
13 #include "BLI_dial_2d.h"
14 #include "BLI_ghash.h"
15 #include "BLI_gsqueue.h"
16 #include "BLI_hash.h"
17 #include "BLI_link_utils.h"
18 #include "BLI_linklist.h"
19 #include "BLI_linklist_stack.h"
20 #include "BLI_listbase.h"
21 #include "BLI_math.h"
22 #include "BLI_math_color_blend.h"
23 #include "BLI_memarena.h"
24 #include "BLI_rand.h"
25 #include "BLI_task.h"
26 #include "BLI_utildefines.h"
27 #include "atomic_ops.h"
28 
29 #include "BLT_translation.h"
30 
31 #include "PIL_time.h"
32 
33 #include "DNA_brush_types.h"
34 #include "DNA_customdata_types.h"
35 #include "DNA_listBase.h"
36 #include "DNA_mesh_types.h"
37 #include "DNA_meshdata_types.h"
38 #include "DNA_node_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_scene_types.h"
41 
42 #include "BKE_attribute.h"
43 #include "BKE_brush.h"
44 #include "BKE_ccg.h"
45 #include "BKE_colortools.h"
46 #include "BKE_context.h"
47 #include "BKE_image.h"
48 #include "BKE_kelvinlet.h"
49 #include "BKE_key.h"
50 #include "BKE_lib_id.h"
51 #include "BKE_main.h"
52 #include "BKE_mesh.h"
53 #include "BKE_mesh_fair.h"
54 #include "BKE_mesh_mapping.h"
55 #include "BKE_mesh_mirror.h"
56 #include "BKE_modifier.h"
57 #include "BKE_multires.h"
58 #include "BKE_node.h"
59 #include "BKE_object.h"
60 #include "BKE_paint.h"
61 #include "BKE_particle.h"
62 #include "BKE_pbvh.h"
63 #include "BKE_pointcache.h"
64 #include "BKE_report.h"
65 #include "BKE_scene.h"
66 #include "BKE_screen.h"
67 #include "BKE_subdiv_ccg.h"
68 #include "BKE_subsurf.h"
69 
70 #include "DEG_depsgraph.h"
71 #include "DEG_depsgraph_query.h"
72 
73 #include "IMB_colormanagement.h"
74 
75 #include "GPU_batch.h"
76 #include "GPU_batch_presets.h"
77 #include "GPU_immediate.h"
78 #include "GPU_immediate_util.h"
79 #include "GPU_matrix.h"
80 #include "GPU_state.h"
81 
82 #include "WM_api.h"
83 #include "WM_message.h"
84 #include "WM_toolsystem.h"
85 #include "WM_types.h"
86 
87 #include "ED_image.h"
88 #include "ED_object.h"
89 #include "ED_screen.h"
90 #include "ED_sculpt.h"
91 #include "ED_space_api.h"
93 #include "ED_view3d.h"
94 
95 #include "paint_intern.h"
96 #include "sculpt_intern.h"
97 
98 #include "RNA_access.h"
99 #include "RNA_define.h"
100 
101 #include "UI_interface.h"
102 #include "UI_resources.h"
103 
104 #include "bmesh.h"
105 #include "bmesh_tools.h"
106 
107 #include <math.h>
108 #include <stdlib.h>
109 #include <string.h>
110 
111 /* Reset the copy of the mesh that is being sculpted on (currently just for the layer brush). */
112 
114 {
117  SculptSession *ss = ob->sculpt;
118 
119  if (!ss) {
120  return OPERATOR_FINISHED;
121  }
123  BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
124 
126 
127  const int totvert = SCULPT_vertex_count_get(ss);
128  ss->persistent_base = MEM_mallocN(sizeof(SculptPersistentBase) * totvert,
129  "layer persistent base");
130 
131  for (int i = 0; i < totvert; i++) {
134  ss->persistent_base[i].disp = 0.0f;
135  }
136 
137  return OPERATOR_FINISHED;
138 }
139 
141 {
142  /* Identifiers. */
143  ot->name = "Set Persistent Base";
144  ot->idname = "SCULPT_OT_set_persistent_base";
145  ot->description = "Reset the copy of the mesh that is being sculpted on";
146 
147  /* API callbacks. */
150 
152 }
153 
154 /************************* SCULPT_OT_optimize *************************/
155 
157 {
159 
160  SCULPT_pbvh_clear(ob);
162 
163  return OPERATOR_FINISHED;
164 }
165 
166 /* The BVH gets less optimal more quickly with dynamic topology than
167  * regular sculpting. There is no doubt more clever stuff we can do to
168  * optimize it on the fly, but for now this gives the user a nicer way
169  * to recalculate it than toggling modes. */
171 {
172  /* Identifiers. */
173  ot->name = "Rebuild BVH";
174  ot->idname = "SCULPT_OT_optimize";
175  ot->description = "Recalculate the sculpt BVH to improve performance";
176 
177  /* API callbacks. */
180 
182 }
183 
184 /********************* Dynamic topology symmetrize ********************/
185 
187 {
189  if (SCULPT_mode_poll(C) && ob->sculpt && ob->sculpt->pbvh) {
190  return BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_GRIDS;
191  }
192  return false;
193 }
194 
196 {
197  Main *bmain = CTX_data_main(C);
199  const Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
200  SculptSession *ss = ob->sculpt;
201  PBVH *pbvh = ss->pbvh;
202  const float dist = RNA_float_get(op->ptr, "merge_tolerance");
203 
204  if (!pbvh) {
205  return OPERATOR_CANCELLED;
206  }
207 
208  switch (BKE_pbvh_type(pbvh)) {
209  case PBVH_BMESH:
210  /* Dyntopo Symmetrize. */
211 
212  /* To simplify undo for symmetrize, all BMesh elements are logged
213  * as deleted, then after symmetrize operation all BMesh elements
214  * are logged as added (as opposed to attempting to store just the
215  * parts that symmetrize modifies). */
216  SCULPT_undo_push_begin(ob, "Dynamic topology symmetrize");
219 
220  BM_mesh_toolflags_set(ss->bm, true);
221 
222  /* Symmetrize and re-triangulate. */
223  BMO_op_callf(ss->bm,
225  "symmetrize input=%avef direction=%i dist=%f use_shapekey=%b",
227  dist,
228  true);
230 
231  /* Bisect operator flags edges (keep tags clean for edge queue). */
233 
234  BM_mesh_toolflags_set(ss->bm, false);
235 
236  /* Finish undo. */
237  BM_log_all_added(ss->bm, ss->bm_log);
239 
240  break;
241  case PBVH_FACES:
242  /* Mesh Symmetrize. */
243  ED_sculpt_undo_geometry_begin(ob, "mesh symmetrize");
244  Mesh *mesh = ob->data;
245 
247 
251 
252  break;
253  case PBVH_GRIDS:
254  return OPERATOR_CANCELLED;
255  }
256 
257  /* Redraw. */
258  SCULPT_pbvh_clear(ob);
260 
261  return OPERATOR_FINISHED;
262 }
263 
265 {
266  /* Identifiers. */
267  ot->name = "Symmetrize";
268  ot->idname = "SCULPT_OT_symmetrize";
269  ot->description = "Symmetrize the topology modifications";
270 
271  /* API callbacks. */
274 
276  "merge_tolerance",
277  0.001f,
278  0.0f,
279  FLT_MAX,
280  "Merge Distance",
281  "Distance within which symmetrical vertices are merged",
282  0.0f,
283  1.0f);
284 }
285 
286 /**** Toggle operator for turning sculpt mode on or off ****/
287 
289 {
290  /* Create persistent sculpt mode data. */
292 
293  /* Create sculpt mode session data. */
294  if (ob->sculpt != NULL) {
296  }
297  ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
299 
301 
303 
304  /* This function expects a fully evaluated depsgraph. */
305  BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
306 
307  /* Here we can detect geometry that was just added to Sculpt Mode as it has the
308  * SCULPT_FACE_SET_NONE assigned, so we can create a new Face Set for it. */
309  /* In sculpt mode all geometry that is assigned to SCULPT_FACE_SET_NONE is considered as not
310  * initialized, which is used is some operators that modify the mesh topology to perform certain
311  * actions in the new polys. After these operations are finished, all polys should have a valid
312  * face set ID assigned (different from SCULPT_FACE_SET_NONE) to manage their visibility
313  * correctly. */
314  /* TODO(pablodp606): Based on this we can improve the UX in future tools for creating new
315  * objects, like moving the transform pivot position to the new area or masking existing
316  * geometry. */
317  SculptSession *ss = ob->sculpt;
318  const int new_face_set = SCULPT_face_set_next_available_get(ss);
319  for (int i = 0; i < ss->totfaces; i++) {
320  if (ss->face_sets[i] == SCULPT_FACE_SET_NONE) {
321  ss->face_sets[i] = new_face_set;
322  }
323  }
324 }
325 
328  Scene *scene,
329  Object *ob,
330  const bool force_dyntopo,
331  ReportList *reports)
332 {
333  const int mode_flag = OB_MODE_SCULPT;
334  Mesh *me = BKE_mesh_from_object(ob);
335 
336  /* Enter sculpt mode. */
337  ob->mode |= mode_flag;
338 
339  sculpt_init_session(bmain, depsgraph, scene, ob);
340 
341  if (!(fabsf(ob->scale[0] - ob->scale[1]) < 1e-4f &&
342  fabsf(ob->scale[1] - ob->scale[2]) < 1e-4f)) {
343  BKE_report(
344  reports, RPT_WARNING, "Object has non-uniform scale, sculpting may be unpredictable");
345  }
346  else if (is_negative_m4(ob->obmat)) {
347  BKE_report(reports, RPT_WARNING, "Object has negative scale, sculpting may be unpredictable");
348  }
349 
352 
354 
355  /* Check dynamic-topology flag; re-enter dynamic-topology mode when changing modes,
356  * As long as no data was added that is not supported. */
357  if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
359 
360  const char *message_unsupported = NULL;
361  if (me->totloop != me->totpoly * 3) {
362  message_unsupported = TIP_("non-triangle face");
363  }
364  else if (mmd != NULL) {
365  message_unsupported = TIP_("multi-res modifier");
366  }
367  else {
369  if (flag == 0) {
370  /* pass */
371  }
372  else if (flag & DYNTOPO_WARN_VDATA) {
373  message_unsupported = TIP_("vertex data");
374  }
375  else if (flag & DYNTOPO_WARN_EDATA) {
376  message_unsupported = TIP_("edge data");
377  }
378  else if (flag & DYNTOPO_WARN_LDATA) {
379  message_unsupported = TIP_("face data");
380  }
381  else if (flag & DYNTOPO_WARN_MODIFIER) {
382  message_unsupported = TIP_("constructive modifier");
383  }
384  else {
385  BLI_assert(0);
386  }
387  }
388 
389  if ((message_unsupported == NULL) || force_dyntopo) {
390  /* Needed because we may be entering this mode before the undo system loads. */
391  wmWindowManager *wm = bmain->wm.first;
392  bool has_undo = wm->undo_stack != NULL;
393  /* Undo push is needed to prevent memory leak. */
394  if (has_undo) {
395  SCULPT_undo_push_begin(ob, "Dynamic topology enable");
396  }
398  if (has_undo) {
401  }
402  }
403  else {
404  BKE_reportf(
405  reports, RPT_WARNING, "Dynamic Topology found: %s, disabled", message_unsupported);
407  }
408  }
409 
410  /* Flush object mode. */
412 }
413 
415 {
416  Main *bmain = CTX_data_main(C);
418  ViewLayer *view_layer = CTX_data_view_layer(C);
419  Object *ob = OBACT(view_layer);
420  ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, false, reports);
421 }
422 
424 {
425  const int mode_flag = OB_MODE_SCULPT;
426  Mesh *me = BKE_mesh_from_object(ob);
427 
429 
430  /* Not needed for now. */
431 #if 0
433  const int flush_recalc = ed_object_sculptmode_flush_recalc_flag(scene, ob, mmd);
434 #endif
435 
436  /* Always for now, so leaving sculpt mode always ensures scene is in
437  * a consistent state. */
438  if (true || /* flush_recalc || */ (ob->sculpt && ob->sculpt->bm)) {
440  }
441 
442  if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
443  /* Dynamic topology must be disabled before exiting sculpt
444  * mode to ensure the undo stack stays in a consistent
445  * state. */
447 
448  /* Store so we know to re-enable when entering sculpt mode. */
450  }
451 
452  /* Leave sculpt mode. */
453  ob->mode &= ~mode_flag;
454 
456 
458 
459  /* Never leave derived meshes behind. */
461 
462  /* Flush object mode. */
464 }
465 
467 {
468  Main *bmain = CTX_data_main(C);
470  ViewLayer *view_layer = CTX_data_view_layer(C);
471  Object *ob = OBACT(view_layer);
473 }
474 
476 {
477  struct wmMsgBus *mbus = CTX_wm_message_bus(C);
478  Main *bmain = CTX_data_main(C);
482  ViewLayer *view_layer = CTX_data_view_layer(C);
483  Object *ob = OBACT(view_layer);
484  const int mode_flag = OB_MODE_SCULPT;
485  const bool is_mode_set = (ob->mode & mode_flag) != 0;
486 
487  if (!is_mode_set) {
488  if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
489  return OPERATOR_CANCELLED;
490  }
491  }
492 
493  if (is_mode_set) {
495  }
496  else {
497  if (depsgraph) {
499  }
500  ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, false, op->reports);
502 
503  if (ob->mode & mode_flag) {
504  Mesh *me = ob->data;
505  /* Dyntopo adds its own undo step. */
506  if ((me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) == 0) {
507  /* Without this the memfile undo step is used,
508  * while it works it causes lag when undoing the first undo step, see T71564. */
510  if (wm->op_undo_depth <= 1) {
511  SCULPT_undo_push_begin(ob, op->type->name);
513  }
514  }
515  }
516  }
517 
519 
520  WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode);
521 
523 
524  return OPERATOR_FINISHED;
525 }
526 
528 {
529  /* Identifiers. */
530  ot->name = "Sculpt Mode";
531  ot->idname = "SCULPT_OT_sculptmode_toggle";
532  ot->description = "Toggle sculpt mode in 3D view";
533 
534  /* API callbacks. */
537 
539 }
540 
542 {
545 
546  ss->preview_vert_index_count = 0;
547  int totpoints = 0;
548 
549  /* This function is called from the cursor drawing code, so the PBVH may not be build yet. */
550  if (!ss->pbvh) {
551  return;
552  }
553 
554  if (!ss->deform_modifiers_active) {
555  return;
556  }
557 
558  if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
559  return;
560  }
561 
562  BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
563 
564  if (!ss->pmap) {
565  return;
566  }
567 
568  float brush_co[3];
570 
571  BLI_bitmap *visited_vertices = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_vertices");
572 
573  /* Assuming an average of 6 edges per vertex in a triangulated mesh. */
574  const int max_preview_vertices = SCULPT_vertex_count_get(ss) * 3 * 2;
575 
576  if (ss->preview_vert_index_list == NULL) {
577  ss->preview_vert_index_list = MEM_callocN(max_preview_vertices * sizeof(int), "preview lines");
578  }
579 
580  GSQueue *not_visited_vertices = BLI_gsqueue_new(sizeof(int));
581  int active_v = SCULPT_active_vertex_get(ss);
582  BLI_gsqueue_push(not_visited_vertices, &active_v);
583 
584  while (!BLI_gsqueue_is_empty(not_visited_vertices)) {
585  int from_v;
586  BLI_gsqueue_pop(not_visited_vertices, &from_v);
588  SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
589  if (totpoints + (ni.size * 2) < max_preview_vertices) {
590  int to_v = ni.index;
591  ss->preview_vert_index_list[totpoints] = from_v;
592  totpoints++;
593  ss->preview_vert_index_list[totpoints] = to_v;
594  totpoints++;
595  if (BLI_BITMAP_TEST(visited_vertices, to_v)) {
596  continue;
597  }
598  BLI_BITMAP_ENABLE(visited_vertices, to_v);
599  const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v);
600  if (len_squared_v3v3(brush_co, co) < radius * radius) {
601  BLI_gsqueue_push(not_visited_vertices, &to_v);
602  }
603  }
604  }
606  }
607 
608  BLI_gsqueue_free(not_visited_vertices);
609 
610  MEM_freeN(visited_vertices);
611 
612  ss->preview_vert_index_count = totpoints;
613 }
614 
616 {
618 
619  ID *data;
620  data = ob->data;
622  return OPERATOR_CANCELLED;
623  }
624 
625  if (ob->type != OB_MESH) {
626  return OPERATOR_CANCELLED;
627  }
628 
629  Mesh *mesh = ob->data;
630 
631  const int mloopcol_layer_n = CustomData_get_active_layer(&mesh->ldata, CD_PROP_BYTE_COLOR);
632  if (mloopcol_layer_n == -1) {
633  return OPERATOR_CANCELLED;
634  }
635  MLoopCol *loopcols = CustomData_get_layer_n(&mesh->ldata, CD_PROP_BYTE_COLOR, mloopcol_layer_n);
636 
637  const int MPropCol_layer_n = CustomData_get_active_layer(&mesh->vdata, CD_PROP_COLOR);
638  if (MPropCol_layer_n == -1) {
639  return OPERATOR_CANCELLED;
640  }
641  const MPropCol *vertcols = CustomData_get_layer_n(&mesh->vdata, CD_PROP_COLOR, MPropCol_layer_n);
642 
643  const MLoop *loops = CustomData_get_layer(&mesh->ldata, CD_MLOOP);
644  const MPoly *polys = CustomData_get_layer(&mesh->pdata, CD_MPOLY);
645 
646  for (int i = 0; i < mesh->totpoly; i++) {
647  const MPoly *c_poly = &polys[i];
648  for (int j = 0; j < c_poly->totloop; j++) {
649  int loop_index = c_poly->loopstart + j;
650  const MLoop *c_loop = &loops[c_poly->loopstart + j];
651  float srgb_color[4];
652  linearrgb_to_srgb_v4(srgb_color, vertcols[c_loop->v].color);
653  loopcols[loop_index].r = (char)(srgb_color[0] * 255);
654  loopcols[loop_index].g = (char)(srgb_color[1] * 255);
655  loopcols[loop_index].b = (char)(srgb_color[2] * 255);
656  loopcols[loop_index].a = (char)(srgb_color[3] * 255);
657  }
658  }
659 
662 
663  return OPERATOR_FINISHED;
664 }
665 
667 {
668  if (!SCULPT_mode_poll(C)) {
669  return false;
670  }
671 
673 
674  if (!ob->sculpt || !ob->sculpt->pbvh || BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_FACES) {
675  return false;
676  }
677 
678  return SCULPT_has_colors(ob->sculpt);
679 }
680 
682 {
683  /* identifiers */
684  ot->name = "Sculpt Vertex Color to Vertex Color";
685  ot->description = "Copy the Sculpt Vertex Color to a regular color layer";
686  ot->idname = "SCULPT_OT_vertex_to_loop_colors";
687 
688  /* api callbacks */
691 
693 }
694 
696 {
698 
699  ID *data;
700  data = ob->data;
702  return OPERATOR_CANCELLED;
703  }
704 
705  if (ob->type != OB_MESH) {
706  return OPERATOR_CANCELLED;
707  }
708 
709  Mesh *mesh = ob->data;
710 
711  const int mloopcol_layer_n = CustomData_get_active_layer(&mesh->ldata, CD_PROP_BYTE_COLOR);
712  if (mloopcol_layer_n == -1) {
713  return OPERATOR_CANCELLED;
714  }
715  const MLoopCol *loopcols = CustomData_get_layer_n(
716  &mesh->ldata, CD_PROP_BYTE_COLOR, mloopcol_layer_n);
717 
718  const int MPropCol_layer_n = CustomData_get_active_layer(&mesh->vdata, CD_PROP_COLOR);
719  if (MPropCol_layer_n == -1) {
720  return OPERATOR_CANCELLED;
721  }
722  MPropCol *vertcols = CustomData_get_layer_n(&mesh->vdata, CD_PROP_COLOR, MPropCol_layer_n);
723 
724  const MLoop *loops = CustomData_get_layer(&mesh->ldata, CD_MLOOP);
725  const MPoly *polys = CustomData_get_layer(&mesh->pdata, CD_MPOLY);
726 
727  for (int i = 0; i < mesh->totpoly; i++) {
728  const MPoly *c_poly = &polys[i];
729  for (int j = 0; j < c_poly->totloop; j++) {
730  int loop_index = c_poly->loopstart + j;
731  const MLoop *c_loop = &loops[c_poly->loopstart + j];
732  vertcols[c_loop->v].color[0] = (loopcols[loop_index].r / 255.0f);
733  vertcols[c_loop->v].color[1] = (loopcols[loop_index].g / 255.0f);
734  vertcols[c_loop->v].color[2] = (loopcols[loop_index].b / 255.0f);
735  vertcols[c_loop->v].color[3] = (loopcols[loop_index].a / 255.0f);
736  srgb_to_linearrgb_v4(vertcols[c_loop->v].color, vertcols[c_loop->v].color);
737  }
738  }
739 
742 
743  return OPERATOR_FINISHED;
744 }
745 
747 {
748  /* identifiers */
749  ot->name = "Vertex Color to Sculpt Vertex Color";
750  ot->description = "Copy the active loop color layer to the vertex color";
751  ot->idname = "SCULPT_OT_loop_to_vertex_colors";
752 
753  /* api callbacks */
756 
758 }
759 
761 {
765  Brush *brush = BKE_paint_brush(&sd->paint);
766  SculptSession *ss = ob->sculpt;
767  int active_vertex = SCULPT_active_vertex_get(ss);
768  float active_vertex_color[4];
769 
770  if (!SCULPT_handles_colors_report(ss, op->reports)) {
771  return OPERATOR_CANCELLED;
772  }
773 
775 
776  /* No color attribute? Set color to white. */
777  if (!SCULPT_has_colors(ss)) {
778  copy_v4_fl(active_vertex_color, 1.0f);
779  }
780  else {
781  SCULPT_vertex_color_get(ss, active_vertex, active_vertex_color);
782  }
783 
784  float color_srgb[3];
785  IMB_colormanagement_scene_linear_to_srgb_v3(color_srgb, active_vertex_color);
786  BKE_brush_color_set(scene, brush, color_srgb);
787 
789 
790  return OPERATOR_FINISHED;
791 }
792 
794 {
795  /* identifiers */
796  ot->name = "Sample Color";
797  ot->idname = "SCULPT_OT_sample_color";
798  ot->description = "Sample the vertex color of the active vertex";
799 
800  /* api callbacks */
803 
805 }
806 
816 #define MASK_BY_COLOR_SLOPE 0.25f
817 
818 static float sculpt_mask_by_color_delta_get(const float *color_a,
819  const float *color_b,
820  const float threshold,
821  const bool invert)
822 {
823  float len = len_v3v3(color_a, color_b);
824  /* Normalize len to the (0, 1) range. */
825  len = len / M_SQRT3;
826 
828  len = 1.0f;
829  }
830  else if (len >= threshold) {
831  len = 0.0f;
832  }
833  else {
835  }
836 
837  if (invert) {
838  return 1.0f - len;
839  }
840  return len;
841 }
842 
843 static float sculpt_mask_by_color_final_mask_get(const float current_mask,
844  const float new_mask,
845  const bool invert,
846  const bool preserve_mask)
847 {
848  if (preserve_mask) {
849  if (invert) {
850  return min_ff(current_mask, new_mask);
851  }
852  return max_ff(current_mask, new_mask);
853  }
854  return new_mask;
855 }
856 
858  float threshold;
859  bool invert;
860  float *new_mask;
861  float initial_color[3];
863 
865  void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
866 {
867  SculptThreadedTaskData *data = userdata;
868  SculptSession *ss = data->ob->sculpt;
869 
871  bool update_node = false;
872 
873  const bool invert = data->mask_by_color_invert;
874  const bool preserve_mask = data->mask_by_color_preserve_mask;
875 
876  PBVHVertexIter vd;
877  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
878  const float current_mask = *vd.mask;
879  const float new_mask = data->mask_by_color_floodfill[vd.index];
880  *vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask);
881  if (current_mask == *vd.mask) {
882  continue;
883  }
884  update_node = true;
885  }
887  if (update_node) {
889  }
890 }
891 
893  SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
894 {
896  float current_color[4];
897 
898  SCULPT_vertex_color_get(ss, to_v, current_color);
899 
900  float new_vertex_mask = sculpt_mask_by_color_delta_get(
901  current_color, data->initial_color, data->threshold, data->invert);
902  data->new_mask[to_v] = new_vertex_mask;
903 
904  if (is_duplicate) {
905  data->new_mask[to_v] = data->new_mask[from_v];
906  }
907 
908  float len = len_v3v3(current_color, data->initial_color);
909  len = len / M_SQRT3;
910  return len <= data->threshold;
911 }
912 
914  const int vertex,
915  const float threshold,
916  const bool invert,
917  const bool preserve_mask)
918 {
919  SculptSession *ss = object->sculpt;
920  const int totvert = SCULPT_vertex_count_get(ss);
921 
922  float *new_mask = MEM_calloc_arrayN(totvert, sizeof(float), "new mask");
923 
924  if (invert) {
925  for (int i = 0; i < totvert; i++) {
926  new_mask[i] = 1.0f;
927  }
928  }
929 
930  SculptFloodFill flood;
931  SCULPT_floodfill_init(ss, &flood);
932  SCULPT_floodfill_add_initial(&flood, vertex);
933 
935  ffd.threshold = threshold;
936  ffd.invert = invert;
937  ffd.new_mask = new_mask;
938 
939  float color[4];
940  SCULPT_vertex_color_get(ss, vertex, color);
941 
943 
945  SCULPT_floodfill_free(&flood);
946 
947  int totnode;
948  PBVHNode **nodes;
949  BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
950 
952  .ob = object,
953  .nodes = nodes,
954  .mask_by_color_floodfill = new_mask,
955  .mask_by_color_vertex = vertex,
956  .mask_by_color_threshold = threshold,
957  .mask_by_color_invert = invert,
958  .mask_by_color_preserve_mask = preserve_mask,
959  };
960 
961  TaskParallelSettings settings;
962  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
964  0, totnode, &data, do_mask_by_color_contiguous_update_nodes_cb, &settings);
965 
966  MEM_SAFE_FREE(nodes);
967 
968  MEM_freeN(new_mask);
969 }
970 
971 static void do_mask_by_color_task_cb(void *__restrict userdata,
972  const int n,
973  const TaskParallelTLS *__restrict UNUSED(tls))
974 {
975  SculptThreadedTaskData *data = userdata;
976  SculptSession *ss = data->ob->sculpt;
977 
979  bool update_node = false;
980 
981  const float threshold = data->mask_by_color_threshold;
982  const bool invert = data->mask_by_color_invert;
983  const bool preserve_mask = data->mask_by_color_preserve_mask;
984  float active_color[4];
985 
986  SCULPT_vertex_color_get(ss, data->mask_by_color_vertex, active_color);
987 
988  PBVHVertexIter vd;
989  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
990  float col[4];
992 
993  const float current_mask = *vd.mask;
994  const float new_mask = sculpt_mask_by_color_delta_get(active_color, col, threshold, invert);
995  *vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask);
996 
997  if (current_mask == *vd.mask) {
998  continue;
999  }
1000  update_node = true;
1001  }
1003  if (update_node) {
1005  }
1006 }
1007 
1009  const int vertex,
1010  const float threshold,
1011  const bool invert,
1012  const bool preserve_mask)
1013 {
1014  SculptSession *ss = object->sculpt;
1015 
1016  int totnode;
1017  PBVHNode **nodes;
1018  BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
1019 
1021  .ob = object,
1022  .nodes = nodes,
1023  .mask_by_color_vertex = vertex,
1024  .mask_by_color_threshold = threshold,
1025  .mask_by_color_invert = invert,
1026  .mask_by_color_preserve_mask = preserve_mask,
1027  };
1028 
1029  TaskParallelSettings settings;
1030  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1031  BLI_task_parallel_range(0, totnode, &data, do_mask_by_color_task_cb, &settings);
1032 
1033  MEM_SAFE_FREE(nodes);
1034 }
1035 
1037 {
1040  SculptSession *ss = ob->sculpt;
1041  View3D *v3d = CTX_wm_view3d(C);
1042  if (v3d->shading.type == OB_SOLID) {
1044  }
1045 
1046  BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
1047 
1048  /* Color data is not available in multi-resolution or dynamic topology. */
1049  if (!SCULPT_handles_colors_report(ss, op->reports)) {
1050  return OPERATOR_CANCELLED;
1051  }
1052 
1054 
1055  /* Tools that are not brushes do not have the brush gizmo to update the vertex as the mouse move,
1056  * so it needs to be updated here. */
1058  const float mval_fl[2] = {UNPACK2(event->mval)};
1059  SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
1060 
1061  SCULPT_undo_push_begin(ob, "Mask by color");
1063 
1064  const int active_vertex = SCULPT_active_vertex_get(ss);
1065  const float threshold = RNA_float_get(op->ptr, "threshold");
1066  const bool invert = RNA_boolean_get(op->ptr, "invert");
1067  const bool preserve_mask = RNA_boolean_get(op->ptr, "preserve_previous_mask");
1068 
1069  if (SCULPT_has_loop_colors(ob)) {
1071  }
1072 
1073  if (RNA_boolean_get(op->ptr, "contiguous")) {
1074  sculpt_mask_by_color_contiguous(ob, active_vertex, threshold, invert, preserve_mask);
1075  }
1076  else {
1077  sculpt_mask_by_color_full_mesh(ob, active_vertex, threshold, invert, preserve_mask);
1078  }
1079 
1082 
1085 
1086  return OPERATOR_FINISHED;
1087 }
1088 
1090 {
1091  /* identifiers */
1092  ot->name = "Mask by Color";
1093  ot->idname = "SCULPT_OT_mask_by_color";
1094  ot->description = "Creates a mask based on the active color attribute";
1095 
1096  /* api callbacks */
1099 
1100  ot->flag = OPTYPE_REGISTER;
1101 
1102  ot->prop = RNA_def_boolean(
1103  ot->srna, "contiguous", false, "Contiguous", "Mask only contiguous color areas");
1104 
1105  ot->prop = RNA_def_boolean(ot->srna, "invert", false, "Invert", "Invert the generated mask");
1106  ot->prop = RNA_def_boolean(
1107  ot->srna,
1108  "preserve_previous_mask",
1109  false,
1110  "Preserve Previous Mask",
1111  "Preserve the previous mask and add or subtract the new one generated by the colors");
1112 
1114  "threshold",
1115  0.35f,
1116  0.0f,
1117  1.0f,
1118  "Threshold",
1119  "How much changes in color affect the mask generation",
1120  0.0f,
1121  1.0f);
1122 }
1123 
1125 {
1151 
1159 
1161 }
Generic geometry attributes built on CustomData.
void BKE_brush_color_set(struct Scene *scene, struct Brush *brush, const float color[3])
Definition: brush.cc:2222
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1528
struct Depsgraph * CTX_data_depsgraph_on_load(const bContext *C)
Definition: context.c:1536
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1353
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:784
struct wmMsgBus * CTX_wm_message_bus(const bContext *C)
Definition: context.c:770
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1505
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
Definition: context.c:1282
int CustomData_get_active_layer(const struct CustomData *data, int type)
void * CustomData_get_layer_n(const struct CustomData *data, int type, int n)
void * CustomData_get_layer(const struct CustomData *data, int type)
struct Mesh * BKE_mesh_from_object(struct Object *ob)
Definition: mesh.cc:1365
void BKE_mesh_batch_cache_dirty_tag(struct Mesh *me, eMeshBatchDirtyMode mode)
void BKE_mesh_normals_tag_dirty(struct Mesh *mesh)
Definition: mesh_normals.cc:95
void BKE_mesh_mirror_apply_mirror_on_axis(struct Main *bmain, struct Mesh *mesh, int axis, float dist)
@ BKE_MESH_BATCH_DIRTY_ALL
void multires_flush_sculpt_updates(struct Object *object)
Definition: multires.c:408
General operations, lookup, etc. for blender objects.
void BKE_object_free_derived_caches(struct Object *ob)
Definition: object.cc:1774
struct Paint * BKE_paint_get_active_from_paintmode(struct Scene *sce, ePaintMode mode)
Definition: paint.c:345
void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene)
Definition: paint.c:1992
struct MultiresModifierData * BKE_sculpt_multires_active(const struct Scene *scene, struct Object *ob)
void BKE_sculpt_update_object_for_edit(struct Depsgraph *depsgraph, struct Object *ob_orig, bool need_pmap, bool need_mask, bool is_paint_tool)
Definition: paint.c:1914
const char PAINT_CURSOR_SCULPT[3]
Definition: paint.c:220
struct Brush * BKE_paint_brush(struct Paint *paint)
Definition: paint.c:607
void BKE_paint_init(struct Main *bmain, struct Scene *sce, ePaintMode mode, const char col[3])
Definition: paint.c:1130
#define SCULPT_FACE_SET_NONE
Definition: BKE_paint.h:267
void BKE_sculptsession_free(struct Object *ob)
Definition: paint.c:1469
void BKE_paint_toolslots_brush_validate(struct Main *bmain, struct Paint *paint)
@ PAINT_MODE_SCULPT
Definition: BKE_paint.h:68
void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
Definition: paint.c:1880
void BKE_sculpt_ensure_orig_mesh_data(struct Scene *scene, struct Object *object)
Definition: paint.c:2144
A BVH for high poly meshes.
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode)
Definition: BKE_pbvh.h:439
PBVHType BKE_pbvh_type(const PBVH *pbvh)
Definition: pbvh.c:1798
#define BKE_pbvh_vertex_iter_end
Definition: BKE_pbvh.h:509
#define PBVH_ITER_UNIQUE
Definition: BKE_pbvh.h:391
@ PBVH_GRIDS
Definition: BKE_pbvh.h:235
@ PBVH_BMESH
Definition: BKE_pbvh.h:236
@ PBVH_FACES
Definition: BKE_pbvh.h:234
void BKE_pbvh_ensure_node_loops(PBVH *pbvh)
Definition: pbvh.c:3280
void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode)
Definition: pbvh.c:3211
void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flags)
Definition: pbvh.c:1567
void BKE_pbvh_node_mark_update_mask(PBVHNode *node)
Definition: pbvh.c:1875
void BKE_pbvh_search_gather(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot)
Definition: pbvh.c:838
@ PBVH_UpdateMask
Definition: BKE_pbvh.h:71
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
void BKE_scene_graph_evaluated_ensure(struct Depsgraph *depsgraph, struct Main *bmain)
Definition: scene.cc:2653
A (mainly) macro array library.
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition: BLI_bitmap.h:40
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition: BLI_bitmap.h:64
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition: BLI_bitmap.h:81
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:16
void BLI_gsqueue_free(GSQueue *queue)
Definition: gsqueue.c:90
GSQueue * BLI_gsqueue_new(size_t elem_size)
Definition: gsqueue.c:69
void BLI_gsqueue_push(GSQueue *queue, const void *item)
Definition: gsqueue.c:97
void BLI_gsqueue_pop(GSQueue *queue, void *r_item)
Definition: gsqueue.c:131
bool BLI_gsqueue_is_empty(const GSQueue *queue)
Definition: gsqueue.c:159
#define M_SQRT3
Definition: BLI_math_base.h:35
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4])
MINLINE void linearrgb_to_srgb_v4(float srgb[4], const float linear[4])
bool is_negative_m4(const float mat[4][4])
Definition: math_matrix.c:2509
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v4_fl(float r[4], float f)
Random number functions.
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:94
#define UNPACK2(a)
#define UNUSED(x)
#define TIP_(msgid)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:588
@ CD_PROP_BYTE_COLOR
@ CD_PROP_COLOR
These structs are the foundation for all linked lists in the library system.
@ ME_SCULPT_DYNAMIC_TOPOLOGY
@ OB_SOLID
@ OB_MODE_SCULPT
Object is a sort of wrapper for general info.
@ OB_MESH
#define OBACT(_view_layer)
@ V3D_SHADING_VERTEX_COLOR
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
void ED_paint_cursor_start(struct Paint *p, bool(*poll)(struct bContext *C))
bool ED_object_mode_compat_set(struct bContext *C, struct Object *ob, eObjectMode mode, struct ReportList *reports)
Definition: object_modes.c:161
bool ED_operator_object_active_editable_mesh(struct bContext *C)
Definition: screen_ops.c:413
void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name)
Definition: sculpt_undo.c:1833
void ED_sculpt_undo_geometry_end(struct Object *ob)
Definition: sculpt_undo.c:1839
BLI_INLINE void IMB_colormanagement_scene_linear_to_srgb_v3(float srgb[3], const float scene_linear[3])
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
Platform independent time functions.
#define C
Definition: RandGen.cpp:25
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
#define NC_GEOM
Definition: WM_types.h:343
#define ND_DRAW
Definition: WM_types.h:410
#define NC_BRUSH
Definition: WM_types.h:335
#define ND_DATA
Definition: WM_types.h:456
#define ND_MODE
Definition: WM_types.h:393
#define NC_SCENE
Definition: WM_types.h:328
#define NA_EDITED
Definition: WM_types.h:523
#define NC_OBJECT
Definition: WM_types.h:329
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
@ BM_EDGE
Definition: bmesh_class.h:384
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
void BM_log_all_added(BMesh *bm, BMLog *log)
Definition: bmesh_log.c:870
void BM_log_before_all_removed(BMesh *bm, BMLog *log)
Definition: bmesh_log.c:897
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_mesh_toolflags_set(BMesh *bm, bool use_toolflags)
Definition: bmesh_mesh.cc:1275
@ BMO_FLAG_RESPECT_HIDE
bool BMO_op_callf(BMesh *bm, int flag, const char *fmt,...)
#define BMO_FLAG_DEFAULTS
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
Scene scene
const Depsgraph * depsgraph
int len
Definition: draw_manager.c:108
uint col
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition: invert.h:8
ccl_gpu_kernel_postfix ccl_global float int int int int float threshold
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:32
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
#define fabsf(x)
Definition: metal/compat.h:219
void paint_cursor_delete_textures(void)
Definition: paint_cursor.c:88
void SCULPT_OT_trim_box_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1773
void SCULPT_OT_face_set_box_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1733
void SCULPT_OT_project_line_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1794
void SCULPT_OT_trim_lasso_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1752
void SCULPT_OT_face_set_lasso_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1714
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4957
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3836
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
const float * SCULPT_vertex_co_get(SculptSession *ss, int index)
Definition: sculpt.c:125
int SCULPT_vertex_count_get(SculptSession *ss)
Definition: sculpt.c:111
void SCULPT_OT_brush_stroke(wmOperatorType *ot)
Definition: sculpt.c:5624
int SCULPT_active_vertex_get(SculptSession *ss)
Definition: sculpt.c:271
bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mval[2], bool use_sampled_normal)
Definition: sculpt.c:4835
void SCULPT_floodfill_init(SculptSession *ss, SculptFloodFill *flood)
Definition: sculpt.c:1072
const float * SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, int index)
Definition: sculpt.c:201
void SCULPT_floodfill_add_initial(SculptFloodFill *flood, int index)
Definition: sculpt.c:1081
const float * SCULPT_active_vertex_co_get(SculptSession *ss)
Definition: sculpt.c:279
void SCULPT_vertex_random_access_ensure(SculptSession *ss)
Definition: sculpt.c:103
void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType update_flags)
Definition: sculpt.c:5212
void SCULPT_vertex_color_get(const SculptSession *ss, int index, float r_color[4])
Definition: sculpt.c:161
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
Definition: sculpt.c:171
bool SCULPT_mode_poll_view3d(bContext *C)
Definition: sculpt.c:3963
void SCULPT_floodfill_free(SculptFloodFill *flood)
Definition: sculpt.c:1174
bool SCULPT_mode_poll(bContext *C)
Definition: sculpt.c:3957
bool SCULPT_has_loop_colors(const Object *ob)
Definition: sculpt.c:148
bool SCULPT_handles_colors_report(SculptSession *ss, ReportList *reports)
Definition: sculpt.c:5303
int SCULPT_face_set_next_available_get(SculptSession *ss)
Definition: sculpt.c:693
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:1143
bool SCULPT_has_colors(const SculptSession *ss)
Definition: sculpt.c:156
void SCULPT_OT_cloth_filter(struct wmOperatorType *ot)
void SCULPT_OT_sample_detail_size(wmOperatorType *ot)
void SCULPT_OT_detail_flood_fill(wmOperatorType *ot)
void SCULPT_OT_set_detail_size(wmOperatorType *ot)
void SCULPT_OT_dyntopo_detail_size_edit(wmOperatorType *ot)
enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob)
void SCULPT_pbvh_clear(Object *ob)
void SCULPT_OT_dynamic_topology_toggle(wmOperatorType *ot)
void sculpt_dynamic_topology_disable_with_undo(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
void SCULPT_dynamic_topology_triangulate(BMesh *bm)
void SCULPT_OT_expand(wmOperatorType *ot)
void SCULPT_OT_face_sets_change_visibility(wmOperatorType *ot)
void SCULPT_OT_face_sets_init(wmOperatorType *ot)
void SCULPT_OT_face_sets_create(wmOperatorType *ot)
void SCULPT_OT_face_sets_edit(struct wmOperatorType *ot)
void SCULPT_OT_face_sets_randomize_colors(wmOperatorType *ot)
void SCULPT_OT_color_filter(struct wmOperatorType *ot)
void SCULPT_OT_mask_filter(struct wmOperatorType *ot)
void SCULPT_OT_dirty_mask(struct wmOperatorType *ot)
void SCULPT_OT_mesh_filter(struct wmOperatorType *ot)
void SCULPT_undo_push_begin(struct Object *ob, const char *name)
Definition: sculpt_undo.c:1545
void SCULPT_undo_push_end(struct Object *ob)
Definition: sculpt_undo.c:1575
#define SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN(ss, v_index, neighbor_iterator)
void SCULPT_OT_set_pivot_position(struct wmOperatorType *ot)
@ SCULPT_UPDATE_MASK
Definition: sculpt_intern.h:46
#define SCULPT_VERTEX_NEIGHBORS_ITER_END(neighbor_iterator)
eDynTopoWarnFlag
@ DYNTOPO_WARN_LDATA
@ DYNTOPO_WARN_MODIFIER
@ DYNTOPO_WARN_VDATA
@ DYNTOPO_WARN_EDATA
SculptUndoNode * SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type)
Definition: sculpt_undo.c:1419
void SCULPT_OT_mask_init(struct wmOperatorType *ot)
@ SCULPT_UNDO_DYNTOPO_SYMMETRIZE
@ SCULPT_UNDO_DYNTOPO_BEGIN
@ SCULPT_UNDO_MASK
void SCULPT_OT_mask_expand(struct wmOperatorType *ot)
static bool sculpt_mask_by_color_contiguous_floodfill_cb(SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
Definition: sculpt_ops.c:892
static bool sculpt_no_multires_poll(bContext *C)
Definition: sculpt_ops.c:186
static bool sculpt_colors_poll(bContext *C)
Definition: sculpt_ops.c:666
static void SCULPT_OT_mask_by_color(wmOperatorType *ot)
Definition: sculpt_ops.c:1089
static int sculpt_optimize_exec(bContext *C, wmOperator *UNUSED(op))
Definition: sculpt_ops.c:156
static void sculpt_mask_by_color_contiguous(Object *object, const int vertex, const float threshold, const bool invert, const bool preserve_mask)
Definition: sculpt_ops.c:913
static int sculpt_sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e))
Definition: sculpt_ops.c:760
static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
Definition: sculpt_ops.c:140
static void SCULPT_OT_sculptmode_toggle(wmOperatorType *ot)
Definition: sculpt_ops.c:527
static int sculpt_symmetrize_exec(bContext *C, wmOperator *op)
Definition: sculpt_ops.c:195
static void SCULPT_OT_loop_to_vertex_colors(wmOperatorType *ot)
Definition: sculpt_ops.c:746
static void SCULPT_OT_sample_color(wmOperatorType *ot)
Definition: sculpt_ops.c:793
void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float radius)
Definition: sculpt_ops.c:541
void ED_object_sculptmode_exit(bContext *C, Depsgraph *depsgraph)
Definition: sculpt_ops.c:466
static void sculpt_init_session(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
Definition: sculpt_ops.c:288
static void SCULPT_OT_optimize(wmOperatorType *ot)
Definition: sculpt_ops.c:170
static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
Definition: sculpt_ops.c:113
static void SCULPT_OT_vertex_to_loop_colors(wmOperatorType *ot)
Definition: sculpt_ops.c:681
void ED_object_sculptmode_exit_ex(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
Definition: sculpt_ops.c:423
static float sculpt_mask_by_color_delta_get(const float *color_a, const float *color_b, const float threshold, const bool invert)
Definition: sculpt_ops.c:818
static int vertex_to_loop_colors_exec(bContext *C, wmOperator *UNUSED(op))
Definition: sculpt_ops.c:615
static void sculpt_mask_by_color_full_mesh(Object *object, const int vertex, const float threshold, const bool invert, const bool preserve_mask)
Definition: sculpt_ops.c:1008
static void do_mask_by_color_task_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: sculpt_ops.c:971
static void do_mask_by_color_contiguous_update_nodes_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: sculpt_ops.c:864
static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
Definition: sculpt_ops.c:475
static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: sculpt_ops.c:1036
#define MASK_BY_COLOR_SLOPE
Definition: sculpt_ops.c:816
void ED_object_sculptmode_enter_ex(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob, const bool force_dyntopo, ReportList *reports)
Definition: sculpt_ops.c:326
void ED_operatortypes_sculpt(void)
Definition: sculpt_ops.c:1124
static int loop_to_vertex_colors_exec(bContext *C, wmOperator *UNUSED(op))
Definition: sculpt_ops.c:695
static void SCULPT_OT_symmetrize(wmOperatorType *ot)
Definition: sculpt_ops.c:264
void ED_object_sculptmode_enter(struct bContext *C, Depsgraph *depsgraph, ReportList *reports)
Definition: sculpt_ops.c:414
struct MaskByColorContiguousFloodFillData MaskByColorContiguousFloodFillData
static float sculpt_mask_by_color_final_mask_get(const float current_mask, const float new_mask, const bool invert, const bool preserve_mask)
Definition: sculpt_ops.c:843
Definition: DNA_ID.h:368
void * first
Definition: DNA_listBase.h:31
unsigned char a
unsigned char b
unsigned char r
unsigned char g
unsigned int v
float color[4]
Definition: BKE_main.h:121
ListBase wm
Definition: BKE_main.h:197
CustomData vdata
uint16_t flag
CustomData pdata
int totpoly
int totloop
CustomData ldata
float scale[3]
float obmat[4][4]
struct SculptSession * sculpt
void * data
float * mask
Definition: BKE_pbvh.h:433
struct ToolSettings * toolsettings
int preview_vert_index_count
Definition: BKE_paint.h:595
int * face_sets
Definition: BKE_paint.h:536
struct BMesh * bm
Definition: BKE_paint.h:539
int * preview_vert_index_list
Definition: BKE_paint.h:594
struct BMLog * bm_log
Definition: BKE_paint.h:544
struct MeshElemMap * pmap
Definition: BKE_paint.h:516
eObjectMode mode_type
Definition: BKE_paint.h:642
SculptPersistentBase * persistent_base
Definition: BKE_paint.h:606
struct PBVH * pbvh
Definition: BKE_paint.h:550
bool deform_modifiers_active
Definition: BKE_paint.h:555
Paint paint
int symmetrize_direction
View3DShading shading
int mval[2]
Definition: WM_types.h:684
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
PropertyRNA * prop
Definition: WM_types.h:981
struct ReportList * reports
struct wmOperatorType * type
struct PointerRNA * ptr
struct UndoStack * undo_stack
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition: wm_files.c:3479
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
void WM_toolsystem_update_from_context_view3d(bContext *C)