[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44301] trunk/blender/source/blender: Flip displacement direction after interpolation in bmesh_loop_interp_mdisps

Sergey Sharybin sergey.vfx at gmail.com
Tue Feb 21 18:23:15 CET 2012


Revision: 44301
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44301
Author:   nazgul
Date:     2012-02-21 17:23:03 +0000 (Tue, 21 Feb 2012)
Log Message:
-----------
Flip displacement direction after interpolation in bmesh_loop_interp_mdisps

This is needed because displacement might been interpolated from a grid
with different orientation and in this case X and Y components of displacement
are need to be flipped in needed order.

Order of flipping is determining by projecting source grids axis orientation
on target grid axis. This probably will give some unwanted artifacts when
interpolating non-planar face but currently can't think about better way
to determine how to flip displacement.

This commit makes operators like Subdivide works much more unpredictable
for sculpting data, but this stuff should be rethinked much more global
because current approach is not acceptable.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/customdata.c
    trunk/blender/source/blender/bmesh/intern/bmesh_interp.c

Modified: trunk/blender/source/blender/blenkernel/intern/customdata.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/customdata.c	2012-02-21 16:34:00 UTC (rev 44300)
+++ trunk/blender/source/blender/blenkernel/intern/customdata.c	2012-02-21 17:23:03 UTC (rev 44301)
@@ -449,6 +449,7 @@
 static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
 				float *UNUSED(sub_weights), int UNUSED(count), void *dest)
 {
+#if 0
 	MDisps *d = dest;
 
 	/* happens when flipping normals of newly created mesh */
@@ -458,6 +459,10 @@
 
 	if (!d->disps && d->totdisp)
 		d->disps = MEM_callocN(sizeof(float)*3*d->totdisp, "blank mdisps in layerInterp_mdisps");
+#else
+	(void) sources;
+	(void) dest;
+#endif
 }
 
 #else // BMESH_TODO

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_interp.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_interp.c	2012-02-21 16:34:00 UTC (rev 44300)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_interp.c	2012-02-21 17:23:03 UTC (rev 44301)
@@ -505,10 +505,20 @@
 	return 1;
 }
 
+static void mdisp_axis_from_quad(double v1[3], double v2[3], double UNUSED(v3[3]), double v4[3],
+                                float axis_x[3], float axis_y[3])
+{
+	VECSUB(axis_x, v4, v1);
+	VECSUB(axis_y, v2, v1);
 
+	normalize_v3(axis_x);
+	normalize_v3(axis_y);
+}
+
 /* tl is loop to project onto, l is loop whose internal displacement, co, is being
  * projected.  x and y are location in loop's mdisps grid of point co. */
-static int mdisp_in_mdispquad(BMesh *bm, BMLoop *l, BMLoop *tl, double p[3], double *x, double *y, int res)
+static int mdisp_in_mdispquad(BMesh *bm, BMLoop *l, BMLoop *tl, double p[3], double *x, double *y,
+                              int res, float axis_x[3], float axis_y[3])
 {
 	double v1[3], v2[3], c[3], v3[3], v4[3], e1[3], e2[3];
 	double eps = FLT_EPSILON * 4000;
@@ -536,9 +546,33 @@
 	*x *= res - 1;
 	*y *= res - 1;
 
+	mdisp_axis_from_quad(v1, v2, v3, v4, axis_x, axis_y);
+
 	return 1;
 }
 
+static void bmesh_loop_flip_disp(float source_axis_x[3], float source_axis_y[3],
+                                 float target_axis_x[3], float target_axis_y[3], float disp[3])
+{
+	float vx[3], vy[3], coord[3];
+
+	mul_v3_v3fl(vx, source_axis_x, disp[0]);
+	mul_v3_v3fl(vy, source_axis_y, disp[1]);
+	add_v3_v3v3(coord, vx, vy);
+
+	project_v3_v3v3(vx, coord, target_axis_x);
+	project_v3_v3v3(vy, coord, target_axis_y);
+
+	disp[0] = len_v3(vx);
+	disp[1] = len_v3(vy);
+
+	if(dot_v3v3(vx, target_axis_x) < 0)
+		disp[0] = -disp[0];
+
+	if(dot_v3v3(vy, target_axis_y) < 0)
+		disp[1] = -disp[1];
+}
+
 static void bmesh_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source)
 {
 	MDisps *mdisps;
@@ -546,6 +580,7 @@
 	BMLoop *l_first;
 	double x, y, d, v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3];
 	int ix, iy, res;
+	float axis_x[3], axis_y[3];
 	
 	/* ignore 2-edged faces */
 	if (target->f->len < 3)
@@ -571,6 +606,8 @@
 		}
 	}
 	
+	mdisp_axis_from_quad(v1, v2, v3, v4, axis_x, axis_y);
+
 	res = (int)sqrt(mdisps->totdisp);
 	d = 1.0 / (double)(res - 1);
 	for (x = 0.0f, ix = 0; ix < res; x += d, ix++) {
@@ -601,15 +638,19 @@
 			do {
 				double x2, y2;
 				MDisps *md1, *md2;
+				float src_axis_x[3], src_axis_y[3];
 
 				md1 = CustomData_bmesh_get(&bm->ldata, target->head.data, CD_MDISPS);
 				md2 = CustomData_bmesh_get(&bm->ldata, l_iter->head.data, CD_MDISPS);
 				
-				if (mdisp_in_mdispquad(bm, target, l_iter, co, &x2, &y2, res)) {
+				if (mdisp_in_mdispquad(bm, target, l_iter, co, &x2, &y2, res, src_axis_x, src_axis_y)) {
 					/* int ix2 = (int)x2; */ /* UNUSED */
 					/* int iy2 = (int)y2; */ /* UNUSED */
 					
 					old_mdisps_bilinear(md1->disps[iy * res + ix], md2->disps, res, (float)x2, (float)y2);
+					bmesh_loop_flip_disp(src_axis_x, src_axis_y, axis_x, axis_y, md1->disps[iy * res + ix]);
+
+					break;
 				}
 			} while ((l_iter = l_iter->next) != l_first);
 		}
@@ -718,8 +759,33 @@
 	}
 }
 
+#if 0
+static void print_loop(BMLoop *loop)
+{
+	BMLoop *cur = loop;
+	do {
+		print_v3("\t\tco", cur->v->co);
+	} while ((cur = cur->next) != loop);
+}
+#endif
+
 void BM_loop_interp_multires(BMesh *bm, BMLoop *target, BMFace *source)
 {
+#if 0
+	{
+		static int count = 0;
+		count++;
+		printf("%s: counter=%d\n", __func__, count);
+		printf("\ttarget=%p:\n", target);
+		print_loop(target);
+		printf("\tsource=%p:\n", source);
+		print_loop(source->l_first);
+		/*if(count!=5) {
+			return;
+		}*/
+	}
+#endif
+
 	bmesh_loop_interp_mdisps(bm, target, source);
 }
 




More information about the Bf-blender-cvs mailing list