[Bf-blender-cvs] [ce47231] master: Math Lib: Add isect_point_tri_v3

Campbell Barton noreply at git.blender.org
Mon Jul 21 09:03:11 CEST 2014


Commit: ce47231cdb961fbd15cb0b403db9577c0e1c0010
Author: Campbell Barton
Date:   Mon Jul 21 16:58:17 2014 +1000
Branches: master
https://developer.blender.org/rBce47231cdb961fbd15cb0b403db9577c0e1c0010

Math Lib: Add isect_point_tri_v3

Add to Python via mathutils.geometry

===================================================================

M	source/blender/blenlib/BLI_math_geom.h
M	source/blender/blenlib/intern/math_geom.c
M	source/blender/python/mathutils/mathutils_geometry.c

===================================================================

diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index ed0777a..57cde56 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -169,6 +169,8 @@ int  isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2],
 bool isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
 int  isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b);
 bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3]);
+bool isect_point_tri_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3],
+                        float r_vi[3]);
 
 /* axis-aligned bounding box */
 bool isect_aabb_aabb_v3(const float min1[3], const float max1[3], const float min2[3], const float max2[3]);
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index efb881c..2cd32b3 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -1910,6 +1910,39 @@ bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v
 	return 1;
 }
 
+/**
+ * \param r_vi The point \a p projected onto the triangle.
+ * \return True when \a p is inside the triangle.
+ * \note Its up to the caller to check the distance between \a p and \a r_vi against an error margin.
+ */
+bool isect_point_tri_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3],
+                        float r_vi[3])
+{
+	if (isect_point_tri_prism_v3(p, v1, v2, v3)) {
+		float no[3], n1[3], n2[3];
+
+		/* Could use normal_tri_v3, but doesn't have to be unit-length */
+		sub_v3_v3v3(n1, v1, v2);
+		sub_v3_v3v3(n2, v2, v3);
+		cross_v3_v3v3(no, n1, n2);
+
+		if (LIKELY(len_squared_v3(no) != 0.0f)) {
+			float plane[4];
+			plane_from_point_normal_v3(plane, v1, no);
+			closest_to_plane_v3(r_vi, plane, p);
+		}
+		else {
+			/* degenerate */
+			copy_v3_v3(r_vi, p);
+		}
+
+		return true;
+	}
+	else {
+		return false;
+	}
+}
+
 bool clip_segment_v3_plane(float p1[3], float p2[3], const float plane[4])
 {
 	float dp[3], div, t, pc[3];
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 9ec84ba..b289f73 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -893,13 +893,69 @@ static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObjec
 	return ret;
 }
 
+PyDoc_STRVAR(M_Geometry_intersect_point_tri_doc,
+".. function:: intersect_point_tri(pt, tri_p1, tri_p2, tri_p3)\n"
+"\n"
+"   Takes 4 vectors: one is the point and the next 3 define the triangle.\n"
+"\n"
+"   :arg pt: Point\n"
+"   :type pt: :class:`mathutils.Vector`\n"
+"   :arg tri_p1: First point of the triangle\n"
+"   :type tri_p1: :class:`mathutils.Vector`\n"
+"   :arg tri_p2: Second point of the triangle\n"
+"   :type tri_p2: :class:`mathutils.Vector`\n"
+"   :arg tri_p3: Third point of the triangle\n"
+"   :type tri_p3: :class:`mathutils.Vector`\n"
+"   :return: Point on the triangles plane or None if its outside the triangle\n"
+"   :rtype: :class:`mathutils.Vector` or None\n"
+);
+static PyObject *M_Geometry_intersect_point_tri(PyObject *UNUSED(self), PyObject *args)
+{
+	VectorObject *pt_vec, *tri_p1, *tri_p2, *tri_p3;
+	float vi[3];
+
+	if (!PyArg_ParseTuple(args, "O!O!O!O!:intersect_point_tri",
+	                      &vector_Type, &pt_vec,
+	                      &vector_Type, &tri_p1,
+	                      &vector_Type, &tri_p2,
+	                      &vector_Type, &tri_p3))
+	{
+		return NULL;
+	}
+
+	if (BaseMath_ReadCallback(pt_vec) == -1 ||
+	    BaseMath_ReadCallback(tri_p1) == -1 ||
+	    BaseMath_ReadCallback(tri_p2) == -1 ||
+	    BaseMath_ReadCallback(tri_p3) == -1)
+	{
+		return NULL;
+	}
+
+	if (pt_vec->size < 3 ||
+	    tri_p1->size < 3 ||
+	    tri_p2->size < 3 ||
+	    tri_p3->size < 3)
+	{
+		PyErr_SetString(PyExc_ValueError,
+		                "One of more of the vector arguments wasn't a 3D vector");
+		return NULL;
+	}
+
+	if (isect_point_tri_v3(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec, vi)) {
+		return Vector_CreatePyObject(vi, 3, Py_NEW, NULL);
+	}
+	else {
+		Py_RETURN_NONE;
+	}
+}
+
 PyDoc_STRVAR(M_Geometry_intersect_point_tri_2d_doc,
 ".. function:: intersect_point_tri_2d(pt, tri_p1, tri_p2, tri_p3)\n"
 "\n"
 "   Takes 4 vectors (using only the x and y coordinates): one is the point and the next 3 define the triangle. Returns 1 if the point is within the triangle, otherwise 0.\n"
 "\n"
 "   :arg pt: Point\n"
-"   :type v1: :class:`mathutils.Vector`\n"
+"   :type pt: :class:`mathutils.Vector`\n"
 "   :arg tri_p1: First point of the triangle\n"
 "   :type tri_p1: :class:`mathutils.Vector`\n"
 "   :arg tri_p2: Second point of the triangle\n"
@@ -1606,6 +1662,7 @@ static PyObject *M_Geometry_convex_hull_2d(PyObject *UNUSED(self), PyObject *poi
 static PyMethodDef M_Geometry_methods[] = {
 	{"intersect_ray_tri", (PyCFunction) M_Geometry_intersect_ray_tri, METH_VARARGS, M_Geometry_intersect_ray_tri_doc},
 	{"intersect_point_line", (PyCFunction) M_Geometry_intersect_point_line, METH_VARARGS, M_Geometry_intersect_point_line_doc},
+	{"intersect_point_tri", (PyCFunction) M_Geometry_intersect_point_tri, METH_VARARGS, M_Geometry_intersect_point_tri_doc},
 	{"intersect_point_tri_2d", (PyCFunction) M_Geometry_intersect_point_tri_2d, METH_VARARGS, M_Geometry_intersect_point_tri_2d_doc},
 	{"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},




More information about the Bf-blender-cvs mailing list