Fixed typo Python API
[blender-staging.git] / source / blender / python / mathutils / mathutils_geometry.c
index c536838..d935949 100644 (file)
@@ -34,8 +34,8 @@
 #ifndef MATH_STANDALONE /* define when building outside blender */
 #  include "MEM_guardedalloc.h"
 #  include "BLI_blenlib.h"
-#  include "BLI_boxpack2d.h"
-#  include "BLI_convexhull2d.h"
+#  include "BLI_boxpack_2d.h"
+#  include "BLI_convexhull_2d.h"
 #  include "BKE_displist.h"
 #  include "BKE_curve.h"
 #endif
@@ -43,6 +43,9 @@
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
 
+#include "../generic/py_capi_utils.h"
+#include "../generic/python_utildefines.h"
+
 /*-------------------------DOC STRINGS ---------------------------*/
 PyDoc_STRVAR(M_Geometry_doc,
 "The Blender geometry module"
@@ -76,24 +79,26 @@ static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject *
        PyObject *py_ray, *py_ray_off, *py_tri[3];
        float dir[3], orig[3], tri[3][3], e1[3], e2[3], pvec[3], tvec[3], qvec[3];
        float det, inv_det, u, v, t;
-       int clip = 1;
+       bool clip = true;
        int i;
 
        if (!PyArg_ParseTuple(
-               args, "OOOOO|i:intersect_ray_tri",
-               UNPACK3_EX(&, py_tri, ), &py_ray, &py_ray_off, &clip))
+               args, "OOOOO|O&:intersect_ray_tri",
+               UNPACK3_EX(&, py_tri, ),
+               &py_ray, &py_ray_off,
+               PyC_ParseBool, &clip))
        {
                return NULL;
        }
 
-       if (((mathutils_array_parse(dir, 3, 3, py_ray, error_prefix) != -1) &&
-            (mathutils_array_parse(orig, 3, 3, py_ray_off, error_prefix) != -1)) == 0)
+       if (((mathutils_array_parse(dir, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_ray, error_prefix) != -1) &&
+            (mathutils_array_parse(orig, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_ray_off, error_prefix) != -1)) == 0)
        {
                return NULL;
        }
 
        for (i = 0; i < ARRAY_SIZE(tri); i++) {
-               if (mathutils_array_parse(tri[i], 2, 2 | MU_ARRAY_SPILL, py_tri[i], error_prefix) == -1) {
+               if (mathutils_array_parse(tri[i], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_tri[i], error_prefix) == -1) {
                        return NULL;
                }
        }
@@ -182,18 +187,14 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject
                return NULL;
        }
 
-       if ((((len = mathutils_array_parse(lines[0], 2, 3, py_lines[0], error_prefix)) != -1) &&
-            (mathutils_array_parse(lines[1], len, len, py_lines[1], error_prefix) != -1) &&
-            (mathutils_array_parse(lines[2], len, len, py_lines[2], error_prefix) != -1) &&
-            (mathutils_array_parse(lines[3], len, len, py_lines[3], error_prefix) != -1)) == 0)
+       if ((((len = mathutils_array_parse(lines[0], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[0], error_prefix)) != -1) &&
+            (mathutils_array_parse(lines[1], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[1], error_prefix) != -1) &&
+            (mathutils_array_parse(lines[2], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[2], error_prefix) != -1) &&
+            (mathutils_array_parse(lines[3], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[3], error_prefix) != -1)) == 0)
        {
                return NULL;
        }
 
-       if (len == 2) {
-               lines[0][2] = lines[1][2] = lines[2][2] = lines[3][2] = 0.0f;
-       }
-
        result = isect_line_line_v3(UNPACK4(lines), i1, i2);
        /* The return-code isnt exposed,
         * this way we can check know how close the lines are. */
@@ -202,13 +203,14 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject
        }
 
        if (result == 0) {
-               /* colinear */
+               /* collinear */
                Py_RETURN_NONE;
        }
        else {
                tuple = PyTuple_New(2);
-               PyTuple_SET_ITEM(tuple, 0, Vector_CreatePyObject(i1, len, NULL));
-               PyTuple_SET_ITEM(tuple, 1, Vector_CreatePyObject(i2, len, NULL));
+               PyTuple_SET_ITEMS(tuple,
+                       Vector_CreatePyObject(i1, len, NULL),
+                       Vector_CreatePyObject(i2, len, NULL));
                return tuple;
        }
 }
