~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * ***** BEGIN GPL LICENSE BLOCK *****
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software Foundation,
 
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
17
 *
 
18
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 
19
 * All rights reserved.
 
20
 *
 
21
 * This is a new part of Blender.
 
22
 *
 
23
 * Contributor(s): Joseph Gilbert, Campbell Barton
 
24
 *
 
25
 * ***** END GPL LICENSE BLOCK *****
 
26
 */
 
27
 
 
28
/** \file blender/python/mathutils/mathutils.c
 
29
 *  \ingroup pymathutils
 
30
 */
 
31
 
 
32
#include <Python.h>
 
33
 
 
34
#include "mathutils.h"
 
35
 
 
36
#include "BLI_math.h"
 
37
#include "BLI_utildefines.h"
 
38
#include "BLI_dynstr.h"
 
39
 
 
40
PyDoc_STRVAR(M_Mathutils_doc,
 
41
"This module provides access to matrices, eulers, quaternions and vectors."
 
42
);
 
43
static int mathutils_array_parse_fast(float *array,
 
44
                                      int size,
 
45
                                      PyObject *value_fast,
 
46
                                      const char *error_prefix)
 
47
{
 
48
        PyObject *item;
 
49
 
 
50
        int i;
 
51
 
 
52
        i = size;
 
53
        do {
 
54
                i--;
 
55
                if (((array[i] = PyFloat_AsDouble((item = PySequence_Fast_GET_ITEM(value_fast, i)))) == -1.0f) &&
 
56
                    PyErr_Occurred())
 
57
                {
 
58
                        PyErr_Format(PyExc_TypeError,
 
59
                                     "%.200s: sequence index %d expected a number, "
 
60
                                     "found '%.200s' type, ",
 
61
                                     error_prefix, i, Py_TYPE(item)->tp_name);
 
62
                        Py_DECREF(value_fast);
 
63
                        return -1;
 
64
                }
 
65
        } while (i);
 
66
 
 
67
        Py_XDECREF(value_fast);
 
68
        return size;
 
69
}
 
70
 
 
71
/* helper functionm returns length of the 'value', -1 on error */
 
72
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
 
73
{
 
74
        int size;
 
75
 
 
76
#if 1 /* approx 6x speedup for mathutils types */
 
77
 
 
78
        if ((size = VectorObject_Check(value)     ? ((VectorObject *)value)->size : 0) ||
 
79
            (size = EulerObject_Check(value)      ? 3 : 0) ||
 
80
            (size = QuaternionObject_Check(value) ? 4 : 0) ||
 
81
            (size = ColorObject_Check(value)      ? 3 : 0))
 
82
        {
 
83
                if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
 
84
                        return -1;
 
85
                }
 
86
 
 
87
                if (size > array_max || size < array_min) {
 
88
                        if (array_max == array_min) {
 
89
                                PyErr_Format(PyExc_ValueError,
 
90
                                             "%.200s: sequence size is %d, expected %d",
 
91
                                             error_prefix, size, array_max);
 
92
                        }
 
93
                        else {
 
94
                                PyErr_Format(PyExc_ValueError,
 
95
                                             "%.200s: sequence size is %d, expected [%d - %d]",
 
96
                                             error_prefix, size, array_min, array_max);
 
97
                        }
 
98
                        return -1;
 
99
                }
 
100
 
 
101
                memcpy(array, ((BaseMathObject *)value)->data, size * sizeof(float));
 
102
                return size;
 
103
        }
 
104
        else
 
105
#endif
 
106
        {
 
107
                PyObject *value_fast = NULL;
 
108
 
 
109
                /* non list/tuple cases */
 
110
                if (!(value_fast = PySequence_Fast(value, error_prefix))) {
 
111
                        /* PySequence_Fast sets the error */
 
112
                        return -1;
 
113
                }
 
114
 
 
115
                size = PySequence_Fast_GET_SIZE(value_fast);
 
116
 
 
117
                if (size > array_max || size < array_min) {
 
118
                        if (array_max == array_min) {
 
119
                                PyErr_Format(PyExc_ValueError,
 
120
                                             "%.200s: sequence size is %d, expected %d",
 
121
                                             error_prefix, size, array_max);
 
122
                        }
 
123
                        else {
 
124
                                PyErr_Format(PyExc_ValueError,
 
125
                                             "%.200s: sequence size is %d, expected [%d - %d]",
 
126
                                             error_prefix, size, array_min, array_max);
 
127
                        }
 
128
                        Py_DECREF(value_fast);
 
129
                        return -1;
 
130
                }
 
131
 
 
132
                return mathutils_array_parse_fast(array, size, value_fast, error_prefix);
 
133
        }
 
