Blender V4.3
MOD_multires.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstddef>
10
11#include "MEM_guardedalloc.h"
12
13#include "BLI_utildefines.h"
14
15#include "BLT_translation.hh"
16
17#include "DNA_defaults.h"
18#include "DNA_mesh_types.h"
19#include "DNA_object_types.h"
20#include "DNA_screen_types.h"
21
22#include "BKE_context.hh"
23#include "BKE_customdata.hh"
24#include "BKE_mesh.hh"
25#include "BKE_modifier.hh"
26#include "BKE_multires.hh"
27#include "BKE_paint.hh"
28#include "BKE_subdiv.hh"
29#include "BKE_subdiv_ccg.hh"
30#include "BKE_subdiv_deform.hh"
31#include "BKE_subdiv_mesh.hh"
32#include "BKE_subsurf.hh"
33
34#include "UI_interface.hh"
35#include "UI_resources.hh"
36
37#include "RNA_access.hh"
38#include "RNA_prototypes.hh"
39
40#include "WM_types.hh" /* For subdivide operator UI. */
41
43
44#include "MOD_ui_common.hh"
45
47 /* Cached subdivision surface descriptor, with topology and settings. */
49};
50
51static void init_data(ModifierData *md)
52{
54
56
58
59 /* Open subdivision panels by default. */
61}
62
63static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
64{
67 r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL;
68 }
69}
70
71static void copy_data(const ModifierData *md_src, ModifierData *md_dst, const int flag)
72{
73 BKE_modifier_copydata_generic(md_src, md_dst, flag);
74}
75
76static void free_runtime_data(void *runtime_data_v)
77{
78 if (runtime_data_v == nullptr) {
79 return;
80 }
81 MultiresRuntimeData *runtime_data = (MultiresRuntimeData *)runtime_data_v;
82 if (runtime_data->subdiv != nullptr) {
84 }
85 MEM_freeN(runtime_data);
86}
87
93
95{
97 if (runtime_data == nullptr) {
98 runtime_data = static_cast<MultiresRuntimeData *>(
99 MEM_callocN(sizeof(*runtime_data), __func__));
100 mmd->modifier.runtime = runtime_data;
101 }
102 return runtime_data;
103}
104
105/* Main goal of this function is to give usable subdivision surface descriptor
106 * which matches settings and topology. */
109 const blender::bke::subdiv::Settings *subdiv_settings,
110 const Mesh *mesh)
111{
114 runtime_data->subdiv, subdiv_settings, mesh);
115 runtime_data->subdiv = subdiv;
116 return subdiv;
117}
118
119/* Subdivide into fully qualified mesh. */
120
122 const ModifierEvalContext *ctx,
123 Mesh *mesh,
125{
126 Mesh *result = mesh;
127 const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
128 const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
129 const bool ignore_control_edges = (ctx->flag & MOD_APPLY_TO_ORIGINAL);
130 const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
131 Object *object = ctx->object;
134 scene,
135 object,
136 mmd,
137 use_render_params,
138 ignore_simplify,
139 ignore_control_edges);
140 if (mesh_settings.resolution < 3) {
141 return result;
142 }
144 result = blender::bke::subdiv::subdiv_to_mesh(subdiv, &mesh_settings, mesh);
145 return result;
146}
147
148/* Subdivide into CCG. */
149
151 const MultiresModifierData *mmd,
152 const ModifierEvalContext *ctx,
153 Mesh *mesh)
154{
155 const bool has_mask = CustomData_has_layer(&mesh->corner_data, CD_GRID_PAINT_MASK);
156 const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
157 const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
158 const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
159 Object *object = ctx->object;
160 const int level = multires_get_level(scene, object, mmd, use_render_params, ignore_simplify);
161 settings->resolution = (1 << level) + 1;
162 settings->need_normal = true;
163 settings->need_mask = has_mask;
164}
165
167 const ModifierEvalContext *ctx,
168 Mesh *mesh,
170{
171 Mesh *result = mesh;
172 SubdivToCCGSettings ccg_settings;
173 multires_ccg_settings_init(&ccg_settings, mmd, ctx, mesh);
174 if (ccg_settings.resolution < 3) {
175 return result;
176 }
178 result = BKE_subdiv_to_ccg_mesh(*subdiv, ccg_settings, *mesh);
179
180 /* NOTE: CCG becomes an owner of Subdiv descriptor, so can not share
181 * this pointer. Not sure if it's needed, but might have a second look
182 * on the ownership model here. */
183 MultiresRuntimeData *runtime_data = static_cast<MultiresRuntimeData *>(mmd->modifier.runtime);
184 runtime_data->subdiv = nullptr;
185
186 return result;
187}
188
189static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
190{
191 Mesh *result = mesh;
192#if !defined(WITH_OPENSUBDIV)
193 BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv");
194 return result;
195#endif
197 blender::bke::subdiv::Settings subdiv_settings;
198 BKE_multires_subdiv_settings_init(&subdiv_settings, mmd);
199 if (subdiv_settings.level == 0) {
200 return result;
201 }
202 MultiresRuntimeData *runtime_data = multires_ensure_runtime(mmd);
203 blender::bke::subdiv::Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh);
204 if (subdiv == nullptr) {
205 /* Happens on bad topology, also on empty input mesh. */
206 return result;
207 }
208 const bool use_clnors = mmd->flags & eMultiresModifierFlag_UseCustomNormals &&
209 mesh->normals_domain() == blender::bke::MeshNormalDomain::Corner;
210 /* NOTE: Orco needs final coordinates on CPU side, which are expected to be
211 * accessible via mesh vertices. For this reason we do not evaluate multires to
212 * grids when orco is requested. */
213 const bool for_orco = (ctx->flag & MOD_APPLY_ORCO) != 0;
214 /* Needed when rendering or baking will in sculpt mode. */
215 const bool for_render = (ctx->flag & MOD_APPLY_RENDER) != 0;
216
217 const bool sculpt_base_mesh = mmd->flags & eMultiresModifierFlag_UseSculptBaseMesh;
218
219 if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco && !for_render && !sculpt_base_mesh) {
220 /* NOTE: CCG takes ownership over Subdiv. */
221 result = multires_as_ccg(mmd, ctx, mesh, subdiv);
222 result->runtime->subdiv_ccg_tot_level = mmd->totlvl;
223 /* TODO(sergey): Usually it is sculpt stroke's update variants which
224 * takes care of this, but is possible that we need this before the
225 * stroke: i.e. when exiting blender right after stroke is done.
226 * Annoying and not so much black-boxed as far as sculpting goes, and
227 * surely there is a better way of solving this. */
228 if (ctx->object->sculpt != nullptr) {
229 SculptSession *sculpt_session = ctx->object->sculpt;
230 sculpt_session->subdiv_ccg = result->runtime->subdiv_ccg.get();
231 sculpt_session->multires.active = true;
232 sculpt_session->multires.modifier = mmd;
233 sculpt_session->multires.level = mmd->sculptlvl;
234 }
235 // blender::bke::subdiv::stats_print(&subdiv->stats);
236 }
237 else {
238 if (use_clnors) {
239 void *data = CustomData_add_layer(
240 &mesh->corner_data, CD_NORMAL, CD_CONSTRUCT, mesh->corners_num);
241 memcpy(data, mesh->corner_normals().data(), mesh->corner_normals().size_in_bytes());
242 }
243
244 result = multires_as_mesh(mmd, ctx, mesh, subdiv);
245
246 if (use_clnors) {
247 float(*corner_normals)[3] = static_cast<float(*)[3]>(
248 CustomData_get_layer_for_write(&result->corner_data, CD_NORMAL, result->corners_num));
249 BKE_mesh_set_custom_normals_normalized(result, corner_normals);
250 CustomData_free_layers(&result->corner_data, CD_NORMAL, result->corners_num);
251 }
252 // blender::bke::subdiv::stats_print(&subdiv->stats);
253 if (subdiv != runtime_data->subdiv) {
255 }
256 }
257 return result;
258}
259
261 const ModifierEvalContext *ctx,
262 Mesh *mesh,
265
266{
267#if !defined(WITH_OPENSUBDIV)
268 BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv");
269 return;
270#endif
271
273
274 blender::bke::subdiv::Settings subdiv_settings;
275 BKE_multires_subdiv_settings_init(&subdiv_settings, mmd);
276 if (subdiv_settings.level == 0) {
277 return;
278 }
279
280 SubdivToCCGSettings ccg_settings;
281 multires_ccg_settings_init(&ccg_settings, mmd, ctx, mesh);
282 if (ccg_settings.resolution < 3) {
283 return;
284 }
285
286 MultiresRuntimeData *runtime_data = multires_ensure_runtime(mmd);
287 blender::bke::subdiv::Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh);
288 if (subdiv == nullptr) {
289 /* Happens on bad topology, also on empty input mesh. */
290 return;
291 }
293 blender::bke::subdiv::deform_coarse_vertices(subdiv, mesh, positions);
294 if (subdiv != runtime_data->subdiv) {
296 }
297}
298
299static void panel_draw(const bContext *C, Panel *panel)
300{
301 uiLayout *col;
302 uiLayout *layout = panel->layout;
303
305
306 uiLayoutSetPropSep(layout, true);
307
308 col = uiLayoutColumn(layout, true);
309 uiItemR(col, ptr, "levels", UI_ITEM_NONE, IFACE_("Level Viewport"), ICON_NONE);
310 uiItemR(col, ptr, "sculpt_levels", UI_ITEM_NONE, IFACE_("Sculpt"), ICON_NONE);
311 uiItemR(col, ptr, "render_levels", UI_ITEM_NONE, IFACE_("Render"), ICON_NONE);
312
313 const bool is_sculpt_mode = CTX_data_active_object(C)->mode & OB_MODE_SCULPT;
314 uiBlock *block = uiLayoutGetBlock(panel->layout);
315 UI_block_lock_set(block, !is_sculpt_mode, N_("Sculpt Base Mesh"));
316 uiItemR(col, ptr, "use_sculpt_base_mesh", UI_ITEM_NONE, IFACE_("Sculpt Base Mesh"), ICON_NONE);
317 UI_block_lock_clear(block);
318
319 uiItemR(layout, ptr, "show_only_control_edges", UI_ITEM_NONE, nullptr, ICON_NONE);
320
321 modifier_panel_end(layout, ptr);
322}
323
324static void subdivisions_panel_draw(const bContext * /*C*/, Panel *panel)
325{
326 uiLayout *row;
327 uiLayout *layout = panel->layout;
328
329 PointerRNA ob_ptr;
331
332 uiLayoutSetEnabled(layout, RNA_enum_get(&ob_ptr, "mode") != OB_MODE_EDIT);
333
335
347 PointerRNA op_ptr;
348 uiItemFullO(layout,
349 "OBJECT_OT_multires_subdivide",
350 IFACE_("Subdivide"),
351 ICON_NONE,
352 nullptr,
355 &op_ptr);
357 RNA_string_set(&op_ptr, "modifier", ((ModifierData *)mmd)->name);
358
359 row = uiLayoutRow(layout, false);
360 uiItemFullO(row,
361 "OBJECT_OT_multires_subdivide",
362 IFACE_("Simple"),
363 ICON_NONE,
364 nullptr,
367 &op_ptr);
368 RNA_enum_set(&op_ptr, "mode", MULTIRES_SUBDIVIDE_SIMPLE);
369 RNA_string_set(&op_ptr, "modifier", ((ModifierData *)mmd)->name);
370 uiItemFullO(row,
371 "OBJECT_OT_multires_subdivide",
372 IFACE_("Linear"),
373 ICON_NONE,
374 nullptr,
377 &op_ptr);
378 RNA_enum_set(&op_ptr, "mode", MULTIRES_SUBDIVIDE_LINEAR);
379 RNA_string_set(&op_ptr, "modifier", ((ModifierData *)mmd)->name);
380
381 uiItemS(layout);
382
383 uiItemO(layout, IFACE_("Unsubdivide"), ICON_NONE, "OBJECT_OT_multires_unsubdivide");
384 uiItemO(layout, IFACE_("Delete Higher"), ICON_NONE, "OBJECT_OT_multires_higher_levels_delete");
385}
386
387static void shape_panel_draw(const bContext * /*C*/, Panel *panel)
388{
389 uiLayout *row;
390 uiLayout *layout = panel->layout;
391
392 PointerRNA ob_ptr;
394
395 uiLayoutSetEnabled(layout, RNA_enum_get(&ob_ptr, "mode") != OB_MODE_EDIT);
396
397 row = uiLayoutRow(layout, false);
398 uiItemO(row, IFACE_("Reshape"), ICON_NONE, "OBJECT_OT_multires_reshape");
399 uiItemO(row, IFACE_("Apply Base"), ICON_NONE, "OBJECT_OT_multires_base_apply");
400}
401
402static void generate_panel_draw(const bContext * /*C*/, Panel *panel)
403{
404 uiLayout *col, *row;
405 uiLayout *layout = panel->layout;
406
409
410 bool is_external = RNA_boolean_get(ptr, "is_external");
411
412 if (mmd->totlvl == 0) {
413 uiItemO(
414 layout, IFACE_("Rebuild Subdivisions"), ICON_NONE, "OBJECT_OT_multires_rebuild_subdiv");
415 }
416
417 col = uiLayoutColumn(layout, false);
418 row = uiLayoutRow(col, false);
419 if (is_external) {
420 uiItemO(row, IFACE_("Pack External"), ICON_NONE, "OBJECT_OT_multires_external_pack");
421 uiLayoutSetPropSep(col, true);
422 row = uiLayoutRow(col, false);
423 uiItemR(row, ptr, "filepath", UI_ITEM_NONE, nullptr, ICON_NONE);
424 }
425 else {
426 uiItemO(col, IFACE_("Save External..."), ICON_NONE, "OBJECT_OT_multires_external_save");
427 }
428}
429
430static void advanced_panel_draw(const bContext * /*C*/, Panel *panel)
431{
432 uiLayout *col;
433 uiLayout *layout = panel->layout;
434
436
437 bool has_displacement = RNA_int_get(ptr, "total_levels") != 0;
438
439 uiLayoutSetPropSep(layout, true);
440
441 uiLayoutSetActive(layout, !has_displacement);
442
443 uiItemR(layout, ptr, "quality", UI_ITEM_NONE, nullptr, ICON_NONE);
444
445 col = uiLayoutColumn(layout, false);
446 uiLayoutSetActive(col, true);
447 uiItemR(col, ptr, "uv_smooth", UI_ITEM_NONE, nullptr, ICON_NONE);
448 uiItemR(col, ptr, "boundary_smooth", UI_ITEM_NONE, nullptr, ICON_NONE);
449
450 uiItemR(layout, ptr, "use_creases", UI_ITEM_NONE, nullptr, ICON_NONE);
451 uiItemR(layout, ptr, "use_custom_normals", UI_ITEM_NONE, nullptr, ICON_NONE);
452}
453
454static void panel_register(ARegionType *region_type)
455{
458 region_type, "subdivide", "Subdivision", nullptr, subdivisions_panel_draw, panel_type);
459 modifier_subpanel_register(region_type, "shape", "Shape", nullptr, shape_panel_draw, panel_type);
461 region_type, "generate", "Generate", nullptr, generate_panel_draw, panel_type);
463 region_type, "advanced", "Advanced", nullptr, advanced_panel_draw, panel_type);
464}
465
467 /*idname*/ "Multires",
468 /*name*/ N_("Multires"),
469 /*struct_name*/ "MultiresModifierData",
470 /*struct_size*/ sizeof(MultiresModifierData),
471 /*srna*/ &RNA_MultiresModifier,
475 /*icon*/ ICON_MOD_MULTIRES,
476
477 /*copy_data*/ copy_data,
478
479 /*deform_verts*/ nullptr,
480 /*deform_matrices*/ deform_matrices,
481 /*deform_verts_EM*/ nullptr,
482 /*deform_matrices_EM*/ nullptr,
483 /*modify_mesh*/ modify_mesh,
484 /*modify_geometry_set*/ nullptr,
485
486 /*init_data*/ init_data,
487 /*required_data_mask*/ required_data_mask,
488 /*free_data*/ free_data,
489 /*is_disabled*/ nullptr,
490 /*update_depsgraph*/ nullptr,
491 /*depends_on_time*/ nullptr,
492 /*depends_on_normals*/ nullptr,
493 /*foreach_ID_link*/ nullptr,
494 /*foreach_tex_link*/ nullptr,
495 /*free_runtime_data*/ free_runtime_data,
496 /*panel_register*/ panel_register,
497 /*blend_write*/ nullptr,
498 /*blend_read*/ nullptr,
499 /*foreach_cache*/ nullptr,
500};
Object * CTX_data_active_object(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
@ CD_CONSTRUCT
void CustomData_free_layers(CustomData *data, eCustomDataType type, int totelem)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
void BKE_mesh_set_custom_normals_normalized(Mesh *mesh, float(*r_custom_loop_normals)[3])
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_SupportsMapping
@ eModifierTypeFlag_RequiresOriginalData
@ eModifierTypeFlag_AcceptsMesh
void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
@ MOD_APPLY_TO_ORIGINAL
@ MOD_APPLY_RENDER
@ MOD_APPLY_IGNORE_SIMPLIFY
@ MOD_APPLY_ORCO
void BKE_multires_subdiv_settings_init(blender::bke::subdiv::Settings *settings, const MultiresModifierData *mmd)
@ MULTIRES_SUBDIVIDE_LINEAR
@ MULTIRES_SUBDIVIDE_CATMULL_CLARK
@ MULTIRES_SUBDIVIDE_SIMPLE
void BKE_multires_subdiv_mesh_settings_init(blender::bke::subdiv::ToMeshSettings *mesh_settings, const Scene *scene, const Object *object, const MultiresModifierData *mmd, bool use_render_params, bool ignore_simplify, bool ignore_control_edges)
int multires_get_level(const Scene *scene, const Object *ob, const MultiresModifierData *mmd, bool render, bool ignore_simplify)
Definition multires.cc:331
Mesh * BKE_subdiv_to_ccg_mesh(blender::bke::subdiv::Subdiv &subdiv, const SubdivToCCGSettings &settings, const Mesh &coarse_mesh)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define IFACE_(msgid)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
@ CD_GRID_PAINT_MASK
#define CD_MASK_CUSTOMLOOPNORMAL
#define DNA_struct_default_get(struct_name)
@ eMultiresModifierFlag_UseSculptBaseMesh
@ eMultiresModifierFlag_UseCustomNormals
struct MultiresModifierData MultiresModifierData
@ eModifierType_Multires
@ OB_MODE_EDIT
@ OB_MODE_SCULPT
Object is a sort of wrapper for general info.
@ UI_PANEL_DATA_EXPAND_ROOT
@ UI_SUBPANEL_DATA_EXPAND_1
Read Guarded memory(de)allocation.
static void init_data(ModifierData *md)
static void generate_panel_draw(const bContext *, Panel *panel)
static blender::bke::subdiv::Subdiv * subdiv_descriptor_ensure(MultiresModifierData *mmd, const blender::bke::subdiv::Settings *subdiv_settings, const Mesh *mesh)
static void panel_register(ARegionType *region_type)
static void free_runtime_data(void *runtime_data_v)
static Mesh * multires_as_ccg(MultiresModifierData *mmd, const ModifierEvalContext *ctx, Mesh *mesh, blender::bke::subdiv::Subdiv *subdiv)
static void copy_data(const ModifierData *md_src, ModifierData *md_dst, const int flag)
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
ModifierTypeInfo modifierType_Multires
static void free_data(ModifierData *md)
static Mesh * multires_as_mesh(MultiresModifierData *mmd, const ModifierEvalContext *ctx, Mesh *mesh, blender::bke::subdiv::Subdiv *subdiv)
static void shape_panel_draw(const bContext *, Panel *panel)
static void advanced_panel_draw(const bContext *, Panel *panel)
static void subdivisions_panel_draw(const bContext *, Panel *panel)
static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
static void multires_ccg_settings_init(SubdivToCCGSettings *settings, const MultiresModifierData *mmd, const ModifierEvalContext *ctx, Mesh *mesh)
static MultiresRuntimeData * multires_ensure_runtime(MultiresModifierData *mmd)
static void deform_matrices(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, blender::MutableSpan< blender::float3 > positions, blender::MutableSpan< blender::float3x3 >)
static void panel_draw(const bContext *C, Panel *panel)
PanelType * modifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelType *parent)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
void UI_block_lock_clear(uiBlock *block)
void uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, IDProperty *properties, wmOperatorCallContext context, eUI_Item_Flag flag, PointerRNA *r_opptr)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
#define UI_ITEM_NONE
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ WM_OP_EXEC_DEFAULT
Definition WM_types.hh:225
draw_view in_light_buf[] float
uint col
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void displacement_attach_from_multires(Subdiv *subdiv, Mesh *mesh, const MultiresModifierData *mmd)
void free(Subdiv *subdiv)
Definition subdiv.cc:192
void deform_coarse_vertices(Subdiv *subdiv, const Mesh *coarse_mesh, MutableSpan< float3 > vert_positions)
Mesh * subdiv_to_mesh(Subdiv *subdiv, const ToMeshSettings *settings, const Mesh *coarse_mesh)
Subdiv * update_from_mesh(Subdiv *subdiv, const Settings *settings, const Mesh *mesh)
Definition subdiv.cc:181
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
int RNA_int_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
ModifierApplyFlag flag
blender::bke::subdiv::Subdiv * subdiv
struct SculptSession * sculpt
struct uiLayout * layout
void * data
Definition RNA_types.hh:42
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:405
struct SculptSession::@48 multires
MultiresModifierData * modifier
Definition BKE_paint.hh:383
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4126
uint8_t flag
Definition wm_window.cc:138