[Bf-blender-cvs] [355ad008a2] master: Surface Deform Modifier: Respect object transforms at bind time

Luca Rood noreply at git.blender.org
Mon Mar 6 07:48:27 CET 2017


Commit: 355ad008a26f9605752108c74e813c43dc0659d2
Author: Luca Rood
Date:   Mon Mar 6 02:40:29 2017 -0300
Branches: master
https://developer.blender.org/rB355ad008a26f9605752108c74e813c43dc0659d2

Surface Deform Modifier: Respect object transforms at bind time

This slightly changes SDef behavior, by now respecting object transforms
at bind time, thus not requiring the objects to be aligned in their
respective local spaces, but instead using world space.

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

M	source/blender/blenloader/intern/versioning_270.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/modifiers/intern/MOD_surfacedeform.c

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

diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index 7106cf6072..d3f33cf725 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -1598,6 +1598,17 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
 				}
 			} FOREACH_NODETREE_END
 		}
+
+		if (!DNA_struct_elem_find(fd->filesdna, "SurfaceDeformModifierData", "float", "mat[4][4]")) {
+			for (Object *ob = main->object.first; ob; ob = ob->id.next) {
+				for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
+					if (md->type == eModifierType_SurfaceDeform) {
+						SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+						unit_m4(smd->mat);
+					}
+				}
+			}
+		}
 	}
 }
 
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 0c17909db2..32b43c7ea5 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1594,6 +1594,7 @@ typedef struct SurfaceDeformModifierData {
 	float falloff;
 	unsigned int numverts, numpoly;
 	int flags;
+	float mat[4][4];
 } SurfaceDeformModifierData;
 
 /* Surface Deform modifier flags */
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 3beb69f079..a999d7629a 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -40,8 +40,9 @@ typedef struct SDefBindCalcData {
 	const MPoly * const mpoly;
 	const MEdge * const medge;
 	const MLoop * const mloop;
-	const MVert * const mvert;
+	float (* const targetCos)[3];
 	float (* const vertexCos)[3];
+	float imat[4][4];
 	const float falloff;
 	int success;
 } SDefBindCalcData;