134
}
 
135
 
 
136
int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, const char *error_prefix)
 
137
{
 
138
        int size;
 
139
 
 
140
#if 1 /* approx 6x speedup for mathutils types */
 
141
 
 
142
        if ((size = VectorObject_Check(value)     ? ((VectorObject *)value)->size : 0) ||
 
143
            (size = EulerObject_Check(value)      ? 3 : 0) ||
 
144
            (size = QuaternionObject_Check(value) ? 4 : 0) ||
 
145
            (size = ColorObject_Check(value)      ? 3 : 0))
 
146
        {
 
147
                if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
 
148
                        return -1;
 
149
                }
 
150
 
 
151
                if (size < array_min) {
 
152
                        PyErr_Format(PyExc_ValueError,
 
153
                                     "%.200s: sequence size is %d, expected > %d",
 
154
                                     error_prefix, size, array_min);
 
155
                        return -1;
 
156
                }
 
157
                
 
158
                *array = PyMem_Malloc(size * sizeof(float));
 
159
                memcpy(*array, ((BaseMathObject *)value)->data, size * sizeof(float));
 
160
                return size;
 
161
        }
 
162
        else
 
163
#endif
 
164
        {
 
165
                PyObject *value_fast = NULL;
 
166
                // *array = NULL;
 
167
 
 
168
                /* non list/tuple cases */
 
169
                if (!(value_fast = PySequence_Fast(value, error_prefix))) {
 
170
                        /* PySequence_Fast sets the error */
 
171
                        return -1;
 
172
                }
 
173
 
 
174
                size = PySequence_Fast_GET_SIZE(value_fast);
 
175
 
 
176
                if (size < array_min) {
 
177
                        PyErr_Format(PyExc_ValueError,
 
178
                                     "%.200s: sequence size is %d, expected > %d",
 
179
                                     error_prefix, size, array_min);
 
180
                        return -1;
 
181
                }
 
182
 
 
183
                *array = PyMem_Malloc(size * sizeof(float));
 
184
 
 
185
                return mathutils_array_parse_fast(*array, size, value_fast, error_prefix);
 
186
        }
 
187
}
 
188
 
 
189
/* parse an array of vectors */
 
190
int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value, const char *error_prefix)
 
191
{
 
192
        PyObject *value_fast = NULL;
 
193
        int i, size;
 
194
 
 
195
        /* non list/tuple cases */
 
196
        if (!(value_fast = PySequence_Fast(value, error_prefix))) {
 
197
                /* PySequence_Fast sets the error */
 
198
                return -1;
 
199
        }
 
200
 
 
201
        size = PySequence_Fast_GET_SIZE(value_fast);
 
202
 
 
203
        if (size != 0) {
 
204
                float *fp;
 
205
 
 
206
                fp = *array = PyMem_Malloc(size * array_dim * sizeof(float));
 
207
 
 
208
                for (i = 0; i < size; i++, fp += array_dim) {
 
209
                        PyObject *item = PySequence_Fast_GET_ITEM(value, i);
 
210
 
 
211
                        if (mathutils_array_parse(fp, array_dim, array_dim, item, error_prefix) == -1) {
 
212
                                PyMem_Free(*array);
 
213
                                *array = NULL;
 
214
                                size = -1;
 
215
                                break;
 
216
                        }
 
217
                }
 
218
        }
 
219
 
 
220
        Py_DECREF(value_fast);
 
221
        return size;
 
222
}
 
223
 
 
224
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
 
