Blender  V3.3
MOD_edgesplit.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
13 #include "BLI_utildefines.h"
14 
15 #include "BLI_math.h"
16 
17 #include "BLT_translation.h"
18 
19 #include "DNA_defaults.h"
20 #include "DNA_mesh_types.h"
21 #include "DNA_object_types.h"
22 #include "DNA_screen_types.h"
23 
24 #include "BKE_context.h"
25 #include "BKE_mesh.h"
26 #include "BKE_modifier.h"
27 #include "BKE_screen.h"
28 
29 #include "UI_interface.h"
30 #include "UI_resources.h"
31 
32 #include "RNA_access.h"
33 #include "RNA_prototypes.h"
34 
35 #include "bmesh.h"
36 #include "bmesh_tools.h"
37 
38 #include "MOD_modifiertypes.h"
39 #include "MOD_ui_common.h"
40 
41 /* For edge split modifier node. */
43 
45 {
46  Mesh *result;
47  BMesh *bm;
48  BMIter iter;
49  BMEdge *e;
50  const float threshold = cosf(emd->split_angle + 0.000000175f);
51  const bool do_split_angle = (emd->flags & MOD_EDGESPLIT_FROMANGLE) != 0 &&
52  emd->split_angle < (float)M_PI;
53  const bool do_split_all = do_split_angle && emd->split_angle < FLT_EPSILON;
54  const bool calc_face_normals = do_split_angle && !do_split_all;
55 
57  &(struct BMeshCreateParams){0},
58  &(struct BMeshFromMeshParams){
59  .calc_face_normal = calc_face_normals,
60  .calc_vert_normal = false,
61  .add_key_index = false,
62  .use_shapekey = false,
63  .active_shapekey = 0,
64  .cd_mask_extra = {.vmask = CD_MASK_ORIGINDEX,
65  .emask = CD_MASK_ORIGINDEX,
66  .pmask = CD_MASK_ORIGINDEX},
67  });
68 
69  if (do_split_angle) {
70  BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
71  /* check for 1 edge having 2 face users */
72  BMLoop *l1, *l2;
73  if ((l1 = e->l) && (l2 = e->l->radial_next) != l1) {
74  if (/* 3+ faces on this edge, always split */
75  UNLIKELY(l1 != l2->radial_next) ||
76  /* O° angle setting, we want to split on all edges. */
77  do_split_all ||
78  /* 2 face edge - check angle. */
79  (dot_v3v3(l1->f->no, l2->f->no) < threshold)) {
81  }
82  }
83  }
84  }
85 
86  if (emd->flags & MOD_EDGESPLIT_FROMFLAG) {
87  BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
88  /* check for 2 or more edge users */
89  if ((e->l) && (e->l->next != e->l)) {
92  }
93  }
94  }
95  }
96 
97  BM_mesh_edgesplit(bm, false, true, false);
98 
99  /* Uncomment for troubleshooting. */
100  // BM_mesh_validate(bm);
101 
103  BM_mesh_free(bm);
104 
105  return result;
106 }
107 
108 static void initData(ModifierData *md)
109 {
111 
112  BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(emd, modifier));
113 
115 }
116 
118 {
119  Mesh *result;
121 
123  return mesh;
124  }
125 
126  result = doEdgeSplit(mesh, emd);
127 
128  return result;
129 }
130 
131 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
132 {
133  uiLayout *row, *sub;
134  uiLayout *layout = panel->layout;
135 
137 
138  uiLayoutSetPropSep(layout, true);
139 
140  row = uiLayoutRowWithHeading(layout, true, IFACE_("Edge Angle"));
141  uiItemR(row, ptr, "use_edge_angle", 0, "", ICON_NONE);
142  sub = uiLayoutRow(row, true);
143  uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_edge_angle"));
144  uiItemR(sub, ptr, "split_angle", 0, "", ICON_NONE);
145 
146  uiItemR(layout, ptr, "use_edge_sharp", 0, IFACE_("Sharp Edges"), ICON_NONE);
147 
148  modifier_panel_end(layout, ptr);
149 }
150 
151 static void panelRegister(ARegionType *region_type)
152 {
154 }
155 
157  /* name */ N_("EdgeSplit"),
158  /* structName */ "EdgeSplitModifierData",
159  /* structSize */ sizeof(EdgeSplitModifierData),
160  /* srna */ &RNA_EdgeSplitModifier,
165  /* icon */ ICON_MOD_EDGESPLIT,
166 
167  /* copyData */ BKE_modifier_copydata_generic,
168 
169  /* deformVerts */ NULL,
170  /* deformMatrices */ NULL,
171  /* deformVertsEM */ NULL,
172  /* deformMatricesEM */ NULL,
173  /* modifyMesh */ modifyMesh,
174  /* modifyGeometrySet */ NULL,
175 
176  /* initData */ initData,
177  /* requiredDataMask */ NULL,
178  /* freeData */ NULL,
179  /* isDisabled */ NULL,
180  /* updateDepsgraph */ NULL,
181  /* dependsOnTime */ NULL,
182  /* dependsOnNormals */ NULL,
183  /* foreachIDLink */ NULL,
184  /* foreachTexLink */ NULL,
185  /* freeRuntimeData */ NULL,
186  /* panelRegister */ panelRegister,
187  /* blendWrite */ NULL,
188  /* blendRead */ NULL,
189 };
struct BMesh * BKE_mesh_to_bmesh_ex(const struct Mesh *me, const struct BMeshCreateParams *create_params, const struct BMeshFromMeshParams *convert_params)
struct Mesh * BKE_mesh_from_bmesh_for_eval_nomain(struct BMesh *bm, const struct CustomData_MeshMasks *cd_mask_extra, const struct Mesh *me_settings)
@ eModifierTypeFlag_AcceptsCVs
Definition: BKE_modifier.h:67
@ eModifierTypeFlag_SupportsMapping
Definition: BKE_modifier.h:68
@ eModifierTypeFlag_EnableInEditmode
Definition: BKE_modifier.h:78
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:69
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:66
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, int flag)
@ eModifierTypeType_Constructive
Definition: BKE_modifier.h:47
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define M_PI
Definition: BLI_math_base.h:20
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
#define UNUSED(x)
#define UNLIKELY(x)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define IFACE_(msgid)
#define CD_MASK_ORIGINDEX
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
@ eModifierType_EdgeSplit
@ MOD_EDGESPLIT_FROMANGLE
@ MOD_EDGESPLIT_FROMFLAG
struct EdgeSplitModifierData EdgeSplitModifierData
Object is a sort of wrapper for general info.
Mesh * doEdgeSplit(const Mesh *mesh, EdgeSplitModifierData *emd)
Definition: MOD_edgesplit.c:44
static Mesh * modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
ModifierTypeInfo modifierType_EdgeSplit
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
static void initData(ModifierData *md)
static void panelRegister(ARegionType *region_type)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
Definition: MOD_ui_common.c:91
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
#define C
Definition: RandGen.cpp:25
uiLayout * uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *heading)
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
@ BM_ELEM_SMOOTH
Definition: bmesh_class.h:477
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only, const bool copy_select)
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
#define BM_elem_flag_enable(ele, hflag)
Definition: bmesh_inline.h:14
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_EDGES_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
Definition: bmesh_mesh.cc:258
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
#define cosf(x)
Definition: cuda/compat.h:101
ccl_gpu_kernel_postfix ccl_global float int int int int float threshold
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
float no[3]
Definition: bmesh_class.h:271
struct BMLoop * radial_next
Definition: bmesh_class.h:204
struct BMFace * f
Definition: bmesh_class.h:171
struct uiLayout * layout
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480