@@ -267,8 +269,9 @@ static PyObject *M_Geometry_intersect_sphere_sphere_2d(PyObject *UNUSED(self), P
            (dist < FLT_EPSILON))
        {
                /* out of range */
-               PyTuple_SET_ITEM(ret, 0,  Py_None); Py_INCREF(Py_None);
-               PyTuple_SET_ITEM(ret, 1,  Py_None); Py_INCREF(Py_None);
+               PyTuple_SET_ITEMS(ret,
+                       Py_INCREF_RET(Py_None),
+                       Py_INCREF_RET(Py_None));
        }
        else {
                const float dist_delta = ((rad_a * rad_a) - (rad_b * rad_b) + (dist * dist)) / (2.0f * dist);
@@ -285,8 +288,9 @@ static PyObject *M_Geometry_intersect_sphere_sphere_2d(PyObject *UNUSED(self), P
                i2[0] = i_cent[0] - h * v_ab[1] / dist;
                i2[1] = i_cent[1] + h * v_ab[0] / dist;
 
-               PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(i1, 2, NULL));
-               PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(i2, 2, NULL));
+               PyTuple_SET_ITEMS(ret,
+                       Vector_CreatePyObject(i1, 2, NULL),
+                       Vector_CreatePyObject(i2, 2, NULL));
        }
 
        return ret;
@@ -411,7 +415,9 @@ static PyObject *M_Geometry_volume_tetrahedron(PyObject *UNUSED(self), PyObject
 PyDoc_STRVAR(M_Geometry_intersect_line_line_2d_doc,
 ".. function:: intersect_line_line_2d(lineA_p1, lineA_p2, lineB_p1, lineB_p2)\n"
 "\n"
-"   Takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None.\n"
+"   Takes 2 segments (defined by 4 vectors) and returns a vector for their point of intersection or None.\n"
+"\n"
+"   .. warning:: Despite its name, this function works on segments, and not on lines.\n"
 "\n"
 "   :arg lineA_p1: First point of the first line\n"
 "   :type lineA_p1: :class:`mathutils.Vector`\n"
@@ -477,12 +483,12 @@ static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObjec
        PyObject *py_line_a, *py_line_b, *py_plane_co, *py_plane_no;
        float line_a[3], line_b[3], plane_co[3], plane_no[3];
        float isect[3];
-       int no_flip = false;
+       bool no_flip = false;
 
        if (!PyArg_ParseTuple(
-               args, "OOOO|i:intersect_line_plane",
+               args, "OOOO|O&:intersect_line_plane",
                &py_line_a, &py_line_b, &py_plane_co, &py_plane_no,
-               &no_flip))
+               PyC_ParseBool, &no_flip))
        {
                return NULL;
        }
@@ -526,13 +532,14 @@ static PyObject *M_Geometry_intersect_plane_plane(PyObject *UNUSED(self), PyObje
        PyObject *ret, *ret_co, *ret_no;
        PyObject *py_plane_a_co, *py_plane_a_no, *py_plane_b_co, *py_plane_b_no;
        float plane_a_co[3], plane_a_no[3], plane_b_co[3], plane_b_no[3];
+       float plane_a[4], plane_b[4];
 
        float isect_co[3];
        float isect_no[3];
 
        if (!PyArg_ParseTuple(
                args, "OOOO:intersect_plane_plane",
-               &plane_a_co, &plane_a_no, &plane_b_co, &plane_b_no))
+               &py_plane_a_co, &py_plane_a_no, &py_plane_b_co, &py_plane_b_no))
        {
                return NULL;
        }
@@ -545,9 +552,12 @@ static PyObject *M_Geometry_intersect_plane_plane(PyObject *UNUSED(self), PyObje
                return NULL;
        }
 