225
{
 
226
        if (EulerObject_Check(value)) {
 
227
                if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
 
228
                        return -1;
 
229
                }
 
230
                else {
 
231
                        eulO_to_mat3(rmat, ((EulerObject *)value)->eul, ((EulerObject *)value)->order);
 
232
                        return 0;
 
233
                }
 
234
        }
 
235
        else if (QuaternionObject_Check(value)) {
 
236
                if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
 
237
                        return -1;
 
238
                }
 
239
                else {
 
240
                        float tquat[4];
 
241
                        normalize_qt_qt(tquat, ((QuaternionObject *)value)->quat);
 
242
                        quat_to_mat3(rmat, tquat);
 
243
                        return 0;
 
244
                }
 
245
        }
 
246
        else if (MatrixObject_Check(value)) {
 
247
                if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
 
248
                        return -1;
 
249
                }
 
250
                else if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) {
 
251
                        PyErr_Format(PyExc_ValueError,
 
252
                                     "%.200s: matrix must have minimum 3x3 dimensions",
 
253
                                     error_prefix);
 
254
                        return -1;
 
255
                }
 
256
                else {
 
257
                        matrix_as_3x3(rmat, (MatrixObject *)value);
 
258
                        normalize_m3(rmat);
 
259
                        return 0;
 
260
                }
 
261
        }
 
262
        else {
 
263
                PyErr_Format(PyExc_TypeError,
 
264
                             "%.200s: expected a Euler, Quaternion or Matrix type, "
 
265
                             "found %.200s", error_prefix, Py_TYPE(value)->tp_name);
 
266
                return -1;
 
267
        }
 
268
}
 
269
 
 
270
 
 
271
//----------------------------------MATRIX FUNCTIONS--------------------
 
272
 
 
273
 
 
274
/* Utility functions */
 
275
 
 
276
// LomontRRDCompare4, Ever Faster Float Comparisons by Randy Dillon
 
277
#define SIGNMASK(i) (-(int)(((unsigned int)(i)) >> 31))
 
278
 
 
279
int EXPP_FloatsAreEqual(float af, float bf, int maxDiff)
 
280
{
 
281
        /* solid, fast routine across all platforms
 
282
         * with constant time behavior */
 
283
        int ai = *(int *)(&af);
 
284
        int bi = *(int *)(&bf);
 
285
        int test = SIGNMASK(ai ^ bi);
 
286
        int diff, v1, v2;
 
287
 
 
288
        assert((0 == test) || (0xFFFFFFFF == test));
 
289
        diff = (ai ^ (test & 0x7fffffff)) - bi;
 
290
        v1 = maxDiff + diff;
 
291
        v2 = maxDiff - diff;
 
292
        return (v1 | v2) >= 0;
 
293
}
 
294
 
 
295
/*---------------------- EXPP_VectorsAreEqual -------------------------
 
296
 * Builds on EXPP_FloatsAreEqual to test vectors */
 
297
int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps)
 
298
{
 
299
        int x;
 
300
        for (x = 0; x < size; x++) {
 
301
                if (EXPP_FloatsAreEqual(vecA[x], vecB[x], floatSteps) == 0)
 
302
                        return 0;
 
303
        }
 
304
        return 1;
 
305
}
 
306
 
 
307
/* dynstr as python string utility funcions, frees 'ds'! */
 
308
PyObject *mathutils_dynstr_to_py(struct DynStr *ds)
 
309
{
 
310
        const int ds_len = BLI_dynstr_get_len(ds); /* space for \0 */
 
311
        char *ds_buf     = PyMem_Malloc(ds_len + 1);
 
312
        PyObject *ret;
 
313
        BLI_dynstr_get_cstring_ex(ds, ds_buf);
 
314
        BLI_dynstr_free(ds);
 
315
        ret = PyUnicode_FromStringAndSize(ds_buf, ds_len);
 
316
        PyMem_Free(ds_buf);
 
317
        return ret;
 
318
}
 
319
 
 
320
/* silly function, we dont use arg. just check its compatible with __deepcopy__ */
 
321
int mathutils_deepcopy_args_check(PyObject *args)
 
