[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15634] branches/soc-2008-jaguarandi/ source/blender: *Added "kept" mesh above surface option on shrinkwrap to nearest surface

André Pinto andresusanopinto at gmail.com
Sat Jul 19 00:24:22 CEST 2008


Revision: 15634
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15634
Author:   jaguarandi
Date:     2008-07-19 00:24:20 +0200 (Sat, 19 Jul 2008)

Log Message:
-----------
*Added "kept" mesh above surface option on shrinkwrap to nearest surface
changed a few code relative to project over normal mode (to try to kept code generic and more independent of modifier itself)

Modified Paths:
--------------
    branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h
    branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c
    branches/soc-2008-jaguarandi/source/blender/blenlib/BLI_kdopbvh.h
    branches/soc-2008-jaguarandi/source/blender/blenlib/intern/BLI_kdopbvh.c
    branches/soc-2008-jaguarandi/source/blender/makesdna/DNA_modifier_types.h
    branches/soc-2008-jaguarandi/source/blender/src/buttons_editing.c

Modified: branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h
===================================================================
--- branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h	2008-07-18 22:16:23 UTC (rev 15633)
+++ branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h	2008-07-18 22:24:20 UTC (rev 15634)
@@ -42,7 +42,27 @@
 #define bitset_unset(set,index)	((set)[(index)>>3] &= ~(1 << ((index)&0x7)))
 
 
+/* SpaceTransform stuff */
+//TODO: should move to other generic space?
+struct Object;
 
+typedef struct SpaceTransform
+{
+	float local2target[4][4];
+	float target2local[4][4];
+
+} SpaceTransform;
+
+void space_transform_setup(SpaceTransform *data, struct Object *local, struct Object *target);
+
+void space_transform_apply (SpaceTransform *data, float *co);
+void space_transform_invert(SpaceTransform *data, float *co);
+
+void space_transform_apply_normal (SpaceTransform *data, float *co);
+void space_transform_invert_normal(SpaceTransform *data, float *co);
+
+
+/* Shrinkwrap stuff */
 struct Object;
 struct DerivedMesh;
 struct ShrinkwrapModifierData;
@@ -59,9 +79,7 @@
 
 	struct DerivedMesh *target;		//mesh we are shrinking to
 	
-	//matrixs for local<->target space transform
-	float local2target[4][4];		
-	float target2local[4][4];
+	SpaceTransform local2target;
 
 	float keptDist;					//Distance to kept from target (units are in local space)
 	//float *weights;				//weights of vertexs
@@ -75,6 +93,7 @@
 
 struct DerivedMesh *shrinkwrapModifier_do(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm, int useRenderParams, int isFinalCalc);
 
+
 #endif
 
 

Modified: branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c
===================================================================
--- branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c	2008-07-18 22:16:23 UTC (rev 15633)
+++ branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c	2008-07-18 22:24:20 UTC (rev 15634)
@@ -121,7 +121,39 @@
 	return FLT_MAX;
 }
 
+/* Space transform */
+void space_transform_setup(SpaceTransform *data, struct Object *local, struct Object *target)
+{
+	Mat4Invert(target->imat, target->obmat); //Invserse might be outdated
+	Mat4MulSerie(data->local2target, target->imat, local->obmat, 0, 0, 0, 0, 0, 0);
+	Mat4Invert(data->target2local, data->local2target);
+}
 
+void space_transform_apply(/* const */ SpaceTransform *data, float *co)
+{
+	VecMat4MulVecfl(co, data->local2target, co);
+//	Mat4Mul3Vecfl(data->local2target, co);
+}
+
+void space_transform_invert(/* const */SpaceTransform *data, float *co)
+{
+	VecMat4MulVecfl(co, data->target2local, co);
+//	Mat4Mul3Vecfl(data->target2local, co);
+}
+
+void space_transform_apply_normal(/* const */ SpaceTransform *data, float *no)
+{
+	Mat4Mul3Vecfl(data->local2target, no);
+	Normalize(no); // TODO: could we just determine de scale value from the matrix?
+}
+
+void space_transform_invert_normal(/* const */ SpaceTransform *data, float *no)
+{
+	Mat4Mul3Vecfl(data->target2local, no);
+	Normalize(no); // TODO: could we just determine de scale value from the matrix?
+}
+
+
 /*
  * BVH tree from mesh vertices
  */
@@ -328,6 +360,8 @@
 			hit->index = index;
 			hit->dist = dist;
 			VECADDFAC(hit->co, ray->origin, ray->direction, dist);