@@ -81,7 +82,7 @@ typedef struct SDefBindWeightData {
 
 typedef struct SDefDeformData {
 	const SDefVert * const bind_verts;
-	const MVert * const mvert;
+	float (* const targetCos)[3];
 	float (* const vertexCos)[3];
 } SDefDeformData;
 
@@ -282,23 +283,25 @@ BLI_INLINE void sortPolyVertsTri(unsigned int *indices, const MLoop * const mloo
 
 BLI_INLINE unsigned int nearestVert(SDefBindCalcData * const data, const float point_co[3])
 {
-	const MVert * const mvert = data->mvert;
 	BVHTreeNearest nearest = {.dist_sq = FLT_MAX, .index = -1};
 	const MPoly *poly;
 	const MEdge *edge;
 	const MLoop *loop;
+	float t_point[3];
 	float max_dist = FLT_MAX;
 	float dist;
 	unsigned int index = 0;
 
-	BLI_bvhtree_find_nearest(data->treeData->tree, point_co, &nearest, data->treeData->nearest_callback, data->treeData);
+	mul_v3_m4v3(t_point, data->imat, point_co);
+
+	BLI_bvhtree_find_nearest(data->treeData->tree, t_point, &nearest, data->treeData->nearest_callback, data->treeData);
 
 	poly = &data->mpoly[data->looptri[nearest.index].poly];
 	loop = &data->mloop[poly->loopstart];
 
 	for (int i = 0; i < poly->totloop; i++, loop++) {
 		edge = &data->medge[loop->e];
-		dist = dist_squared_to_line_segment_v3(point_co, mvert[edge->v1].co, mvert[edge->v2].co);
+		dist = dist_squared_to_line_segment_v3(point_co, data->targetCos[edge->v1], data->targetCos[edge->v2]);
 
 		if (dist < max_dist) {
 			max_dist = dist;
@@ -307,7 +310,7 @@ BLI_INLINE unsigned int nearestVert(SDefBindCalcData * const data, const float p
 	}
 
 	edge = &data->medge[index];
-	if (len_squared_v3v3(point_co, mvert[edge->v1].co) < len_squared_v3v3(point_co, mvert[edge->v2].co)) {
+	if (len_squared_v3v3(point_co, data->targetCos[edge->v1]) < len_squared_v3v3(point_co, data->targetCos[edge->v2])) {
 		return edge->v1;
 	}
 	else {
@@ -456,7 +459,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData * const data,
 				}
 
 				for (int j = 0; j < poly->totloop; j++, loop++) {
-					copy_v3_v3(bpoly->coords[j], data->mvert[loop->v].co);
+					copy_v3_v3(bpoly->coords[j], data->targetCos[loop->v]);
 
 					/* Find corner and edge indices within poly loop array */
 					if (loop->v == nearest) {
@@ -845,8 +848,8 @@ static void bindVert(void *userdata, void *UNUSED(userdata_chunk), const int ind
 					sortPolyVertsEdge(sdbind->vert_inds, &data->mloop[bpoly->loopstart],
 					                  bpoly->edge_inds[bpoly->dominant_edge], bpoly->numverts);
 
-					copy_v3_v3(v1, data->mvert[sdbind->vert_inds[0]].co);
-					copy_v3_v3(v2, data->mvert[sdbind->vert_inds[1]].co);
+					copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]);
+					copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]);
 					copy_v3_v3(v3, bpoly->centroid);
 
 					mid_v3_v3v3v3(cent, v1, v2, v3);
@@ -887,9 +890,9 @@ static void bindVert(void *userdata, void *UNUSED(userdata_chunk), const int ind
 
 					sortPolyVertsTri(sdbind->vert_inds, &data->mloop[bpoly->loopstart], bpoly->edge_vert_inds[0], bpoly->numverts);
 
-					copy_v3_v3(v1, data->mvert[sdbind->vert_inds[0]].co);
-					copy_v3_v3(v2, data->mvert[sdbind->vert_inds[1]].co);
-					copy_v3_v3(v3, data->mvert[sdbind->vert_inds[2]].co);
+					copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]);
+					copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]);
+					copy_v3_v3(v3, data->targetCos[sdbind->vert_inds[2]]);
 
 					mid_v3_v3v3v3(cent, v1, v2, v3);
 					normal_tri_v3(norm, v1, v2, v3);
@@ -917,14 +920,14 @@ static void bindVert(void *userdata, void *UNUSED(userdata_chunk), const int ind
 }
 
 static bool surfacedeformBind(SurfaceDeformModifierData *smd, float (*vertexCos)[3],
-                              unsigned int numverts, unsigned int tnumpoly, DerivedMesh *tdm)
+                              unsigned int numverts, unsigned int tnumpoly, unsigned int tnumverts, DerivedMesh *tdm)
 {
 	BVHTreeFromMesh treeData = {NULL};
+	const MVert *mvert = tdm->getVertArray(tdm);
 	const MPoly *mpoly = tdm->getPolyArray(tdm);
 	const MEdge *medge = tdm->getEdgeArray(tdm);
 	const MLoop *mloop = tdm->getLoopArray(tdm);
 	unsigned int tnumedges = tdm->getNumEdges(tdm);
-	unsigned int tnumverts = tdm->getNumVerts(tdm);
 	int adj_result;
 	SDefAdjacencyArray *vert_edges;
 	SDefAdjacency *adj_array;
@@ -988,15 +991,29 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd, float (*vertexCos)
 		                     .medge = medge,
 		                     .mloop = mloop,
 		                     .looptri = tdm->getLoopTriArray(tdm),
-		                     .mvert = tdm->getVertArray(tdm),
+		                     .targetCos = MEM_mallocN(sizeof(float[3]) * tnumverts, "SDefTargetBindVertArray"),
 		                     .bind_verts = smd->verts,
 		                     .vertexCos = vertexCos,
 		                     .falloff = smd->falloff,
 		                     .success = MOD_SDEF_BIND_RESULT_SUCCESS};
 
+	if (data.targetCos == NULL) {
+		modifier_setError((ModifierData *)smd, "Out of memory");
+		freeData((ModifierData *)smd);
+		return false;
+	}
+
+	invert_m4_m4(data.imat, smd->mat);
+
+	for (int i = 0; i < tnumverts; i++) {
+		mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
+	}
+
 	BLI_task_parallel_range_ex(0, numverts, &data, NULL, 0, bindVert,
 	                           numverts > 10000, false);
 
+	MEM_freeN(data.targetCos);
+
 	if (data.success == MOD_SDEF_BIND_RESULT_MEM_ERR) {
 		modifier_setError((ModifierData *)smd, "Out of memory");
 		freeData((ModifierData *)smd);
@@ -1032,7 +1049,6 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
 {
 	const SDefDeformData * const data = (SDefDeformData *)userdata;
 	const SDefBind *sdbind = data->bind_verts[index].binds;
-	const MVert * const mvert = data->mvert;
 	float * const vertexCos = data->vertexCos[index];
 	float norm[3], temp[3];
 
@@ -1043,7 +1059,7 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
 		float (*coords)[3] = MEM_mallocN(sizeof(*coords) * sdbind->numverts, "SDefDoPolyCoords");
 
 		for (int k = 0; k < sdbind->numverts; k++) {
-			copy_v3_v3(coords[k], mvert[sdbind->vert_inds[k]].co);
+			copy_v3_v3(coords[k], data->targetCos[sdbind->vert_inds[k]]);
 		}
 
 		normal_poly_v3(norm, coords, sdbind->numverts);
@@ -1051,9 +1067,9 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
 
 		/* ---------- looptri mode ---------- */
 		if (sdbind->mode == MOD_SDEF_MODE_LOOPTRI) {
-			madd_v3_v3fl(temp, mvert[sdbind->vert_inds[0]].co, sdbind->vert_weights[0]);
-			madd_v3_v3fl(temp, mvert[sdbind->vert_inds[1]].co, sdbind->vert_weights[1]);
-			madd_v3_v3fl(temp, mvert[sdbind->vert_inds[2]].co, sdbind->vert_weights[2]);
+			madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
+			madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
+			madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[2]], sdbind->vert_weights[2]);
 		}
 		else {
 			/* ---------- ngon mode ---------- */
@@ -1068,8 +1084,8 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
 				float cent[3];
 				mid_v3_v3_array(cent, coords, sdbind->numverts);
 
-				madd_v3_v3fl(temp, mvert[sdbind->vert_inds[0]].co, sdbind->vert_weights[0]);
-				madd_v3_v3fl(temp, mvert[sdbind->vert_inds[1]].co, sdbind->vert_weights[1]);
+				madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
+				madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
 				madd_v3_v3fl(temp, cent, sdbind->vert_weights[2]);
 			}
 		}
@@ -1083,12 +1099,11 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
 	}
 }
 
-static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], unsigned int numverts)
+static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], unsigned int numverts, Object *ob)
 {
 	SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
 	DerivedMesh *tdm;
-	unsigned int tnumpoly;
-	bool tdm_vert_alloc;
+	unsigned int tnumverts, tnumpoly;
 
 	/* Exit function if bind flag is not set (free bind data if any) */
 	if (!(smd->flags & MOD_SDEF_BIND)) {
@@ -1105,11 +1120,17 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
 		tdm = smd->target->derivedFinal;
 	}

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list