~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to source/blender/python/mathutils/mathutils_Vector.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
 
36
36
#include "BLI_math.h"
37
37
#include "BLI_utildefines.h"
38
 
#include "BLI_dynstr.h"
 
38
 
 
39
#ifndef MATH_STANDALONE
 
40
#  include "BLI_dynstr.h"
 
41
#endif
39
42
 
40
43
#define MAX_DIMENSIONS 4
41
44
 
54
57
/* Supports 2D, 3D, and 4D vector objects both int and float values
55
58
 * accepted. Mixed float and int values accepted. Ints are parsed to float
56
59
 */
57
 
static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds))
 
60
static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
58
61
{
59
62
        float *vec = NULL;
60
63
        int size = 3; /* default to a 3D vector */
61
64
 
 
65
        if (kwds && PyDict_Size(kwds)) {
 
66
                PyErr_SetString(PyExc_TypeError,
 
67
                                "Vector(): "
 
68
                                "takes no keyword args");
 
69
                return NULL;
 
70
        }
 
71
 
62
72
        switch (PyTuple_GET_SIZE(args)) {
63
73
                case 0:
64
74
                        vec = PyMem_Malloc(size * sizeof(float));
74
84
                        break;
75
85
                case 1:
76
86
                        if ((size = mathutils_array_parse_alloc(&vec, 2, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1) {
77
 
                                if (vec) {
78
 
                                        PyMem_Free(vec);
79
 
                                }
80
87
                                return NULL;
81
88
                        }
82
89
                        break;
86
93
                                        "more then a single arg given");
87
94
                        return NULL;
88
95
        }
89
 
        return Vector_CreatePyObject(vec, size, Py_NEW, type);
 
96
        return Vector_CreatePyObject_alloc(vec, size, type);
90
97
}
91
98
 
92
99
static PyObject *vec__apply_to_copy(PyNoArgsFunction vec_func, VectorObject *self)
294
301
        if ((value_size = mathutils_array_parse_alloc(&iter_vec, 2, value,
295
302
                                                      "Vector.Repeat(vector, size), invalid 'vector' arg")) == -1)
296
303
        {
 
304
                return NULL;
 
305
        }
 
306
 
 
307
        if (iter_vec == NULL) {
 
308
                PyErr_SetString(PyExc_MemoryError,
 
309
                                "Vector.Repeat(): "
 
310
                                "problem allocating pointer space");
 
311
                return NULL;
 
312
        }
 
313
 
 
314
        vec = PyMem_Malloc(size * sizeof(float));
 
315
 
 
316
        if (vec == NULL) {
297
317
                PyMem_Free(iter_vec);
298
 
                return NULL;
299
 
        }
300
 
 
301
 
        if (iter_vec == NULL) {
302
 
                PyErr_SetString(PyExc_MemoryError,
303
 
                                "Vector.Repeat(): "
304
 
                                "problem allocating pointer space");
305
 
                return NULL;
306
 
        }
307
 
 
308
 
        vec = PyMem_Malloc(size * sizeof(float));
309
 
 
310
 
        if (vec == NULL) {
311
318
                PyErr_SetString(PyExc_MemoryError,
312
319
                                "Vector.Repeat(): "
313
320
                                "problem allocating pointer space");
891
898
static PyObject *Vector_dot(VectorObject *self, PyObject *value)
892
899
{
893
900
        float *tvec;
 
901
        PyObject *ret;
894
902
 
895
903
        if (BaseMath_ReadCallback(self) == -1)
896
904
                return NULL;
897
905
 
898
906
        if (mathutils_array_parse_alloc(&tvec, self->size, value, "Vector.dot(other), invalid 'other' arg") == -1) {
899
 
                goto cleanup;
 
907
                return NULL;
900
908
        }
901
909
 
902
 
        return PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->size));
903
 
 
904
 
cleanup:
 
910
        ret = PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->size));
905
911
        PyMem_Free(tvec);
906
 
        return NULL;
 
912
        return ret;
907
913
}
908
914
 
