[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59679] trunk/blender/source/blender: Simplify line/plane intersection, add line_plane_factor_v3().

Campbell Barton ideasman42 at gmail.com
Sat Aug 31 04:06:27 CEST 2013


Revision: 59679
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59679
Author:   campbellbarton
Date:     2013-08-31 02:06:23 +0000 (Sat, 31 Aug 2013)
Log Message:
-----------
Simplify line/plane intersection, add line_plane_factor_v3().

Remove no_flip option for isect_line_plane_v3(), its quite specific and only used for ED_view3d_win_to_3d().

Modified Paths:
--------------
    trunk/blender/source/blender/blenlib/BLI_math_geom.h
    trunk/blender/source/blender/blenlib/intern/math_geom.c
    trunk/blender/source/blender/editors/space_view3d/view3d_project.c
    trunk/blender/source/blender/editors/transform/transform.c
    trunk/blender/source/blender/python/mathutils/mathutils_geometry.c

Modified: trunk/blender/source/blender/blenlib/BLI_math_geom.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_math_geom.h	2013-08-30 23:49:38 UTC (rev 59678)
+++ trunk/blender/source/blender/blenlib/BLI_math_geom.h	2013-08-31 02:06:23 UTC (rev 59679)
@@ -97,6 +97,10 @@
 
 float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3]);
 float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2]);
+
+float line_plane_factor_v3(const float plane_co[3], const float plane_no[3],
+                           const float l1[3], const float l2[3]);
+
 void limit_dist_v3(float v1[3], float v2[3], const float dist);
 
 /******************************* Intersection ********************************/
@@ -130,7 +134,7 @@
 
 bool isect_point_planes_v3(float (*planes)[4], int totplane, const float p[3]);
 bool isect_line_plane_v3(float out[3], const float l1[3], const float l2[3],
-                         const float plane_co[3], const float plane_no[3], const bool no_flip);
+                         const float plane_co[3], const float plane_no[3]);
 
 void isect_plane_plane_v3(float r_isect_co[3], float r_isect_no[3],
                           const float plane_a_co[3], const float plane_a_no[3],

Modified: trunk/blender/source/blender/blenlib/intern/math_geom.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_geom.c	2013-08-30 23:49:38 UTC (rev 59678)
+++ trunk/blender/source/blender/blenlib/intern/math_geom.c	2013-08-31 02:06:23 UTC (rev 59679)
@@ -1121,50 +1121,28 @@
  * \param l2 The second point of the line.
  * \param plane_co A point on the plane to intersect with.
  * \param plane_no The direction of the plane (does not need to be normalized).
- * \param no_flip When true, the intersection point will always be from l1 to l2, even if this is not on the plane.
+ *
+ * \note #line_plane_factor_v3() shares logic.
  */
 bool isect_line_plane_v3(float out[3],
                          const float l1[3], const float l2[3],
-                         const float plane_co[3], const float plane_no[3], const bool no_flip)
+                         const float plane_co[3], const float plane_no[3])
 {
-	float l_vec[3]; /* l1 -> l2 normalized vector */
-	float p_no[3]; /* 'plane_no' normalized */
+	float u[3], h[3];
 	float dot;
 
-	sub_v3_v3v3(l_vec, l2, l1);
+	sub_v3_v3v3(u, l2, l1);
+	sub_v3_v3v3(h, l1, plane_co);
+	dot = dot_v3v3(plane_no, u);
 
-	normalize_v3(l_vec);
-	normalize_v3_v3(p_no, plane_no);
-
-	dot = dot_v3v3(l_vec, p_no);
-	if (dot == 0.0f) {
-		return 0;
+	if (fabsf(dot) > FLT_EPSILON) {
+		float lambda = -dot_v3v3(plane_no, h) / dot;
+		madd_v3_v3v3fl(out, l1, u, lambda);
+		return true;
 	}
 	else {
-		float l1_plane[3]; /* line point aligned with the plane */
-		float dist; /* 'plane_no' aligned distance to the 'plane_co' */
-
-		/* for predictable flipping since the plane is only used to
-		 * define a direction, ignore its flipping and aligned with 'l_vec' */
-		if (dot < 0.0f) {
-			dot = -dot;
-			negate_v3(p_no);
-		}
-
-		add_v3_v3v3(l1_plane, l1, p_no);
-
-		dist = line_point_factor_v3(plane_co, l1, l1_plane);
-
-		/* treat line like a ray, when 'no_flip' is set */
-		if (no_flip && dist < 0.0f) {
-			dist = -dist;
-		}
-
-		mul_v3_fl(l_vec, dist / dot);
-
-		add_v3_v3v3(out, l1, l_vec);
-
-		return 1;
+		/* The segment is parallel to plane */
+		return false;
 	}
 }
 
@@ -1190,7 +1168,7 @@
 	cross_v3_v3v3(r_isect_no, plane_a_no, plane_b_no); /* direction is simply the cross product */
 	cross_v3_v3v3(plane_a_co_other, plane_a_no, r_isect_no);
 	add_v3_v3(plane_a_co_other, plane_a_co);
-	isect_line_plane_v3(r_isect_co, plane_a_co, plane_a_co_other, plane_b_co, plane_b_no, FALSE);
+	isect_line_plane_v3(r_isect_co, plane_a_co, plane_a_co_other, plane_b_co, plane_b_no);
 }
 
 