+
+			CalcNormFloat(t0, t1, t2, hit->no);
 		}
 
 		t1 = t2;
@@ -883,25 +917,24 @@
 	{
 		float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup);
 
-		float orig[3], final[3]; //Coords relative to target
+		float final[3]; //Coords relative to target
 		float normal[3];
 		float dist;
 
 		if(weight == 0.0f) continue;	//Skip vertexs where we have no influence
 
-		VecMat4MulVecfl(orig, calc->local2target, vert[i].co);
-		VECCOPY(final, orig);
+		VECCOPY(final, vert[i].co);
+		space_transform_apply(&calc->local2target, final);
 
 		//We also need to apply the rotation to normal
 		if(calc->smd->shrinkType == MOD_SHRINKWRAP_NORMAL)
 		{
 			NormalShortToFloat(normal, vert[i].no);
-			Mat4Mul3Vecfl(calc->local2target, normal);
-			Normalize(normal);	//Watch out for scaling (TODO: do we really needed a unit-len normal?)
+			space_transform_apply_normal(&calc->local2target, normal);
 		}
 		(callback)(calc->target, final, normal);
 
-		VecMat4MulVecfl(final, calc->target2local, final);
+		space_transform_invert(&calc->local2target, final);
 
 		dist = VecLenf(vert[i].co, final);
 		if(dist > 1e-5) weight *= (dist - calc->keptDist)/dist;
@@ -1075,6 +1108,7 @@
 	calc->final = new;
 }
 
+
 void shrinkwrap_projectToCutPlane(ShrinkwrapCalcData *calc_data)
 {
 	if(calc_data->smd->cutPlane && calc_data->moved)
@@ -1099,10 +1133,7 @@
 				return;
 			}
 
-			Mat4Invert (calc.smd->cutPlane->imat, calc.smd->cutPlane->obmat);	//inverse is outdated
-			Mat4MulSerie(calc.local2target, calc.smd->cutPlane->imat, calc.ob->obmat, 0, 0, 0, 0, 0, 0);
-			Mat4Invert(calc.target2local, calc.local2target);
-	
+			space_transform_setup(&calc.local2target, calc.ob, calc.smd->cutPlane);
 			calc.keptDist = 0;
 		}
 
@@ -1172,12 +1203,10 @@
 			printf("Target derived mesh is null! :S\n");
 		}
 
-		//TODO should we reduce the number of matrix mults? by choosing applying matrixs to target or to derived mesh?
-		//Calculate matrixs for local <-> target
-		Mat4Invert (smd->target->imat, smd->target->obmat);	//inverse is outdated
-		Mat4MulSerie(calc.local2target, smd->target->imat, ob->obmat, 0, 0, 0, 0, 0, 0);
-		Mat4Invert(calc.target2local, calc.local2target);
-	
+		//TODO there might be several "bugs" on non-uniform scales matrixs.. because it will no longer be nearest surface, not sphere projection
+		//because space has been deformed
+		space_transform_setup(&calc.local2target, ob, smd->target);
+
 		calc.keptDist = smd->keptDist;	//TODO: smd->keptDist is in global units.. must change to local
 	}
 
@@ -1282,7 +1311,8 @@
 		float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup);
 		if(weight == 0.0f) continue;
 