909
915
PyDoc_STRVAR(Vector_angle_doc,
1097
1103
        if (BaseMath_ReadCallback(self) == -1)
1098
1104
                return NULL;
1099
1105
 
1100
 
        //get dot products
 
1106
        /* get dot products */
1101
1107
        for (x = 0; x < size; x++) {
1102
1108
                dot += (double)(self->vec[x] * tvec[x]);
1103
1109
                dot2 += (double)(tvec[x] * tvec[x]);
1104
1110
        }
1105
 
        //projection
 
1111
        /* projection */
1106
1112
        dot /= dot2;
1107
1113
        for (x = 0; x < size; x++) {
1108
1114
                vec[x] = (float)dot * tvec[x];
1133
1139
        if (!PyArg_ParseTuple(args, "Of:lerp", &value, &fac))
1134
1140
                return NULL;
1135
1141
 
 
1142
        if (BaseMath_ReadCallback(self) == -1) {
 
1143
                return NULL;
 
1144
        }
 
1145
 
1136
1146
        if (mathutils_array_parse_alloc(&tvec, size, value, "Vector.lerp(other), invalid 'other' arg") == -1) {
1137
 
                goto cleanup;
1138
 
        }
1139
 
 
1140
 
        if (BaseMath_ReadCallback(self) == -1) {
1141
 
                goto cleanup;
 
1147
                return NULL;
1142
1148
        }
1143
1149
 
1144
1150
        vec = PyMem_Malloc(size * sizeof(float));
1158
1164
        PyMem_Free(tvec);
1159
1165
 
1160
1166
        return Vector_CreatePyObject_alloc(vec, size, Py_TYPE(self));
1161
 
 
1162
 
cleanup:
1163
 
        PyMem_Free(tvec);
1164
 
        return NULL;
1165
1167
}
1166
1168
 
1167
1169
PyDoc_STRVAR(Vector_rotate_doc,
1232
1234
        return ret;
1233
1235
}
1234
1236
 
 
1237
#ifndef MATH_STANDALONE
1235
1238
static PyObject *Vector_str(VectorObject *self)
1236
1239
{
1237
1240
        int i;
1253
1256
 
1254
1257
        return mathutils_dynstr_to_py(ds); /* frees ds */
1255
1258
}
1256
 
 
 
1259
#endif
1257
1260
 
1258
1261
/* Sequence Protocol */
1259
1262
/* sequence length len(vector) */
1363
1366
 
1364
1367
        size = (end - begin);
1365
1368
        if (mathutils_array_parse_alloc(&vec, size, seq, "vector[begin:end] = [...]") == -1) {
1366
 
                goto cleanup;
 
1369
                return -1;
1367
1370
        }
1368
1371
 
1369
1372
        if (vec == NULL) {
1376
1379
        /*parsed well - now set in vector*/
1377
1380
        memcpy(self->vec + begin, vec, size * sizeof(float));
1378
1381
 
 
1382
        PyMem_Free(vec);
 
1383
 
1379
1384
        if (BaseMath_WriteCallback(self) == -1)
1380
1385
                return -1;
1381
1386
 
1382
 
        PyMem_Free(vec);
1383
 
 
1384
1387
        return 0;
1385
 
 
1386
 
cleanup:
1387
 
        PyMem_Free(vec);
1388
 
        return -1;
1389
1388
}
1390
1389
 
1391
1390
/* Numeric Protocols */
1535
1534
}
1536
1535
 
1537
1536
/*------------------------obj * obj------------------------------
1538
 
 * mulplication*/
 
1537
 * multiplication */
1539
1538
 
1540
1539
 
1541
1540
/* COLUMN VECTOR Multiplication (Matrix X Vector)
1692
1691
        return NULL;
1693
1692
}
1694
1693
 
1695
 
/* mulplication in-place: obj *= obj */
 