@@ -1716,6 +1694,20 @@
 #endif
 }
 
+/**
+ * \note #isect_line_plane_v3() shares logic
+ */
+float line_plane_factor_v3(const float plane_co[3], const float plane_no[3],
+                           const float l1[3], const float l2[3])
+{
+	float u[3], h[3];
+	float dot;
+	sub_v3_v3v3(u, l2, l1);
+	sub_v3_v3v3(h, l1, plane_co);
+	dot = dot_v3v3(plane_no, u);
+	return (dot != 0.0f) ? -dot_v3v3(plane_no, h) / dot : 0.0f;
+}
+
 /* ensure the distance between these points is no greater then 'dist'
  * if it is, scale then both into the center */
 void limit_dist_v3(float v1[3], float v2[3], const float dist)

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_project.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_project.c	2013-08-30 23:49:38 UTC (rev 59678)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_project.c	2013-08-31 02:06:23 UTC (rev 59679)
@@ -405,15 +405,15 @@
 	float line_end[3];
 
 	if (rv3d->is_persp) {
-		float mousevec[3];
+		float mousevec[3], lambda;
 		copy_v3_v3(line_sta, rv3d->viewinv[3]);
 		ED_view3d_win_to_vector(ar, mval, mousevec);
 		add_v3_v3v3(line_end, line_sta, mousevec);
 
-		if (isect_line_plane_v3(out, line_sta, line_end, depth_pt, rv3d->viewinv[2], true) == 0) {
-			/* highly unlikely to ever happen, mouse vector parallel with view plane */
-			zero_v3(out);
-		}
+		/* note, we could use isect_line_plane_v3() however we want the intersection to be infront of the
+		 * view no matter what, so apply the unsigned factor instead */
+		lambda = line_plane_factor_v3(depth_pt, rv3d->viewinv[2], line_sta, line_end);
+		interp_v3_v3v3(out, line_sta, line_end, fabsf(lambda));
 	}
 	else {
 		float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f;

Modified: trunk/blender/source/blender/editors/transform/transform.c
===================================================================
--- trunk/blender/source/blender/editors/transform/transform.c	2013-08-30 23:49:38 UTC (rev 59678)
+++ trunk/blender/source/blender/editors/transform/transform.c	2013-08-31 02:06:23 UTC (rev 59679)
@@ -4828,7 +4828,7 @@
 		float tvec[3];
 		if (isect_line_plane_v3(tvec,
 		                        l_iter->v->co, l_iter->next->v->co,
-		                        l_tmp->v->co, plane_no, false))
+		                        l_tmp->v->co, plane_no))
 		{
 			const float fac = line_point_factor_v3(tvec, l_iter->v->co, l_iter->next->v->co);
 			/* allow some overlap to avoid missing the intersection because of float precision */

Modified: trunk/blender/source/blender/python/mathutils/mathutils_geometry.c
===================================================================
--- trunk/blender/source/blender/python/mathutils/mathutils_geometry.c	2013-08-30 23:49:38 UTC (rev 59678)
+++ trunk/blender/source/blender/python/mathutils/mathutils_geometry.c	2013-08-31 02:06:23 UTC (rev 59679)
@@ -568,22 +568,19 @@
 "   :type plane_co: :class:`mathutils.Vector`\n"
 "   :arg plane_no: The direction the plane is facing\n"
 "   :type plane_no: :class:`mathutils.Vector`\n"
-"   :arg no_flip: Always return an intersection on the directon defined bt line_a -> line_b\n"
-"   :type no_flip: :boolean\n"
 "   :return: The point of intersection or None when not found\n"
 "   :rtype: :class:`mathutils.Vector` or None\n"
 );
 static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObject *args)
 {
 	VectorObject *line_a, *line_b, *plane_co, *plane_no;
-	int no_flip = 0;
 	float isect[3];
+
 	if (!PyArg_ParseTuple(args, "O!O!O!O!|i:intersect_line_plane",
 	                      &vector_Type, &line_a,
 	                      &vector_Type, &line_b,
 	                      &vector_Type, &plane_co,
-	                      &vector_Type, &plane_no,
-	                      &no_flip))
+	                      &vector_Type, &plane_no))
 	{
 		return NULL;
 	}
@@ -603,7 +600,7 @@
 		return NULL;
 	}
 
-	if (isect_line_plane_v3(isect, line_a->vec, line_b->vec, plane_co->vec, plane_no->vec, no_flip) == 1) {
+	if (isect_line_plane_v3(isect, line_a->vec, line_b->vec, plane_co->vec, plane_no->vec) == 1) {
 		return Vector_CreatePyObject(isect, 3, Py_NEW, NULL);
 	}
 	else {




More information about the Bf-blender-cvs mailing list