-		VecMat4MulVecfl(tmp_co, calc->local2target, vert[i].co);
+		VECCOPY(tmp_co, vert[i].co);
+		space_transform_apply(&calc->local2target, tmp_co);
 
 		if(nearest.index != -1)
 		{
@@ -1296,7 +1326,7 @@
 		{
 			float dist;
 
-			VecMat4MulVecfl(tmp_co, calc->target2local, nearest.nearest);
+			space_transform_invert(&calc->local2target, tmp_co);
 			dist = VecLenf(vert[i].co, tmp_co);
 			if(dist > 1e-5) weight *= (dist - calc->keptDist)/dist;
 			VecLerpf(vert[i].co, vert[i].co, tmp_co, weight);	//linear interpolation
@@ -1314,6 +1344,7 @@
  * it builds a RayTree from the target mesh and then performs a
  * raycast for each vertex (ray direction = normal)
  */
+/*
 void shrinkwrap_calc_normal_projection_raytree(ShrinkwrapCalcData *calc)
 {
 	int i;
@@ -1354,7 +1385,6 @@
 		Mat4Mul3Vecfl(calc->local2target, tmp_no);	//Watch out for scaling on normal
 		Normalize(tmp_no);							//(TODO: do we really needed a unit-len normal? and we could know the scale factor before hand?)
 
-
 		if(use_normal & MOD_SHRINKWRAP_ALLOW_DEFAULT_NORMAL)
 		{
 			dist = raytree_cast_ray(target, tmp_co, tmp_no, face_normal);
@@ -1404,7 +1434,62 @@
 
 	free_raytree_from_mesh(target);
 }
+*/
 
+
+/*
+ * This function raycast a single vertex and updates the hit if the "hit" is considered valid.
+ * Returns TRUE if "hit" was updated.
+ * Opts control whether an hit is valid or not
+ * Supported options are:
+ *	MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE (front faces hits are ignored)
+ *	MOD_SHRINKWRAP_CULL_TARGET_BACKFACE (back faces hits are ignored)
+ */
+static int normal_projection_project_vertex(char options, const float *vert, const float *dir,/* const */ SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, BVHMeshCallbackUserdata *userdata)
+{
+	float tmp_co[3], tmp_no[3];
+	BVHTreeRayHit hit_tmp;
+	memcpy( &hit_tmp, hit, sizeof(hit_tmp) );
+
+	//Apply space transform (TODO readjust dist)
+	if(transf)
+	{
+		VECCOPY( tmp_co, vert );
+		space_transform_apply( transf, tmp_co );
+		vert = tmp_co;
+
+		VECCOPY( tmp_no, dir );
+		space_transform_apply_normal( transf, tmp_no );
+		dir = tmp_no;
+	}
+
+	hit_tmp.index = -1;
+
+	BLI_bvhtree_ray_cast(tree, vert, dir, &hit_tmp, callback, userdata);
+
+	if(hit_tmp.index != -1)
+	{
+		float dot = INPR( dir, hit_tmp.no);
+
+		if(((options & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) && dot < 0)
+		|| ((options & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) && dot > 0))
+			return FALSE; //Ignore hit
+
+
+		//Inverting space transform (TODO readjust dist)
+		if(transf)
+		{
+			space_transform_invert( transf, hit_tmp.co );
+			space_transform_invert_normal( transf, hit_tmp.no );
+		}
+
+		memcpy(hit, &hit_tmp, sizeof(hit_tmp) );
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
 void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
 {
 	int i;
@@ -1417,6 +1502,14 @@
 	BVHMeshCallbackUserdata userdata;
 	BVHTree_RayCastCallback callback = NULL;
 
+
+	//cutTree
+	BVHTree *limit_tree = NULL;
+	BVHMeshCallbackUserdata limit_userdata;
+	BVHTree_RayCastCallback limit_callback = NULL;
+	SpaceTransform local2cut;
+
+
 	int	numVerts;
 	MVert *vert = NULL;
 	MDeformVert *dvert = NULL;
@@ -1429,6 +1522,21 @@
 	bvhtree_meshcallbackdata_init(&userdata, calc->target, calc->keptDist);
 	callback = mesh_faces_spherecast;
 
+	if(calc->smd->cutPlane)
+	{
+		DerivedMesh * limit_mesh = (DerivedMesh *)calc->smd->cutPlane->derivedFinal;
+		if(limit_mesh)
+		{
+			BENCH(limit_tree = bvhtree_from_mesh_faces(limit_mesh, 0.0, 4, 6));
+			bvhtree_meshcallbackdata_init(&limit_userdata, limit_mesh, 0.0);
+			limit_callback = mesh_faces_spherecast;
+
+			space_transform_setup( &local2cut, calc->ob, calc->smd->cutPlane);
+		}
+		else printf("CutPlane finalDerived mesh is null\n");
+	}
+
+
 	//Project each vertex along normal
 	numVerts= calc->final->getNumVerts(calc->final);
 	vert	= calc->final->getVertDataArray(calc->final, CD_MVERT);	
@@ -1437,69 +1545,39 @@
 	for(i=0; i<numVerts; i++)
 	{
 		float tmp_co[3], tmp_no[3];
+		float lim = 1000;		//TODO: we should use FLT_MAX here, but sweepsphere code isnt prepared for that
 		float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup);
 
 		if(weight == 0.0f) continue;
 
-		//Transform coordinates local->target
-		VecMat4MulVecfl(tmp_co, calc->local2target, vert[i].co);
-
+		VECCOPY(tmp_co, vert[i].co);
 		NormalShortToFloat(tmp_no, vert[i].no);
-		Mat4Mul3Vecfl(calc->local2target, tmp_no);	//Watch out for scaling on normal

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list