[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25572] trunk/blender/source/blender: barycentric transform utility geometry function.

Campbell Barton ideasman42 at gmail.com
Sun Dec 27 02:32:59 CET 2009


Revision: 25572
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25572
Author:   campbellbarton
Date:     2009-12-27 02:32:58 +0100 (Sun, 27 Dec 2009)

Log Message:
-----------
barycentric transform utility geometry function.
>From 2 triangles and 1 point, the relative position between the point and the first triangle is applied to the second triangle to find the target point.
the barycentric weights are calculated in 2D space with a signed area so values outside the triangle bounds are supported.

wrapped by python:
 pt_to = Geometry.BarycentricTransform(pt_from, t1a, t1b, t1c, t2a, t1b, t1c)

NOTE: 
- moved some barycentric weight functions out of projection painting into the math lib.
- ended up making some of the math functions use const args.
TODO:
- support exceptional cases. zero area tries and similar.

Modified Paths:
--------------
    trunk/blender/source/blender/blenlib/BLI_math_geom.h
    trunk/blender/source/blender/blenlib/BLI_math_rotation.h
    trunk/blender/source/blender/blenlib/BLI_math_vector.h
    trunk/blender/source/blender/blenlib/intern/math_geom.c
    trunk/blender/source/blender/blenlib/intern/math_rotation.c
    trunk/blender/source/blender/blenlib/intern/math_vector.c
    trunk/blender/source/blender/blenlib/intern/math_vector_inline.c
    trunk/blender/source/blender/editors/sculpt_paint/paint_image.c
    trunk/blender/source/blender/python/generic/Geometry.c

Modified: trunk/blender/source/blender/blenlib/BLI_math_geom.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_math_geom.h	2009-12-27 01:28:13 UTC (rev 25571)
+++ trunk/blender/source/blender/blenlib/BLI_math_geom.h	2009-12-27 01:32:58 UTC (rev 25572)
@@ -37,12 +37,13 @@
 void cent_tri_v3(float r[3], float a[3], float b[3], float c[3]);
 void cent_quad_v3(float r[3], float a[3], float b[3], float c[3], float d[3]);
 
-float normal_tri_v3(float r[3], float a[3], float b[3], float c[3]);
-float normal_quad_v3(float r[3], float a[3], float b[3], float c[3], float d[3]);
+float normal_tri_v3(float r[3], const float a[3], const float b[3], const float c[3]);
+float normal_quad_v3(float r[3], const float a[3], const float b[3], const float c[3], const float d[3]);
 
-float area_tri_v2(float a[2], float b[2], float c[2]);
-float area_tri_v3(float a[3], float b[3], float c[3]);
-float area_quad_v3(float a[3], float b[3], float c[3], float d[3]);
+float area_tri_v2(const float a[2], const float b[2], const float c[2]);
+float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2]);
+float area_tri_v3(const float a[3], const float b[3], const float c[3]);
+float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]);
 float area_poly_v3(int nr, float verts[][3], float normal[3]);
 
 /********************************* Distance **********************************/
@@ -120,6 +121,13 @@
 void interp_cubic_v3(float x[3], float v[3],
 	float x1[3], float v1[3], float x2[3], float v2[3], float t);
 
+void barycentric_transform(float pt_tar[3], float const pt_src[3],
+	const float tri_tar_p1[3], const float tri_tar_p2[3], const float tri_tar_p3[3],
+	const float tri_src_p1[3], const float tri_src_p2[3], const float tri_src_p3[3]);
+
+void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2],
+	const float co[2], float w[3]);
+
 /***************************** View & Projection *****************************/
 
 void lookat_m4(float mat[4][4], float vx, float vy, 

Modified: trunk/blender/source/blender/blenlib/BLI_math_rotation.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_math_rotation.h	2009-12-27 01:28:13 UTC (rev 25571)
+++ trunk/blender/source/blender/blenlib/BLI_math_rotation.h	2009-12-27 01:32:58 UTC (rev 25572)
@@ -70,7 +70,8 @@
 void mat4_to_quat(float q[4], float mat[4][4]);
 void tri_to_quat(float q[4], float a[3], float b[3], float c[3]);
 void vec_to_quat(float q[4], float vec[3], short axis, short upflag);
-void rotation_between_vecs_to_quat(float q[4], float v1[3], float v2[3]);
+/* note: v1 and v2 must be normalized */
+void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3]);
 
 /* TODO: don't what this is, but it's not the same as mat3_to_quat */
 void mat3_to_quat_is_ok(float q[4], float mat[3][3]);

