Blender  V2.93
MOD_edgesplit.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 by the Blender Foundation.
17  * All rights reserved.
18  */
19 
29 #include "BLI_utildefines.h"
30 
31 #include "BLI_math.h"
32 
33 #include "BLT_translation.h"
34 
35 #include "DNA_defaults.h"
36 #include "DNA_mesh_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_screen_types.h"
39 
40 #include "BKE_context.h"
41 #include "BKE_mesh.h"
42 #include "BKE_modifier.h"
43 #include "BKE_screen.h"
44 
45 #include "UI_interface.h"
46 #include "UI_resources.h"
47 
48 #include "RNA_access.h"
49 
50 #include "bmesh.h"
51 #include "bmesh_tools.h"
52 
53 #include "MOD_modifiertypes.h"
54 #include "MOD_ui_common.h"
55 
56 /* For edge split modifier node. */
58 
60 {
61  Mesh *result;
62  BMesh *bm;
63  BMIter iter;
64  BMEdge *e;
65  const float threshold = cosf(emd->split_angle + 0.000000175f);
66  const bool do_split_angle = (emd->flags & MOD_EDGESPLIT_FROMANGLE) != 0 &&
67  emd->split_angle < (float)M_PI;
68  const bool do_split_all = do_split_angle && emd->split_angle < FLT_EPSILON;
69  const bool calc_face_normals = do_split_angle && !do_split_all;
70 
72  &(struct BMeshCreateParams){0},
73  &(struct BMeshFromMeshParams){
74  .calc_face_normal = calc_face_normals,
75  .add_key_index = false,
76  .use_shapekey = false,
77  .active_shapekey = 0,
78  .cd_mask_extra = {.vmask = CD_MASK_ORIGINDEX,
79  .emask = CD_MASK_ORIGINDEX,
80  .pmask = CD_MASK_ORIGINDEX},
81  });
82 
83  if (do_split_angle) {
84  BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
85  /* check for 1 edge having 2 face users */
86  BMLoop *l1, *l2;
87  if ((l1 = e->l) && (l2 = e->l->radial_next) != l1) {
88  if (/* 3+ faces on this edge, always split */
89  UNLIKELY(l1 != l2->radial_next) ||
90  /* O° angle setting, we want to split on all edges. */
91  do_split_all ||
92  /* 2 face edge - check angle*/
93  (dot_v3v3(l1->f->no, l2->f->no) < threshold)) {
95  }
96  }
97  }
98  }
99 
100  if (emd->flags & MOD_EDGESPLIT_FROMFLAG) {
101  BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
102  /* check for 2 or more edge users */
103  if ((e->l) && (e->l->next != e->l)) {
106  }
107  }
108  }
109  }
110 
111  BM_mesh_edgesplit(bm, false, true, false);
112 
113  /* BM_mesh_validate(bm); */ /* for troubleshooting */
114 
116  BM_mesh_free(bm);
117 
118  result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
119  return result;
120 }
121 
122 static void initData(ModifierData *md)
123 {
125 
126  BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(emd, modifier));
127 
129 }
130 
132 {
133  Mesh *result;
135 
137  return mesh;
138  }
139 
140  result = doEdgeSplit(mesh, emd);
141 
142  return result;
143 }
144 
145 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
146 {
147  uiLayout *row, *sub;
148  uiLayout *layout = panel->layout;
149 
151 
152  uiLayoutSetPropSep(layout, true);
153 
154  row = uiLayoutRowWithHeading(layout, true, IFACE_("Edge Angle"));
155  uiItemR(row, ptr, "use_edge_angle", 0, "", ICON_NONE);
156  sub = uiLayoutRow(row, true);
157  uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_edge_angle"));
158  uiItemR(sub, ptr, "split_angle", 0, "", ICON_NONE);
159 
160  uiItemR(layout, ptr, "use_edge_sharp", 0, IFACE_("Sharp Edges"), ICON_NONE);
161 
162  modifier_panel_end(layout, ptr);
163 }
164 
165 static void panelRegister(ARegionType *region_type)
166 {
168 }
169 
171  /* name */ "EdgeSplit",
172  /* structName */ "EdgeSplitModifierData",
173  /* structSize */ sizeof(EdgeSplitModifierData),
174  /* srna */ &RNA_EdgeSplitModifier,
179  /* icon */ ICON_MOD_EDGESPLIT,
180 
181  /* copyData */ BKE_modifier_copydata_generic,
182 
183  /* deformVerts */ NULL,
184  /* deformMatrices */ NULL,
185  /* deformVertsEM */ NULL,
186  /* deformMatricesEM */ NULL,
187  /* modifyMesh */ modifyMesh,
188  /* modifyHair */ NULL,
189  /* modifyGeometrySet */ NULL,
190  /* modifyVolume */ NULL,
191 
192  /* initData */ initData,
193  /* requiredDataMask */ NULL,
194  /* freeData */ NULL,
195  /* isDisabled */ NULL,
196  /* updateDepsgraph */ NULL,
197  /* dependsOnTime */ NULL,
198  /* dependsOnNormals */ NULL,
199  /* foreachIDLink */ NULL,
200  /* foreachTexLink */ NULL,
201  /* freeRuntimeData */ NULL,
202  /* panelRegister */ panelRegister,
203  /* blendWrite */ NULL,
204  /* blendRead */ NULL,
205 };
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:81
@ eModifierTypeFlag_SupportsMapping
Definition: BKE_modifier.h:82
@ eModifierTypeFlag_EnableInEditmode
Definition: BKE_modifier.h:92
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:83
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:80
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, const int flag)
@ eModifierTypeType_Constructive
Definition: BKE_modifier.h:61
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define M_PI
Definition: BLI_math_base.h:38
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_NORMAL
#define CD_MASK_ORIGINDEX
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:44
@ 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:59
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)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
StructRNA RNA_EdgeSplitModifier
#define C
Definition: RandGen.cpp:39
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:26
#define BM_elem_flag_enable(ele, hflag)
Definition: bmesh_inline.h:28
#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.c:307
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
#define cosf(x)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
float no[3]
Definition: bmesh_class.h:280
struct BMLoop * radial_next
Definition: bmesh_class.h:216
struct BMFace * f
Definition: bmesh_class.h:183
struct uiLayout * layout
PointerRNA * ptr
Definition: wm_files.c:3157