Blender  V2.93
MOD_mask.cc
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 
24 #include "MEM_guardedalloc.h"
25 
26 #include "BLI_utildefines.h"
27 
28 #include "BLI_ghash.h"
29 #include "BLI_listbase.h"
30 
31 #include "BLT_translation.h"
32 
33 #include "DNA_armature_types.h"
34 #include "DNA_defaults.h"
35 #include "DNA_mesh_types.h"
36 #include "DNA_meshdata_types.h"
37 #include "DNA_modifier_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_screen_types.h"
40 
41 #include "BKE_action.h" /* BKE_pose_channel_find_name */
42 #include "BKE_context.h"
43 #include "BKE_customdata.h"
44 #include "BKE_deform.h"
45 #include "BKE_lib_query.h"
46 #include "BKE_mesh.h"
47 #include "BKE_modifier.h"
48 #include "BKE_screen.h"
49 
50 #include "UI_interface.h"
51 #include "UI_resources.h"
52 
53 #include "RNA_access.h"
54 
55 #include "DEG_depsgraph_build.h"
56 #include "DEG_depsgraph_query.h"
57 
58 #include "MOD_modifiertypes.h"
59 #include "MOD_ui_common.h"
60 
61 #include "BLI_array.hh"
62 #include "BLI_listbase_wrapper.hh"
63 #include "BLI_vector.hh"
64 
65 using blender::Array;
69 using blender::Span;
70 using blender::Vector;
71 
72 static void initData(ModifierData *md)
73 {
75 
77 
79 }
80 
81 static void requiredDataMask(Object *UNUSED(ob),
82  ModifierData *UNUSED(md),
83  CustomData_MeshMasks *r_cddata_masks)
84 {
85  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
86 }
87 
88 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
89 {
90  MaskModifierData *mmd = reinterpret_cast<MaskModifierData *>(md);
91  walk(userData, ob, (ID **)&mmd->ob_arm, IDWALK_CB_NOP);
92 }
93 
95 {
96  MaskModifierData *mmd = reinterpret_cast<MaskModifierData *>(md);
97  if (mmd->ob_arm) {
98  bArmature *arm = (bArmature *)mmd->ob_arm->data;
99  /* Tag relationship in depsgraph, but also on the armature. */
100  /* TODO(sergey): Is it a proper relation here? */
101  DEG_add_object_relation(ctx->node, mmd->ob_arm, DEG_OB_COMP_TRANSFORM, "Mask Modifier");
102  arm->flag |= ARM_HAS_VIZ_DEPS;
103  DEG_add_modifier_to_transform_relation(ctx->node, "Mask Modifier");
104  }
105 }
106 
107 /* A vertex will be in the mask if a selected bone influences it more than a certain threshold. */
109  Object *ob,
110  Object *armature_ob,
111  float threshold,
112  MutableSpan<bool> r_vertex_mask)
113 {
114  /* Element i is true if there is a selected bone that uses vertex group i. */
115  Vector<bool> selected_bone_uses_group;
116 
118  bPoseChannel *pchan = BKE_pose_channel_find_name(armature_ob->pose, def->name);
119  bool bone_for_group_exists = pchan && pchan->bone && (pchan->bone->flag & BONE_SELECTED);
120  selected_bone_uses_group.append(bone_for_group_exists);
121  }
122 
123  Span<bool> use_vertex_group = selected_bone_uses_group;
124 
125  for (int i : r_vertex_mask.index_range()) {
126  Span<MDeformWeight> weights(dvert[i].dw, dvert[i].totweight);
127  r_vertex_mask[i] = false;
128 
129  /* check the groups that vertex is assigned to, and see if it was any use */
130  for (const MDeformWeight &dw : weights) {
131  if (use_vertex_group.get(dw.def_nr, false)) {
132  if (dw.weight > threshold) {
133  r_vertex_mask[i] = true;
134  break;
135  }
136  }
137  }
138  }
139 }
140 
141 /* A vertex will be in the mask if the vertex group influences it more than a certain threshold. */
143  int defgrp_index,
144  float threshold,
145  MutableSpan<bool> r_vertex_mask)
146 {
147  for (int i : r_vertex_mask.index_range()) {
148  const bool found = BKE_defvert_find_weight(&dvert[i], defgrp_index) > threshold;
149  r_vertex_mask[i] = found;
150  }
151 }
152 
154 {
155  for (bool &value : array) {
156  value = !value;
157  }
158 }
159 
160 static void compute_masked_vertices(Span<bool> vertex_mask,
161  MutableSpan<int> r_vertex_map,
162  uint *r_num_masked_vertices)
163 {
164  BLI_assert(vertex_mask.size() == r_vertex_map.size());
165 
166  uint num_masked_vertices = 0;
167  for (uint i_src : r_vertex_map.index_range()) {
168  if (vertex_mask[i_src]) {
169  r_vertex_map[i_src] = num_masked_vertices;
170  num_masked_vertices++;
171  }
172  else {
173  r_vertex_map[i_src] = -1;
174  }
175  }
176 
177  *r_num_masked_vertices = num_masked_vertices;
178 }
179 
180 static void computed_masked_edges(const Mesh *mesh,
181  Span<bool> vertex_mask,
182  MutableSpan<int> r_edge_map,
183  uint *r_num_masked_edges)
184 {
185  BLI_assert(mesh->totedge == r_edge_map.size());
186 
187  uint num_masked_edges = 0;
188  for (int i : IndexRange(mesh->totedge)) {
189  const MEdge &edge = mesh->medge[i];
190 
191  /* only add if both verts will be in new mesh */
192  if (vertex_mask[edge.v1] && vertex_mask[edge.v2]) {
193  r_edge_map[i] = num_masked_edges;
194  num_masked_edges++;
195  }
196  else {
197  r_edge_map[i] = -1;
198  }
199  }
200 
201  *r_num_masked_edges = num_masked_edges;
202 }
203 
204 static void computed_masked_polygons(const Mesh *mesh,
205  Span<bool> vertex_mask,
206  Vector<int> &r_masked_poly_indices,
207  Vector<int> &r_loop_starts,
208  uint *r_num_masked_polys,
209  uint *r_num_masked_loops)
210 {
211  BLI_assert(mesh->totvert == vertex_mask.size());
212 
213  r_masked_poly_indices.reserve(mesh->totpoly);
214  r_loop_starts.reserve(mesh->totloop);
215 
216  uint num_masked_loops = 0;
217  for (int i : IndexRange(mesh->totpoly)) {
218  const MPoly &poly_src = mesh->mpoly[i];
219 
220  bool all_verts_in_mask = true;
221  Span<MLoop> loops_src(&mesh->mloop[poly_src.loopstart], poly_src.totloop);
222  for (const MLoop &loop : loops_src) {
223  if (!vertex_mask[loop.v]) {
224  all_verts_in_mask = false;
225  break;
226  }
227  }
228 
229  if (all_verts_in_mask) {
230  r_masked_poly_indices.append_unchecked(i);
231  r_loop_starts.append_unchecked(num_masked_loops);
232  num_masked_loops += poly_src.totloop;
233  }
234  }
235 
236  *r_num_masked_polys = r_masked_poly_indices.size();
237  *r_num_masked_loops = num_masked_loops;
238 }
239 
240 static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh,
241  Mesh &dst_mesh,
242  Span<int> vertex_map)
243 {
244  BLI_assert(src_mesh.totvert == vertex_map.size());
245  for (const int i_src : vertex_map.index_range()) {
246  const int i_dst = vertex_map[i_src];
247  if (i_dst == -1) {
248  continue;
249  }
250 
251  const MVert &v_src = src_mesh.mvert[i_src];
252  MVert &v_dst = dst_mesh.mvert[i_dst];
253 
254  v_dst = v_src;
255  CustomData_copy_data(&src_mesh.vdata, &dst_mesh.vdata, i_src, i_dst, 1);
256  }
257 }
258 
259 static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh,
260  Mesh &dst_mesh,
261  Span<int> vertex_map,
262  Span<int> edge_map)
263 {
264  BLI_assert(src_mesh.totvert == vertex_map.size());
265  BLI_assert(src_mesh.totedge == edge_map.size());
266  for (const int i_src : IndexRange(src_mesh.totedge)) {
267  const int i_dst = edge_map[i_src];
268  if (i_dst == -1) {
269  continue;
270  }
271 
272  const MEdge &e_src = src_mesh.medge[i_src];
273  MEdge &e_dst = dst_mesh.medge[i_dst];
274 
275  CustomData_copy_data(&src_mesh.edata, &dst_mesh.edata, i_src, i_dst, 1);
276  e_dst = e_src;
277  e_dst.v1 = vertex_map[e_src.v1];
278  e_dst.v2 = vertex_map[e_src.v2];
279  }
280 }
281 
282 static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
283  Mesh &dst_mesh,
284  Span<int> vertex_map,
285  Span<int> edge_map,
286  Span<int> masked_poly_indices,
287  Span<int> new_loop_starts)
288 {
289  for (const int i_dst : masked_poly_indices.index_range()) {
290  const int i_src = masked_poly_indices[i_dst];
291 
292  const MPoly &mp_src = src_mesh.mpoly[i_src];
293  MPoly &mp_dst = dst_mesh.mpoly[i_dst];
294  const int i_ml_src = mp_src.loopstart;
295  const int i_ml_dst = new_loop_starts[i_dst];
296 
297  CustomData_copy_data(&src_mesh.pdata, &dst_mesh.pdata, i_src, i_dst, 1);
298  CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src, i_ml_dst, mp_src.totloop);
299 
300  const MLoop *ml_src = src_mesh.mloop + i_ml_src;
301  MLoop *ml_dst = dst_mesh.mloop + i_ml_dst;
302 
303  mp_dst = mp_src;
304  mp_dst.loopstart = i_ml_dst;
305  for (int i : IndexRange(mp_src.totloop)) {
306  ml_dst[i].v = vertex_map[ml_src[i].v];
307  ml_dst[i].e = edge_map[ml_src[i].e];
308  }
309  }
310 }
311 
312 /* Components of the algorithm:
313  * 1. Figure out which vertices should be present in the output mesh.
314  * 2. Find edges and polygons only using those vertices.
315  * 3. Create a new mesh that only uses the found vertices, edges and polygons.
316  */
318 {
319  MaskModifierData *mmd = reinterpret_cast<MaskModifierData *>(md);
320  Object *ob = ctx->object;
321  const bool invert_mask = mmd->flag & MOD_MASK_INV;
322 
323  /* Return empty or input mesh when there are no vertex groups. */
325  if (dvert == nullptr) {
326  return invert_mask ? mesh : BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0);
327  }
328 
329  /* Quick test to see if we can return early. */
330  if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) || (mesh->totvert == 0) ||
332  return mesh;
333  }
334 
335  Array<bool> vertex_mask;
336  if (mmd->mode == MOD_MASK_MODE_ARM) {
337  Object *armature_ob = mmd->ob_arm;
338 
339  /* Return input mesh if there is no armature with bones. */
340  if (ELEM(NULL, armature_ob, armature_ob->pose, ob->defbase.first)) {
341  return mesh;
342  }
343 
344  vertex_mask = Array<bool>(mesh->totvert);
345  compute_vertex_mask__armature_mode(dvert, ob, armature_ob, mmd->threshold, vertex_mask);
346  }
347  else {
348  int defgrp_index = BKE_object_defgroup_name_index(ob, mmd->vgroup);
349 
350  /* Return input mesh if the vertex group does not exist. */
351  if (defgrp_index == -1) {
352  return mesh;
353  }
354 
355  vertex_mask = Array<bool>(mesh->totvert);
356  compute_vertex_mask__vertex_group_mode(dvert, defgrp_index, mmd->threshold, vertex_mask);
357  }
358 
359  if (invert_mask) {
360  invert_boolean_array(vertex_mask);
361  }
362 
363  Array<int> vertex_map(mesh->totvert);
364  uint num_masked_vertices;
365  compute_masked_vertices(vertex_mask, vertex_map, &num_masked_vertices);
366 
367  Array<int> edge_map(mesh->totedge);
368  uint num_masked_edges;
369  computed_masked_edges(mesh, vertex_mask, edge_map, &num_masked_edges);
370 
371  Vector<int> masked_poly_indices;
372  Vector<int> new_loop_starts;
373  uint num_masked_polys;
374  uint num_masked_loops;
376  vertex_mask,
377  masked_poly_indices,
378  new_loop_starts,
379  &num_masked_polys,
380  &num_masked_loops);
381 
383  mesh, num_masked_vertices, num_masked_edges, 0, num_masked_loops, num_masked_polys);
384 
386  copy_masked_edges_to_new_mesh(*mesh, *result, vertex_map, edge_map);
388  *mesh, *result, vertex_map, edge_map, masked_poly_indices, new_loop_starts);
389 
391  /* Tag to recalculate normals later. */
392  result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
393 
394  return result;
395 }
396 
397 static bool isDisabled(const struct Scene *UNUSED(scene),
398  ModifierData *md,
399  bool UNUSED(useRenderParams))
400 {
401  MaskModifierData *mmd = reinterpret_cast<MaskModifierData *>(md);
402 
403  /* The object type check is only needed here in case we have a placeholder
404  * object assigned (because the library containing the armature is missing).
405  *
406  * In other cases it should be impossible to have a type mismatch.
407  */
408  return mmd->ob_arm && mmd->ob_arm->type != OB_ARMATURE;
409 }
410 
411 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
412 {
413  uiLayout *sub, *row;
414  uiLayout *layout = panel->layout;
415 
416  PointerRNA ob_ptr;
418 
419  int mode = RNA_enum_get(ptr, "mode");
420 
421  uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
422 
423  uiLayoutSetPropSep(layout, true);
424 
425  if (mode == MOD_MASK_MODE_ARM) {
426  row = uiLayoutRow(layout, true);
427  uiItemR(row, ptr, "armature", 0, nullptr, ICON_NONE);
428  sub = uiLayoutRow(row, true);
429  uiLayoutSetPropDecorate(sub, false);
430  uiItemR(sub, ptr, "invert_vertex_group", 0, "", ICON_ARROW_LEFTRIGHT);
431  }
432  else if (mode == MOD_MASK_MODE_VGROUP) {
433  modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr);
434  }
435 
436  uiItemR(layout, ptr, "threshold", 0, nullptr, ICON_NONE);
437 
438  modifier_panel_end(layout, ptr);
439 }
440 
441 static void panelRegister(ARegionType *region_type)
442 {
444 }
445 
447  /* name */ "Mask",
448  /* structName */ "MaskModifierData",
449  /* structSize */ sizeof(MaskModifierData),
450  /* srna */ &RNA_MaskModifier,
452  /* flags */
455  /* icon */ ICON_MOD_MASK,
456 
457  /* copyData */ BKE_modifier_copydata_generic,
458 
459  /* deformVerts */ nullptr,
460  /* deformMatrices */ nullptr,
461  /* deformVertsEM */ nullptr,
462  /* deformMatricesEM */ nullptr,
463  /* modifyMesh */ modifyMesh,
464  /* modifyHair */ nullptr,
465  /* modifyGeometrySet */ nullptr,
466  /* modifyVolume */ nullptr,
467 
468  /* initData */ initData,
469  /* requiredDataMask */ requiredDataMask,
470  /* freeData */ nullptr,
471  /* isDisabled */ isDisabled,
472  /* updateDepsgraph */ updateDepsgraph,
473  /* dependsOnTime */ nullptr,
474  /* dependsOnNormals */ nullptr,
475  /* foreachIDLink */ foreachIDLink,
476  /* foreachTexLink */ nullptr,
477  /* freeRuntimeData */ nullptr,
478  /* panelRegister */ panelRegister,
479  /* blendWrite */ nullptr,
480  /* blendRead */ nullptr,
481 };
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer(const struct CustomData *data, int type)
void CustomData_copy_data(const struct CustomData *source, struct CustomData *dest, int source_index, int dest_index, int count)
support for deformation groups and hooks.
int BKE_object_defgroup_name_index(const struct Object *ob, const char *name)
float BKE_defvert_find_weight(const struct MDeformVert *dvert, const int defgroup)
Definition: deform.c:632
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:47
struct Mesh * BKE_mesh_new_nomain_from_template(const struct Mesh *me_src, int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
void BKE_mesh_calc_edges_loose(struct Mesh *mesh)
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:120
ModifierTypeFlag
Definition: BKE_modifier.h:79
@ eModifierTypeFlag_SupportsMapping
Definition: BKE_modifier.h:82
@ 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_Nonconstructive
Definition: BKE_modifier.h:63
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
void DEG_add_object_relation(struct DepsNodeHandle *node_handle, struct Object *object, eDepsObjectComponentType component, const char *description)
void DEG_add_modifier_to_transform_relation(struct DepsNodeHandle *node_handle, const char *description)
@ DEG_OB_COMP_TRANSFORM
@ BONE_SELECTED
@ ARM_HAS_VIZ_DEPS
#define CD_MASK_NORMAL
#define CD_MASK_MDEFORMVERT
@ CD_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:44
@ MOD_MASK_MODE_ARM
@ MOD_MASK_MODE_VGROUP
struct MaskModifierData MaskModifierData
@ MOD_MASK_INV
@ eModifierType_Mask
Object is a sort of wrapper for general info.
@ OB_ARMATURE
Read Guarded memory(de)allocation.
static void compute_vertex_mask__armature_mode(MDeformVert *dvert, Object *ob, Object *armature_ob, float threshold, MutableSpan< bool > r_vertex_mask)
Definition: MOD_mask.cc:108
static Mesh * modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
Definition: MOD_mask.cc:317
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
Definition: MOD_mask.cc:94
static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
Definition: MOD_mask.cc:397
static void compute_vertex_mask__vertex_group_mode(MDeformVert *dvert, int defgrp_index, float threshold, MutableSpan< bool > r_vertex_mask)
Definition: MOD_mask.cc:142
static void computed_masked_edges(const Mesh *mesh, Span< bool > vertex_mask, MutableSpan< int > r_edge_map, uint *r_num_masked_edges)
Definition: MOD_mask.cc:180
static void requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md), CustomData_MeshMasks *r_cddata_masks)
Definition: MOD_mask.cc:81
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
Definition: MOD_mask.cc:88
static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span< int > vertex_map, Span< int > edge_map)
Definition: MOD_mask.cc:259
static void invert_boolean_array(MutableSpan< bool > array)
Definition: MOD_mask.cc:153
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
Definition: MOD_mask.cc:411
static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span< int > vertex_map, Span< int > edge_map, Span< int > masked_poly_indices, Span< int > new_loop_starts)
Definition: MOD_mask.cc:282
static void initData(ModifierData *md)
Definition: MOD_mask.cc:72
static void panelRegister(ARegionType *region_type)
Definition: MOD_mask.cc:441
ModifierTypeInfo modifierType_Mask
Definition: MOD_mask.cc:446
static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span< int > vertex_map)
Definition: MOD_mask.cc:240
static void computed_masked_polygons(const Mesh *mesh, Span< bool > vertex_mask, Vector< int > &r_masked_poly_indices, Vector< int > &r_loop_starts, uint *r_num_masked_polys, uint *r_num_masked_loops)
Definition: MOD_mask.cc:204
static void compute_masked_vertices(Span< bool > vertex_mask, MutableSpan< int > r_vertex_map, uint *r_num_masked_vertices)
Definition: MOD_mask.cc:160
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)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
StructRNA RNA_MaskModifier
#define C
Definition: RandGen.cpp:39
@ UI_ITEM_R_EXPAND
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)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
constexpr int64_t size() const
Definition: BLI_span.hh:524
constexpr IndexRange index_range() const
Definition: BLI_span.hh:659
constexpr T get(int64_t index, const T &fallback) const
Definition: BLI_span.hh:337
constexpr int64_t size() const
Definition: BLI_span.hh:254
constexpr IndexRange index_range() const
Definition: BLI_span.hh:414
int64_t size() const
Definition: BLI_vector.hh:662
void append_unchecked(ForwardT &&value)
Definition: BLI_vector.hh:477
void append(const T &value)
Definition: BLI_vector.hh:438
void reserve(const int64_t min_capacity)
Definition: BLI_vector.hh:355
Scene scene
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
Definition: DNA_ID.h:273
void * first
Definition: DNA_listBase.h:47
unsigned int v1
unsigned int v2
unsigned int e
unsigned int v
struct Object * ob_arm
struct MEdge * medge
struct CustomData pdata ldata
struct MVert * mvert
int totedge
int totvert
struct MLoop * mloop
int totpoly
int totloop
struct MPoly * mpoly
struct Object * object
Definition: BKE_modifier.h:154
struct DepsNodeHandle * node
Definition: BKE_modifier.h:147
ListBase defbase
struct bPose * pose
void * data
struct uiLayout * layout
struct Bone * bone
PointerRNA * ptr
Definition: wm_files.c:3157