Modified: trunk/blender/source/blender/blenlib/BLI_math_vector.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_math_vector.h	2009-12-27 01:28:13 UTC (rev 25571)
+++ trunk/blender/source/blender/blenlib/BLI_math_vector.h	2009-12-27 01:32:58 UTC (rev 25572)
@@ -51,8 +51,8 @@
 MINLINE void zero_v2(float r[2]);
 MINLINE void zero_v3(float r[3]);
 
-MINLINE void copy_v2_v2(float r[2], float a[2]);
-MINLINE void copy_v3_v3(float r[3], float a[3]);
+MINLINE void copy_v2_v2(float r[2], const float a[2]);
+MINLINE void copy_v3_v3(float r[3], const float a[3]);
 
 MINLINE void swap_v2_v2(float a[2], float b[2]);
 MINLINE void swap_v3_v3(float a[3], float b[3]);
@@ -67,7 +67,7 @@
 MINLINE void sub_v2_v2(float r[2], float a[2]);
 MINLINE void sub_v2_v2v2(float r[2], float a[2], float b[2]);
 MINLINE void sub_v3_v3(float r[3], float a[3]);
-MINLINE void sub_v3_v3v3(float r[3], float a[3], float b[3]);
+MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3]);
 
 MINLINE void mul_v2_fl(float r[2], float f);
 MINLINE void mul_v3_fl(float r[3], float f);
@@ -87,7 +87,7 @@
 MINLINE float dot_v3v3(float a[3], float b[3]);
 
 MINLINE float cross_v2v2(float a[2], float b[2]);
-MINLINE void cross_v3_v3v3(float r[3], float a[3], float b[3]);
+MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]);
 
 MINLINE void star_m3_v3(float R[3][3],float a[3]);
 
@@ -103,11 +103,11 @@
 
 /******************************* Interpolation *******************************/
 
-void interp_v2_v2v2(float r[2], float a[2], float b[2], float t);
-void interp_v2_v2v2v2(float r[2], float a[2], float b[2], float c[3], float t[3]);
-void interp_v3_v3v3(float r[3], float a[3], float b[3], float t);
-void interp_v3_v3v3v3(float p[3], float v1[3], float v2[3], float v3[3], float w[3]);
-void interp_v3_v3v3v3v3(float p[3], float v1[3], float v2[3], float v3[3], float v4[3], float w[4]);
+void interp_v2_v2v2(float r[2], const float a[2], const float b[2], const float t);
+void interp_v2_v2v2v2(float r[2], const float a[2], const float b[2], const float c[3], const float t[3]);
+void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t);
+void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3]);
+void interp_v3_v3v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float w[4]);
 
 void mid_v3_v3v3(float r[3], float a[3], float b[3]);
 
@@ -130,7 +130,7 @@
 float angle_normalized_v2v2(float a[2], float b[2]);
 float angle_v3v3(float a[2], float b[2]);
 float angle_v3v3v3(float a[2], float b[2], float c[2]);
-float angle_normalized_v3v3(float a[3], float b[3]);
+float angle_normalized_v3v3(const float v1[3], const float v2[3]);
 void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3]);
 void angle_quad_v3(float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
 

Modified: trunk/blender/source/blender/blenlib/intern/math_geom.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_geom.c	2009-12-27 01:28:13 UTC (rev 25571)
+++ trunk/blender/source/blender/blenlib/intern/math_geom.c	2009-12-27 01:32:58 UTC (rev 25572)
@@ -49,7 +49,7 @@
 	cent[2]= 0.25f*(v1[2]+v2[2]+v3[2]+v4[2]);
 }
 
-float normal_tri_v3(float *n, float *v1, float *v2, float *v3)
+float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
 {
 	float n1[3],n2[3];
 
@@ -65,7 +65,7 @@
 	return normalize_v3(n);
 }
 
-float normal_quad_v3(float *n, float *v1, float *v2, float *v3, float *v4)
+float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
 {
 	/* real cross! */
 	float n1[3],n2[3];
@@ -85,13 +85,17 @@
 	return normalize_v3(n);
 }
 
