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:
authorSybren A. Stüvel <sybren@stuvel.eu>2018-05-03 15:02:05 +0300
committerSybren A. Stüvel <sybren@stuvel.eu>2018-05-03 15:11:22 +0300
commit181356edba042698ac44f002ee7093984c1b79ae (patch)
tree49989284340f18eec3b7c2bfe6bb6f017fe21731
parent1677ea89c7ad34c32a00eca44eeea705f49d9e25 (diff)
Restored HQ normals in Solidify modifier
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c104
1 files changed, 101 insertions, 3 deletions
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index cac08bd6d3a..43fceaae22a 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -68,6 +68,106 @@ BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref)
return !((edge_ref->f1 == 0) && (edge_ref->f2 == 0));
}
+/**
+ * \param dm Mesh to calculate normals for.
+ * \param face_nors Precalculated face normals.
+ * \param r_vert_nors Return vert normals.
+ */
+static void mesh_calc_hq_normal(Mesh *mesh, float (*face_nors)[3], float (*r_vert_nors)[3])
+{
+ int i, numVerts, numEdges, numFaces;
+ MPoly *mpoly, *mp;
+ MLoop *mloop, *ml;
+ MEdge *medge, *ed;
+ MVert *mvert, *mv;
+
+ numVerts = mesh->totvert;
+ numEdges = mesh->totedge;
+ numFaces = mesh->totface;
+ mpoly = mesh->mpoly;
+ medge = mesh->medge;
+ mvert = mesh->mvert;
+ mloop = mesh->mloop;
+
+ /* we don't want to overwrite any referenced layers */
+
+ /* Doesn't work here! */
+#if 0
+ mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, numVerts);
+ cddm->mvert = mv;
+#endif
+
+ mv = mvert;
+ mp = mpoly;
+
+ {
+ EdgeFaceRef *edge_ref_array = MEM_calloc_arrayN((size_t)numEdges, sizeof(EdgeFaceRef), "Edge Connectivity");
+ EdgeFaceRef *edge_ref;
+ float edge_normal[3];
+
+ /* This loop adds an edge hash if its not there, and adds the face index */
+ for (i = 0; i < numFaces; i++, mp++) {
+ int j;
+
+ ml = mloop + mp->loopstart;
+
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ /* --- add edge ref to face --- */
+ edge_ref = &edge_ref_array[ml->e];
+ if (!edgeref_is_init(edge_ref)) {
+ edge_ref->f1 = i;
+ edge_ref->f2 = -1;
+ }
+ else if ((edge_ref->f1 != -1) && (edge_ref->f2 == -1)) {
+ edge_ref->f2 = i;
+ }
+ else {
+ /* 3+ faces using an edge, we can't handle this usefully */
+ edge_ref->f1 = edge_ref->f2 = -1;
+#ifdef USE_NONMANIFOLD_WORKAROUND
+ medge[ml->e].flag |= ME_EDGE_TMP_TAG;
+#endif
+ }
+ /* --- done --- */
+ }
+ }
+
+ for (i = 0, ed = medge, edge_ref = edge_ref_array; i < numEdges; i++, ed++, edge_ref++) {
+ /* Get the edge vert indices, and edge value (the face indices that use it) */
+
+ if (edgeref_is_init(edge_ref) && (edge_ref->f1 != -1)) {
+ if (edge_ref->f2 != -1) {
+ /* We have 2 faces using this edge, calculate the edges normal
+ * using the angle between the 2 faces as a weighting */
+#if 0
+ add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]);
+ normalize_v3_length(
+ edge_normal,
+ angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2]));
+#else
+ mid_v3_v3v3_angle_weighted(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]);
+#endif
+ }
+ else {
+ /* only one face attached to that edge */
+ /* an edge without another attached- the weight on this is undefined */
+ copy_v3_v3(edge_normal, face_nors[edge_ref->f1]);
+ }
+ add_v3_v3(r_vert_nors[ed->v1], edge_normal);
+ add_v3_v3(r_vert_nors[ed->v2], edge_normal);
+ }
+ }
+ MEM_freeN(edge_ref_array);
+ }
+
+ /* normalize vertex normals and assign */
+ for (i = 0; i < numVerts; i++, mv++) {
+ if (normalize_v3(r_vert_nors[i]) == 0.0f) {
+ normal_short_to_float_v3(r_vert_nors[i], mv->no);
+ }
+ }
+}
+
static void initData(ModifierData *md)
{
SolidifyModifierData *smd = (SolidifyModifierData *) md;
@@ -266,9 +366,7 @@ static Mesh *applyModifier(
if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) {
vert_nors = MEM_calloc_arrayN(numVerts, 3 * sizeof(float), "mod_solid_vno_hq");
- BKE_mesh_calc_normals_poly(mesh->mvert, vert_nors, mesh->totvert,
- mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly,
- NULL, false);
+ mesh_calc_hq_normal(mesh, face_nors, vert_nors);
}
result = BKE_mesh_from_template(mesh,