1694
/* multiplication in-place: obj *= obj */
1696
1695
static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
1697
1696
{
1698
1697
        VectorObject *vec = (VectorObject *)v1;
1869
1868
 
1870
1869
 
1871
1870
/*------------------------tp_richcmpr
1872
 
 * returns -1 execption, 0 false, 1 true */
 
1871
 * returns -1 exception, 0 false, 1 true */
1873
1872
static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
1874
1873
{
1875
1874
        VectorObject *vecA = NULL, *vecB = NULL;
1876
1875
        int result = 0;
1877
 
        double epsilon = .000001f;
 
1876
        double epsilon = 0.000001f;
1878
1877
        double lenA, lenB;
1879
1878
 
1880
1879
        if (!VectorObject_Check(objectA) || !VectorObject_Check(objectB)) {
1981
1980
        else if (PySlice_Check(item)) {
1982
1981
                Py_ssize_t start, stop, step, slicelength;
1983
1982
 
1984
 
                if (PySlice_GetIndicesEx((void *)item, self->size, &start, &stop, &step, &slicelength) < 0)
 
1983
                if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0)
1985
1984
                        return NULL;
1986
1985
 
1987
1986
                if (slicelength <= 0) {
2017
2016
        else if (PySlice_Check(item)) {
2018
2017
                Py_ssize_t start, stop, step, slicelength;
2019
2018
 
2020
 
                if (PySlice_GetIndicesEx((void *)item, self->size, &start, &stop, &step, &slicelength) < 0)
 
2019
                if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0)
2021
2020
                        return -1;
2022
2021
 
2023
2022
                if (step == 1)
2051
2050
        NULL,                       /*nb_divmod*/
2052
2051
        NULL,                       /*nb_power*/
2053
2052
        (unaryfunc)     Vector_neg, /*nb_negative*/
2054
 
        (unaryfunc)     NULL,       /*tp_positive*/
 
2053
        (unaryfunc)     Vector_copy,/*tp_positive*/
2055
2054
        (unaryfunc)     NULL,       /*tp_absolute*/
2056
2055
        (inquiry)   NULL,           /*tp_bool*/
2057
2056
        (unaryfunc) NULL,           /*nb_invert*/
2268
2267
        axis_from = 0;
2269
2268
        swizzleClosure = GET_INT_FROM_POINTER(closure);
2270
2269
 
 
2270
        /* We must first copy current vec into tvec, else some org values may be lost.
 
2271
         * See [#31760].
 
2272
         * Assuming self->size can't be higher than MAX_DIMENSIONS! */
 
2273
        memcpy(tvec, self->vec, self->size * sizeof(float));
 
2274
 
2271
2275
        while (swizzleClosure & SWIZZLE_VALID_AXIS) {
2272
2276
                axis_to = swizzleClosure & SWIZZLE_AXIS;
2273
2277
                tvec[axis_to] = vec_assign[axis_from];
2275
2279
                axis_from++;
2276
2280
        }
2277
2281
 
2278
 
        memcpy(self->vec, tvec, axis_from * sizeof(float));
 
2282
        /* We must copy back the whole tvec into vec, else some changes may be lost (e.g. xz...).
 
2283
         * See [#31760]. */
 
2284
        memcpy(self->vec, tvec, self->size * sizeof(float));
2279
2285
        /* continue with BaseMathObject_WriteCallback at the end */
2280
2286
 
2281
2287
        if (BaseMath_WriteCallback(self) == -1)
2707
2713
        memcpy(vec_cpy, vec->vec, vec_size * sizeof(float));
2708
2714
 
2709
2715
        r_vec[3] = 1.0f;
2710
 
        //muliplication
 
2716
        /* muliplication */
2711
2717
        for (col = 0; col < mat->num_col; col++) {
2712
2718
                double dot = 0.0;
2713
2719
                for (row = 0; row < mat->num_row; row++) {
2714
 
                        dot += MATRIX_ITEM(mat, row, col) * vec_cpy[row];
 
2720
                        dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[row]);
2715
2721
                }
2716
2722
                r_vec[z++] = (float)dot;
2717
2723
        }
2731
2737
 
2732
2738
        negate_vn(self->vec, self->size);
2733
2739
 
2734
 
        (void)BaseMath_WriteCallback(self); // already checked for error
 
2740
        (void)BaseMath_WriteCallback(self);  /* already checked for error */
2735
2741
        Py_RETURN_NONE;
2736
2742
}
2737
2743
 
2782
2788
/* Note
2783
2789
 * Py_TPFLAGS_CHECKTYPES allows us to avoid casting all types to Vector when coercing
2784
2790
 * but this means for eg that
2785
 
 * (vec * mat) and (mat * vec) both get sent to Vector_mul and it neesd to sort out the order
 
2791
 * (vec * mat) and (mat * vec) both get sent to Vector_mul and it needs to sort out the order
2786
2792
 */
2787
2793
 
2788
2794
PyDoc_STRVAR(vector_doc,
2814
2820
 
2815
2821
        NULL,                       /* hashfunc tp_hash; */
2816
2822
        NULL,                       /* ternaryfunc tp_call; */
 
2823
#ifndef MATH_STANDALONE
2817
2824
        (reprfunc)Vector_str,       /* reprfunc tp_str; */
 
2825
#else
 
2826
        NULL,                       /* reprfunc tp_str; */
 
2827
#endif
2818
2828
        NULL,                       /* getattrofunc tp_getattro; */
2819
2829
        NULL,                       /* setattrofunc tp_setattro; */
2820
2830
 
2827
2837
        /*** Assigned meaning in release 2.0 ***/
2828
2838
 
2829
2839
        /* call function for all accessible objects */
2830
 
        (traverseproc)BaseMathObject_traverse,  //tp_traverse
 
2840
        (traverseproc)BaseMathObject_traverse,  /* tp_traverse */
2831
2841
 
2832
2842
        /* delete references to contained objects */
2833
 
        (inquiry)BaseMathObject_clear,  //tp_clear
 
2843
        (inquiry)BaseMathObject_clear,  /* tp_clear */
2834
2844
 
2835
2845
        /***  Assigned meaning in release 2.1 ***/
2836
2846
        /*** rich comparisons ***/
2906
2916
                        }
2907
2917
                        else { /* new empty */
2908
2918
                                fill_vn_fl(self->vec, size, 0.0f);
2909
 
                                if (size == 4) { /* do the homogenous thing */
 
2919
                                if (size == 4) {  /* do the homogeneous thing */
2910
2920
                                        self->vec[3] = 1.0f;
2911
2921
                                }
2912
2922
                        }