-float area_tri_v2(float *v1, float *v2, float *v3)
+float area_tri_v2(const float v1[2], const float v2[2], const float v3[2])
 {
-	return (float)(0.5*fabs((v1[0]-v2[0])*(v2[1]-v3[1]) + (v1[1]-v2[1])*(v3[0]-v2[0])));
+	return (float)(0.5f*fabs((v1[0]-v2[0])*(v2[1]-v3[1]) + (v1[1]-v2[1])*(v3[0]-v2[0])));
 }
 
+float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2])
+{
+   return (float)(0.5f*((v1[0]-v2[0])*(v2[1]-v3[1]) + (v1[1]-v2[1])*(v3[0]-v2[0])));
+}
 
-float area_quad_v3(float *v1, float *v2, float *v3,  float *v4)  /* only convex Quadrilaterals */
+float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])  /* only convex Quadrilaterals */
 {
 	float len, vec1[3], vec2[3], n[3];
 
@@ -108,7 +112,7 @@
 	return (len/2.0f);
 }
 
-float area_tri_v3(float *v1, float *v2, float *v3)  /* Triangles */
+float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])  /* Triangles */
 {
 	float len, vec1[3], vec2[3], n[3];
 
@@ -1334,6 +1338,77 @@
 	}
 }
 
+/* used by projection painting
+ * note: using area_tri_signed_v2 means locations outside the triangle are correctly weighted */
+void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
+{
+   float wtot_inv, wtot;
+
+   w[0] = area_tri_signed_v2(v2, v3, co);
+   w[1] = area_tri_signed_v2(v3, v1, co);
+   w[2] = area_tri_signed_v2(v1, v2, co);
+   wtot = w[0]+w[1]+w[2];
+
+   if (wtot != 0.0f) {
+       wtot_inv = 1.0f/wtot;
+
+       w[0] = w[0]*wtot_inv;
+       w[1] = w[1]*wtot_inv;
+       w[2] = w[2]*wtot_inv;
+   }
+   else /* dummy values for zero area face */
+       w[0] = w[1] = w[2] = 1.0f/3.0f;
+}
+
+/* given 2 triangles in 3D space, and a point in relation to the first triangle.
+ * calculate the location of a point in relation to the second triangle.
+ * Useful for finding relative positions with geometry */
+void barycentric_transform(float pt_tar[3], float const pt_src[3],
+		const float tri_tar_p1[3], const float tri_tar_p2[3], const float tri_tar_p3[3],
+		const float tri_src_p1[3], const float tri_src_p2[3], const float tri_src_p3[3])
+{
+	/* this works by moving the source triangle so its normal is pointing on the Z
+	 * axis where its barycentric wights can be calculated in 2D and its Z offset can
+	 *  be re-applied. The weights are applied directly to the targets 3D points and the
+	 *  z-depth is used to scale the targets normal as an offset.
+	 * This saves transforming the target into its Z-Up orientation and back (which could also work) */
+	const float z_up[3] = {0, 0, 1};
+	float no_tar[3], no_src[3];
+	float quat_src[4];
+	float pt_src_xy[3];
+	float  tri_xy_src[3][3];
+	float w_src[3];
+	float area_tar, area_src;
+	float z_ofs_src;
+
+	normal_tri_v3(no_tar, tri_tar_p1, tri_tar_p2, tri_tar_p3);
+	normal_tri_v3(no_src, tri_src_p1, tri_src_p2, tri_src_p3);
+
+	rotation_between_vecs_to_quat(quat_src, no_src, z_up);
+	normalize_qt(quat_src);
+
+	copy_v3_v3(pt_src_xy, pt_src);
+	copy_v3_v3(tri_xy_src[0], tri_src_p1);
+	copy_v3_v3(tri_xy_src[1], tri_src_p2);
+	copy_v3_v3(tri_xy_src[2], tri_src_p3);
+
+	/* make the source tri xy space */
+	mul_qt_v3(quat_src, pt_src_xy);
+	mul_qt_v3(quat_src, tri_xy_src[0]);
+	mul_qt_v3(quat_src, tri_xy_src[1]);
+	mul_qt_v3(quat_src, tri_xy_src[2]);
+
+	barycentric_weights_v2(tri_xy_src[0], tri_xy_src[1], tri_xy_src[2], pt_src_xy, w_src);
+	interp_v3_v3v3v3(pt_tar, tri_tar_p1, tri_tar_p2, tri_tar_p3, w_src);
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list