Blender V4.5
MOD_bevel.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
8
9#include <algorithm>
10
11#include "BLI_math_vector.h"
12#include "BLI_utildefines.h"
13
14#include "BLT_translation.hh"
15
17#include "DNA_defaults.h"
18#include "DNA_object_types.h"
19#include "DNA_screen_types.h"
20
21#include "BKE_attribute.hh"
22#include "BKE_curveprofile.h"
23#include "BKE_deform.hh"
24#include "BKE_mesh.hh"
25#include "BKE_modifier.hh"
26
27#include "UI_interface.hh"
28#include "UI_resources.hh"
29
30#include "RNA_access.hh"
31#include "RNA_define.hh"
32#include "RNA_prototypes.hh"
33
34#include "MOD_ui_common.hh"
35#include "MOD_util.hh"
36
37#include "BLO_read_write.hh"
38
39#include "GEO_randomize.hh"
40
41#include "bmesh.hh"
42#include "bmesh_tools.hh"
43
54
55static void copy_data(const ModifierData *md_src, ModifierData *md_dst, const int flag)
56{
57 const BevelModifierData *bmd_src = (const BevelModifierData *)md_src;
58 BevelModifierData *bmd_dst = (BevelModifierData *)md_dst;
59
60 BKE_modifier_copydata_generic(md_src, md_dst, flag);
62}
63
64static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
65{
67
68 /* Ask for vertex-groups if we need them. */
69 if (bmd->defgrp_name[0] != '\0') {
70 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
71 }
72}
73
74static std::string ensure_weight_attribute_meta_data(Mesh &mesh,
75 const blender::StringRef name,
76 const blender::bke::AttrDomain domain,
77 bool &r_attr_converted)
78{
79 using namespace blender;
81 return "";
82 }
83 bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
84 const std::optional<bke::AttributeMetaData> meta_data = attributes.lookup_meta_data(name);
85 if (!meta_data) {
86 r_attr_converted = false;
87 return name;
88 }
89 if (meta_data->domain == domain && meta_data->data_type == CD_PROP_FLOAT) {
90 r_attr_converted = false;
91 return name;
92 }
93
94 Array<float> weight(attributes.domain_size(domain));
95 attributes.lookup<float>(name, domain).varray.materialize(weight);
96 const std::string new_name = BKE_attribute_calc_unique_name(AttributeOwner::from_id(&mesh.id),
97 name);
98 attributes.add<float>(
99 new_name, domain, bke::AttributeInitVArray(VArray<float>::ForSpan(weight)));
100 r_attr_converted = true;
101 return new_name;
102}
103
104/*
105 * This calls the new bevel code (added since 2.64)
106 */
107static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
108{
109 using namespace blender;
110 if (mesh->verts_num == 0) {
111 return mesh;
112 }
113 Mesh *result;
114 BMesh *bm;
115 BMIter iter;
116 BMEdge *e;
117 BMVert *v;
118 float weight, weight2;
119 int vgroup = -1;
120 const MDeformVert *dvert = nullptr;
122 const float threshold = cosf(bmd->bevel_angle + 0.000000175f);
123 const bool do_clamp = !(bmd->flags & MOD_BEVEL_OVERLAP_OK);
124 const int offset_type = bmd->val_flags;
125 const int profile_type = bmd->profile_type;
126 const float value = bmd->value;
127 const int mat = std::clamp(int(bmd->mat), -1, ctx->object->totcol - 1);
128 const bool loop_slide = (bmd->flags & MOD_BEVEL_EVEN_WIDTHS) == 0;
129 const bool mark_seam = (bmd->edge_flags & MOD_BEVEL_MARK_SEAM);
130 const bool mark_sharp = (bmd->edge_flags & MOD_BEVEL_MARK_SHARP);
131 bool harden_normals = (bmd->flags & MOD_BEVEL_HARDEN_NORMALS);
132 const int face_strength_mode = bmd->face_str_mode;
133 const int miter_outer = bmd->miter_outer;
134 const int miter_inner = bmd->miter_inner;
135 const float spread = bmd->spread;
136 const bool invert_vgroup = (bmd->flags & MOD_BEVEL_INVERT_VGROUP) != 0;
137
138 BMeshCreateParams create_params{};
139 BMeshFromMeshParams convert_params{};
140 convert_params.calc_face_normal = true;
141 convert_params.calc_vert_normal = true;
142 convert_params.add_key_index = false;
143 convert_params.use_shapekey = false;
144 convert_params.active_shapekey = 0;
145 convert_params.cd_mask_extra.vmask = CD_MASK_ORIGINDEX;
146 convert_params.cd_mask_extra.emask = CD_MASK_ORIGINDEX;
147 convert_params.cd_mask_extra.pmask = CD_MASK_ORIGINDEX;
148
149 bool vert_weight_converted;
150 const std::string vert_weight_name = ensure_weight_attribute_meta_data(
151 *mesh, bmd->vertex_weight_name, bke::AttrDomain::Point, vert_weight_converted);
152 bool edge_weight_converted;
153 const std::string edge_weight_name = ensure_weight_attribute_meta_data(
154 *mesh, bmd->edge_weight_name, bke::AttrDomain::Edge, edge_weight_converted);
155
156 bm = BKE_mesh_to_bmesh_ex(mesh, &create_params, &convert_params);
157
158 if ((bmd->lim_flags & MOD_BEVEL_VGROUP) && bmd->defgrp_name[0]) {
159 MOD_get_vgroup(ctx->object, mesh, bmd->defgrp_name, &dvert, &vgroup);
160 }
161
162 const int bweight_offset_vert = CustomData_get_offset_named(
163 &bm->vdata, CD_PROP_FLOAT, vert_weight_name);
164 const int bweight_offset_edge = CustomData_get_offset_named(
165 &bm->edata, CD_PROP_FLOAT, edge_weight_name);
166
168 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
169 if (bmd->lim_flags & MOD_BEVEL_WEIGHT) {
170 weight = bweight_offset_vert == -1 ? 0.0f : BM_ELEM_CD_GET_FLOAT(v, bweight_offset_vert);
171 if (weight == 0.0f) {
172 continue;
173 }
174 }
175 else {
177 dvert, BM_elem_index_get(v), vgroup, invert_vgroup);
178 /* Check is against 0.5 rather than != 0.0 because cascaded bevel modifiers will
179 * interpolate weights for newly created vertices, and may cause unexpected "selection" */
180 if (weight < 0.5f) {
181 continue;
182 }
183 }
185 }
186 }
187 else if (bmd->lim_flags & MOD_BEVEL_ANGLE) {
188 BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
189 /* check for 1 edge having 2 face users */
190 BMLoop *l_a, *l_b;
191 if (BM_edge_loop_pair(e, &l_a, &l_b)) {
192 if (dot_v3v3(l_a->f->no, l_b->f->no) < threshold) {
196 }
197 }
198 }
199 }
200 else {
201 /* crummy, is there a way just to operator on all? - campbell */
202 BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
203 if (BM_edge_is_manifold(e)) {
204 if (bmd->lim_flags & MOD_BEVEL_WEIGHT) {
205 weight = bweight_offset_edge == -1 ? 0.0f : BM_ELEM_CD_GET_FLOAT(e, bweight_offset_edge);
206 if (weight == 0.0f) {
207 continue;
208 }
209 }
210 else {
212 dvert, BM_elem_index_get(e->v1), vgroup, invert_vgroup);
214 dvert, BM_elem_index_get(e->v2), vgroup, invert_vgroup);
215 if (weight < 0.5f || weight2 < 0.5f) {
216 continue;
217 }
218 }
222 }
223 }
224 }
225
227 value,
228 offset_type,
229 profile_type,
230 bmd->res,
231 bmd->profile,
232 bmd->affect_type,
234 do_clamp,
235 dvert,
236 vgroup,
237 mat,
238 loop_slide,
239 mark_seam,
240 mark_sharp,
241 harden_normals,
242 face_strength_mode,
243 miter_outer,
244 miter_inner,
245 spread,
246 bmd->custom_profile,
247 bmd->vmesh_method,
248 bweight_offset_vert,
249 bweight_offset_edge);
250
252
253 /* Make sure we never allocated these. */
254 BLI_assert(bm->vtoolflagpool == nullptr && bm->etoolflagpool == nullptr &&
255 bm->ftoolflagpool == nullptr);
256
258
259 if (vert_weight_converted) {
260 result->attributes_for_write().remove(vert_weight_name);
261 }
262 if (edge_weight_converted) {
263 result->attributes_for_write().remove(edge_weight_name);
264 }
265
267
268 return result;
269}
270
276
277static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
278{
280 return (bmd->value == 0.0f);
281}
282
283static void panel_draw(const bContext * /*C*/, Panel *panel)
284{
285 uiLayout *col, *sub;
286 uiLayout *layout = panel->layout;
287
288 PointerRNA ob_ptr;
290
291 bool edge_bevel = RNA_enum_get(ptr, "affect") != MOD_BEVEL_AFFECT_VERTICES;
292
293 layout->prop(ptr, "affect", UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE);
294
295 uiLayoutSetPropSep(layout, true);
296
297 col = &layout->column(false);
298 col->prop(ptr, "offset_type", UI_ITEM_NONE, std::nullopt, ICON_NONE);
299 if (RNA_enum_get(ptr, "offset_type") == BEVEL_AMT_PERCENT) {
300 col->prop(ptr, "width_pct", UI_ITEM_NONE, std::nullopt, ICON_NONE);
301 }
302 else {
303 col->prop(ptr, "width", UI_ITEM_NONE, IFACE_("Amount"), ICON_NONE);
304 }
305
306 layout->prop(ptr, "segments", UI_ITEM_NONE, std::nullopt, ICON_NONE);
307
308 layout->separator();
309
310 col = &layout->column(false);
311 col->prop(ptr, "limit_method", UI_ITEM_NONE, std::nullopt, ICON_NONE);
312 int limit_method = RNA_enum_get(ptr, "limit_method");
313 if (limit_method == MOD_BEVEL_ANGLE) {
314 sub = &col->column(false);
315 uiLayoutSetActive(sub, edge_bevel);
316 col->prop(ptr, "angle_limit", UI_ITEM_NONE, std::nullopt, ICON_NONE);
317 }
318 else if (limit_method == MOD_BEVEL_WEIGHT) {
319 const char *prop_name = edge_bevel ? "edge_weight" : "vertex_weight";
320 col->prop(ptr, prop_name, UI_ITEM_NONE, std::nullopt, ICON_NONE);
321 }
322 else if (limit_method == MOD_BEVEL_VGROUP) {
323 modifier_vgroup_ui(col, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", std::nullopt);
324 }
325
327}
328
329static void profile_panel_draw(const bContext * /*C*/, Panel *panel)
330{
331 uiLayout *row;
332 uiLayout *layout = panel->layout;
333
335
336 int profile_type = RNA_enum_get(ptr, "profile_type");
337 int miter_inner = RNA_enum_get(ptr, "miter_inner");
338 int miter_outer = RNA_enum_get(ptr, "miter_outer");
339 bool edge_bevel = RNA_enum_get(ptr, "affect") != MOD_BEVEL_AFFECT_VERTICES;
340
341 layout->prop(ptr, "profile_type", UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE);
342
343 uiLayoutSetPropSep(layout, true);
344
346 row = &layout->row(false);
348 row,
349 profile_type == MOD_BEVEL_PROFILE_SUPERELLIPSE ||
350 (profile_type == MOD_BEVEL_PROFILE_CUSTOM && edge_bevel &&
351 !((miter_inner == MOD_BEVEL_MITER_SHARP) && (miter_outer == MOD_BEVEL_MITER_SHARP))));
352 row->prop(ptr,
353 "profile",
355 (profile_type == MOD_BEVEL_PROFILE_SUPERELLIPSE) ? IFACE_("Shape") :
356 IFACE_("Miter Shape"),
357 ICON_NONE);
358
359 if (profile_type == MOD_BEVEL_PROFILE_CUSTOM) {
360 uiLayout *sub = &layout->column(false);
361 uiLayoutSetPropDecorate(sub, false);
362 uiTemplateCurveProfile(sub, ptr, "custom_profile");
363 }
364 }
365}
366
367static void geometry_panel_draw(const bContext * /*C*/, Panel *panel)
368{
369 uiLayout *row;
370 uiLayout *layout = panel->layout;
371
373
374 bool edge_bevel = RNA_enum_get(ptr, "affect") != MOD_BEVEL_AFFECT_VERTICES;
375
376 uiLayoutSetPropSep(layout, true);
377
378 row = &layout->row(false);
379 uiLayoutSetActive(row, edge_bevel);
380 row->prop(ptr, "miter_outer", UI_ITEM_NONE, IFACE_("Miter Outer"), ICON_NONE);
381 row = &layout->row(false);
382 uiLayoutSetActive(row, edge_bevel);
383 row->prop(ptr, "miter_inner", UI_ITEM_NONE, IFACE_("Inner"), ICON_NONE);
384 if (RNA_enum_get(ptr, "miter_inner") == BEVEL_MITER_ARC) {
385 row = &layout->row(false);
386 uiLayoutSetActive(row, edge_bevel);
387 row->prop(ptr, "spread", UI_ITEM_NONE, std::nullopt, ICON_NONE);
388 }
389 layout->separator();
390
391 row = &layout->row(false);
392 uiLayoutSetActive(row, edge_bevel);
393 row->prop(ptr, "vmesh_method", UI_ITEM_NONE, IFACE_("Intersections"), ICON_NONE);
394 layout->prop(ptr, "use_clamp_overlap", UI_ITEM_NONE, std::nullopt, ICON_NONE);
395 row = &layout->row(false);
396 uiLayoutSetActive(row, edge_bevel);
397 row->prop(ptr, "loop_slide", UI_ITEM_NONE, std::nullopt, ICON_NONE);
398}
399
400static void shading_panel_draw(const bContext * /*C*/, Panel *panel)
401{
402 uiLayout *col;
403 uiLayout *layout = panel->layout;
404
406
407 bool edge_bevel = RNA_enum_get(ptr, "affect") != MOD_BEVEL_AFFECT_VERTICES;
408
409 uiLayoutSetPropSep(layout, true);
410
411 layout->prop(ptr, "harden_normals", UI_ITEM_NONE, std::nullopt, ICON_NONE);
412
413 col = &layout->column(true, IFACE_("Mark"));
414 uiLayoutSetActive(col, edge_bevel);
415 col->prop(ptr, "mark_seam", UI_ITEM_NONE, IFACE_("Seam"), ICON_NONE);
416 col->prop(ptr, "mark_sharp", UI_ITEM_NONE, IFACE_("Sharp"), ICON_NONE);
417
418 layout->prop(ptr, "material", UI_ITEM_NONE, std::nullopt, ICON_NONE);
419 layout->prop(ptr, "face_strength_mode", UI_ITEM_NONE, std::nullopt, ICON_NONE);
420}
421
422static void panel_register(ARegionType *region_type)
423{
426 region_type, "profile", "Profile", nullptr, profile_panel_draw, panel_type);
428 region_type, "geometry", "Geometry", nullptr, geometry_panel_draw, panel_type);
430 region_type, "shading", "Shading", nullptr, shading_panel_draw, panel_type);
431}
432
433static void blend_write(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
434{
435 const BevelModifierData *bmd = (const BevelModifierData *)md;
436
438
439 if (bmd->custom_profile) {
441 }
442}
443
444static void blend_read(BlendDataReader *reader, ModifierData *md)
445{
447
449 if (bmd->custom_profile) {
451 }
452}
453
455 /*idname*/ "Bevel",
456 /*name*/ N_("Bevel"),
457 /*struct_name*/ "BevelModifierData",
458 /*struct_size*/ sizeof(BevelModifierData),
459 /*srna*/ &RNA_BevelModifier,
463 /*icon*/ ICON_MOD_BEVEL,
464 /*copy_data*/ copy_data,
465 /*deform_verts*/ nullptr,
466 /*deform_matrices*/ nullptr,
467 /*deform_verts_EM*/ nullptr,
468 /*deform_matrices_EM*/ nullptr,
469 /*modify_mesh*/ modify_mesh,
470 /*modify_geometry_set*/ nullptr,
471 /*init_data*/ init_data,
472 /*required_data_mask*/ required_data_mask,
473 /*free_data*/ free_data,
474 /*is_disabled*/ is_disabled,
475 /*update_depsgraph*/ nullptr,
476 /*depends_on_time*/ nullptr,
477 /*depends_on_normals*/ nullptr,
478 /*foreach_ID_link*/ nullptr,
479 /*foreach_tex_link*/ nullptr,
480 /*free_runtime_data*/ nullptr,
481 /*panel_register*/ panel_register,
482 /*blend_write*/ blend_write,
483 /*blend_read*/ blend_read,
484 /*foreach_cache*/ nullptr,
485};
std::string BKE_attribute_calc_unique_name(const AttributeOwner &owner, blender::StringRef name)
Definition attribute.cc:383
struct CurveProfile * BKE_curveprofile_copy(const struct CurveProfile *profile)
void BKE_curveprofile_blend_read(struct BlendDataReader *reader, struct CurveProfile *profile)
struct CurveProfile * BKE_curveprofile_add(eCurveProfilePresets preset)
void BKE_curveprofile_blend_write(struct BlendWriter *writer, const struct CurveProfile *profile)
void BKE_curveprofile_free(struct CurveProfile *profile)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
support for deformation groups and hooks.
float BKE_defvert_array_find_weight_safe(const MDeformVert *dvert, int index, int defgroup, bool invert)
Definition deform.cc:769
Mesh * BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings)
BMesh * BKE_mesh_to_bmesh_ex(const Mesh *mesh, const BMeshCreateParams *create_params, const BMeshFromMeshParams *convert_params)
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_AcceptsCVs
@ eModifierTypeFlag_EnableInEditmode
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
#define BLI_assert(a)
Definition BLI_assert.h:46
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define BLO_read_struct(reader, struct_name, ptr_p)
#define IFACE_(msgid)
@ PROF_PRESET_LINE
@ CD_PROP_FLOAT
#define DNA_struct_default_get(struct_name)
@ MOD_BEVEL_MITER_SHARP
@ MOD_BEVEL_MARK_SHARP
@ MOD_BEVEL_MARK_SEAM
@ eModifierType_Bevel
@ MOD_BEVEL_PROFILE_CUSTOM
@ MOD_BEVEL_PROFILE_SUPERELLIPSE
@ MOD_BEVEL_HARDEN_NORMALS
@ MOD_BEVEL_INVERT_VGROUP
@ MOD_BEVEL_WEIGHT
@ MOD_BEVEL_OVERLAP_OK
@ MOD_BEVEL_VGROUP
@ MOD_BEVEL_EVEN_WIDTHS
@ MOD_BEVEL_ANGLE
@ MOD_BEVEL_AFFECT_VERTICES
Object is a sort of wrapper for general info.
static bool is_disabled
static void init_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
static void required_data_mask(ModifierData *, CustomData_MeshMasks *r_cddata_masks)
static void blend_read(BlendDataReader *, ModifierData *md)
static void panel_draw(const bContext *, Panel *panel)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
Definition MOD_array.cc:862
static void init_data(ModifierData *md)
Definition MOD_bevel.cc:44
static void panel_register(ARegionType *region_type)
Definition MOD_bevel.cc:422
static void geometry_panel_draw(const bContext *, Panel *panel)
Definition MOD_bevel.cc:367
static std::string ensure_weight_attribute_meta_data(Mesh &mesh, const blender::StringRef name, const blender::bke::AttrDomain domain, bool &r_attr_converted)
Definition MOD_bevel.cc:74
static void shading_panel_draw(const bContext *, Panel *panel)
Definition MOD_bevel.cc:400
static void copy_data(const ModifierData *md_src, ModifierData *md_dst, const int flag)
Definition MOD_bevel.cc:55
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
Definition MOD_bevel.cc:107
static void free_data(ModifierData *md)
Definition MOD_bevel.cc:271
static void blend_read(BlendDataReader *reader, ModifierData *md)
Definition MOD_bevel.cc:444
static void profile_panel_draw(const bContext *, Panel *panel)
Definition MOD_bevel.cc:329
static void panel_draw(const bContext *, Panel *panel)
Definition MOD_bevel.cc:283
static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
Definition MOD_bevel.cc:64
static void blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
Definition MOD_bevel.cc:433
ModifierTypeInfo modifierType_Bevel
Definition MOD_bevel.cc:454
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const StringRefNull vgroup_prop, const std::optional< StringRefNull > invert_vgroup_prop, const std::optional< StringRefNull > text)
PanelType * modifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelType *parent)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_error_message_draw(uiLayout *layout, PointerRNA *ptr)
void MOD_get_vgroup(const Object *ob, const Mesh *mesh, const char *name, const MDeformVert **dvert, int *defgrp_index)
Definition MOD_util.cc:156
void uiTemplateCurveProfile(uiLayout *layout, PointerRNA *ptr, blender::StringRefNull propname)
@ UI_ITEM_R_EXPAND
@ UI_ITEM_R_SLIDER
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
#define UI_ITEM_NONE
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
void BM_mesh_bevel(BMesh *bm, const float offset, const int offset_type, const int profile_type, const int segments, const float profile, const bool affect_type, const bool use_weights, const bool limit_offset, const MDeformVert *dvert, const int vertex_group, const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp, const bool harden_normals, const int face_strength_mode, const int miter_outer, const int miter_inner, const float spread, const CurveProfile *custom_profile, const int vmesh_method, const int bweight_offset_vert, const int bweight_offset_edge)
#define BM_ELEM_CD_GET_FLOAT(ele, offset)
@ BM_ELEM_TAG
#define BM_elem_index_get(ele)
#define BM_elem_flag_enable(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
BMesh * bm
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
@ BEVEL_MITER_ARC
@ BEVEL_AMT_PERCENT
bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
BLI_INLINE bool BM_edge_is_manifold(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMLoop * l_b
ATTR_WARN_UNUSED_RESULT const BMVert * v
static AttributeOwner from_id(ID *id)
Definition attribute.cc:43
static VArray ForSpan(Span< T > values)
GAttributeReader lookup(const StringRef attribute_id) const
int domain_size(const AttrDomain domain) const
std::optional< AttributeMetaData > lookup_meta_data(StringRef attribute_id) const
bool add(const StringRef attribute_id, const AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer)
#define cosf(x)
uint col
#define CD_MASK_ORIGINDEX
#define CD_MASK_MDEFORMVERT
bool allow_procedural_attribute_access(StringRef attribute_name)
void debug_randomize_mesh_order(Mesh *mesh)
Definition randomize.cc:217
int RNA_enum_get(PointerRNA *ptr, const char *name)
float no[3]
struct BMFace * f
struct CustomData_MeshMasks cd_mask_extra
struct CurveProfile * custom_profile
Definition DNA_ID.h:404
int verts_num
struct uiLayout * layout
uiLayout & column(bool align)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
uiLayout & row(bool align)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4227
uint8_t flag
Definition wm_window.cc:139