Fixed typo Python API
[blender-staging.git] / source / blender / python / mathutils / mathutils_geometry.c
index 261234e..d935949 100644 (file)
 #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
 
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
+
+#include "../generic/py_capi_utils.h"
 #include "../generic/python_utildefines.h"
 
 /*-------------------------DOC STRINGS ---------------------------*/
@@ -77,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;
                }
        }
@@ -183,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. */
@@ -203,7 +203,7 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject
        }
 
        if (result == 0) {
-               /* colinear */
+               /* collinear */
                Py_RETURN_NONE;
        }
        else {
@@ -415,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"
@@ -481,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;
        }
@@ -530,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;
        }
@@ -549,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);
 
@@ -593,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;
        }
@@ -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;
        }
@@ -734,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))
@@ -745,14 +753,14 @@ 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_ITEMS(ret,
                Vector_CreatePyObject(pt_out, size, NULL),
@@ -791,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;
                }
        }
@@ -854,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"
@@ -864,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"
 );
@@ -874,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, )))
@@ -946,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"
 );
@@ -971,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++) {
@@ -1061,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;
                                                                        }
                                                                }
@@ -1080,9 +1085,7 @@ 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);
@@ -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++;
                }
@@ -1427,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);
        }
@@ -1465,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++) {