Blender V5.0
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
8
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 /* Ensures that deformation from sculpt mode is taken into account before duplicating the mesh to
91 * extract the geometry. */
93
94 Mesh *mesh = static_cast<Mesh *>(ob->data);
95 Mesh *new_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id);
96
97 const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(new_mesh);
98 BMeshCreateParams bm_create_params{};
99 bm_create_params.use_toolflags = true;
100 BMesh *bm = BM_mesh_create(&allocsize, &bm_create_params);
101
102 BMeshFromMeshParams mesh_to_bm_params{};
103 mesh_to_bm_params.calc_face_normal = true;
104 mesh_to_bm_params.calc_vert_normal = true;
105 BM_mesh_bm_from_me(bm, new_mesh, &mesh_to_bm_params);
106
108
109 /* Generate the tags for deleting geometry in the extracted object. */
110 tag_fn(bm, params);
111
112 /* Delete all tagged faces. */
115
116 BMVert *v;
117 BMEdge *ed;
118 BMIter iter;
119 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
120 mul_v3_v3(v->co, ob->scale);
121 }
122
123 if (params->add_boundary_loop) {
124 BM_ITER_MESH (ed, &iter, bm, BM_EDGES_OF_MESH) {
126 }
128
129 for (int repeat = 0; repeat < params->num_smooth_iterations; repeat++) {
131 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
133 }
134 for (int i = 0; i < 3; i++) {
135 if (!EDBM_op_callf(em,
136 op,
137 "smooth_vert verts=%hv factor=%f mirror_clip_x=%b mirror_clip_y=%b "
138 "mirror_clip_z=%b "
139 "clip_dist=%f use_axis_x=%b use_axis_y=%b use_axis_z=%b",
141 1.0,
142 false,
143 false,
144 false,
145 0.1,
146 true,
147 true,
148 true))
149 {
150 continue;
151 }
152 }
153
155 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
157 }
158 for (int i = 0; i < 1; i++) {
159 if (!EDBM_op_callf(em,
160 op,
161 "smooth_vert verts=%hv factor=%f mirror_clip_x=%b mirror_clip_y=%b "
162 "mirror_clip_z=%b "
163 "clip_dist=%f use_axis_x=%b use_axis_y=%b use_axis_z=%b",
165 0.5,
166 false,
167 false,
168 false,
169 0.1,
170 true,
171 true,
172 true))
173 {
174 continue;
175 }
176 }
177 }
178 }
179
181
182 BKE_id_free(bmain, new_mesh);
183 BMeshToMeshParams bm_to_mesh_params{};
184 bm_to_mesh_params.calc_object_remap = false;
185 new_mesh = BKE_mesh_from_bmesh_nomain(bm, &bm_to_mesh_params, mesh);
186
187 /* Remove the Face Sets as they need to be recreated when entering Sculpt Mode in the new object.
188 * TODO(pablodobarro): In the future we can try to preserve them from the original mesh. */
189 new_mesh->attributes_for_write().remove(".sculpt_face_set");
190
191 /* Remove the mask from the new object so it can be sculpted directly after extracting. */
192 new_mesh->attributes_for_write().remove(".sculpt_mask");
193
195 MEM_delete(em);
196
197 if (new_mesh->verts_num == 0) {
198 BKE_id_free(bmain, new_mesh);
199 return OPERATOR_FINISHED;
200 }
201
202 ushort local_view_bits = 0;
203 if (v3d && v3d->localvd) {
204 local_view_bits = v3d->local_view_uid;
205 }
207 C, OB_MESH, nullptr, ob->loc, ob->rot, false, local_view_bits);
208 BKE_mesh_nomain_to_mesh(new_mesh, static_cast<Mesh *>(new_ob->data), new_ob);
209
210 if (params->apply_shrinkwrap) {
212 }
213
214 if (params->add_solidify) {
216 op->reports, bmain, scene, new_ob, "geometry_extract_solidify", eModifierType_Solidify);
218 new_ob, "mask_extract_solidify");
219 if (sfmd) {
220 sfmd->offset = -0.05f;
221 }
222 }
223
229
230 return OPERATOR_FINISHED;
231}
232
234{
235 const float threshold = params->mask_threshold;
236
238 const int cd_vert_mask_offset = CustomData_get_offset_named(
239 &bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
240
241 BMFace *f;
242 BMIter iter;
243 BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
244 bool keep_face = true;
245 BMVert *v;
246 BMIter face_iter;
249 continue;
250 };
251 BM_ITER_ELEM (v, &face_iter, f, BM_VERTS_OF_FACE) {
252 const float mask = BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
253 if (mask < threshold) {
254 keep_face = false;
255 break;
256 }
257 }
258 BM_elem_flag_set(f, BM_ELEM_TAG, !keep_face);
259 }
260}
261
263{
264 const int tag_face_set_id = params->active_face_set;
265
267 const int cd_face_sets_offset = CustomData_get_offset_named(
268 &bm->pdata, CD_PROP_INT32, ".sculpt_face_set");
269
270 BMFace *f;
271 BMIter iter;
272 BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
273 const int face_set = BM_ELEM_CD_GET_INT(f, cd_face_sets_offset);
274 BM_elem_flag_set(f, BM_ELEM_TAG, face_set != tag_face_set_id);
275 }
276}
277
279{
281 Mesh *mesh = static_cast<Mesh *>(ob->data);
282 if (!mesh->attributes().contains(".sculpt_mask")) {
283 return OPERATOR_CANCELLED;
284 }
285
287 params.mask_threshold = RNA_float_get(op->ptr, "mask_threshold");
288 params.num_smooth_iterations = RNA_int_get(op->ptr, "smooth_iterations");
289 params.add_boundary_loop = RNA_boolean_get(op->ptr, "add_boundary_loop");
290 params.apply_shrinkwrap = RNA_boolean_get(op->ptr, "apply_shrinkwrap");
291 params.add_solidify = RNA_boolean_get(op->ptr, "add_solidify");
292
293 /* Push an undo step prior to extraction.
294 * NOTE: A second push happens after the operator due to
295 * the OPTYPE_UNDO flag; having an initial undo step here
296 * is just needed to preserve the active object pointer.
297 *
298 * Fixes #103261.
299 */
300 ED_undo_push_op(C, op);
301
303}
304
306{
308 C, op, e, IFACE_("Create Mesh From Paint Mask"), IFACE_("Extract"));
309}
310
312{
313 RNA_def_boolean(srna,
314 "add_boundary_loop",
315 true,
316 "Add Boundary Loop",
317 "Add an extra edge loop to better preserve the shape when applying a "
318 "subdivision surface modifier");
319 RNA_def_int(srna,
320 "smooth_iterations",
321 4,
322 0,
323 INT_MAX,
324 "Smooth Iterations",
325 "Smooth iterations applied to the extracted mesh",
326 0,
327 20);
328 RNA_def_boolean(srna,
329 "apply_shrinkwrap",
330 true,
331 "Project to Sculpt",
332 "Project the extracted mesh into the original sculpt");
333 RNA_def_boolean(srna,
334 "add_solidify",
335 true,
336 "Extract as Solid",
337 "Extract the mask as a solid object with a solidify modifier");
338}
339
341{
342 ot->name = "Mask Extract";
343 ot->description = "Create a new mesh object from the current paint mask";
344 ot->idname = "SCULPT_OT_paint_mask_extract";
345
349
351
353 ot->srna,
354 "mask_threshold",
355 0.5f,
356 0.0f,
357 1.0f,
358 "Threshold",
359 "Minimum mask value to consider the vertex valid to extract a face from the original mesh",
360 0.0f,
361 1.0f);
362
364}
365
367{
368 using namespace blender::ed;
369 if (!CTX_wm_region_view3d(C)) {
370 return OPERATOR_CANCELLED;
371 }
372 ARegion *region = CTX_wm_region(C);
373
374 const float mval[2] = {float(event->xy[0] - region->winrct.xmin),
375 float(event->xy[1] - region->winrct.ymin)};
376
378 const int face_set_id = sculpt_paint::face_set::active_update_and_get(C, ob, mval);
379 if (face_set_id == SCULPT_FACE_SET_NONE) {
380 return OPERATOR_CANCELLED;
381 }
382
384 params.active_face_set = face_set_id;
385 params.num_smooth_iterations = 0;
386 params.add_boundary_loop = false;
387 params.apply_shrinkwrap = true;
388 params.add_solidify = true;
390}
391
393{
394 ot->name = "Face Set Extract";
395 ot->description = "Create a new mesh object from the selected Face Set";
396 ot->idname = "SCULPT_OT_face_set_extract";
397
399 ot->invoke = face_set_extract_invoke;
400
402
404}
405
406static void slice_paint_mask(BMesh *bm, bool invert, bool fill_holes, float mask_threshold)
407{
408 BMVert *v;
409 BMFace *f;
410 BMIter iter;
411 BMIter face_iter;
412
413 /* Delete all masked faces */
414 const int cd_vert_mask_offset = CustomData_get_offset_named(
415 &bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
416 BLI_assert(cd_vert_mask_offset != -1);
418
419 BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
420 bool keep_face = true;
421 BM_ITER_ELEM (v, &face_iter, f, BM_VERTS_OF_FACE) {
422 const float mask = BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
423 if (mask < mask_threshold) {
424 keep_face = false;
425 break;
426 }
427 }
429 keep_face = false;
430 };
431 /* This invert behavior is fragile, as it potentially marks faces which are hidden */
432 if (invert) {
433 keep_face = !keep_face;
434 }
435 BM_elem_flag_set(f, BM_ELEM_TAG, keep_face);
436 }
437
441
442 if (fill_holes) {
443 BM_mesh_edgenet(bm, false, true);
447 "triangulate faces=%hf quad_method=%i ngon_method=%i",
449 0,
450 0);
451
455 "recalc_face_normals faces=%hf",
458 }
459}
460
462{
463 using namespace blender;
464 using namespace blender::ed;
465 const Scene &scene = *CTX_data_scene(C);
466 Main &bmain = *CTX_data_main(C);
468 View3D *v3d = CTX_wm_view3d(C);
469 Mesh *mesh = static_cast<Mesh *>(ob.data);
470
471 if (!mesh->attributes().contains(".sculpt_mask")) {
472 return OPERATOR_CANCELLED;
473 }
474
475 bool create_new_object = RNA_boolean_get(op->ptr, "new_object");
476 bool fill_holes = RNA_boolean_get(op->ptr, "fill_holes");
477 float mask_threshold = RNA_float_get(op->ptr, "mask_threshold");
478
479 Mesh *new_mesh = (Mesh *)BKE_id_copy(&bmain, &mesh->id);
480
481 /* Undo crashes when new object is created in the middle of a sculpt, see #87243. */
482 if (ob.mode == OB_MODE_SCULPT && !create_new_object) {
484 }
485
486 const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(new_mesh);
487 BMeshCreateParams bm_create_params{};
488 bm_create_params.use_toolflags = true;
489 BMesh *bm = BM_mesh_create(&allocsize, &bm_create_params);
490
491 BMeshFromMeshParams mesh_to_bm_params{};
492 mesh_to_bm_params.calc_face_normal = true;
493 BM_mesh_bm_from_me(bm, new_mesh, &mesh_to_bm_params);
494
495 slice_paint_mask(bm, false, fill_holes, mask_threshold);
496 BKE_id_free(&bmain, new_mesh);
497 BMeshToMeshParams bm_to_mesh_params{};
498 bm_to_mesh_params.calc_object_remap = false;
499 new_mesh = BKE_mesh_from_bmesh_nomain(bm, &bm_to_mesh_params, mesh);
501
502 if (create_new_object) {
503 ushort local_view_bits = 0;
504 if (v3d && v3d->localvd) {
505 local_view_bits = v3d->local_view_uid;
506 }
508 C, OB_MESH, nullptr, ob.loc, ob.rot, false, local_view_bits);
509 Mesh *new_ob_mesh = (Mesh *)BKE_id_copy(&bmain, &mesh->id);
510
511 const BMAllocTemplate allocsize_new_ob = BMALLOC_TEMPLATE_FROM_ME(new_ob_mesh);
512 bm = BM_mesh_create(&allocsize_new_ob, &bm_create_params);
513
514 BM_mesh_bm_from_me(bm, new_ob_mesh, &mesh_to_bm_params);
515
516 slice_paint_mask(bm, true, fill_holes, mask_threshold);
517 BKE_id_free(&bmain, new_ob_mesh);
518 new_ob_mesh = BKE_mesh_from_bmesh_nomain(bm, &bm_to_mesh_params, mesh);
520
521 /* Remove the mask from the new object so it can be sculpted directly after slicing. */
522 new_ob_mesh->attributes_for_write().remove(".sculpt_mask");
523
524 Mesh *new_mesh = static_cast<Mesh *>(new_ob->data);
525 BKE_mesh_nomain_to_mesh(new_ob_mesh, new_mesh, new_ob);
531 }
532
533 mesh = static_cast<Mesh *>(ob.data);
534 BKE_mesh_nomain_to_mesh(new_mesh, mesh, &ob);
535
536 if (ob.mode == OB_MODE_SCULPT) {
537 if (mesh->attributes().contains(".sculpt_face_set")) {
538 /* Assign a new Face Set ID to the new faces created by the slice operation. */
539 const int next_face_set_id = sculpt_paint::face_set::find_next_available_id(ob);
541 }
542 if (!create_new_object) {
545 }
546 }
547
551
552 return OPERATOR_FINISHED;
553}
554
556{
557 PropertyRNA *prop;
558
559 ot->name = "Mask Slice";
560 ot->description = "Slices the paint mask from the mesh";
561 ot->idname = "SCULPT_OT_paint_mask_slice";
562
565
567
569 ot->srna,
570 "mask_threshold",
571 0.5f,
572 0.0f,
573 1.0f,
574 "Threshold",
575 "Minimum mask value to consider the vertex valid to extract a face from the original mesh",
576 0.0f,
577 1.0f);
578 prop = RNA_def_boolean(
579 ot->srna, "fill_holes", true, "Fill Holes", "Fill holes after slicing the mask");
581 prop = RNA_def_boolean(ot->srna,
582 "new_object",
583 true,
584 "Slice to New Object",
585 "Create a new object from the sliced mask");
587}
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:132
BMEditMesh * BKE_editmesh_create(BMesh *bm)
Definition editmesh.cc:32
void BKE_id_free(Main *bmain, void *idv)
ID * BKE_id_copy(Main *bmain, const ID *id)
Definition lib_id.cc:782
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, bool process_shape_keys=true)
@ 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:324
void BKE_sculptsession_free_pbvh(Object &object)
Definition paint.cc:2286
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:46
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:1074
@ CD_PROP_FLOAT
@ CD_PROP_INT32
@ eModifierType_Solidify
@ OB_MODE_SCULPT
Object is a sort of wrapper for general info.
@ OB_MESH
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
bool ED_operator_object_active_editable_mesh(bContext *C)
void ED_undo_push_op(bContext *C, wmOperator *op)
Definition ed_undo.cc:359
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition RNA_types.hh:344
#define C
Definition RandGen.cpp:29
#define NC_GEOM
Definition WM_types.hh:393
#define ND_DATA
Definition WM_types.hh:509
@ OPTYPE_DEPENDS_ON_CURSOR
Definition WM_types.hh:218
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
#define ND_MODIFIER
Definition WM_types.hh:462
#define NC_OBJECT
Definition WM_types.hh:379
#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
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
BPy_StructRNA * depsgraph
AttributeSet attributes
nullptr float
bool edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char hflag, const bool use_normal_flip)
static bool geometry_extract_poll(bContext *C)
static wmOperatorStatus geometry_extract_apply(bContext *C, wmOperator *op, GeometryExtractTagMeshFunc *tag_fn, GeometryExtractParams *params)
static void geometry_extract_tag_face_set(BMesh *bm, GeometryExtractParams *params)
static wmOperatorStatus paint_mask_slice_exec(bContext *C, wmOperator *op)
void SCULPT_OT_face_set_extract(wmOperatorType *ot)
static void geometry_extract_props(StructRNA *srna)
static wmOperatorStatus paint_mask_extract_invoke(bContext *C, wmOperator *op, const wmEvent *e)
void(BMesh *, GeometryExtractParams *) GeometryExtractTagMeshFunc
static void geometry_extract_tag_masked_faces(BMesh *bm, GeometryExtractParams *params)
static wmOperatorStatus face_set_extract_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void SCULPT_OT_paint_mask_slice(wmOperatorType *ot)
static wmOperatorStatus paint_mask_extract_exec(bContext *C, wmOperator *op)
void SCULPT_OT_paint_mask_extract(wmOperatorType *ot)
static void slice_paint_mask(BMesh *bm, bool invert, bool fill_holes, float mask_threshold)
bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt,...)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
CCL_NAMESPACE_BEGIN ccl_device float invert(const float color, const float factor)
Definition invert.h:11
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
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 initialize_none_to_id(Mesh *mesh, int new_id)
int active_update_and_get(bContext *C, Object &ob, const float mval_fl[2])
void geometry_begin(const Scene &scene, Object &ob, const wmOperator *op)
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)
int verts_num
float loc[3]
float scale[3]
float rot[3]
struct SculptSession * sculpt
struct View3D * localvd
unsigned short local_view_uid
int ymin
int xmin
int xy[2]
Definition WM_types.hh:761
struct ReportList * reports
struct PointerRNA * ptr
i
Definition text_draw.cc:230
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition wm_files.cc:4237
wmOperatorStatus 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, std::optional< std::string > message)