Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-08-31 06:06:23 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-08-31 06:06:23 +0400
commit11c988ba00f2991850050ff4c2e3cb34c2546047 (patch)
treee61413337f5e8b92284569f06b553516b2675536
parent29f6616d609fbd92cf313b0fdec555c2fcb4ede0 (diff)
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().
-rw-r--r--source/blender/blenlib/BLI_math_geom.h6
-rw-r--r--source/blender/blenlib/intern/math_geom.c64
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c10
-rw-r--r--source/blender/editors/transform/transform.c2
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c9
5 files changed, 42 insertions, 49 deletions
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 4307645bb91..559157370ca 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -97,6 +97,10 @@ void closest_on_tri_to_point_v3(float r[3], const float p[3], const float t1[3],
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_ray_plane_v3(const float p1[3], const float d[3],
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],
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 375b258acf9..68f246e3982 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -1121,50 +1121,28 @@ bool isect_point_planes_v3(float (*planes)[4], int totplane, const float p[3])
* \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);
-
- normalize_v3(l_vec);
- normalize_v3_v3(p_no, plane_no);
+ sub_v3_v3v3(u, l2, l1);
+ sub_v3_v3v3(h, l1, plane_co);
+ dot = dot_v3v3(plane_no, u);
- 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 @@ void isect_plane_plane_v3(float r_isect_co[3], float r_isect_no[3],
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 @@ float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2
#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)
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index 5e71913ea4a..28ffdea0e6c 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -405,15 +405,15 @@ void ED_view3d_win_to_3d(const ARegion *ar, const float depth_pt[3], const float
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;
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 0eada494715..82c117a7486 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -4828,7 +4828,7 @@ static bool bm_loop_calc_opposite_co(BMLoop *l_tmp,
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 */
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 2d4aa988db2..54e9ccf4a70 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -568,22 +568,19 @@ PyDoc_STRVAR(M_Geometry_intersect_line_plane_doc,
" :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 @@ static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObjec
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 {