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},

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to