Blender V4.3
editmesh_mask_extract.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2019 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "DNA_mesh_types.h"
10#include "DNA_modifier_types.h"
11#include "DNA_object_types.h"
12
13#include "BKE_attribute.hh"
14#include "BKE_context.hh"
15#include "BKE_customdata.hh"
16#include "BKE_editmesh.hh"
17#include "BKE_lib_id.hh"
18#include "BKE_mesh.hh"
19#include "BKE_modifier.hh"
20#include "BKE_paint.hh"
21#include "BKE_shrinkwrap.hh"
22
23#include "BLI_math_vector.h"
24
25#include "BLT_translation.hh"
26
27#include "DEG_depsgraph.hh"
29
30#include "RNA_access.hh"
31#include "RNA_define.hh"
32
33#include "WM_api.hh"
34#include "WM_types.hh"
35
36#include "ED_object.hh"
37#include "ED_screen.hh"
38#include "ED_sculpt.hh"
39#include "ED_undo.hh"
40
41#include "bmesh_tools.hh"
42
43#include "MEM_guardedalloc.h"
44
45#include "mesh_intern.hh" /* own include */
46
48{
50 if (ob != nullptr && ob->mode == OB_MODE_SCULPT) {
51 if (ob->sculpt->bm) {
52 CTX_wm_operator_poll_msg_set(C, "The geometry cannot be extracted with dyntopo activated");
53 return false;
54 }
56 }
57 return false;
58}
59
61 /* For extracting Face Sets. */
63
64 /* For extracting Mask. */
66
67 /* Common parameters. */
72};
73
74/* Function that tags in BMesh the faces that should be deleted in the extracted object. */
76
78 wmOperator *op,
81{
82 Main *bmain = CTX_data_main(C);
84 View3D *v3d = CTX_wm_view3d(C);
85 Scene *scene = CTX_data_scene(C);
87
89
90 BKE_sculpt_mask_layers_ensure(&depsgraph, bmain, ob, nullptr);
91
92 /* Ensures that deformation from sculpt mode is taken into account before duplicating the mesh to
93 * extract the geometry. */
95
96 Mesh *mesh = static_cast<Mesh *>(ob->data);
97 Mesh *new_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id);
98
99 const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(new_mesh);
100 BMeshCreateParams bm_create_params{};
101 bm_create_params.use_toolflags = true;
102 BMesh *bm = BM_mesh_create(&allocsize, &bm_create_params);
103
104 BMeshFromMeshParams mesh_to_bm_params{};
105 mesh_to_bm_params.calc_face_normal = true;
106 mesh_to_bm_params.calc_vert_normal = true;
107 BM_mesh_bm_from_me(bm, new_mesh, &mesh_to_bm_params);
108
110
111 /* Generate the tags for deleting geometry in the extracted object. */
112 tag_fn(bm, params);
113
114 /* Delete all tagged faces. */
117
118 BMVert *v;
119 BMEdge *ed;
120 BMIter iter;
121 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
122 mul_v3_v3(v->co, ob->scale);
123 }
124
125 if (params->add_boundary_loop) {
126 BM_ITER_MESH (ed, &iter, bm, BM_EDGES_OF_MESH) {
128 }
130
131 for (int repeat = 0; repeat < params->num_smooth_iterations; repeat++) {
133 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
135 }
136 for (int i = 0; i < 3; i++) {
137 if (!EDBM_op_callf(em,
138 op,
139 "smooth_vert verts=%hv factor=%f mirror_clip_x=%b mirror_clip_y=%b "
140 "mirror_clip_z=%b "
141 "clip_dist=%f use_axis_x=%b use_axis_y=%b use_axis_z=%b",
143 1.0,
144 false,
145 false,
146 false,
147 0.1,
148 true,
149 true,
150 true))
151 {
152 continue;
153 }
154 }
155
157 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
159 }
160 for (int i = 0; i < 1; i++) {
161 if (!EDBM_op_callf(em,
162 op,
163 "smooth_vert verts=%hv factor=%f mirror_clip_x=%b mirror_clip_y=%b "
164 "mirror_clip_z=%b "
165 "clip_dist=%f use_axis_x=%b use_axis_y=%b use_axis_z=%b",
167 0.5,
168 false,
169 false,
170 false,
171 0.1,
172 true,
173 true,
174 true))
175 {
176 continue;
177 }
178 }
179 }
180 }
181
183
184 BKE_id_free(bmain, new_mesh);
185 BMeshToMeshParams bm_to_mesh_params{};
186 bm_to_mesh_params.calc_object_remap = false;
187 new_mesh = BKE_mesh_from_bmesh_nomain(bm, &bm_to_mesh_params, mesh);
188
189 /* Remove the Face Sets as they need to be recreated when entering Sculpt Mode in the new object.
190 * TODO(pablodobarro): In the future we can try to preserve them from the original mesh. */
191 new_mesh->attributes_for_write().remove(".sculpt_face_set");
192
193 /* Remove the mask from the new object so it can be sculpted directly after extracting. */
194 new_mesh->attributes_for_write().remove(".sculpt_mask");
195
197 MEM_delete(em);
198
199 if (new_mesh->verts_num == 0) {
200 BKE_id_free(bmain, new_mesh);
201 return OPERATOR_FINISHED;
202 }
203
204 ushort local_view_bits = 0;
205 if (v3d && v3d->localvd) {
206 local_view_bits = v3d->local_view_uid;
207 }
209 C, OB_MESH, nullptr, ob->loc, ob->rot, false, local_view_bits);
210 BKE_mesh_nomain_to_mesh(new_mesh, static_cast<Mesh *>(new_ob->data), new_ob);
211
212 if (params->apply_shrinkwrap) {
214 }
215
216 if (params->add_solidify) {
218 op->reports, bmain, scene, new_ob, "geometry_extract_solidify", eModifierType_Solidify);
220 new_ob, "mask_extract_solidify");
221 if (sfmd) {
222 sfmd->offset = -0.05f;
223 }
224 }
225
231
232 return OPERATOR_FINISHED;
233}
234
236{
237 const float threshold = params->mask_threshold;
238
240 const int cd_vert_mask_offset = CustomData_get_offset_named(
241 &bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
242
243 BMFace *f;
244 BMIter iter;
245 BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
246 bool keep_face = true;
247 BMVert *v;
248 BMIter face_iter;
251 continue;
252 };
253 BM_ITER_ELEM (v, &face_iter, f, BM_VERTS_OF_FACE) {
254 const float mask = BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
255 if (mask < threshold) {
256 keep_face = false;
257 break;
258 }
259 }
260 BM_elem_flag_set(f, BM_ELEM_TAG, !keep_face);
261 }
262}
263
265{
266 const int tag_face_set_id = params->active_face_set;
267
269 const int cd_face_sets_offset = CustomData_get_offset_named(
270 &bm->pdata, CD_PROP_INT32, ".sculpt_face_set");
271
272 BMFace *f;
273 BMIter iter;
274 BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
275 const int face_set = BM_ELEM_CD_GET_INT(f, cd_face_sets_offset);
276 BM_elem_flag_set(f, BM_ELEM_TAG, face_set != tag_face_set_id);
277 }
278}
279
281{
283 params.mask_threshold = RNA_float_get(op->ptr, "mask_threshold");
284 params.num_smooth_iterations = RNA_int_get(op->ptr, "smooth_iterations");
285 params.add_boundary_loop = RNA_boolean_get(op->ptr, "add_boundary_loop");
286 params.apply_shrinkwrap = RNA_boolean_get(op->ptr, "apply_shrinkwrap");
287 params.add_solidify = RNA_boolean_get(op->ptr, "add_solidify");
288
289 /* Push an undo step prior to extraction.
290 * NOTE: A second push happens after the operator due to
291 * the OPTYPE_UNDO flag; having an initial undo step here
292 * is just needed to preserve the active object pointer.
293 *
294 * Fixes #103261.
295 */
296 ED_undo_push_op(C, op);
297
299}
300
302{
304 C, op, e, IFACE_("Create Mesh From Paint Mask"), IFACE_("Extract"));
305}
306
308{
309 RNA_def_boolean(srna,
310 "add_boundary_loop",
311 true,
312 "Add Boundary Loop",
313 "Add an extra edge loop to better preserve the shape when applying a "
314 "subdivision surface modifier");
315 RNA_def_int(srna,
316 "smooth_iterations",
317 4,
318 0,
319 INT_MAX,
320 "Smooth Iterations",
321 "Smooth iterations applied to the extracted mesh",
322 0,
323 20);
324 RNA_def_boolean(srna,
325 "apply_shrinkwrap",
326 true,
327 "Project to Sculpt",
328 "Project the extracted mesh into the original sculpt");
329 RNA_def_boolean(srna,
330 "add_solidify",
331 true,
332 "Extract as Solid",
333 "Extract the mask as a solid object with a solidify modifier");
334}
335
337{
338 ot->name = "Mask Extract";
339 ot->description = "Create a new mesh object from the current paint mask";
340 ot->idname = "MESH_OT_paint_mask_extract";
341
345
347
349 ot->srna,
350 "mask_threshold",
351 0.5f,
352 0.0f,
353 1.0f,
354 "Threshold",
355 "Minimum mask value to consider the vertex valid to extract a face from the original mesh",
356 0.0f,
357 1.0f);
358
360}
361
362static int face_set_extract_invoke(bContext *C, wmOperator *op, const wmEvent *event)
363{
364 using namespace blender::ed;
365 if (!CTX_wm_region_view3d(C)) {
366 return OPERATOR_CANCELLED;
367 }
368 ARegion *region = CTX_wm_region(C);
369
370 const float mval[2] = {float(event->xy[0] - region->winrct.xmin),
371 float(event->xy[1] - region->winrct.ymin)};
372
374 const int face_set_id = sculpt_paint::face_set::active_update_and_get(C, ob, mval);
375 if (face_set_id == SCULPT_FACE_SET_NONE) {
376 return OPERATOR_CANCELLED;
377 }
378
380 params.active_face_set = face_set_id;
381 params.num_smooth_iterations = 0;
382 params.add_boundary_loop = false;
383 params.apply_shrinkwrap = true;
384 params.add_solidify = true;
386}
387
389{
390 ot->name = "Face Set Extract";
391 ot->description = "Create a new mesh object from the selected Face Set";
392 ot->idname = "MESH_OT_face_set_extract";
393
396
398
400}
401
402static void slice_paint_mask(BMesh *bm, bool invert, bool fill_holes, float mask_threshold)
403{
404 BMVert *v;
405 BMFace *f;
406 BMIter iter;
407 BMIter face_iter;
408
409 /* Delete all masked faces */
410 const int cd_vert_mask_offset = CustomData_get_offset_named(
411 &bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
412 BLI_assert(cd_vert_mask_offset != -1);
414
415 BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
416 bool keep_face = true;
417 BM_ITER_ELEM (v, &face_iter, f, BM_VERTS_OF_FACE) {
418 const float mask = BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
419 if (mask < mask_threshold) {
420 keep_face = false;
421 break;
422 }
423 }
425 keep_face = false;
426 };
427 /* This invert behavior is fragile, as it potentially marks faces which are hidden */
428 if (invert) {
429 keep_face = !keep_face;
430 }
431 BM_elem_flag_set(f, BM_ELEM_TAG, keep_face);
432 }
433
437
438 if (fill_holes) {
439 BM_mesh_edgenet(bm, false, true);
443 "triangulate faces=%hf quad_method=%i ngon_method=%i",
445 0,
446 0);
447
451 "recalc_face_normals faces=%hf",
454 }
455}
456
458{
459 using namespace blender;
460 using namespace blender::ed;
461 const Scene &scene = *CTX_data_scene(C);
462 Main &bmain = *CTX_data_main(C);
464 View3D *v3d = CTX_wm_view3d(C);
465
466 BKE_sculpt_mask_layers_ensure(nullptr, nullptr, &ob, nullptr);
467
468 bool create_new_object = RNA_boolean_get(op->ptr, "new_object");
469 bool fill_holes = RNA_boolean_get(op->ptr, "fill_holes");
470 float mask_threshold = RNA_float_get(op->ptr, "mask_threshold");
471
472 Mesh *mesh = static_cast<Mesh *>(ob.data);
473 Mesh *new_mesh = (Mesh *)BKE_id_copy(&bmain, &mesh->id);
474
475 /* Undo crashes when new object is created in the middle of a sculpt, see #87243. */
476 if (ob.mode == OB_MODE_SCULPT && !create_new_object) {
477 sculpt_paint::undo::geometry_begin(scene, ob, op);
478 }
479
480 const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(new_mesh);
481 BMeshCreateParams bm_create_params{};
482 bm_create_params.use_toolflags = true;
483 BMesh *bm = BM_mesh_create(&allocsize, &bm_create_params);
484
485 BMeshFromMeshParams mesh_to_bm_params{};
486 mesh_to_bm_params.calc_face_normal = true;
487 BM_mesh_bm_from_me(bm, new_mesh, &mesh_to_bm_params);
488
489 slice_paint_mask(bm, false, fill_holes, mask_threshold);
490 BKE_id_free(&bmain, new_mesh);
491 BMeshToMeshParams bm_to_mesh_params{};
492 bm_to_mesh_params.calc_object_remap = false;
493 new_mesh = BKE_mesh_from_bmesh_nomain(bm, &bm_to_mesh_params, mesh);
495
496 if (create_new_object) {
497 ushort local_view_bits = 0;
498 if (v3d && v3d->localvd) {
499 local_view_bits = v3d->local_view_uid;
500 }
502 C, OB_MESH, nullptr, ob.loc, ob.rot, false, local_view_bits);
503 Mesh *new_ob_mesh = (Mesh *)BKE_id_copy(&bmain, &mesh->id);
504
505 const BMAllocTemplate allocsize_new_ob = BMALLOC_TEMPLATE_FROM_ME(new_ob_mesh);
506 bm = BM_mesh_create(&allocsize_new_ob, &bm_create_params);
507
508 BM_mesh_bm_from_me(bm, new_ob_mesh, &mesh_to_bm_params);
509
510 slice_paint_mask(bm, true, fill_holes, mask_threshold);
511 BKE_id_free(&bmain, new_ob_mesh);
512 new_ob_mesh = BKE_mesh_from_bmesh_nomain(bm, &bm_to_mesh_params, mesh);
514
515 /* Remove the mask from the new object so it can be sculpted directly after slicing. */
516 new_ob_mesh->attributes_for_write().remove(".sculpt_mask");
517
518 Mesh *new_mesh = static_cast<Mesh *>(new_ob->data);
519 BKE_mesh_nomain_to_mesh(new_ob_mesh, new_mesh, new_ob);
524 WM_event_add_notifier(C, NC_GEOM | ND_DATA, new_mesh);
525 }
526
527 mesh = static_cast<Mesh *>(ob.data);
528 BKE_mesh_nomain_to_mesh(new_mesh, mesh, &ob);
529
530 if (ob.mode == OB_MODE_SCULPT) {
531 if (mesh->attributes().contains(".sculpt_face_set")) {
532 /* Assign a new Face Set ID to the new faces created by the slice operation. */
533 const int next_face_set_id = sculpt_paint::face_set::find_next_available_id(ob);
534 sculpt_paint::face_set::initialize_none_to_id(mesh, next_face_set_id);
535 }
536 if (!create_new_object) {
537 sculpt_paint::undo::geometry_end(ob);
539 }
540 }
541
545
546 return OPERATOR_FINISHED;
547}
548
550{
551 PropertyRNA *prop;
552
553 ot->name = "Mask Slice";
554 ot->description = "Slices the paint mask from the mesh";
555 ot->idname = "MESH_OT_paint_mask_slice";
556
559
561
563 ot->srna,
564 "mask_threshold",
565 0.5f,
566 0.0f,
567 1.0f,
568 "Threshold",
569 "Minimum mask value to consider the vertex valid to extract a face from the original mesh",
570 0.0f,
571 1.0f);
572 prop = RNA_def_boolean(
573 ot->srna, "fill_holes", true, "Fill Holes", "Fill holes after slicing the mask");
575 prop = RNA_def_boolean(ot->srna,
576 "new_object",
577 true,
578 "Slice to New Object",
579 "Create a new object from the sliced mask");
581}
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
Depsgraph * CTX_data_depsgraph_on_load(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void BKE_editmesh_free_data(BMEditMesh *em)
Definition editmesh.cc:120
BMEditMesh * BKE_editmesh_create(BMesh *bm)
Definition editmesh.cc:34
void BKE_id_free(Main *bmain, void *idv)
ID * BKE_id_copy(Main *bmain, const ID *id)
Definition lib_id.cc:765
void BKE_mesh_batch_cache_dirty_tag(Mesh *mesh, eMeshBatchDirtyMode mode)
Mesh * BKE_mesh_from_bmesh_nomain(BMesh *bm, const BMeshToMeshParams *params, const Mesh *me_settings)
void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
@ BKE_MESH_BATCH_DIRTY_ALL
Definition BKE_mesh.h:38
ModifierData * BKE_modifiers_findby_name(const Object *ob, const char *name)
#define SCULPT_FACE_SET_NONE
Definition BKE_paint.hh:341
void BKE_sculptsession_free_pbvh(Object &object)
Definition paint.cc:2099
void BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph, Main *bmain, Object *ob, MultiresModifierData *mmd)
Definition paint.cc:2610
void BKE_shrinkwrap_mesh_nearest_surface_deform(Depsgraph *depsgraph, Scene *scene, Object *ob_source, Object *ob_target)
#define BLI_assert(a)
Definition BLI_assert.h:50
MINLINE void mul_v3_v3(float r[3], const float a[3])
unsigned short ushort
#define IFACE_(msgid)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ CD_PROP_FLOAT
@ CD_PROP_INT32
@ eModifierType_Solidify
@ OB_MODE_SCULPT
Object is a sort of wrapper for general info.
@ OB_MESH
bool ED_operator_object_active_editable_mesh(bContext *C)
void ED_undo_push_op(bContext *C, wmOperator *op)
Definition ed_undo.cc:381
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition RNA_types.hh:245
@ OPTYPE_DEPENDS_ON_CURSOR
Definition WM_types.hh:198
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define NC_GEOM
Definition WM_types.hh:360
#define ND_DATA
Definition WM_types.hh:475
#define ND_MODIFIER
Definition WM_types.hh:429
#define NC_OBJECT
Definition WM_types.hh:346
#define BM_ELEM_CD_GET_FLOAT(ele, offset)
#define BM_ELEM_CD_GET_INT(ele, offset)
@ BM_ELEM_HIDDEN
@ BM_ELEM_SELECT
@ BM_ELEM_TAG
void BM_mesh_delete_hflag_context(BMesh *bm, const char hflag, const int type)
void BM_mesh_edgenet(BMesh *bm, const bool use_edge_tag, const bool use_new_face_tag)
#define BM_elem_flag_set(ele, hflag, val)
#define BM_elem_flag_test_bool(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
@ BM_VERTS_OF_FACE
@ BM_FACES_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_hflag_enable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const BMeshCreateParams *params)
BMesh Make Mesh.
#define BMALLOC_TEMPLATE_FROM_ME(...)
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *params)
void BM_mesh_normals_update(BMesh *bm)
#define BM_FACE
#define BM_EDGE
#define BM_VERT
bool BMO_op_callf(BMesh *bm, int flag, const char *fmt,...)
#define BMO_FLAG_DEFAULTS
@ BMO_FLAG_RESPECT_HIDE
bool BM_vert_is_boundary(const BMVert *v)
BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
const Depsgraph * depsgraph
bool edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char hflag, const bool use_normal_flip)
void MESH_OT_paint_mask_extract(wmOperatorType *ot)
static int geometry_extract_apply(bContext *C, wmOperator *op, GeometryExtractTagMeshFunc *tag_fn, GeometryExtractParams *params)
void MESH_OT_paint_mask_slice(wmOperatorType *ot)
static int paint_mask_extract_invoke(bContext *C, wmOperator *op, const wmEvent *e)
static bool geometry_extract_poll(bContext *C)
static int face_set_extract_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void geometry_extract_tag_face_set(BMesh *bm, GeometryExtractParams *params)
static void geometry_extract_props(StructRNA *srna)
void(BMesh *, GeometryExtractParams *) GeometryExtractTagMeshFunc
static int paint_mask_extract_exec(bContext *C, wmOperator *op)
static void geometry_extract_tag_masked_faces(BMesh *bm, GeometryExtractParams *params)
static int paint_mask_slice_exec(bContext *C, wmOperator *op)
static void slice_paint_mask(BMesh *bm, bool invert, bool fill_holes, float mask_threshold)
void MESH_OT_face_set_extract(wmOperatorType *ot)
bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt,...)
draw_view in_light_buf[] float
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition invert.h:9
ModifierData * modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
Object * add_type(bContext *C, int type, const char *name, const float loc[3], const float rot[3], bool enter_editmode, unsigned short local_view_bits) ATTR_NONNULL(1) ATTR_RETURNS_NONNULL
void object_sculpt_mode_exit(Main &bmain, Depsgraph &depsgraph, Scene &scene, Object &ob)
int RNA_int_get(PointerRNA *ptr, const char *name)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_float_factor(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
float co[3]
CustomData vdata
CustomData pdata
int verts_num
float loc[3]
float scale[3]
float rot[3]
struct SculptSession * sculpt
struct View3D * localvd
unsigned short local_view_uid
int xy[2]
Definition WM_types.hh:726
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
StructRNA * srna
Definition WM_types.hh:1080
struct ReportList * reports
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition wm_files.cc:4125
int WM_operator_props_popup_confirm_ex(bContext *C, wmOperator *op, const wmEvent *, std::optional< std::string > title, std::optional< std::string > confirm_text, const bool cancel_default)