-       if (isect_plane_plane_v3(isect_co, isect_no,
-                                plane_a_co, plane_a_no,
-                                plane_b_co, plane_b_no))
+       plane_from_point_normal_v3(plane_a, plane_a_co, plane_a_no);
+       plane_from_point_normal_v3(plane_b, plane_b_co, plane_b_no);
+
+       if (isect_plane_plane_v3(
+               plane_a, plane_b,
+               isect_co, isect_no))
        {
                normalize_v3(isect_no);
 
@@ -555,16 +565,14 @@ static PyObject *M_Geometry_intersect_plane_plane(PyObject *UNUSED(self), PyObje
                ret_no = Vector_CreatePyObject(isect_no, 3, NULL);
        }
        else {
-               ret_co = Py_None;
-               ret_no = Py_None;
-
-               Py_INCREF(ret_co);
-               Py_INCREF(ret_no);
+               ret_co = Py_INCREF_RET(Py_None);
+               ret_no = Py_INCREF_RET(Py_None);
        }
 
        ret = PyTuple_New(2);
-       PyTuple_SET_ITEM(ret, 0, ret_co);
-       PyTuple_SET_ITEM(ret, 1, ret_no);
+       PyTuple_SET_ITEMS(ret,
+               ret_co,
+               ret_no);
        return ret;
 }
 
@@ -591,14 +599,15 @@ static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObje
        PyObject *py_line_a, *py_line_b, *py_sphere_co;
        float line_a[3], line_b[3], sphere_co[3];
        float sphere_radius;
-       int clip = true;
+       bool clip = true;
 
        float isect_a[3];
        float isect_b[3];
 
        if (!PyArg_ParseTuple(
-               args, "OOOf|i:intersect_line_sphere",
-               &py_line_a, &py_line_b, &py_sphere_co, &sphere_radius, &clip))
+               args, "OOOf|O&:intersect_line_sphere",
+               &py_line_a, &py_line_b, &py_sphere_co, &sphere_radius,
+               PyC_ParseBool, &clip))
        {
                return NULL;
        }
@@ -631,11 +640,9 @@ static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObje
                                break;
                }
 
-               if (use_a) { PyTuple_SET_ITEM(ret, 0,  Vector_CreatePyObject(isect_a, 3, NULL)); }
-               else       { PyTuple_SET_ITEM(ret, 0,  Py_None); Py_INCREF(Py_None); }
-
-               if (use_b) { PyTuple_SET_ITEM(ret, 1,  Vector_CreatePyObject(isect_b, 3, NULL)); }
-               else       { PyTuple_SET_ITEM(ret, 1,  Py_None); Py_INCREF(Py_None); }
+               PyTuple_SET_ITEMS(ret,
+                       use_a ? Vector_CreatePyObject(isect_a, 3, NULL) : Py_INCREF_RET(Py_None),
+                       use_b ? Vector_CreatePyObject(isect_b, 3, NULL) : Py_INCREF_RET(Py_None));
 
                return ret;
        }
@@ -665,14 +672,15 @@ static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyO
        PyObject *py_line_a, *py_line_b, *py_sphere_co;
        float line_a[2], line_b[2], sphere_co[2];
        float sphere_radius;
-       int clip = true;
+       bool clip = true;
 
        float isect_a[2];
        float isect_b[2];
 
        if (!PyArg_ParseTuple(
-               args, "OOOf|i:intersect_line_sphere_2d",
-               &py_line_a, &py_line_b, &py_sphere_co, &sphere_radius, &clip))
+               args, "OOOf|O&:intersect_line_sphere_2d",
+               &py_line_a, &py_line_b, &py_sphere_co, &sphere_radius,
+               PyC_ParseBool, &clip))
        {
                return NULL;
        }
@@ -705,11 +713,9 @@ static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyO
                                break;
                }
 
-               if (use_a) { PyTuple_SET_ITEM(ret, 0,  Vector_CreatePyObject(isect_a, 2, NULL)); }
-               else       { PyTuple_SET_ITEM(ret, 0,  Py_None); Py_INCREF(Py_None); }
-
-               if (use_b) { PyTuple_SET_ITEM(ret, 1,  Vector_CreatePyObject(isect_b, 2, NULL)); }
-               else       { PyTuple_SET_ITEM(ret, 1,  Py_None); Py_INCREF(Py_None); }
+               PyTuple_SET_ITEMS(ret,
+                       use_a ? Vector_CreatePyObject(isect_a, 2, NULL) : Py_INCREF_RET(Py_None),
+                       use_b ? Vector_CreatePyObject(isect_b, 2, NULL) : Py_INCREF_RET(Py_None));
 
                return ret;
        }
@@ -736,7 +742,7 @@ static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObjec
        float lambda;
        PyObject *ret;
        int size = 2;
-       
+
        if (!PyArg_ParseTuple(
                args, "OOO:intersect_point_line",
                &py_pt, &py_line_a, &py_line_b))
