Blender  V3.3
MOD_normal_edit.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <string.h>
8 
9 #include "MEM_guardedalloc.h"
10 
11 #include "BLI_utildefines.h"
12 
13 #include "BLI_bitmap.h"
14 #include "BLI_math.h"
15 
16 #include "BLT_translation.h"
17 
18 #include "DNA_defaults.h"
19 #include "DNA_mesh_types.h"
20 #include "DNA_meshdata_types.h"
21 #include "DNA_object_types.h"
22 #include "DNA_screen_types.h"
23 
24 #include "BKE_context.h"
25 #include "BKE_deform.h"
26 #include "BKE_lib_id.h"
27 #include "BKE_lib_query.h"
28 #include "BKE_mesh.h"
29 #include "BKE_screen.h"
30 
31 #include "UI_interface.h"
32 #include "UI_resources.h"
33 
34 #include "RNA_access.h"
35 #include "RNA_prototypes.h"
36 
37 #include "DEG_depsgraph_query.h"
38 
39 #include "MOD_ui_common.h"
40 #include "MOD_util.h"
41 
43  Object *ob,
44  Object *ob_center,
45  const float offset[3],
46  const int verts_num,
47  float (*r_cos)[3],
48  float r_size[3])
49 {
50  float min_co[3], max_co[3];
51  float diff[3];
52  bool do_diff = false;
53 
54  INIT_MINMAX(min_co, max_co);
55 
56  MVert *mv = mesh->mvert;
57  for (int i = 0; i < mesh->totvert; i++, mv++) {
58  copy_v3_v3(r_cos[i], mv->co);
59  if (r_size != NULL && ob_center == NULL) {
60  minmax_v3v3_v3(min_co, max_co, r_cos[i]);
61  }
62  }
63 
64  /* Get size (i.e. deformation of the spheroid generating normals),
65  * either from target object, or own geometry. */
66  if (r_size != NULL) {
67  if (ob_center != NULL) {
68  /* Using 'scale' as 'size' here. The input object is typically an empty
69  * who's scale is used to define an ellipsoid instead of a simple sphere. */
70 
71  /* Not we are not interested in signs here - they are even troublesome actually,
72  * due to security clamping! */
73  abs_v3_v3(r_size, ob_center->scale);
74  }
75  else {
76  /* Set size. */
77  sub_v3_v3v3(r_size, max_co, min_co);
78  }
79 
80  /* Error checks - we do not want one or more of our sizes to be null! */
81  if (is_zero_v3(r_size)) {
82  r_size[0] = r_size[1] = r_size[2] = 1.0f;
83  }
84  else {
85  CLAMP_MIN(r_size[0], FLT_EPSILON);
86  CLAMP_MIN(r_size[1], FLT_EPSILON);
87  CLAMP_MIN(r_size[2], FLT_EPSILON);
88  }
89  }
90 
91  if (ob_center != NULL) {
92  float inv_obmat[4][4];
93 
94  /* Translate our coordinates so that center of ob_center is at (0, 0, 0). */
95  /* Get ob_center (world) coordinates in ob local coordinates.
96  * No need to take into account ob_center's space here, see T44027. */
97  invert_m4_m4(inv_obmat, ob->obmat);
98  mul_v3_m4v3(diff, inv_obmat, ob_center->obmat[3]);
99  negate_v3(diff);
100 
101  do_diff = true;
102  }
103  else if (offset != NULL && !is_zero_v3(offset)) {
105 
106  do_diff = true;
107  }
108  /* Else, no need to change coordinates! */
109 
110  if (do_diff) {
111  int i = verts_num;
112  while (i--) {
113  add_v3_v3(r_cos[i], diff);
114  }
115  }
116 }
117 
118 /* Note this modifies nos_new in-place. */
119 static void mix_normals(const float mix_factor,
120  MDeformVert *dvert,
121  const int defgrp_index,
122  const bool use_invert_vgroup,
123  const float mix_limit,
124  const short mix_mode,
125  const int verts_num,
126  MLoop *mloop,
127  float (*nos_old)[3],
128  float (*nos_new)[3],
129  const int loops_num)
130 {
131  /* Mix with org normals... */
132  float *facs = NULL, *wfac;
133  float(*no_new)[3], (*no_old)[3];
134  int i;
135 
136  if (dvert) {
137  facs = MEM_malloc_arrayN((size_t)loops_num, sizeof(*facs), __func__);
139  dvert, defgrp_index, verts_num, mloop, loops_num, use_invert_vgroup, facs);
140  }
141 
142  for (i = loops_num, no_new = nos_new, no_old = nos_old, wfac = facs; i--;
143  no_new++, no_old++, wfac++) {
144  const float fac = facs ? *wfac * mix_factor : mix_factor;
145 
146  switch (mix_mode) {
148  add_v3_v3(*no_new, *no_old);
149  normalize_v3(*no_new);
150  break;
152  sub_v3_v3(*no_new, *no_old);
153  normalize_v3(*no_new);
154  break;
156  mul_v3_v3(*no_new, *no_old);
157  normalize_v3(*no_new);
158  break;
160  break;
161  }
162 
164  *no_new,
165  *no_old,
166  *no_new,
167  (mix_limit < (float)M_PI) ? min_ff(fac, mix_limit / angle_v3v3(*no_new, *no_old)) : fac);
168  }
169 
170  MEM_SAFE_FREE(facs);
171 }
172 
173 /* Check poly normals and new loop normals are compatible, otherwise flip polygons
174  * (and invert matching poly normals). */
175 static bool polygons_check_flip(MLoop *mloop,
176  float (*nos)[3],
177  CustomData *ldata,
178  MPoly *mpoly,
179  float (*polynors)[3],
180  const int polys_num)
181 {
182  MPoly *mp;
183  MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS);
184  int i;
185  bool flipped = false;
186 
187  for (i = 0, mp = mpoly; i < polys_num; i++, mp++) {
188  float norsum[3] = {0.0f};
189  float(*no)[3];
190  int j;
191 
192  for (j = 0, no = &nos[mp->loopstart]; j < mp->totloop; j++, no++) {
193  add_v3_v3(norsum, *no);
194  }
195 
196  if (!normalize_v3(norsum)) {
197  continue;
198  }
199 
200  /* If average of new loop normals is opposed to polygon normal, flip polygon. */
201  if (dot_v3v3(polynors[i], norsum) < 0.0f) {
202  BKE_mesh_polygon_flip_ex(mp, mloop, ldata, nos, mdisp, true);
203  negate_v3(polynors[i]);
204  flipped = true;
205  }
206  }
207 
208  return flipped;
209 }
210 
212  const ModifierEvalContext *UNUSED(ctx),
213  Object *ob,
214  Mesh *mesh,
215  short (*clnors)[2],
216  float (*loopnors)[3],
217  const float (*polynors)[3],
218  const short mix_mode,
219  const float mix_factor,
220  const float mix_limit,
221  MDeformVert *dvert,
222  const int defgrp_index,
223  const bool use_invert_vgroup,
224  MVert *mvert,
225  const int verts_num,
226  MEdge *medge,
227  const int edges_num,
228  MLoop *mloop,
229  const int loops_num,
230  MPoly *mpoly,
231  const int polys_num)
232 {
233  Object *ob_target = enmd->target;
234 
235  const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0;
236  int i;
237 
238  float(*cos)[3] = MEM_malloc_arrayN((size_t)verts_num, sizeof(*cos), __func__);
239  float(*nos)[3] = MEM_malloc_arrayN((size_t)loops_num, sizeof(*nos), __func__);
240  float size[3];
241 
242  BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)verts_num, __func__);
243 
244  generate_vert_coordinates(mesh, ob, ob_target, enmd->offset, verts_num, cos, size);
245 
277  {
278  const float a = size[0], b = size[1], c = size[2];
279  const float m2 = (b * b) / (a * a);
280  const float n2 = (c * c) / (a * a);
281 
282  MLoop *ml;
283  float(*no)[3];
284 
285  /* We reuse cos to now store the ellipsoid-normal of the verts! */
286  for (i = loops_num, ml = mloop, no = nos; i--; ml++, no++) {
287  const int vidx = ml->v;
288  float *co = cos[vidx];
289 
290  if (!BLI_BITMAP_TEST(done_verts, vidx)) {
291  const float x2 = co[0] * co[0];
292  const float y2 = co[1] * co[1];
293  const float z2 = co[2] * co[2];
294  const float a2 = x2 + (y2 / m2) + (z2 / n2);
295  const float b2 = (m2 * x2) + y2 + (m2 * z2 / n2);
296  const float c2 = (n2 * x2) + (n2 * y2 / m2) + z2;
297 
298  co[0] /= a2;
299  co[1] /= b2;
300  co[2] /= c2;
301  normalize_v3(co);
302 
303  BLI_BITMAP_ENABLE(done_verts, vidx);
304  }
305  copy_v3_v3(*no, co);
306  }
307  }
308 
309  if (loopnors) {
310  mix_normals(mix_factor,
311  dvert,
312  defgrp_index,
313  use_invert_vgroup,
314  mix_limit,
315  mix_mode,
316  verts_num,
317  mloop,
318  loopnors,
319  nos,
320  loops_num);
321  }
322 
323  if (do_polynors_fix &&
325  mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), polys_num)) {
326  /* We need to recompute vertex normals! */
328  }
329 
332  verts_num,
333  medge,
334  edges_num,
335  mloop,
336  nos,
337  loops_num,
338  mpoly,
339  polynors,
340  polys_num,
341  clnors);
342 
343  MEM_freeN(cos);
344  MEM_freeN(nos);
345  MEM_freeN(done_verts);
346 }
347 
349  const ModifierEvalContext *UNUSED(ctx),
350  Object *ob,
351  Mesh *mesh,
352  short (*clnors)[2],
353  float (*loopnors)[3],
354  const float (*polynors)[3],
355  const short mix_mode,
356  const float mix_factor,
357  const float mix_limit,
358  MDeformVert *dvert,
359  const int defgrp_index,
360  const bool use_invert_vgroup,
361  MVert *mvert,
362  const int verts_num,
363  MEdge *medge,
364  const int edges_num,
365  MLoop *mloop,
366  const int loops_num,
367  MPoly *mpoly,
368  const int polys_num)
369 {
370  Object *ob_target = enmd->target;
371 
372  const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0;
373  const bool use_parallel_normals = (enmd->flag & MOD_NORMALEDIT_USE_DIRECTION_PARALLEL) != 0;
374 
375  float(*nos)[3] = MEM_malloc_arrayN((size_t)loops_num, sizeof(*nos), __func__);
376 
377  float target_co[3];
378  int i;
379 
380  /* Get target's center coordinates in ob local coordinates. */
381  float mat[4][4];
382 
383  invert_m4_m4(mat, ob->obmat);
384  mul_m4_m4m4(mat, mat, ob_target->obmat);
385  copy_v3_v3(target_co, mat[3]);
386 
387  if (use_parallel_normals) {
388  float no[3];
389 
390  sub_v3_v3v3(no, target_co, enmd->offset);
391  normalize_v3(no);
392 
393  for (i = loops_num; i--;) {
394  copy_v3_v3(nos[i], no);
395  }
396  }
397  else {
398  float(*cos)[3] = MEM_malloc_arrayN((size_t)verts_num, sizeof(*cos), __func__);
399  generate_vert_coordinates(mesh, ob, ob_target, NULL, verts_num, cos, NULL);
400 
401  BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)verts_num, __func__);
402  MLoop *ml;
403  float(*no)[3];
404 
405  /* We reuse cos to now store the 'to target' normal of the verts! */
406  for (i = loops_num, no = nos, ml = mloop; i--; no++, ml++) {
407  const int vidx = ml->v;
408  float *co = cos[vidx];
409 
410  if (!BLI_BITMAP_TEST(done_verts, vidx)) {
411  sub_v3_v3v3(co, target_co, co);
412  normalize_v3(co);
413 
414  BLI_BITMAP_ENABLE(done_verts, vidx);
415  }
416 
417  copy_v3_v3(*no, co);
418  }
419 
420  MEM_freeN(done_verts);
421  MEM_freeN(cos);
422  }
423 
424  if (loopnors) {
425  mix_normals(mix_factor,
426  dvert,
427  defgrp_index,
428  use_invert_vgroup,
429  mix_limit,
430  mix_mode,
431  verts_num,
432  mloop,
433  loopnors,
434  nos,
435  loops_num);
436  }
437 
438  if (do_polynors_fix &&
440  mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), polys_num)) {
442  }
443 
446  verts_num,
447  medge,
448  edges_num,
449  mloop,
450  nos,
451  loops_num,
452  mpoly,
453  polynors,
454  polys_num,
455  clnors);
456 
457  MEM_freeN(nos);
458 }
459 
461 {
462  if (enmd->mode == MOD_NORMALEDIT_MODE_RADIAL) {
463  return true;
464  }
465  if ((enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) && enmd->target) {
466  return true;
467  }
468  return false;
469 }
470 
472 {
473  if (is_valid_target(enmd)) {
474  return true;
475  }
476  BKE_modifier_set_error(ob, (ModifierData *)enmd, "Invalid target settings");
477  return false;
478 }
479 
481  const ModifierEvalContext *ctx,
482  Object *ob,
483  Mesh *mesh)
484 {
485  const bool use_invert_vgroup = ((enmd->flag & MOD_NORMALEDIT_INVERT_VGROUP) != 0);
486  const bool use_current_clnors = !((enmd->mix_mode == MOD_NORMALEDIT_MIX_COPY) &&
487  (enmd->mix_factor == 1.0f) && (enmd->defgrp_name[0] == '\0') &&
488  (enmd->mix_limit == (float)M_PI));
489 
490  /* Do not run that modifier at all if autosmooth is disabled! */
491  if (!is_valid_target_with_error(ctx->object, enmd) || mesh->totloop == 0) {
492  return mesh;
493  }
494 
495  /* XXX TODO(Rohan Rathi):
496  * Once we fully switch to Mesh evaluation of modifiers,
497  * we can expect to get that flag from the COW copy.
498  * But for now, it is lost in the DM intermediate step,
499  * so we need to directly check orig object's data. */
500 #if 0
501  if (!(mesh->flag & ME_AUTOSMOOTH))
502 #else
503  if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH))
504 #endif
505  {
507  ob, (ModifierData *)enmd, "Enable 'Auto Smooth' in Object Data Properties");
508  return mesh;
509  }
510 
511  Mesh *result;
512  if (mesh->medge == ((Mesh *)ob->data)->medge) {
513  /* We need to duplicate data here, otherwise setting custom normals
514  * (which may also affect sharp edges) could
515  * modify original mesh, see T43671. */
517  }
518  else {
519  result = mesh;
520  }
521 
522  const int verts_num = result->totvert;
523  const int edges_num = result->totedge;
524  const int loops_num = result->totloop;
525  const int polys_num = result->totpoly;
526  MVert *mvert = result->mvert;
527  MEdge *medge = result->medge;
528  MLoop *mloop = result->mloop;
529  MPoly *mpoly = result->mpoly;
530 
531  int defgrp_index;
532  MDeformVert *dvert;
533 
534  float(*loopnors)[3] = NULL;
535 
536  CustomData *ldata = &result->ldata;
537 
538  const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(result);
539  const float(*poly_normals)[3] = BKE_mesh_poly_normals_ensure(result);
540 
541  short(*clnors)[2] = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL);
542  if (use_current_clnors) {
544  loopnors = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loopnors), __func__);
545 
547  vert_normals,
548  verts_num,
549  medge,
550  edges_num,
551  mloop,
552  loopnors,
553  loops_num,
554  mpoly,
555  poly_normals,
556  polys_num,
557  true,
558  result->smoothresh,
559  NULL,
560  clnors,
561  NULL);
562  }
563 
564  if (clnors == NULL) {
565  clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, loops_num);
566  }
567 
568  MOD_get_vgroup(ob, result, enmd->defgrp_name, &dvert, &defgrp_index);
569 
570  if (enmd->mode == MOD_NORMALEDIT_MODE_RADIAL) {
572  ctx,
573  ob,
574  result,
575  clnors,
576  loopnors,
577  poly_normals,
578  enmd->mix_mode,
579  enmd->mix_factor,
580  enmd->mix_limit,
581  dvert,
582  defgrp_index,
583  use_invert_vgroup,
584  mvert,
585  verts_num,
586  medge,
587  edges_num,
588  mloop,
589  loops_num,
590  mpoly,
591  polys_num);
592  }
593  else if (enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) {
595  ctx,
596  ob,
597  result,
598  clnors,
599  loopnors,
600  poly_normals,
601  enmd->mix_mode,
602  enmd->mix_factor,
603  enmd->mix_limit,
604  dvert,
605  defgrp_index,
606  use_invert_vgroup,
607  mvert,
608  verts_num,
609  medge,
610  edges_num,
611  mloop,
612  loops_num,
613  mpoly,
614  polys_num);
615  }
616 
617  MEM_SAFE_FREE(loopnors);
618 
619  result->runtime.is_original = false;
620 
621  return result;
622 }
623 
624 static void initData(ModifierData *md)
625 {
627 
628  BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(enmd, modifier));
629 
631 }
632 
633 static void requiredDataMask(Object *UNUSED(ob),
634  ModifierData *md,
635  CustomData_MeshMasks *r_cddata_masks)
636 {
638 
639  r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL;
640 
641  /* Ask for vertexgroups if we need them. */
642  if (enmd->defgrp_name[0] != '\0') {
643  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
644  }
645 }
646 
648 {
649  return true;
650 }
651 
652 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
653 {
655 
656  walk(userData, ob, (ID **)&enmd->target, IDWALK_CB_NOP);
657 }
658 
659 static bool isDisabled(const struct Scene *UNUSED(scene),
660  ModifierData *md,
661  bool UNUSED(useRenderParams))
662 {
664 
665  return !is_valid_target(enmd);
666 }
667 
669 {
671  if (enmd->target) {
672  DEG_add_object_relation(ctx->node, enmd->target, DEG_OB_COMP_TRANSFORM, "NormalEdit Modifier");
673  DEG_add_modifier_to_transform_relation(ctx->node, "NormalEdit Modifier");
674  }
675 }
676 
678 {
679  return normalEditModifier_do((NormalEditModifierData *)md, ctx, ctx->object, mesh);
680 }
681 
682 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
683 {
684  uiLayout *col;
685  uiLayout *layout = panel->layout;
686 
687  PointerRNA ob_ptr;
689 
690  int mode = RNA_enum_get(ptr, "mode");
691 
692  uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
693 
694  uiLayoutSetPropSep(layout, true);
695 
696  uiItemR(layout, ptr, "target", 0, NULL, ICON_NONE);
697 
698  col = uiLayoutColumn(layout, false);
700  uiItemR(col, ptr, "use_direction_parallel", 0, NULL, ICON_NONE);
701 
702  modifier_panel_end(layout, ptr);
703 }
704 
705 /* This panel could be open by default, but it isn't currently. */
706 static void mix_mode_panel_draw(const bContext *UNUSED(C), Panel *panel)
707 {
708  uiLayout *row;
709  uiLayout *layout = panel->layout;
710 
711  PointerRNA ob_ptr;
713 
714  uiLayoutSetPropSep(layout, true);
715 
716  uiItemR(layout, ptr, "mix_mode", 0, NULL, ICON_NONE);
717  uiItemR(layout, ptr, "mix_factor", 0, NULL, ICON_NONE);
718 
719  modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
720 
721  row = uiLayoutRow(layout, true);
722  uiItemR(row, ptr, "mix_limit", 0, NULL, ICON_NONE);
723  uiItemR(row,
724  ptr,
725  "no_polynors_fix",
726  0,
727  "",
728  (RNA_boolean_get(ptr, "no_polynors_fix") ? ICON_LOCKED : ICON_UNLOCKED));
729 }
730 
731 static void offset_panel_draw(const bContext *UNUSED(C), Panel *panel)
732 {
733  uiLayout *layout = panel->layout;
734 
736 
737  int mode = RNA_enum_get(ptr, "mode");
738  PointerRNA target_ptr = RNA_pointer_get(ptr, "target");
739  bool needs_object_offset = (mode == MOD_NORMALEDIT_MODE_RADIAL &&
740  RNA_pointer_is_null(&target_ptr)) ||
742  RNA_boolean_get(ptr, "use_direction_parallel"));
743 
744  uiLayoutSetPropSep(layout, true);
745 
746  uiLayoutSetActive(layout, needs_object_offset);
747  uiItemR(layout, ptr, "offset", 0, NULL, ICON_NONE);
748 }
749 
750 static void panelRegister(ARegionType *region_type)
751 {
752  PanelType *panel_type = modifier_panel_register(
753  region_type, eModifierType_NormalEdit, panel_draw);
754  modifier_subpanel_register(region_type, "mix", "Mix", NULL, mix_mode_panel_draw, panel_type);
755  modifier_subpanel_register(region_type, "offset", "Offset", NULL, offset_panel_draw, panel_type);
756 }
757 
759  /* name */ N_("NormalEdit"),
760  /* structName */ "NormalEditModifierData",
761  /* structSize */ sizeof(NormalEditModifierData),
762  /* srna */ &RNA_NormalEditModifier,
766  /* icon */ ICON_MOD_NORMALEDIT,
767 
768  /* copyData */ BKE_modifier_copydata_generic,
769 
770  /* deformVerts */ NULL,
771  /* deformMatrices */ NULL,
772  /* deformVertsEM */ NULL,
773  /* deformMatricesEM */ NULL,
774  /* modifyMesh */ modifyMesh,
775  /* modifyGeometrySet */ NULL,
776 
777  /* initData */ initData,
778  /* requiredDataMask */ requiredDataMask,
779  /* freeData */ NULL,
780  /* isDisabled */ isDisabled,
781  /* updateDepsgraph */ updateDepsgraph,
782  /* dependsOnTime */ NULL,
783  /* dependsOnNormals */ dependsOnNormals,
784  /* foreachIDLink */ foreachIDLink,
785  /* foreachTexLink */ NULL,
786  /* freeRuntimeData */ NULL,
787  /* panelRegister */ panelRegister,
788  /* blendWrite */ NULL,
789  /* blendRead */ NULL,
790 };
typedef float(TangentPoint)[2]
@ CD_CALLOC
void * CustomData_get_layer(const struct CustomData *data, int type)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.cc:2776
void * CustomData_duplicate_referenced_layer(struct CustomData *data, int type, int totelem)
Definition: customdata.cc:2976
support for deformation groups and hooks.
void BKE_defvert_extract_vgroup_to_loopweights(const struct MDeformVert *dvert, int defgroup, int num_verts, struct MLoop *loops, int num_loops, bool invert_vgroup, float *r_weights)
@ LIB_ID_COPY_LOCALIZE
Definition: BKE_lib_id.h:187
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, int flag)
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:33
const float(* BKE_mesh_poly_normals_ensure(const struct Mesh *mesh))[3]
void BKE_mesh_polygon_flip_ex(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata, float(*lnors)[3], struct MDisps *mdisp, bool use_loop_mdisp_flip)
void BKE_mesh_normals_loop_custom_set(const struct MVert *mverts, const float(*vert_normals)[3], int numVerts, struct MEdge *medges, int numEdges, struct MLoop *mloops, float(*r_custom_loopnors)[3], int numLoops, struct MPoly *mpolys, const float(*polynors)[3], int numPolys, short(*r_clnors_data)[2])
const float(* BKE_mesh_vertex_normals_ensure(const struct Mesh *mesh))[3]
void BKE_mesh_normals_loop_split(const struct MVert *mverts, const float(*vert_normals)[3], int numVerts, struct MEdge *medges, int numEdges, struct MLoop *mloops, float(*r_loopnors)[3], int numLoops, struct MPoly *mpolys, const float(*polynors)[3], int numPolys, bool use_split_normals, float split_angle, MLoopNorSpaceArray *r_lnors_spacearr, short(*clnors_data)[2], int *r_loop_to_poly)
float(* BKE_mesh_poly_normals_for_write(struct Mesh *mesh))[3]
void BKE_mesh_normals_tag_dirty(struct Mesh *mesh)
Definition: mesh_normals.cc:95
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:107
@ 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
void BKE_modifier_set_error(const struct Object *ob, struct ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition: BLI_bitmap.h:40
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition: BLI_bitmap.h:64
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition: BLI_bitmap.h:81
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:16
MINLINE float min_ff(float a, float b)
#define M_PI
Definition: BLI_math_base.h:20
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
float angle_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:385
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
Definition: math_vector.c:867
MINLINE float normalize_v3(float r[3])
MINLINE void mul_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3_slerp_safe(float target[3], const float a[3], const float b[3], float t)
Definition: math_vector.c:92
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void negate_v3(float r[3])
MINLINE void abs_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
#define INIT_MINMAX(min, max)
#define UNUSED(x)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define CLAMP_MIN(a, b)
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
#define CD_MASK_MDEFORMVERT
@ CD_CUSTOMLOOPNORMAL
#define CD_MASK_CUSTOMLOOPNORMAL
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
@ ME_AUTOSMOOTH
struct NormalEditModifierData NormalEditModifierData
@ MOD_NORMALEDIT_NO_POLYNORS_FIX
@ MOD_NORMALEDIT_INVERT_VGROUP
@ MOD_NORMALEDIT_USE_DIRECTION_PARALLEL
@ MOD_NORMALEDIT_MIX_COPY
@ MOD_NORMALEDIT_MIX_ADD
@ MOD_NORMALEDIT_MIX_SUB
@ MOD_NORMALEDIT_MIX_MUL
@ eModifierType_NormalEdit
@ MOD_NORMALEDIT_MODE_RADIAL
@ MOD_NORMALEDIT_MODE_DIRECTIONAL
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
static bool is_valid_target(NormalEditModifierData *enmd)
static Mesh * modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
static void mix_mode_panel_draw(const bContext *UNUSED(C), Panel *panel)
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static bool is_valid_target_with_error(const Object *ob, NormalEditModifierData *enmd)
ModifierTypeInfo modifierType_NormalEdit
static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
static void offset_panel_draw(const bContext *UNUSED(C), Panel *panel)
static void mix_normals(const float mix_factor, MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup, const float mix_limit, const short mix_mode, const int verts_num, MLoop *mloop, float(*nos_old)[3], float(*nos_new)[3], const int loops_num)
static bool polygons_check_flip(MLoop *mloop, float(*nos)[3], CustomData *ldata, MPoly *mpoly, float(*polynors)[3], const int polys_num)
static void generate_vert_coordinates(Mesh *mesh, Object *ob, Object *ob_center, const float offset[3], const int verts_num, float(*r_cos)[3], float r_size[3])
static void normalEditModifier_do_radial(NormalEditModifierData *enmd, const ModifierEvalContext *UNUSED(ctx), Object *ob, Mesh *mesh, short(*clnors)[2], float(*loopnors)[3], const float(*polynors)[3], const short mix_mode, const float mix_factor, const float mix_limit, MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup, MVert *mvert, const int verts_num, MEdge *medge, const int edges_num, MLoop *mloop, const int loops_num, MPoly *mpoly, const int polys_num)
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
static bool dependsOnNormals(ModifierData *UNUSED(md))
static Mesh * normalEditModifier_do(NormalEditModifierData *enmd, const ModifierEvalContext *ctx, Object *ob, Mesh *mesh)
static void normalEditModifier_do_directional(NormalEditModifierData *enmd, const ModifierEvalContext *UNUSED(ctx), Object *ob, Mesh *mesh, short(*clnors)[2], float(*loopnors)[3], const float(*polynors)[3], const short mix_mode, const float mix_factor, const float mix_limit, MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup, MVert *mvert, const int verts_num, MEdge *medge, const int edges_num, MLoop *mloop, const int loops_num, MPoly *mpoly, const int polys_num)
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
static void initData(ModifierData *md)
static void panelRegister(ARegionType *region_type)
static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
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)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
PanelType * modifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelType *parent)
void MOD_get_vgroup(Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index)
Definition: MOD_util.c:235
#define C
Definition: RandGen.cpp:25
void uiLayoutSetActive(uiLayout *layout, bool active)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
@ UI_ITEM_R_EXPAND
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Scene scene
uint col
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:34
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt=1)
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5167
bool RNA_pointer_is_null(const PointerRNA *ptr)
Definition: rna_access.c:164
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
Definition: DNA_ID.h:368
unsigned int v
struct MEdge * medge
struct MVert * mvert
uint16_t flag
int totvert
int totloop
CustomData ldata
struct Object * object
Definition: BKE_modifier.h:141
struct DepsNodeHandle * node
Definition: BKE_modifier.h:134
float scale[3]
float obmat[4][4]
void * data
struct uiLayout * layout
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480