[Bf-blender-cvs] [13aa3de6975] blender2.8: Modifier stack: port 'normals edit' to new Mesh-based system.

Bastien Montagne noreply at git.blender.org
Mon May 7 14:38:08 CEST 2018


Commit: 13aa3de697536a85a19ed1d4bf48cd6b26f676eb
Author: Bastien Montagne
Date:   Mon May 7 14:36:00 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB13aa3de697536a85a19ed1d4bf48cd6b26f676eb

Modifier stack: port 'normals edit' to new Mesh-based system.

Note that custom normals drawing seems to be broken, and there also are
some refresh issues in some cases... But this is same with old DM-based
code, so not related to modifiers themselves probably.

===================================================================

M	source/blender/modifiers/intern/MOD_normal_edit.c

===================================================================

diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c
index e056dffc160..7f080a0bd20 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.h"
 #include "BKE_library_query.h"
 #include "BKE_mesh.h"
 #include "BKE_deform.h"
@@ -46,7 +47,7 @@
 
 
 static void generate_vert_coordinates(
-        DerivedMesh *dm, Object *ob, Object *ob_center, const float offset[3],
+        Mesh *mesh, Object *ob, Object *ob_center, const float offset[3],
         const int num_verts, float (*r_cos)[3], float r_size[3])
 {
 	float min_co[3], max_co[3];
@@ -55,30 +56,37 @@ static void generate_vert_coordinates(
 
 	INIT_MINMAX(min_co, max_co);
 
-	dm->getVertCos(dm, r_cos);
+	MVert *mv = mesh->mvert;
+	for (int i = 0; i < mesh->totvert; i++, mv++) {
+		copy_v3_v3(r_cos[i], mv->co);
+		if (r_size != NULL && ob_center == NULL) {
+			minmax_v3v3_v3(min_co, max_co, r_cos[i]);
+		}
+	}
 
 	/* Get size (i.e. deformation of the spheroid generating normals), either from target object, or own geometry. */
-	if (ob_center) {
-		/* Not we are not interested in signs here - they are even troublesome actually, due to security clamping! */
-		abs_v3_v3(r_size, ob_center->size);
-	}
-	else {
-		minmax_v3v3_v3_array(min_co, max_co, r_cos, num_verts);
-		/* Set size. */
-		sub_v3_v3v3(r_size, max_co, min_co);
-	}
+	if (r_size != NULL) {
+		if (ob_center != NULL) {
+			/* Not we are not interested in signs here - they are even troublesome actually, due to security clamping! */
+			abs_v3_v3(r_size, ob_center->size);
+		}
+		else {
+			/* Set size. */
+			sub_v3_v3v3(r_size, max_co, min_co);
+		}
 
-	/* Error checks - we do not want one or more of our sizes to be null! */
-	if (is_zero_v3(r_size)) {
-		r_size[0] = r_size[1] = r_size[2] = 1.0f;
-	}
-	else {
-		CLAMP_MIN(r_size[0], FLT_EPSILON);
-		CLAMP_MIN(r_size[1], FLT_EPSILON);
-		CLAMP_MIN(r_size[2], FLT_EPSILON);
+		/* Error checks - we do not want one or more of our sizes to be null! */
+		if (is_zero_v3(r_size)) {
+			r_size[0] = r_size[1] = r_size[2] = 1.0f;
+		}
+		else {
+			CLAMP_MIN(r_size[0], FLT_EPSILON);
+			CLAMP_MIN(r_size[1], FLT_EPSILON);
+			CLAMP_MIN(r_size[2], FLT_EPSILON);
+		}
 	}
 
-	if (ob_center) {
+	if (ob_center != NULL) {
 		float inv_obmat[4][4];
 
 		/* Translate our coordinates so that center of ob_center is at (0, 0, 0). */
@@ -90,7 +98,7 @@ static void generate_vert_coordinates(
 
 		do_diff = true;
 	}
-	else if (!is_zero_v3(offset)) {
+	else if (offset != NULL && !is_zero_v3(offset)) {
 		negate_v3_v3(diff, offset);
 
 		do_diff = true;
@@ -186,7 +194,7 @@ static bool polygons_check_flip(
 }
 
 static void normalEditModifier_do_radial(
-        NormalEditModifierData *enmd, Object *ob, DerivedMesh *dm,
+        NormalEditModifierData *enmd, Object *ob, Mesh *mesh,
         short (*clnors)[2], float (*loopnors)[3], 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,
@@ -201,7 +209,7 @@ static void normalEditModifier_do_radial(
 
 	BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)num_verts, __func__);
 
-	generate_vert_coordinates(dm, ob, enmd->target, enmd->offset, num_verts, cos, size);
+	generate_vert_coordinates(mesh, ob, enmd->target, enmd->offset, num_verts, cos, size);
 
 	/**
 	 * size gives us our spheroid coefficients ``(A, B, C)``.
@@ -270,10 +278,11 @@ static void normalEditModifier_do_radial(
 		            mix_limit, 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;
+	if (polygons_check_flip(mloop, nos, &mesh->ldata, mpoly, polynors, num_polys)) {
+		/* XXX TODO is this still needed? */
+		// mesh->dirty |= DM_DIRTY_TESS_CDLAYERS;
 		/* We need to recompute vertex normals! */
-		dm->calcNormals(dm);
+		BKE_mesh_calc_normals(mesh);
 	}
 
 	BKE_mesh_normals_loop_custom_set(mvert, num_verts, medge, num_edges, mloop, nos, num_loops,
@@ -285,7 +294,7 @@ static void normalEditModifier_do_radial(
 }
 
 static void normalEditModifier_do_directional(
-        NormalEditModifierData *enmd, Object *ob, DerivedMesh *dm,
+        NormalEditModifierData *enmd, Object *ob, Mesh *mesh,
         short (*clnors)[2], float (*loopnors)[3], 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,
@@ -294,22 +303,17 @@ static void normalEditModifier_do_directional(
 {
 	const bool use_parallel_normals = (enmd->flag & MOD_NORMALEDIT_USE_DIRECTION_PARALLEL) != 0;
 
-	float (*cos)[3] = MEM_malloc_arrayN((size_t)num_verts, sizeof(*cos), __func__);
 	float (*nos)[3] = MEM_malloc_arrayN((size_t)num_loops, sizeof(*nos), __func__);
 
 	float target_co[3];
 	int i;
 
-	dm->getVertCos(dm, cos);
-
 	/* Get target's center coordinates in ob local coordinates. */
-	{
-		float mat[4][4];
+	float mat[4][4];
 
-		invert_m4_m4(mat, ob->obmat);
-		mul_m4_m4m4(mat, mat, enmd->target->obmat);
-		copy_v3_v3(target_co, mat[3]);
-	}
+	invert_m4_m4(mat, ob->obmat);
+	mul_m4_m4m4(mat, mat, enmd->target->obmat);
+	copy_v3_v3(target_co, mat[3]);
 
 	if (use_parallel_normals) {
 		float no[3];
@@ -322,6 +326,9 @@ static void normalEditModifier_do_directional(
 		}
 	}
 	else {
+		float (*cos)[3] = MEM_malloc_arrayN((size_t)num_verts, sizeof(*cos), __func__);
+		generate_vert_coordinates(mesh, ob, enmd->target, NULL, num_verts, cos, NULL);
+
 		BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)num_verts, __func__);
 		MLoop *ml;
 		float (*no)[3];
@@ -342,6 +349,7 @@ static void normalEditModifier_do_directional(
 		}
 
 		MEM_freeN(done_verts);
+		MEM_freeN(cos);
 	}
 
 	if (loopnors) {
@@ -349,14 +357,13 @@ static void normalEditModifier_do_directional(
 		            mix_limit, 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;
+	if (polygons_check_flip(mloop, nos, &mesh->ldata, mpoly, polynors, num_polys)) {
+		mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
 	}
 
 	BKE_mesh_normals_loop_custom_set(mvert, num_verts, medge, num_edges, mloop, nos, num_loops,
 	                                 mpoly, (const float(*)[3])polynors, num_polys, clnors);
 
-	MEM_freeN(cos);
 	MEM_freeN(nos);
 }
 
@@ -372,93 +379,105 @@ static bool is_valid_target(NormalEditModifierData *enmd)
 	return false;
 }
 
-static DerivedMesh *normalEditModifier_do(NormalEditModifierData *enmd, Object *ob, DerivedMesh *dm)
+static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, Object *ob, Mesh *mesh)
 {
-	Mesh *me = ob->data;
-
-	const int num_verts = dm->getNumVerts(dm);
-	const int num_edges = dm->getNumEdges(dm);
-	const int num_loops = dm->getNumLoops(dm);
-	const int num_polys = dm->getNumPolys(dm);
-	MVert *mvert;
-	MEdge *medge;
-	MLoop *mloop;
-	MPoly *mpoly;
-
 	const bool use_invert_vgroup = ((enmd->flag & MOD_NORMALEDIT_INVERT_VGROUP) != 0);
 	const bool use_current_clnors = !((enmd->mix_mode == MOD_NORMALEDIT_MIX_COPY) &&
 	                                  (enmd->mix_factor == 1.0f) &&
 	                                  (enmd->defgrp_name[0] == '\0') &&
 	                                  (enmd->mix_limit == (float)M_PI));
 
+	/* Do not run that modifier at all if autosmooth is disabled! */
+	if (!is_valid_target(enmd) || mesh->totloop == 0) {
+		return mesh;
+	}
+
+	/* XXX TODO ARG GRRR XYQWNMPRXTYY
+	 * Once we fully switch to Mesh evaluation of modifiers, we can expect to get that flag from the COW copy.
+	 * But for now, it is lost in the DM intermediate step, so we need to directly check orig object's data. */
+#if 0
+	if (!(mesh->flag & ME_AUTOSMOOTH)) {
+#else
+	if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) {
+#endif
+		modifier_setError((ModifierData *)enmd, "Enable 'Auto Smooth' option in mesh settings");
+		return mesh;
+	}
+
+	Mesh *result;
+	BKE_id_copy_ex(
+	            NULL, &mesh->id, (ID **)&result,
+	            LIB_ID_CREATE_NO_MAIN |
+	            LIB_ID_CREATE_NO_USER_REFCOUNT |
+	            LIB_ID_CREATE_NO_DEG_TAG|
+	            LIB_ID_COPY_NO_PREVIEW,
+	            false);
+
+	const int num_verts = result->totvert;
+	const int num_edges = result->totedge;
+	const int num_loops = result->totloop;
+	const int num_polys = result->totpoly;
+	MVert *mvert = result->mvert;
+	MEdge *medge = result->medge;
+	MLoop *mloop = result->mloop;
+	MPoly *mpoly = result->mpoly;
+
 	int defgrp_index;
 	MDeformVert *dvert;
 
 	float (*loopnors)[3] = NULL;
-	short (*clnors)[2];
+	short (*clnors)[2] = NULL;
 
 	float (*polynors)[3];
-	bool free_polynors = false;
 
-	/* Do not run that modifier at all if autosmooth is disabled! */
-	if (!is_valid_target(enmd) || !num_loops) {
-		return dm;
+	CustomData *ldata = &result->ldata;
+	if (CustomData_has_layer(ldata, CD_NORMAL)) {
+		loopnors = CustomData_get_layer(ldata, CD_NORMAL);
 	}
-
-	if (!(me->flag & ME_AUTOSMOOTH)) {
-		modifier_setError((ModifierData *)enmd, "Enable 'Auto Smooth' option in mesh settings");
-		return dm;
+	else {
+		loopnors = CustomData_add_layer(ldata, CD_NORMAL, CD_CALLOC, NULL, num_loops);
 	}
 
-	medge = dm->getEdgeArray(dm);
-	if (me->medge == medge) {
-		/* We need to duplicate data here, otherwise setting custom normals (which may also affect sharp edges) could
-		 * modify org mesh, see T43671. */
-		dm = CDDM_copy(dm);
-		medge = dm->getEdgeArray(dm);
+	/* Compute poly (always needed) and vert normals. */
+	CustomData *pdata = &result->pdata;
+	polynors = CustomData_get_layer(pdata, CD_NORMAL);
+	if (!polynors) {
+		polynors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, num_polys);
 	}
-	mvert = dm->getVertArray(dm);
-	mloop = dm->getLoopArray(dm);
-	mpoly = dm->getPolyArray(dm);
+	BKE_mesh_calc_normals_poly(mvert, NULL, num_verts, mloop, mpoly, num_loops, num_polys, polynors,
+	            

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list