322
{
 
323
        PyObject *dummy_pydict;
 
324
        return PyArg_ParseTuple(args, "|O!:__deepcopy__", &PyDict_Type, &dummy_pydict) != 0;
 
325
}
 
326
 
 
327
/* Mathutils Callbacks */
 
328
 
 
329
/* for mathutils internal use only, eventually should re-alloc but to start with we only have a few users */
 
330
#define MATHUTILS_TOT_CB 10
 
331
static Mathutils_Callback *mathutils_callbacks[MATHUTILS_TOT_CB] = {NULL};
 
332
 
 
333
unsigned char Mathutils_RegisterCallback(Mathutils_Callback *cb)
 
334
{
 
335
        unsigned char i;
 
336
        
 
337
        /* find the first free slot */
 
338
        for (i = 0; mathutils_callbacks[i]; i++) {
 
339
                if (mathutils_callbacks[i] == cb) /* already registered? */
 
340
                        return i;
 
341
        }
 
342
 
 
343
        BLI_assert(i + 1 < MATHUTILS_TOT_CB);
 
344
 
 
345
        mathutils_callbacks[i] = cb;
 
346
        return i;
 
347
}
 
348
 
 
349
/* use macros to check for NULL */
 
350
int _BaseMathObject_ReadCallback(BaseMathObject *self)
 
351
{
 
352
        Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
 
353
        if (LIKELY(cb->get(self, self->cb_subtype) != -1)) {
 
354
                return 0;
 
355
        }
 
356
 
 
357
        if (!PyErr_Occurred()) {
 
358
                PyErr_Format(PyExc_RuntimeError,
 
359
                             "%s read, user has become invalid",
 
360
                             Py_TYPE(self)->tp_name);
 
361
        }
 
362
        return -1;
 
363
}
 
364
 
 
365
int _BaseMathObject_WriteCallback(BaseMathObject *self)
 
366
{
 
367
        Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
 
368
        if (LIKELY(cb->set(self, self->cb_subtype) != -1)) {
 
369
                return 0;
 
370
        }
 
371
 
 
372
        if (!PyErr_Occurred()) {
 
373
                PyErr_Format(PyExc_RuntimeError,
 
374
                             "%s write, user has become invalid",
 
375
                             Py_TYPE(self)->tp_name);
 
376
        }
 
377
        return -1;
 
378
}
 
379
 
 
380
int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index)
 
381
{
 
382
        Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
 
383
        if (LIKELY(cb->get_index(self, self->cb_subtype, index) != -1)) {
 
384
                return 0;
 
385
        }
 
386
 
 
387
        if (!PyErr_Occurred()) {
 
388
                PyErr_Format(PyExc_RuntimeError,
 
389
                             "%s read index, user has become invalid",
 
390
                             Py_TYPE(self)->tp_name);
 
391
        }
 
392
        return -1;
 
393
}
 
394
 
 
395
int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index)
 
396
{
 
397
        Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
 
398
        if (LIKELY(cb->set_index(self, self->cb_subtype, index) != -1)) {
 
399
                return 0;
 
400
        }
 
401
 
 
402
        if (!PyErr_Occurred()) {
 
403
                PyErr_Format(PyExc_RuntimeError,
 
404
                             "%s write index, user has become invalid",
 
405
                             Py_TYPE(self)->tp_name);
 
406
        }
 
407
        return -1;
 
408
}
 
409
 
 
410
/* BaseMathObject generic functions for all mathutils types */
 
411
char BaseMathObject_owner_doc[] = "The item this is wrapping or None  (read-only).";
 
412
PyObject *BaseMathObject_owner_get(BaseMathObject *self, void *UNUSED(closure))
 
413
{
 
414
        PyObject *ret = self->cb_user ? self->cb_user : Py_None;
 
415
        Py_INCREF(ret);
 
416
        return ret;
 
417
}
 
418
 
 
419
char BaseMathObject_is_wrapped_doc[] = "True when this object wraps external data (read-only).\n\n:type: boolean";
 
420
PyObject *BaseMathObject_is_wrapped_get(BaseMathObject *self, void *UNUSED(closure))
 
421
{
 
422
        return PyBool_FromLong((self->wrapped == Py_WRAP) ? 1 : 0);
 
423
}
 
