Blender V5.0
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"
29#include "UI_resources.hh"
30
31#include "RNA_access.hh"
32#include "RNA_define.hh"
33#include "RNA_prototypes.hh"
34
35#include "MOD_ui_common.hh"
36#include "MOD_util.hh"
37
38#include "BLO_read_write.hh"
39
40#include "GEO_randomize.hh"
41
42#include "bmesh.hh"
43#include "bmesh_tools.hh"
44
55
56static void copy_data(const ModifierData *md_src, ModifierData *md_dst, const int flag)
57{
58 const BevelModifierData *bmd_src = (const BevelModifierData *)md_src;
59 BevelModifierData *bmd_dst = (BevelModifierData *)md_dst;
60
61 BKE_modifier_copydata_generic(md_src, md_dst, flag);
63}
64
65static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
66{
68
69 /* Ask for vertex-groups if we need them. */
70 if (bmd->defgrp_name[0] != '\0') {
71 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
72 }
73}
74
75static std::string ensure_weight_attribute_meta_data(Mesh &mesh,
77 const blender::bke::AttrDomain domain,
78 bool &r_attr_converted)
79{
80 using namespace blender;
82 return "";
83 }
84 bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
85 const std::optional<bke::AttributeMetaData> meta_data = attributes.lookup_meta_data(name);
86 if (!meta_data) {
87 r_attr_converted = false;
88 return name;
89 }
90 if (meta_data->domain == domain && meta_data->data_type == bke::AttrType::Float) {
91 r_attr_converted = false;
92 return name;
93 }
94
95 Array<float> weight(attributes.domain_size(domain));
96 attributes.lookup<float>(name, domain).varray.materialize(weight);
97 const std::string new_name = BKE_attribute_calc_unique_name(AttributeOwner::from_id(&mesh.id),
98 name);
99 attributes.add<float>(
100 new_name, domain, bke::AttributeInitVArray(VArray<float>::from_span(weight)));
101 r_attr_converted = true;
102 return new_name;
103}
104
105/*
106 * This calls the new bevel code (added since 2.64)
107 */
108static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
109{
110 using namespace blender;
111 if (mesh->verts_num == 0) {
112 return mesh;
113 }
114 Mesh *result;
115 BMesh *bm;
116 BMIter iter;
117 BMEdge *e;
118 BMVert *v;
119 float weight, weight2;
120 int vgroup = -1;
121 const MDeformVert *dvert = nullptr;
123 const float threshold = cosf(bmd->bevel_angle + 0.000000175f);
124 const bool do_clamp = !(bmd->flags & MOD_BEVEL_OVERLAP_OK);
125 const int offset_type = bmd->val_flags;
126 const int profile_type = bmd->profile_type;
127 const float value = bmd->value;
128 const int mat = std::clamp(int(bmd->mat), -1, ctx->object->totcol - 1);
129 const bool loop_slide = (bmd->flags & MOD_BEVEL_EVEN_WIDTHS) == 0;
130 const bool mark_seam = (bmd->edge_flags & MOD_BEVEL_MARK_SEAM);
131 const bool mark_sharp = (bmd->edge_flags & MOD_BEVEL_MARK_SHARP);
132 bool harden_normals = (bmd->flags & MOD_BEVEL_HARDEN_NORMALS);
133 const int face_strength_mode = bmd->face_str_mode;
134 const int miter_outer = bmd->miter_outer;
135 const int miter_inner = bmd->miter_inner;
136 const float spread = bmd->spread;
137 const bool invert_vgroup = (bmd->flags & MOD_BEVEL_INVERT_VGROUP) != 0;
138
139 BMeshCreateParams create_params{};
140 BMeshFromMeshParams convert_params{};
141 convert_params.calc_face_normal = true;
142 convert_params.calc_vert_normal = true;
143 convert_params.add_key_index = false;
144 convert_params.use_shapekey = false;
145 convert_params.active_shapekey = 0;
146 convert_params.cd_mask_extra.vmask = CD_MASK_ORIGINDEX;
147 convert_params.cd_mask_extra.emask = CD_MASK_ORIGINDEX;
148 convert_params.cd_mask_extra.pmask = CD_MASK_ORIGINDEX;
149
150 bool vert_weight_converted;
151 const std::string vert_weight_name = ensure_weight_attribute_meta_data(
152 *mesh, bmd->vertex_weight_name, bke::AttrDomain::Point, vert_weight_converted);
153 bool edge_weight_converted;
154 const std::string edge_weight_name = ensure_weight_attribute_meta_data(
155 *mesh, bmd->edge_weight_name, bke::AttrDomain::Edge, edge_weight_converted);
156
157 bm = BKE_mesh_to_bmesh_ex(mesh, &create_params, &convert_params);
158
159 if ((bmd->lim_flags & MOD_BEVEL_VGROUP) && bmd->defgrp_name[0]) {
160 MOD_get_vgroup(ctx->object, mesh, bmd->defgrp_name, &dvert, &vgroup);
161 }
162
163 const int bweight_offset_vert = CustomData_get_offset_named(
164 &bm->vdata, CD_PROP_FLOAT, vert_weight_name);
165 const int bweight_offset_edge = CustomData_get_offset_named(
166 &bm->edata, CD_PROP_FLOAT, edge_weight_name);
167
169 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
170 if (bmd->lim_flags & MOD_BEVEL_WEIGHT) {
171 weight = bweight_offset_vert == -1 ? 0.0f : BM_ELEM_CD_GET_FLOAT(v, bweight_offset_vert);
172 if (weight == 0.0f) {
173 continue;
174 }
175 }
176 else {
178 dvert, BM_elem_index_get(v), vgroup, invert_vgroup);
179 /* Check is against 0.5 rather than != 0.0 because cascaded bevel modifiers will
180 * interpolate weights for newly created vertices, and may cause unexpected "selection" */
181 if (weight < 0.5f) {
182 continue;
183 }
184 }
186 }
187 }
188 else if (bmd->lim_flags & MOD_BEVEL_ANGLE) {
189 BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
190 /* check for 1 edge having 2 face users */
191 BMLoop *l_a, *l_b;
192 if (BM_edge_loop_pair(e, &l_a, &l_b)) {
193 if (dot_v3v3(l_a->f->no, l_b->f->no) < threshold) {
197 }
198 }
199 }
200 }
201 else {
202 /* crummy, is there a way just to operator on all? - campbell */
203 BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
204 if (BM_edge_is_manifold(e)) {
205 if (bmd->lim_flags & MOD_BEVEL_WEIGHT) {
206 weight = bweight_offset_edge == -1 ? 0.0f : BM_ELEM_CD_GET_FLOAT(e, bweight_offset_edge);
207 if (weight == 0.0f) {
208 continue;
209 }
210 }
211 else {
213 dvert, BM_elem_index_get(e->v1), vgroup, invert_vgroup);
215 dvert, BM_elem_index_get(e->v2), vgroup, invert_vgroup);
216 if (weight < 0.5f || weight2 < 0.5f) {
217 continue;
218 }
219 }
223 }
224 }
225 }
226
228 value,
229 offset_type,
230 profile_type,
231 bmd->res,
232 bmd->profile,
233 bmd->affect_type,
235 do_clamp,
236 dvert,
237 vgroup,
238 mat,
239 loop_slide,
240 mark_seam,
241 mark_sharp,
242 harden_normals,
243 face_strength_mode,
244 miter_outer,
245 miter_inner,
246 spread,
247 bmd->custom_profile,
248 bmd->vmesh_method,
249 bweight_offset_vert,
250 bweight_offset_edge);
251
253
254 /* Make sure we never allocated these. */
255 BLI_assert(bm->vtoolflagpool == nullptr && bm->etoolflagpool == nullptr &&
256 bm->ftoolflagpool == nullptr);
257
259
260 if (vert_weight_converted) {
261 result->attributes_for_write().remove(vert_weight_name);
262 }
263 if (edge_weight_converted) {
264 result->attributes_for_write().remove(edge_weight_name);
265 }
266
268
269 return result;
270}
271
277
278static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
279{
281 return (bmd->value == 0.0f);
282}
283
284static void panel_draw(const bContext * /*C*/, Panel *panel)
285{
286 uiLayout *col, *sub;
287 uiLayout *layout = panel->layout;
288
289 PointerRNA ob_ptr;
291
292 bool edge_bevel = RNA_enum_get(ptr, "affect") != MOD_BEVEL_AFFECT_VERTICES;
293
294 layout->prop(ptr, "affect", UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE);
295
296 layout->use_property_split_set(true);
297
298 col = &layout->column(false);
299 col->prop(ptr, "offset_type", UI_ITEM_NONE, std::nullopt, ICON_NONE);
300 if (RNA_enum_get(ptr, "offset_type") == BEVEL_AMT_PERCENT) {
301 col->prop(ptr, "width_pct", UI_ITEM_NONE, std::nullopt, ICON_NONE);
302 }
303 else {
304 col->prop(ptr, "width", UI_ITEM_NONE, IFACE_("Amount"), ICON_NONE);
305 }
306
307 layout->prop(ptr, "segments", UI_ITEM_NONE, std::nullopt, ICON_NONE);
308
309 layout->separator();
310
311 col = &layout->column(false);
312 col->prop(ptr, "limit_method", UI_ITEM_NONE, std::nullopt, ICON_NONE);
313 int limit_method = RNA_enum_get(ptr, "limit_method");
314 if (limit_method == MOD_BEVEL_ANGLE) {
315 sub = &col->column(false);
316 sub->active_set(edge_bevel);
317 col->prop(ptr, "angle_limit", UI_ITEM_NONE, std::nullopt, ICON_NONE);
318 }
319 else if (limit_method == MOD_BEVEL_WEIGHT) {
320 const char *prop_name = edge_bevel ? "edge_weight" : "vertex_weight";
321 col->prop(ptr, prop_name, UI_ITEM_NONE, std::nullopt, ICON_NONE);
322 }
323 else if (limit_method == MOD_BEVEL_VGROUP) {
324 modifier_vgroup_ui(col, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", std::nullopt);
325 }
326
328}
329
330static void profile_panel_draw(const bContext * /*C*/, Panel *panel)
331{
332 uiLayout *row;
333 uiLayout *layout = panel->layout;
334
336
337 int profile_type = RNA_enum_get(ptr, "profile_type");
338 int miter_inner = RNA_enum_get(ptr, "miter_inner");
339 int miter_outer = RNA_enum_get(ptr, "miter_outer");
340 bool edge_bevel = RNA_enum_get(ptr, "affect") != MOD_BEVEL_AFFECT_VERTICES;
341
342 layout->prop(ptr, "profile_type", UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE);
343
344 layout->use_property_split_set(true);
345
347 row = &layout->row(false);
348 row->active_set(
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 sub->use_property_decorate_set(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 layout->use_property_split_set(true);
377
378 row = &layout->row(false);
379 row->active_set(edge_bevel);
380 row->prop(ptr, "miter_outer", UI_ITEM_NONE, IFACE_("Miter Outer"), ICON_NONE);
381 row = &layout->row(false);
382 row->active_set(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 row->active_set(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 row->active_set(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 row->active_set(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 layout->use_property_split_set(true);
410
411 layout->prop(ptr, "harden_normals", UI_ITEM_NONE, std::nullopt, ICON_NONE);
412
413 col = &layout->column(true, IFACE_("Mark"));
414 col->active_set(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 /*foreach_working_space_color*/ nullptr,
486};
std::string BKE_attribute_calc_unique_name(const AttributeOwner &owner, blender::StringRef name)
Definition attribute.cc:370
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:780
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
#define CD_MASK_ORIGINDEX
#define CD_MASK_MDEFORMVERT
@ CD_PROP_FLOAT
#define DNA_struct_default_get(struct_name)
@ 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_PROFILE_CUSTOM
@ MOD_BEVEL_PROFILE_SUPERELLIPSE
@ MOD_BEVEL_MARK_SHARP
@ MOD_BEVEL_MARK_SEAM
@ eModifierType_Bevel
@ MOD_BEVEL_MITER_SHARP
@ 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:45
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:75
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:56
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
Definition MOD_bevel.cc:108
static void free_data(ModifierData *md)
Definition MOD_bevel.cc:272
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:330
static void panel_draw(const bContext *, Panel *panel)
Definition MOD_bevel.cc:284
static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
Definition MOD_bevel.cc:65
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
#define UI_ITEM_NONE
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:44
static VArray from_span(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 AttrType data_type, const AttributeInit &initializer)
uint col
bool allow_procedural_attribute_access(StringRef attribute_name)
void debug_randomize_mesh_order(Mesh *mesh)
Definition randomize.cc:288
const char * name
#define cosf
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:414
int verts_num
struct uiLayout * layout
void use_property_decorate_set(bool is_sep)
uiLayout & column(bool align)
void active_set(bool active)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
uiLayout & row(bool align)
void use_property_split_set(bool value)
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:4238
uint8_t flag
Definition wm_window.cc:145