author Campbell Barton Thu, 19 May 2011 04:28:09 +0000 (04:28 +0000) committer Campbell Barton Thu, 19 May 2011 04:28:09 +0000 (04:28 +0000)

index 0e21eab771735a99a52b91204a1be29a574c4d4a..60436328477dddcd900b01fc8d1b0f8848737005 100644 (file)
# <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 @@ def region_2d_to_vector_3d(region, rv3d, coord):
"""
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,22 +67,28 @@ def region_2d_to_location_3d(region, rv3d, coord, depth_location):
: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 rv3d.is_perspective:
+        from mathutils.geometry import intersect_line_plane

-    if _is_persp_matrix(persmat):
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 + region_2d_to_vector_3d(region, rv3d, coord)
-
-    return intersect_point_line(depth_location, origin_start, origin_end)[0]
+        origin_end = origin_start + coord_vec
+        return intersect_point_line(depth_location, origin_start, origin_end)[0]

def location_3d_to_region_2d(region, rv3d, coord):
index 6031c716807b0713af402e0847f311e215b4a046..49b5eff3aa8d42257810755a972fe8daf9757ee4 100644 (file)
@@ -497,6 +497,60 @@ static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObj
}

+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 ||
+       ) {
+               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 @@ static PyMethodDef M_Geometry_methods[]= {