[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [36761] trunk/blender: add python access to mathutils.intersect_line_plane, update view3d_utils module to use it.

Campbell Barton ideasman42 at gmail.com
Thu May 19 06:28:09 CEST 2011


Revision: 36761
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=36761
Author:   campbellbarton
Date:     2011-05-19 04:28:09 +0000 (Thu, 19 May 2011)
Log Message:
-----------
add python access to mathutils.intersect_line_plane, update view3d_utils module to use it.

Modified Paths:
--------------
    trunk/blender/release/scripts/modules/bpy_extras/view3d_utils.py
    trunk/blender/source/blender/python/generic/mathutils_geometry.c

Modified: trunk/blender/release/scripts/modules/bpy_extras/view3d_utils.py
===================================================================
--- trunk/blender/release/scripts/modules/bpy_extras/view3d_utils.py	2011-05-19 03:59:52 UTC (rev 36760)
+++ trunk/blender/release/scripts/modules/bpy_extras/view3d_utils.py	2011-05-19 04:28:09 UTC (rev 36761)
@@ -19,17 +19,6 @@
 # <pep8 compliant>
 
 
-def _is_persp_matrix(persmat, eps=0.00001):
-    """
-    crummy way to check if its a perspective matrix
-    """
-    return not (
-            abs(persmat[0][3]) < eps and \
-            abs(persmat[1][3]) < eps and \
-            abs(persmat[2][3]) < eps and \
-            abs(persmat[3][3] - 1.0) < eps)
-
-
 def region_2d_to_vector_3d(region, rv3d, coord):
     """
     Return a direction vector from the viewport at the spesific 2d region
@@ -47,13 +36,13 @@
     """
     from mathutils import Vector
 
-    persmat = rv3d.perspective_matrix.copy()
     viewvec = rv3d.view_matrix.inverted()[2].xyz.normalized()
 
-    if _is_persp_matrix(persmat):
+    if rv3d.is_perspective:
         dx = (2.0 * coord[0] / region.width) - 1.0
         dy = (2.0 * coord[1] / region.height) - 1.0
-        
+
+        persmat = rv3d.perspective_matrix.copy()
         perspinv_x, perspinv_y = persmat.inverted().to_3x3()[0:2]
         return ((perspinv_x * dx + perspinv_y * dy) - viewvec).normalized()
     else:
@@ -78,24 +67,30 @@
     :return: normalized 3d vector.
     :rtype: :class:`Vector`
     """
+    from mathutils import Vector
     from mathutils.geometry import intersect_point_line
 
     persmat = rv3d.perspective_matrix.copy()
+    coord_vec = region_2d_to_vector_3d(region, rv3d, coord)
+    depth_location = Vector(depth_location)
 
-    if _is_persp_matrix(persmat):
+    if rv3d.is_perspective:
+        from mathutils.geometry import intersect_line_plane
+
         origin_start = rv3d.view_matrix.inverted()[3].to_3d()
+        origin_end = origin_start + coord_vec
+        view_vec = rv3d.view_matrix.inverted()[2]
+        return intersect_line_plane(origin_start, origin_end, depth_location, view_vec, 1)
     else:
         dx = (2.0 * coord[0] / region.width) - 1.0
         dy = (2.0 * coord[1] / region.height) - 1.0
         persinv = persmat.inverted()
         viewinv = rv3d.view_matrix.inverted()
         origin_start = (persinv[0].xyz * dx) + (persinv[1].xyz * dy) + viewinv[3].xyz
+        origin_end = origin_start + coord_vec
+        return intersect_point_line(depth_location, origin_start, origin_end)[0]
 
-    origin_end = origin_start + region_2d_to_vector_3d(region, rv3d, coord)
-    
-    return intersect_point_line(depth_location, origin_start, origin_end)[0]
 
-
 def location_3d_to_region_2d(region, rv3d, coord):
     """
     Return the *region* relative 2d location of a 3d position.

Modified: trunk/blender/source/blender/python/generic/mathutils_geometry.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_geometry.c	2011-05-19 03:59:52 UTC (rev 36760)
+++ trunk/blender/source/blender/python/generic/mathutils_geometry.c	2011-05-19 04:28:09 UTC (rev 36761)
@@ -497,6 +497,60 @@
 }
 
 
+static char M_Geometry_intersect_line_plane_doc[] =
+".. function:: intersect_line_plane(line_a, line_b, plane_co, plane_no, no_flip=False)\n"
+"\n"
+"   Takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None.\n"
+"\n"
+"   :arg line_a: First point of the first line\n"
+"   :type line_a: :class:`mathutils.Vector`\n"
+"   :arg line_b: Second point of the first line\n"
+"   :type line_b: :class:`mathutils.Vector`\n"
+"   :arg plane_co: A point on the plane\n"
+"   :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_line_2d",
+	  &vector_Type, &line_a,
+	  &vector_Type, &line_b,
+	  &vector_Type, &plane_co,
+	  &vector_Type, &plane_no,
+	  &no_flip)
+	) {
+		return NULL;
+	}
+
+	if(		BaseMath_ReadCallback(line_a) == -1 ||
+	        BaseMath_ReadCallback(line_b) == -1 ||
+	        BaseMath_ReadCallback(plane_co) == -1 ||
+	        BaseMath_ReadCallback(plane_no) == -1
+	) {
+		return NULL;
+	}
+
+	if(ELEM4(2, line_a->size, line_b->size, plane_co->size, plane_no->size)) {
+		PyErr_SetString(PyExc_RuntimeError, "geometry.intersect_line_plane(...) can't use 2D Vectors");
+		return NULL;
+	}
+
+	if(isect_line_plane_v3(isect, line_a->vec, line_b->vec, plane_co->vec, plane_no->vec, no_flip) == 1) {
+		return newVectorObject(isect, 3, Py_NEW, NULL);
+	}
+	else {
+		Py_RETURN_NONE;
+	}
+}
+
 static char M_Geometry_intersect_point_line_doc[] =
 ".. function:: intersect_point_line(pt, line_p1, line_p2)\n"
 "\n"
@@ -860,6 +914,7 @@
 	{"intersect_point_quad_2d", (PyCFunction) M_Geometry_intersect_point_quad_2d, METH_VARARGS, M_Geometry_intersect_point_quad_2d_doc},
 	{"intersect_line_line", (PyCFunction) M_Geometry_intersect_line_line, METH_VARARGS, M_Geometry_intersect_line_line_doc},
 	{"intersect_line_line_2d", (PyCFunction) M_Geometry_intersect_line_line_2d, METH_VARARGS, M_Geometry_intersect_line_line_2d_doc},
+	{"intersect_line_plane", (PyCFunction) M_Geometry_intersect_line_plane, METH_VARARGS, M_Geometry_intersect_line_plane_doc},
 	{"interpolate_bezier", (PyCFunction) M_Geometry_interpolate_bezier, METH_VARARGS, M_Geometry_interpolate_bezier_doc},
 	{"area_tri", (PyCFunction) M_Geometry_area_tri, METH_VARARGS, M_Geometry_area_tri_doc},
 	{"normal", (PyCFunction) M_Geometry_normal, METH_VARARGS, M_Geometry_normal_doc},




More information about the Bf-blender-cvs mailing list