Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/modifiers/intern/MOD_normal_edit.c')
-rw-r--r--source/blender/modifiers/intern/MOD_normal_edit.c59
1 files changed, 47 insertions, 12 deletions
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c
index 87d75c6f1a7..355dd6d6677 100644
--- a/source/blender/modifiers/intern/MOD_normal_edit.c
+++ b/source/blender/modifiers/intern/MOD_normal_edit.c
@@ -38,6 +38,7 @@
#include "BLI_bitmap.h"
#include "BKE_cdderivedmesh.h"
+#include "BKE_library_query.h"
#include "BKE_mesh.h"
#include "BKE_deform.h"
@@ -84,7 +85,7 @@ static void generate_vert_coordinates(
/* Translate our coordinates so that center of ob_center is at (0, 0, 0). */
/* Get ob_center (world) coordinates in ob local coordinates.
- * No need to take into accound ob_center's space here, see T44027. */
+ * No need to take into account ob_center's space here, see T44027. */
invert_m4_m4(inv_obmat, ob->obmat);
mul_v3_m4v3(diff, inv_obmat, ob_center->obmat[3]);
negate_v3(diff);
@@ -148,6 +149,40 @@ static void mix_normals(
MEM_SAFE_FREE(facs);
}
+/* Check poly normals and new loop normals are compatible, otherwise flip polygons
+ * (and invert matching poly normals). */
+static bool polygons_check_flip(
+ MLoop *mloop, float (*nos)[3], CustomData *ldata,
+ MPoly *mpoly, float (*polynors)[3], const int num_polys)
+{
+ MPoly *mp;
+ int i;
+ bool flipped = false;
+
+ for (i = 0, mp = mpoly; i < num_polys; i++, mp++) {
+ float norsum[3] = {0.0f};
+ float (*no)[3];
+ int j;
+
+ for (j = 0, no = &nos[mp->loopstart]; j < mp->totloop; j++, no++) {
+ add_v3_v3(norsum, *no);
+ }
+
+ if (!normalize_v3(norsum)) {
+ continue;
+ }
+
+ /* If average of new loop normals is opposed to polygon normal, flip polygon. */
+ if (dot_v3v3(polynors[i], norsum) < 0.0f) {
+ BKE_mesh_polygon_flip(mp, mloop, ldata);
+ negate_v3(polynors[i]);
+ flipped = true;
+ }
+ }
+
+ return flipped;
+}
+
static void normalEditModifier_do_radial(
NormalEditModifierData *smd, Object *ob, DerivedMesh *dm,
short (*clnors)[2], float (*loopnors)[3], float (*polynors)[3],
@@ -233,6 +268,10 @@ static void normalEditModifier_do_radial(
mix_mode, num_verts, mloop, loopnors, nos, num_loops);
}
+ if (polygons_check_flip(mloop, nos, dm->getLoopDataLayout(dm), mpoly, polynors, num_polys)) {
+ dm->dirty |= DM_DIRTY_TESS_CDLAYERS;
+ }
+
BKE_mesh_normals_loop_custom_set(mvert, num_verts, medge, num_edges, mloop, nos, num_loops,
mpoly, (const float(*)[3])polynors, num_polys, clnors);
@@ -306,6 +345,10 @@ static void normalEditModifier_do_directional(
mix_mode, num_verts, mloop, loopnors, nos, num_loops);
}
+ if (polygons_check_flip(mloop, nos, dm->getLoopDataLayout(dm), mpoly, polynors, num_polys)) {
+ dm->dirty |= DM_DIRTY_TESS_CDLAYERS;
+ }
+
BKE_mesh_normals_loop_custom_set(mvert, num_verts, medge, num_edges, mloop, nos, num_loops,
mpoly, (const float(*)[3])polynors, num_polys, clnors);
@@ -387,7 +430,7 @@ static DerivedMesh *normalEditModifier_do(NormalEditModifierData *smd, Object *o
polynors = dm->getPolyDataArray(dm, CD_NORMAL);
if (!polynors) {
polynors = MEM_mallocN(sizeof(*polynors) * num_polys, __func__);
- BKE_mesh_calc_normals_poly(mvert, num_verts, mloop, mpoly, num_loops, num_polys, polynors, false);
+ BKE_mesh_calc_normals_poly(mvert, NULL, num_verts, mloop, mpoly, num_loops, num_polys, polynors, false);
free_polynors = true;
}
@@ -450,14 +493,7 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk,
{
NormalEditModifierData *smd = (NormalEditModifierData *) md;
- walk(userData, ob, &smd->target);
-}
-
-static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
-{
- NormalEditModifierData *smd = (NormalEditModifierData *) md;
-
- walk(userData, ob, (ID **)&smd->target);
+ walk(userData, ob, &smd->target, IDWALK_NOP);
}
static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
@@ -504,7 +540,6 @@ ModifierTypeInfo modifierType_NormalEdit = {
/* structSize */ sizeof(NormalEditModifierData),
/* type */ eModifierTypeType_Constructive,
/* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs |
eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode,
@@ -524,6 +559,6 @@ ModifierTypeInfo modifierType_NormalEdit = {
/* dependsOnTime */ NULL,
/* dependsOnNormals */ dependsOnNormals,
/* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ foreachIDLink,
+ /* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
};