424
 
 
425
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
 
426
{
 
427
        Py_VISIT(self->cb_user);
 
428
        return 0;
 
429
}
 
430
 
 
431
int BaseMathObject_clear(BaseMathObject *self)
 
432
{
 
433
        Py_CLEAR(self->cb_user);
 
434
        return 0;
 
435
}
 
436
 
 
437
void BaseMathObject_dealloc(BaseMathObject *self)
 
438
{
 
439
        /* only free non wrapped */
 
440
        if (self->wrapped != Py_WRAP) {
 
441
                PyMem_Free(self->data);
 
442
        }
 
443
 
 
444
        if (self->cb_user) {
 
445
                PyObject_GC_UnTrack(self);
 
446
                BaseMathObject_clear(self);
 
447
        }
 
448
 
 
449
        Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); // breaks subtypes
 
450
}
 
451
 
 
452
/*----------------------------MODULE INIT-------------------------*/
 
453
static struct PyMethodDef M_Mathutils_methods[] = {
 
454
        {NULL, NULL, 0, NULL}
 
455
};
 
456
 
 
457
static struct PyModuleDef M_Mathutils_module_def = {
 
458
        PyModuleDef_HEAD_INIT,
 
459
        "mathutils",  /* m_name */
 
460
        M_Mathutils_doc,  /* m_doc */
 
461
        0,  /* m_size */
 
462
        M_Mathutils_methods,  /* m_methods */
 
463
        NULL,  /* m_reload */
 
464
        NULL,  /* m_traverse */
 
465
        NULL,  /* m_clear */
 
466
        NULL,  /* m_free */
 
467
};
 
468
 
 
469
PyMODINIT_FUNC PyInit_mathutils(void)
 
470
{
 
471
        PyObject *mod;
 
472
        PyObject *submodule;
 
473
        PyObject *sys_modules = PyThreadState_GET()->interp->modules;
 
474
 
 
475
        if (PyType_Ready(&vector_Type) < 0)
 
476
                return NULL;
 
477
        if (PyType_Ready(&matrix_Type) < 0)
 
478
                return NULL;
 
479
        if (PyType_Ready(&matrix_access_Type) < 0)
 
480
                return NULL;
 
481
        if (PyType_Ready(&euler_Type) < 0)
 
482
                return NULL;
 
483
        if (PyType_Ready(&quaternion_Type) < 0)
 
484
                return NULL;
 
485
        if (PyType_Ready(&color_Type) < 0)
 
486
                return NULL;
 
487
 
 
488
        mod = PyModule_Create(&M_Mathutils_module_def);
 
489
        
 
490
        /* each type has its own new() function */
 
491
        PyModule_AddObject(mod, vector_Type.tp_name,     (PyObject *)&vector_Type);
 
492
        PyModule_AddObject(mod, matrix_Type.tp_name,     (PyObject *)&matrix_Type);
 
493
        PyModule_AddObject(mod, euler_Type.tp_name,      (PyObject *)&euler_Type);
 
494
        PyModule_AddObject(mod, quaternion_Type.tp_name, (PyObject *)&quaternion_Type);
 
495
        PyModule_AddObject(mod, color_Type.tp_name,      (PyObject *)&color_Type);
 
496
        
 
497
        /* submodule */
 
498
        PyModule_AddObject(mod, "geometry",       (submodule = PyInit_mathutils_geometry()));
 
499
        /* XXX, python doesnt do imports with this usefully yet
 
500
         * 'from mathutils.geometry import PolyFill'
 
501
         * ...fails without this. */
 
502
        PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
 
503
        Py_INCREF(submodule);
 
504
 
 
505
        /* Noise submodule */
 
506
        PyModule_AddObject(mod, "noise", (submodule = PyInit_mathutils_noise()));
 
507
        PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
 
508
        Py_INCREF(submodule);
 
509
 
 
510
        mathutils_matrix_row_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_row_cb);
 
511
        mathutils_matrix_col_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_col_cb);
 
512
        mathutils_matrix_translation_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_translation_cb);
 
513
 
 
514
        return mod;
 
515
}