@@ -747,17 +753,18 @@ static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObjec
        /* accept 2d verts */
        if ((((size = mathutils_array_parse(pt, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_pt, error_prefix)) != -1) &&
             (mathutils_array_parse(line_a, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_line_a, error_prefix) != -1) &&
-            (mathutils_array_parse(line_b, 3, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_line_b, error_prefix) != -1)) == 0)
+            (mathutils_array_parse(line_b, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_line_b, error_prefix) != -1)) == 0)
        {
                return NULL;
        }
 
        /* do the calculation */
        lambda = closest_to_line_v3(pt_out, pt, line_a, line_b);
-       
+
        ret = PyTuple_New(2);
-       PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(pt_out, size, NULL));
-       PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(lambda));
+       PyTuple_SET_ITEMS(ret,
+               Vector_CreatePyObject(pt_out, size, NULL),
+               PyFloat_FromDouble(lambda));
        return ret;
 }
 
@@ -792,11 +799,11 @@ static PyObject *M_Geometry_intersect_point_tri(PyObject *UNUSED(self), PyObject
                return NULL;
        }
 
-       if (mathutils_array_parse(pt, 3, 3 | MU_ARRAY_SPILL, py_pt, error_prefix) == -1) {
+       if (mathutils_array_parse(pt, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_pt, error_prefix) == -1) {
                return NULL;
        }
        for (i = 0; i < ARRAY_SIZE(tri); i++) {
-               if (mathutils_array_parse(tri[i], 3, 3 | MU_ARRAY_SPILL, py_tri[i], error_prefix) == -1) {
+               if (mathutils_array_parse(tri[i], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_tri[i], error_prefix) == -1) {
                        return NULL;
                }
        }
@@ -855,7 +862,7 @@ PyDoc_STRVAR(M_Geometry_intersect_point_quad_2d_doc,
 "\n"
 "   Takes 5 vectors (using only the x and y coordinates): one is the point and the next 4 define the quad, \n"
 "   only the x and y are used from the vectors. Returns 1 if the point is within the quad, otherwise 0.\n"
-"   Works only with convex quads without singular edges."
+"   Works only with convex quads without singular edges.\n"
 "\n"
 "   :arg pt: Point\n"
 "   :type pt: :class:`mathutils.Vector`\n"
@@ -865,7 +872,7 @@ PyDoc_STRVAR(M_Geometry_intersect_point_quad_2d_doc,
 "   :type quad_p2: :class:`mathutils.Vector`\n"
 "   :arg quad_p3: Third point of the quad\n"
 "   :type quad_p3: :class:`mathutils.Vector`\n"
-"   :arg quad_p4: Forth point of the quad\n"
+"   :arg quad_p4: Fourth point of the quad\n"
 "   :type quad_p4: :class:`mathutils.Vector`\n"
 "   :rtype: int\n"
 );
@@ -875,7 +882,7 @@ static PyObject *M_Geometry_intersect_point_quad_2d(PyObject *UNUSED(self), PyOb
        PyObject *py_pt, *py_quad[4];
        float pt[2], quad[4][2];
        int i;
-       
+
        if (!PyArg_ParseTuple(
                args, "OOOOO:intersect_point_quad_2d",
                &py_pt, UNPACK4_EX(&, py_quad, )))
@@ -947,12 +954,12 @@ PyDoc_STRVAR(M_Geometry_barycentric_transform_doc,
 "   :type tri_a2: :class:`mathutils.Vector`\n"
 "   :arg tri_a3: source triangle vertex.\n"
 "   :type tri_a3: :class:`mathutils.Vector`\n"
-"   :arg tri_a1: target triangle vertex.\n"
-"   :type tri_a1: :class:`mathutils.Vector`\n"
-"   :arg tri_a2: target triangle vertex.\n"
-"   :type tri_a2: :class:`mathutils.Vector`\n"
-"   :arg tri_a3: target triangle vertex.\n"
-"   :type tri_a3: :class:`mathutils.Vector`\n"
+"   :arg tri_b1: target triangle vertex.\n"
+"   :type tri_b1: :class:`mathutils.Vector`\n"
+"   :arg tri_b2: target triangle vertex.\n"
+"   :type tri_b2: :class:`mathutils.Vector`\n"
+"   :arg tri_b3: target triangle vertex.\n"
+"   :type tri_b3: :class:`mathutils.Vector`\n"
 "   :return: The transformed point\n"
 "   :rtype: :class:`mathutils.Vector`'s\n"
 );
@@ -972,7 +979,7 @@ static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObje
                return NULL;
        }
 
-       if (mathutils_array_parse(pt_src, 2, 2 | MU_ARRAY_SPILL, py_pt_src, error_prefix) == -1) {
+       if (mathutils_array_parse(pt_src, 3, 3 | MU_ARRAY_SPILL, py_pt_src, error_prefix) == -1) {
                return NULL;
        }
        for (i = 0; i < ARRAY_SIZE(tri_src); i++) {
@@ -1062,10 +1069,7 @@ static PyObject *M_Geometry_points_in_planes(PyObject *UNUSED(self), PyObject *a
 
                                                                        if (l == len) { /* ok */
                                                                                /* python */
-                                                                               PyObject *item = Vector_CreatePyObject(potentialVertex, 3, NULL);
-                                                                               PyList_Append(py_verts, item);
-                                                                               Py_DECREF(item);
-
+                                                                               PyList_APPEND(py_verts, Vector_CreatePyObject(potentialVertex, 3, NULL));
                                                                                planes_used[i] = planes_used[j] = planes_used[k] = true;
                                                                        }
                                                                }
@@ -1081,17 +1085,16 @@ static PyObject *M_Geometry_points_in_planes(PyObject *UNUSED(self), PyObject *a
                /* now make a list of used planes */
                for (i = 0; i < len; i++) {
                        if (planes_used[i]) {
-                               PyObject *item = PyLong_FromLong(i);
-                               PyList_Append(py_plane_index, item);
-                               Py_DECREF(item);
+                               PyList_APPEND(py_plane_index, PyLong_FromLong(i));
                        }
                }
                PyMem_Free(planes_used);
 
                {
                        PyObject *ret = PyTuple_New(2);
-                       PyTuple_SET_ITEM(ret, 0, py_verts);
-                       PyTuple_SET_ITEM(ret, 1, py_plane_index);
+                       PyTuple_SET_ITEMS(ret,
+                               py_verts,
+                               py_plane_index);
                        return ret;
                }
        }
@@ -1137,7 +1140,7 @@ static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject
 
        for (i = 0; i < 4; i++) {
                int dims_tmp;
-               if ((((dims_tmp = mathutils_array_parse(data[i], 2, 2 | MU_ARRAY_SPILL, py_data[i], error_prefix)) == -1))) {
+               if ((dims_tmp = mathutils_array_parse(data[i], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_data[i], error_prefix)) == -1) {
                        return NULL;
                }
                dims = max_ii(dims, dims_tmp);
@@ -1276,7 +1279,7 @@ static PyObject *M_Geometry_tessellate_polygon(PyObject *UNUSED(self), PyObject
                index = 0;
                dl_face = dl->index;
                while (index < dl->parts) {
-                       PyList_SET_ITEM(tri_list, index, Py_BuildValue("iii", dl_face[0], dl_face[1], dl_face[2]));
+                       PyList_SET_ITEM(tri_list, index, PyC_Tuple_Pack_I32(dl_face[0], dl_face[1], dl_face[2]));
                        dl_face += 3;
                        index++;
                }
@@ -1397,8 +1400,9 @@ static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlis
        }
 
        ret = PyTuple_New(2);
-       PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(tot_width));
-       PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_height));
+       PyTuple_SET_ITEMS(ret,
+               PyFloat_FromDouble(tot_width),
+               PyFloat_FromDouble(tot_height));
        return ret;
 }
 
@@ -1426,7 +1430,7 @@ static PyObject *M_Geometry_box_fit_2d(PyObject *UNUSED(self), PyObject *pointli
 
        if (len) {
                /* Non Python function */
-               angle = BLI_convexhull_aabb_fit_points_2d((const float (*)[2])points, len);
+               angle = BLI_convexhull_aabb_fit_points_2d(points, len);
 
                PyMem_Free(points);
        }
@@ -1464,7 +1468,7 @@ static PyObject *M_Geometry_convex_hull_2d(PyObject *UNUSED(self), PyObject *poi
                index_map  = MEM_mallocN(sizeof(*index_map) * len * 2, __func__);
 
                /* Non Python function */
-               len_ret = BLI_convexhull_2d((const float (*)[2])points, len, index_map);
+               len_ret = BLI_convexhull_2d(points, len, index_map);
 
                ret = PyList_New(len_ret);
                for (i = 0; i < len_ret; i++) {