merge with trunk r38787
This commit is contained in:
@@ -18,3 +18,4 @@
|
||||
|
||||
add_subdirectory(intern)
|
||||
add_subdirectory(generic)
|
||||
add_subdirectory(mathutils)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# TODO, split into 2 files.
|
||||
# TODO, split into 3 files.
|
||||
|
||||
Import ('env')
|
||||
|
||||
@@ -18,7 +18,14 @@ if is_debug:
|
||||
defs.append('_DEBUG')
|
||||
|
||||
sources = env.Glob('generic/*.c')
|
||||
env.BlenderLib( libname = 'bf_python_ext', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [362,165]) # ketsji is 360
|
||||
env.BlenderLib( libname = 'bf_python_ext', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [363,165]) # ketsji is 360
|
||||
|
||||
|
||||
# mathutils
|
||||
defs = []
|
||||
|
||||
sources = env.Glob('mathutils/*.c')
|
||||
env.BlenderLib( libname = 'bf_python_mathutils', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [362,165])
|
||||
|
||||
|
||||
# bpy
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
|
||||
set(INC
|
||||
.
|
||||
../../blenlib
|
||||
../../makesdna
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../blenloader
|
||||
../../makesdna
|
||||
../../../../intern/guardedalloc
|
||||
)
|
||||
|
||||
@@ -37,13 +37,6 @@ set(SRC
|
||||
bgl.c
|
||||
blf_py_api.c
|
||||
bpy_internal_import.c
|
||||
mathutils.c
|
||||
mathutils_Color.c
|
||||
mathutils_Euler.c
|
||||
mathutils_Matrix.c
|
||||
mathutils_Quaternion.c
|
||||
mathutils_Vector.c
|
||||
mathutils_geometry.c
|
||||
noise_py_api.c
|
||||
py_capi_utils.c
|
||||
|
||||
@@ -51,13 +44,6 @@ set(SRC
|
||||
bgl.h
|
||||
blf_py_api.h
|
||||
bpy_internal_import.h
|
||||
mathutils.h
|
||||
mathutils_Color.h
|
||||
mathutils_Euler.h
|
||||
mathutils_Matrix.h
|
||||
mathutils_Quaternion.h
|
||||
mathutils_Vector.h
|
||||
mathutils_geometry.h
|
||||
noise_py_api.h
|
||||
py_capi_utils.h
|
||||
)
|
||||
|
||||
@@ -48,12 +48,15 @@ static PyObject *Buffer_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
|
||||
|
||||
/* Buffer sequence methods */
|
||||
|
||||
static int Buffer_len(PyObject *self);
|
||||
static PyObject *Buffer_item(PyObject *self, int i);
|
||||
static PyObject *Buffer_slice(PyObject *self, int begin, int end);
|
||||
static int Buffer_ass_item(PyObject *self, int i, PyObject *v);
|
||||
static int Buffer_ass_slice(PyObject *self, int begin, int end,
|
||||
static int Buffer_len(Buffer *self);
|
||||
static PyObject *Buffer_item(Buffer *self, int i);
|
||||
static PyObject *Buffer_slice(Buffer *self, int begin, int end);
|
||||
static int Buffer_ass_item(Buffer *self, int i, PyObject *v);
|
||||
static int Buffer_ass_slice(Buffer *self, int begin, int end,
|
||||
PyObject *seq);
|
||||
static PyObject *Buffer_subscript(Buffer *self, PyObject *item);
|
||||
static int Buffer_ass_subscript(Buffer *self, PyObject *item,
|
||||
PyObject *value);
|
||||
|
||||
static PySequenceMethods Buffer_SeqMethods = {
|
||||
(lenfunc) Buffer_len, /*sq_length */
|
||||
@@ -68,12 +71,80 @@ static PySequenceMethods Buffer_SeqMethods = {
|
||||
(ssizeargfunc) NULL, /* sq_inplace_repeat */
|
||||
};
|
||||
|
||||
static void Buffer_dealloc(PyObject *self);
|
||||
static PyObject *Buffer_tolist(PyObject *self, void *arg);
|
||||
static PyObject *Buffer_dimensions(PyObject *self, void *arg);
|
||||
static PyObject *Buffer_repr(PyObject *self);
|
||||
static PyMethodDef Buffer_methods[];
|
||||
static PyGetSetDef Buffer_getseters[];
|
||||
|
||||
static PyMappingMethods Buffer_AsMapping = {
|
||||
(lenfunc)Buffer_len,
|
||||
(binaryfunc)Buffer_subscript,
|
||||
(objobjargproc)Buffer_ass_subscript
|
||||
};
|
||||
|
||||
static void Buffer_dealloc(Buffer *self);
|
||||
static PyObject *Buffer_repr(Buffer *self);
|
||||
|
||||
static PyObject *Buffer_to_list(Buffer *self)
|
||||
{
|
||||
int i, len= self->dimensions[0];
|
||||
PyObject *list= PyList_New(len);
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
PyList_SET_ITEM(list, i, Buffer_item(self, i));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static PyObject *Buffer_to_list_recursive(Buffer *self)
|
||||
{
|
||||
PyObject *list;
|
||||
|
||||
if(self->ndimensions > 1) {
|
||||
int i, len= self->dimensions[0];
|
||||
list= PyList_New(len);
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
Buffer *sub= (Buffer *)Buffer_item(self, i);
|
||||
PyList_SET_ITEM(list, i, Buffer_to_list_recursive(sub));
|
||||
Py_DECREF(sub);
|
||||
}
|
||||
}
|
||||
else {
|
||||
list= Buffer_to_list(self);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/* *DEPRECATED* 2011/7/17 bgl.Buffer.list */
|
||||
static PyObject *Buffer_list(Buffer *self, void *UNUSED(arg))
|
||||
{
|
||||
fprintf(stderr, "Warning: 'Buffer.list' deprecated, use '[:]' instead\n");
|
||||
return Buffer_to_list(self);
|
||||
}
|
||||
|
||||
static PyObject *Buffer_dimensions(Buffer *self, void *UNUSED(arg))
|
||||
{
|
||||
PyObject *list= PyList_New(self->ndimensions);
|
||||
int i;
|
||||
|
||||
for (i= 0; i<self->ndimensions; i++) {
|
||||
PyList_SET_ITEM(list, i, PyLong_FromLong(self->dimensions[i]));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static PyMethodDef Buffer_methods[] = {
|
||||
{"to_list", (PyCFunction)Buffer_to_list_recursive, METH_NOARGS,
|
||||
"return the buffer as a list"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static PyGetSetDef Buffer_getseters[] = {
|
||||
{(char *)"list", (getter)Buffer_list, NULL, NULL, NULL},
|
||||
{(char *)"dimensions", (getter)Buffer_dimensions, NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
PyTypeObject BGL_bufferType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
@@ -88,7 +159,7 @@ PyTypeObject BGL_bufferType = {
|
||||
(reprfunc) Buffer_repr, /*tp_repr */
|
||||
NULL, /*tp_as_number */
|
||||
&Buffer_SeqMethods, /*tp_as_sequence */
|
||||
NULL, /* PyMappingMethods *tp_as_mapping; */
|
||||
&Buffer_AsMapping, /* PyMappingMethods *tp_as_mapping; */
|
||||
|
||||
/* More standard operations (here for binary compatibility) */
|
||||
|
||||
@@ -229,7 +300,8 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject
|
||||
int ndimensions = 0;
|
||||
|
||||
if(kwds && PyDict_Size(kwds)) {
|
||||
PyErr_SetString(PyExc_TypeError, "bgl.Buffer(): takes no keyword args");
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"bgl.Buffer(): takes no keyword args");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -286,7 +358,7 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject
|
||||
|
||||
buffer= BGL_MakeBuffer(type, ndimensions, dimensions, NULL);
|
||||
if (init && ndimensions) {
|
||||
if (Buffer_ass_slice((PyObject *) buffer, 0, dimensions[0], init)) {
|
||||
if (Buffer_ass_slice(buffer, 0, dimensions[0], init)) {
|
||||
Py_DECREF(buffer);
|
||||
return NULL;
|
||||
}
|
||||
@@ -297,51 +369,48 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject
|
||||
|
||||
/*@ Buffer sequence methods */
|
||||
|
||||
static int Buffer_len(PyObject *self)
|
||||
static int Buffer_len(Buffer *self)
|
||||
{
|
||||
Buffer *buf= (Buffer *) self;
|
||||
return buf->dimensions[0];
|
||||
return self->dimensions[0];
|
||||
}
|
||||
|
||||
static PyObject *Buffer_item(PyObject *self, int i)
|
||||
static PyObject *Buffer_item(Buffer *self, int i)
|
||||
{
|
||||
Buffer *buf= (Buffer *) self;
|
||||
|
||||
if (i >= buf->dimensions[0]) {
|
||||
if (i >= self->dimensions[0] || i < 0) {
|
||||
PyErr_SetString(PyExc_IndexError, "array index out of range");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (buf->ndimensions==1) {
|
||||
switch (buf->type) {
|
||||
case GL_BYTE: return Py_BuildValue("b", buf->buf.asbyte[i]);
|
||||
case GL_SHORT: return Py_BuildValue("h", buf->buf.asshort[i]);
|
||||
case GL_INT: return Py_BuildValue("i", buf->buf.asint[i]);
|
||||
case GL_FLOAT: return PyFloat_FromDouble(buf->buf.asfloat[i]);
|
||||
case GL_DOUBLE: return Py_BuildValue("d", buf->buf.asdouble[i]);
|
||||
if (self->ndimensions==1) {
|
||||
switch (self->type) {
|
||||
case GL_BYTE: return Py_BuildValue("b", self->buf.asbyte[i]);
|
||||
case GL_SHORT: return Py_BuildValue("h", self->buf.asshort[i]);
|
||||
case GL_INT: return Py_BuildValue("i", self->buf.asint[i]);
|
||||
case GL_FLOAT: return PyFloat_FromDouble(self->buf.asfloat[i]);
|
||||
case GL_DOUBLE: return Py_BuildValue("d", self->buf.asdouble[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Buffer *newbuf;
|
||||
int j, length, size;
|
||||
|
||||
|
||||
length= 1;
|
||||
for (j=1; j<buf->ndimensions; j++) {
|
||||
length*= buf->dimensions[j];
|
||||
for (j=1; j < self->ndimensions; j++) {
|
||||
length *= self->dimensions[j];
|
||||
}
|
||||
size= BGL_typeSize(buf->type);
|
||||
size= BGL_typeSize(self->type);
|
||||
|
||||
newbuf= (Buffer *) PyObject_NEW(Buffer, &BGL_bufferType);
|
||||
|
||||
Py_INCREF(self);
|
||||
newbuf->parent= self;
|
||||
newbuf->parent= (PyObject *)self;
|
||||
|
||||
newbuf->ndimensions= buf->ndimensions-1;
|
||||
newbuf->type= buf->type;
|
||||
newbuf->buf.asvoid= buf->buf.asbyte + i*length*size;
|
||||
newbuf->ndimensions= self->ndimensions - 1;
|
||||
newbuf->type= self->type;
|
||||
newbuf->buf.asvoid= self->buf.asbyte + i*length*size;
|
||||
newbuf->dimensions= MEM_mallocN(newbuf->ndimensions*sizeof(int),
|
||||
"Buffer dimensions");
|
||||
memcpy(newbuf->dimensions, buf->dimensions+1,
|
||||
memcpy(newbuf->dimensions, self->dimensions+1,
|
||||
newbuf->ndimensions*sizeof(int));
|
||||
|
||||
return (PyObject *) newbuf;
|
||||
@@ -350,16 +419,14 @@ static PyObject *Buffer_item(PyObject *self, int i)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *Buffer_slice(PyObject *self, int begin, int end)
|
||||
static PyObject *Buffer_slice(Buffer *self, int begin, int end)
|
||||
{
|
||||
Buffer *buf= (Buffer *) self;
|
||||
PyObject *list;
|
||||
int count;
|
||||
|
||||
if (begin<0) begin= 0;
|
||||
if (end>buf->dimensions[0])
|
||||
end= buf->dimensions[0];
|
||||
if (begin>end) begin= end;
|
||||
if (begin < 0) begin= 0;
|
||||
if (end > self->dimensions[0]) end= self->dimensions[0];
|
||||
if (begin > end) begin= end;
|
||||
|
||||
list= PyList_New(end-begin);
|
||||
|
||||
@@ -369,21 +436,19 @@ static PyObject *Buffer_slice(PyObject *self, int begin, int end)
|
||||
return list;
|
||||
}
|
||||
|
||||
static int Buffer_ass_item(PyObject *self, int i, PyObject *v)
|
||||
static int Buffer_ass_item(Buffer *self, int i, PyObject *v)
|
||||
{
|
||||
Buffer *buf= (Buffer *) self;
|
||||
|
||||
if (i >= buf->dimensions[0]) {
|
||||
if (i >= self->dimensions[0] || i < 0) {
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"array assignment index out of range");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buf->ndimensions!=1) {
|
||||
PyObject *row= Buffer_item(self, i);
|
||||
if (self->ndimensions!=1) {
|
||||
Buffer *row= (Buffer *)Buffer_item(self, i);
|
||||
|
||||
if (row) {
|
||||
int ret= Buffer_ass_slice(row, 0, buf->dimensions[1], v);
|
||||
int ret= Buffer_ass_slice(row, 0, self->dimensions[1], v);
|
||||
Py_DECREF(row);
|
||||
return ret;
|
||||
}
|
||||
@@ -392,31 +457,30 @@ static int Buffer_ass_item(PyObject *self, int i, PyObject *v)
|
||||
}
|
||||
}
|
||||
|
||||
switch(buf->type) {
|
||||
switch(self->type) {
|
||||
case GL_BYTE:
|
||||
return PyArg_Parse(v, "b:Expected ints", &buf->buf.asbyte[i]) ? 0:-1;
|
||||
return PyArg_Parse(v, "b:Expected ints", &self->buf.asbyte[i]) ? 0:-1;
|
||||
case GL_SHORT:
|
||||
return PyArg_Parse(v, "h:Expected ints", &buf->buf.asshort[i]) ? 0:-1;
|
||||
return PyArg_Parse(v, "h:Expected ints", &self->buf.asshort[i]) ? 0:-1;
|
||||
case GL_INT:
|
||||
return PyArg_Parse(v, "i:Expected ints", &buf->buf.asint[i]) ? 0:-1;
|
||||
return PyArg_Parse(v, "i:Expected ints", &self->buf.asint[i]) ? 0:-1;
|
||||
case GL_FLOAT:
|
||||
return PyArg_Parse(v, "f:Expected floats", &buf->buf.asfloat[i]) ? 0:-1;
|
||||
return PyArg_Parse(v, "f:Expected floats", &self->buf.asfloat[i]) ? 0:-1;
|
||||
case GL_DOUBLE:
|
||||
return PyArg_Parse(v, "d:Expected floats", &buf->buf.asdouble[i]) ? 0:-1;
|
||||
return PyArg_Parse(v, "d:Expected floats", &self->buf.asdouble[i]) ? 0:-1;
|
||||
default:
|
||||
return 0; /* should never happen */
|
||||
}
|
||||
}
|
||||
|
||||
static int Buffer_ass_slice(PyObject *self, int begin, int end, PyObject *seq)
|
||||
static int Buffer_ass_slice(Buffer *self, int begin, int end, PyObject *seq)
|
||||
{
|
||||
Buffer *buf= (Buffer *) self;
|
||||
PyObject *item;
|
||||
int count, err=0;
|
||||
|
||||
if (begin<0) begin= 0;
|
||||
if (end>buf->dimensions[0]) end= buf->dimensions[0];
|
||||
if (begin>end) begin= end;
|
||||
if (begin < 0) begin= 0;
|
||||
if (end > self->dimensions[0]) end= self->dimensions[0];
|
||||
if (begin > end) begin= end;
|
||||
|
||||
if (!PySequence_Check(seq)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
@@ -448,62 +512,94 @@ static int Buffer_ass_slice(PyObject *self, int begin, int end, PyObject *seq)
|
||||
return err;
|
||||
}
|
||||
|
||||
static void Buffer_dealloc(PyObject *self)
|
||||
static PyObject *Buffer_subscript(Buffer *self, PyObject *item)
|
||||
{
|
||||
Buffer *buf = (Buffer *)self;
|
||||
if (PyIndex_Check(item)) {
|
||||
Py_ssize_t i;
|
||||
i = PyNumber_AsSsize_t(item, PyExc_IndexError);
|
||||
if (i == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
if (i < 0)
|
||||
i += self->dimensions[0];
|
||||
return Buffer_item(self, i);
|
||||
}
|
||||
else if (PySlice_Check(item)) {
|
||||
Py_ssize_t start, stop, step, slicelength;
|
||||
|
||||
if (buf->parent) Py_DECREF(buf->parent);
|
||||
else MEM_freeN (buf->buf.asvoid);
|
||||
if (PySlice_GetIndicesEx((void *)item, self->dimensions[0], &start, &stop, &step, &slicelength) < 0)
|
||||
return NULL;
|
||||
|
||||
if (slicelength <= 0) {
|
||||
return PyTuple_New(0);
|
||||
}
|
||||
else if (step == 1) {
|
||||
return Buffer_slice(self, start, stop);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"slice steps not supported with vectors");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"buffer indices must be integers, not %.200s",
|
||||
Py_TYPE(item)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int Buffer_ass_subscript(Buffer *self, PyObject *item, PyObject *value)
|
||||
{
|
||||
if (PyIndex_Check(item)) {
|
||||
Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
|
||||
if (i == -1 && PyErr_Occurred())
|
||||
return -1;
|
||||
if (i < 0)
|
||||
i += self->dimensions[0];
|
||||
return Buffer_ass_item(self, i, value);
|
||||
}
|
||||
else if (PySlice_Check(item)) {
|
||||
Py_ssize_t start, stop, step, slicelength;
|
||||
|
||||
if (PySlice_GetIndicesEx((void *)item, self->dimensions[0], &start, &stop, &step, &slicelength) < 0)
|
||||
return -1;
|
||||
|
||||
if (step == 1)
|
||||
return Buffer_ass_slice(self, start, stop, value);
|
||||
else {
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"slice steps not supported with vectors");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"buffer indices must be integers, not %.200s",
|
||||
Py_TYPE(item)->tp_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Buffer_dealloc(Buffer *self)
|
||||
{
|
||||
if (self->parent) Py_DECREF(self->parent);
|
||||
else MEM_freeN (self->buf.asvoid);
|
||||
|
||||
MEM_freeN(self->dimensions);
|
||||
|
||||
MEM_freeN (buf->dimensions);
|
||||
|
||||
PyObject_DEL(self);
|
||||
}
|
||||
|
||||
static PyObject *Buffer_to_list(PyObject *self)
|
||||
|
||||
static PyObject *Buffer_repr(Buffer *self)
|
||||
{
|
||||
int i, len= ((Buffer *)self)->dimensions[0];
|
||||
PyObject *list= PyList_New(len);
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
PyList_SET_ITEM(list, i, Buffer_item(self, i));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static PyObject *Buffer_dimensions(PyObject *self, void *UNUSED(arg))
|
||||
{
|
||||
Buffer *buffer= (Buffer *) self;
|
||||
PyObject *list= PyList_New(buffer->ndimensions);
|
||||
int i;
|
||||
|
||||
for (i= 0; i<buffer->ndimensions; i++) {
|
||||
PyList_SET_ITEM(list, i, PyLong_FromLong(buffer->dimensions[i]));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static PyMethodDef Buffer_methods[] = {
|
||||
{"to_list", (PyCFunction)Buffer_to_list, METH_NOARGS,
|
||||
"return the buffer as a list"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static PyGetSetDef Buffer_getseters[] = {
|
||||
{(char *)"dimensions", (getter)Buffer_dimensions, NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static PyObject *Buffer_repr(PyObject *self)
|
||||
{
|
||||
PyObject *list= Buffer_to_list(self);
|
||||
PyObject *list= Buffer_to_list_recursive(self);
|
||||
PyObject *repr;
|
||||
const char *typestr= "UNKNOWN";
|
||||
Buffer *buffer= (Buffer *)self;
|
||||
|
||||
switch(buffer->type) {
|
||||
switch(self->type) {
|
||||
case GL_BYTE: typestr= "GL_BYTE"; break;
|
||||
case GL_SHORT: typestr= "GL_SHORT"; break;
|
||||
case GL_INT: typestr= "GL_BYTE"; break;
|
||||
|
||||
@@ -25,13 +25,13 @@
|
||||
|
||||
set(INC
|
||||
..
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../blenloader
|
||||
../../editors/include
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../blenkernel
|
||||
../../blenloader
|
||||
../../windowmanager
|
||||
../../editors/include
|
||||
../../../../intern/guardedalloc
|
||||
)
|
||||
|
||||
@@ -88,9 +88,6 @@ if(WITH_PYTHON_SAFETY)
|
||||
endif()
|
||||
|
||||
if(WITH_AUDASPACE)
|
||||
list(APPEND INC
|
||||
../../../intern/audaspace/intern
|
||||
)
|
||||
add_definitions(-DWITH_AUDASPACE)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -55,10 +55,10 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
/* external util modules */
|
||||
#include "../generic/mathutils.h"
|
||||
#include "../generic/IDProp.h"
|
||||
#include "../generic/bgl.h"
|
||||
#include "../generic/blf_py_api.h"
|
||||
#include "../generic/IDProp.h"
|
||||
#include "../mathutils/mathutils.h"
|
||||
|
||||
PyObject *bpy_package_py= NULL;
|
||||
|
||||
|
||||
@@ -66,10 +66,10 @@
|
||||
#include "../generic/py_capi_utils.h"
|
||||
|
||||
/* inittab initialization functions */
|
||||
#include "../generic/noise_py_api.h"
|
||||
#include "../generic/mathutils.h"
|
||||
#include "../generic/bgl.h"
|
||||
#include "../generic/blf_py_api.h"
|
||||
#include "../generic/noise_py_api.h"
|
||||
#include "../mathutils/mathutils.h"
|
||||
|
||||
/* for internal use, when starting and ending python scripts */
|
||||
|
||||
@@ -175,8 +175,8 @@ extern PyObject *AUD_initPython(void);
|
||||
|
||||
static struct _inittab bpy_internal_modules[]= {
|
||||
{(char *)"noise", BPyInit_noise},
|
||||
{(char *)"mathutils", BPyInit_mathutils},
|
||||
// {(char *)"mathutils.geometry", BPyInit_mathutils_geometry},
|
||||
{(char *)"mathutils", PyInit_mathutils},
|
||||
// {(char *)"mathutils.geometry", PyInit_mathutils_geometry},
|
||||
{(char *)"bgl", BPyInit_bgl},
|
||||
{(char *)"blf", BPyInit_blf},
|
||||
#ifdef WITH_AUDASPACE
|
||||
|
||||
@@ -346,7 +346,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
|
||||
static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item);
|
||||
|
||||
#ifdef USE_MATHUTILS
|
||||
#include "../generic/mathutils.h" /* so we can have mathutils callbacks */
|
||||
#include "../mathutils/mathutils.h" /* so we can have mathutils callbacks */
|
||||
|
||||
static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length);
|
||||
static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback);
|
||||
@@ -4548,7 +4548,7 @@ PyTypeObject pyrna_struct_meta_idprop_Type= {
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
|
||||
NULL, /* tp_compare */ /* deprecated in python 3.0! */
|
||||
NULL, /* tp_repr */
|
||||
|
||||
/* Method suites for standard classes */
|
||||
|
||||
52
source/blender/python/mathutils/CMakeLists.txt
Executable file
52
source/blender/python/mathutils/CMakeLists.txt
Executable file
@@ -0,0 +1,52 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# Contributor(s): Campbell Barton
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
.
|
||||
../../blenlib
|
||||
../../blenkernel
|
||||
../../makesdna
|
||||
../../../../intern/guardedalloc
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
mathutils.c
|
||||
mathutils_Color.c
|
||||
mathutils_Euler.c
|
||||
mathutils_Matrix.c
|
||||
mathutils_Quaternion.c
|
||||
mathutils_Vector.c
|
||||
mathutils_geometry.c
|
||||
|
||||
mathutils.h
|
||||
mathutils_Color.h
|
||||
mathutils_Euler.h
|
||||
mathutils_Matrix.h
|
||||
mathutils_Quaternion.h
|
||||
mathutils_Vector.h
|
||||
mathutils_geometry.h
|
||||
)
|
||||
|
||||
|
||||
blender_add_lib(bf_python_mathutils "${SRC}" "${INC}" "${INC_SYS}")
|
||||
8
source/blender/python/generic/mathutils.c → source/blender/python/mathutils/mathutils.c
Normal file → Executable file
8
source/blender/python/generic/mathutils.c → source/blender/python/mathutils/mathutils.c
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils.c 38409 2011-07-15 04:01:47Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -75,7 +75,7 @@ static int mathutils_array_parse_fast(float *array, int array_min, int array_max
|
||||
do {
|
||||
i--;
|
||||
if(((array[i]= PyFloat_AsDouble((item= PySequence_Fast_GET_ITEM(value_fast, i)))) == -1.0f) && PyErr_Occurred()) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%.200s: sequence index %d expected a number, "
|
||||
"found '%.200s' type, ",
|
||||
error_prefix, i, Py_TYPE(item)->tp_name);
|
||||
@@ -345,7 +345,7 @@ static struct PyModuleDef M_Mathutils_module_def = {
|
||||
NULL, /* m_free */
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC BPyInit_mathutils(void)
|
||||
PyMODINIT_FUNC PyInit_mathutils(void)
|
||||
{
|
||||
PyObject *submodule;
|
||||
PyObject *item;
|
||||
@@ -371,7 +371,7 @@ PyMODINIT_FUNC BPyInit_mathutils(void)
|
||||
PyModule_AddObject(submodule, "Color", (PyObject *)&color_Type);
|
||||
|
||||
/* submodule */
|
||||
PyModule_AddObject(submodule, "geometry", (item=BPyInit_mathutils_geometry()));
|
||||
PyModule_AddObject(submodule, "geometry", (item=PyInit_mathutils_geometry()));
|
||||
/* XXX, python doesnt do imports with this usefully yet
|
||||
* 'from mathutils.geometry import PolyFill'
|
||||
* ...fails without this. */
|
||||
6
source/blender/python/generic/mathutils.h → source/blender/python/mathutils/mathutils.h
Normal file → Executable file
6
source/blender/python/generic/mathutils.h → source/blender/python/mathutils/mathutils.h
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils.h 38674 2011-07-25 01:44:19Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -67,7 +67,7 @@ int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg);
|
||||
int BaseMathObject_clear(BaseMathObject *self);
|
||||
void BaseMathObject_dealloc(BaseMathObject * self);
|
||||
|
||||
PyMODINIT_FUNC BPyInit_mathutils(void);
|
||||
PyMODINIT_FUNC PyInit_mathutils(void);
|
||||
|
||||
int EXPP_FloatsAreEqual(float A, float B, int floatSteps);
|
||||
int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps);
|
||||
@@ -108,4 +108,6 @@ int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
|
||||
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
|
||||
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix);
|
||||
|
||||
int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject *mat);
|
||||
|
||||
#endif /* MATHUTILS_H */
|
||||
24
source/blender/python/generic/mathutils_Color.c → source/blender/python/mathutils/mathutils_Color.c
Normal file → Executable file
24
source/blender/python/generic/mathutils_Color.c → source/blender/python/mathutils/mathutils_Color.c
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils_Color.c 38409 2011-07-15 04:01:47Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -259,7 +259,7 @@ static int Color_ass_slice(ColorObject *self, int begin, int end, PyObject *seq)
|
||||
return -1;
|
||||
|
||||
if(size != (end - begin)){
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"color[begin:end] = []: "
|
||||
"size mismatch in slice assignment");
|
||||
return -1;
|
||||
@@ -296,7 +296,7 @@ static PyObject *Color_subscript(ColorObject *self, PyObject *item)
|
||||
return Color_slice(self, start, stop);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"slice steps not supported with color");
|
||||
return NULL;
|
||||
}
|
||||
@@ -328,7 +328,7 @@ static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *valu
|
||||
if (step == 1)
|
||||
return Color_ass_slice(self, start, stop, value);
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"slice steps not supported with color");
|
||||
return -1;
|
||||
}
|
||||
@@ -371,7 +371,7 @@ static PyObject *Color_add(PyObject *v1, PyObject *v2)
|
||||
float col[COLOR_SIZE];
|
||||
|
||||
if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Color addition: "
|
||||
"arguments not valid for this operation");
|
||||
return NULL;
|
||||
@@ -393,7 +393,7 @@ static PyObject *Color_iadd(PyObject *v1, PyObject *v2)
|
||||
ColorObject *color1 = NULL, *color2 = NULL;
|
||||
|
||||
if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Color addition: "
|
||||
"arguments not valid for this operation");
|
||||
return NULL;
|
||||
@@ -418,7 +418,7 @@ static PyObject *Color_sub(PyObject *v1, PyObject *v2)
|
||||
float col[COLOR_SIZE];
|
||||
|
||||
if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Color subtraction: "
|
||||
"arguments not valid for this operation");
|
||||
return NULL;
|
||||
@@ -440,7 +440,7 @@ static PyObject *Color_isub(PyObject *v1, PyObject *v2)
|
||||
ColorObject *color1= NULL, *color2= NULL;
|
||||
|
||||
if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Color subtraction: "
|
||||
"arguments not valid for this operation");
|
||||
return NULL;
|
||||
@@ -555,7 +555,9 @@ static PyObject *Color_imul(PyObject *v1, PyObject *v2)
|
||||
mul_vn_fl(color->col, COLOR_SIZE, scalar);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "Color multiplication: arguments not acceptable for this operation");
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Color multiplication: "
|
||||
"arguments not acceptable for this operation");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -846,9 +848,7 @@ PyObject *newColorObject(float *col, int type, PyTypeObject *base_type)
|
||||
self->wrapped = Py_NEW;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Color(): invalid type, internal error");
|
||||
return NULL;
|
||||
Py_FatalError("Color(): invalid type!");
|
||||
}
|
||||
}
|
||||
|
||||
2
source/blender/python/generic/mathutils_Color.h → source/blender/python/mathutils/mathutils_Color.h
Normal file → Executable file
2
source/blender/python/generic/mathutils_Color.h → source/blender/python/mathutils/mathutils_Color.h
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils_Color.h 38409 2011-07-15 04:01:47Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
22
source/blender/python/generic/mathutils_Euler.c → source/blender/python/mathutils/mathutils_Euler.c
Normal file → Executable file
22
source/blender/python/generic/mathutils_Euler.c → source/blender/python/mathutils/mathutils_Euler.c
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils_Euler.c 38409 2011-07-15 04:01:47Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -38,10 +38,6 @@
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#ifndef int32_t
|
||||
#include "BLO_sys_types.h"
|
||||
#endif
|
||||
|
||||
#define EULER_SIZE 3
|
||||
|
||||
//----------------------------------mathutils.Euler() -------------------
|
||||
@@ -89,7 +85,7 @@ static const char *euler_order_str(EulerObject *self)
|
||||
short euler_order_from_string(const char *str, const char *error_prefix)
|
||||
{
|
||||
if((str[0] && str[1] && str[2] && str[3]=='\0')) {
|
||||
switch(*((int32_t *)str)) {
|
||||
switch(*((PY_INT32_T *)str)) {
|
||||
case 'X'|'Y'<<8|'Z'<<16: return EULER_ORDER_XYZ;
|
||||
case 'X'|'Z'<<8|'Y'<<16: return EULER_ORDER_XZY;
|
||||
case 'Y'|'X'<<8|'Z'<<16: return EULER_ORDER_YXZ;
|
||||
@@ -99,7 +95,7 @@ short euler_order_from_string(const char *str, const char *error_prefix)
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"%s: invalid euler order '%s'",
|
||||
error_prefix, str);
|
||||
return -1;
|
||||
@@ -209,7 +205,7 @@ static PyObject *Euler_rotate_axis(EulerObject * self, PyObject *args)
|
||||
return NULL;
|
||||
}
|
||||
if(!(ELEM3(*axis, 'X', 'Y', 'Z') && axis[1]=='\0')){
|
||||
PyErr_SetString(PyExc_TypeError, "euler.rotate(): "
|
||||
PyErr_SetString(PyExc_ValueError, "euler.rotate(): "
|
||||
"expected axis to be 'X', 'Y' or 'Z'");
|
||||
return NULL;
|
||||
}
|
||||
@@ -449,7 +445,7 @@ static int Euler_ass_slice(EulerObject *self, int begin, int end, PyObject *seq)
|
||||
return -1;
|
||||
|
||||
if(size != (end - begin)){
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"euler[begin:end] = []: "
|
||||
"size mismatch in slice assignment");
|
||||
return -1;
|
||||
@@ -486,7 +482,7 @@ static PyObject *Euler_subscript(EulerObject *self, PyObject *item)
|
||||
return Euler_slice(self, start, stop);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"slice steps not supported with eulers");
|
||||
return NULL;
|
||||
}
|
||||
@@ -519,7 +515,7 @@ static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *valu
|
||||
if (step == 1)
|
||||
return Euler_ass_slice(self, start, stop, value);
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"slice steps not supported with euler");
|
||||
return -1;
|
||||
}
|
||||
@@ -701,9 +697,7 @@ PyObject *newEulerObject(float *eul, short order, int type, PyTypeObject *base_t
|
||||
self->wrapped = Py_NEW;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Euler(): invalid type, internal error");
|
||||
return NULL;
|
||||
Py_FatalError("Euler(): invalid type!");
|
||||
}
|
||||
|
||||
self->order= order;
|
||||
2
source/blender/python/generic/mathutils_Euler.h → source/blender/python/mathutils/mathutils_Euler.h
Normal file → Executable file
2
source/blender/python/generic/mathutils_Euler.h → source/blender/python/mathutils/mathutils_Euler.h
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils_Euler.h 38409 2011-07-15 04:01:47Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
143
source/blender/python/generic/mathutils_Matrix.c → source/blender/python/mathutils/mathutils_Matrix.c
Normal file → Executable file
143
source/blender/python/generic/mathutils_Matrix.c → source/blender/python/mathutils/mathutils_Matrix.c
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils_Matrix.c 38674 2011-07-25 01:44:19Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "mathutils.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
static PyObject *Matrix_copy(MatrixObject *self);
|
||||
@@ -225,7 +224,7 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args)
|
||||
if(vec && PyUnicode_Check(vec)) {
|
||||
axis= _PyUnicode_AsString((PyObject *)vec);
|
||||
if(axis==NULL || axis[0]=='\0' || axis[1]!='\0' || axis[0] < 'X' || axis[0] > 'Z') {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"mathutils.RotationMatrix(): "
|
||||
"3rd argument axis value must be a 3D vector "
|
||||
"or a string in 'X', 'Y', 'Z'");
|
||||
@@ -240,19 +239,19 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args)
|
||||
angle= angle_wrap_rad(angle);
|
||||
|
||||
if(matSize != 2 && matSize != 3 && matSize != 4) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"mathutils.RotationMatrix(): "
|
||||
"can only return a 2x2 3x3 or 4x4 matrix");
|
||||
return NULL;
|
||||
}
|
||||
if(matSize == 2 && (vec != NULL)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"mathutils.RotationMatrix(): "
|
||||
"cannot create a 2x2 rotation matrix around arbitrary axis");
|
||||
return NULL;
|
||||
}
|
||||
if((matSize == 3 || matSize == 4) && (axis == NULL) && (vec == NULL)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"mathutils.RotationMatrix(): "
|
||||
"axis of rotation for 3d and 4d matrices is required");
|
||||
return NULL;
|
||||
@@ -300,7 +299,7 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args)
|
||||
}
|
||||
else {
|
||||
/* should never get here */
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"mathutils.RotationMatrix(): unknown error");
|
||||
return NULL;
|
||||
}
|
||||
@@ -365,7 +364,7 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args)
|
||||
return NULL;
|
||||
}
|
||||
if(matSize != 2 && matSize != 3 && matSize != 4) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Matrix.Scale(): "
|
||||
"can only return a 2x2 3x3 or 4x4 matrix");
|
||||
return NULL;
|
||||
@@ -451,7 +450,7 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args)
|
||||
return NULL;
|
||||
}
|
||||
if(matSize != 2 && matSize != 3 && matSize != 4) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"mathutils.Matrix.OrthoProjection(): "
|
||||
"can only return a 2x2 3x3 or 4x4 matrix");
|
||||
return NULL;
|
||||
@@ -568,7 +567,7 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
|
||||
return NULL;
|
||||
}
|
||||
if(matSize != 2 && matSize != 3 && matSize != 4) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"mathutils.Matrix.Shear(): "
|
||||
"can only return a 2x2 3x3 or 4x4 matrix");
|
||||
return NULL;
|
||||
@@ -578,7 +577,7 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
|
||||
float const factor= PyFloat_AsDouble(fac);
|
||||
|
||||
if(factor==-1.0f && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"mathutils.Matrix.Shear(): "
|
||||
"the factor to be a float");
|
||||
return NULL;
|
||||
@@ -595,7 +594,7 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
|
||||
mat[1] = factor;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Matrix.Shear(): "
|
||||
"expected: X, Y or wrong matrix size for shearing plane");
|
||||
return NULL;
|
||||
@@ -627,7 +626,7 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
|
||||
mat[2] = factor[1];
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"mathutils.Matrix.Shear(): "
|
||||
"expected: X, Y, XY, XZ, YZ");
|
||||
return NULL;
|
||||
@@ -686,7 +685,7 @@ static PyObject *Matrix_to_quaternion(MatrixObject *self)
|
||||
|
||||
/*must be 3-4 cols, 3-4 rows, square matrix*/
|
||||
if((self->col_size < 3) || (self->row_size < 3) || (self->col_size != self->row_size)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"matrix.to_quat(): "
|
||||
"inappropriate matrix size - expects 3x3 or 4x4 matrix");
|
||||
return NULL;
|
||||
@@ -750,7 +749,7 @@ static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args)
|
||||
mat= tmat;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"matrix.to_euler(): "
|
||||
"inappropriate matrix size - expects 3x3 or 4x4 matrix");
|
||||
return NULL;
|
||||
@@ -879,7 +878,7 @@ static PyObject *Matrix_to_3x3(MatrixObject *self)
|
||||
return NULL;
|
||||
|
||||
if((self->col_size < 3) || (self->row_size < 3)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"matrix.to_3x3(): inappropriate matrix size");
|
||||
return NULL;
|
||||
}
|
||||
@@ -903,7 +902,7 @@ static PyObject *Matrix_to_translation(MatrixObject *self)
|
||||
return NULL;
|
||||
|
||||
if((self->col_size < 3) || self->row_size < 4){
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"matrix.to_translation(): "
|
||||
"inappropriate matrix size");
|
||||
return NULL;
|
||||
@@ -933,7 +932,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self)
|
||||
|
||||
/*must be 3-4 cols, 3-4 rows, square matrix*/
|
||||
if((self->col_size < 3) || (self->row_size < 3)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"matrix.to_scale(): "
|
||||
"inappropriate matrix size, 3x3 minimum size");
|
||||
return NULL;
|
||||
@@ -969,7 +968,7 @@ static PyObject *Matrix_invert(MatrixObject *self)
|
||||
return NULL;
|
||||
|
||||
if(self->row_size != self->col_size){
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"matrix.invert(ed): "
|
||||
"only square matrices are supported");
|
||||
return NULL;
|
||||
@@ -1050,7 +1049,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value)
|
||||
return NULL;
|
||||
|
||||
if(self->col_size != 3 || self->row_size != 3) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Matrix must have 3x3 dimensions");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1082,7 +1081,7 @@ static PyObject *Matrix_decompose(MatrixObject *self)
|
||||
float size[3];
|
||||
|
||||
if(self->col_size != 4 || self->row_size != 4) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"matrix.decompose(): "
|
||||
"inappropriate matrix size - expects 4x4 matrix");
|
||||
return NULL;
|
||||
@@ -1125,7 +1124,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
|
||||
return NULL;
|
||||
|
||||
if(self->row_size != mat2->row_size || self->col_size != mat2->col_size) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"matrix.lerp(): "
|
||||
"expects both matrix objects of the same dimensions");
|
||||
return NULL;
|
||||
@@ -1142,7 +1141,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
|
||||
blend_m3_m3m3((float (*)[3])mat, (float (*)[3])self->contigPtr, (float (*)[3])mat2->contigPtr, fac);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"matrix.lerp(): "
|
||||
"only 3x3 and 4x4 matrices supported");
|
||||
return NULL;
|
||||
@@ -1168,7 +1167,7 @@ static PyObject *Matrix_determinant(MatrixObject *self)
|
||||
return NULL;
|
||||
|
||||
if(self->row_size != self->col_size){
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"matrix.determinant: "
|
||||
"only square matrices are supported");
|
||||
return NULL;
|
||||
@@ -1192,7 +1191,7 @@ static PyObject *Matrix_transpose(MatrixObject *self)
|
||||
return NULL;
|
||||
|
||||
if(self->row_size != self->col_size){
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"matrix.transpose(d): "
|
||||
"only square matrices are supported");
|
||||
return NULL;
|
||||
@@ -1261,7 +1260,7 @@ static PyObject *Matrix_identity(MatrixObject *self)
|
||||
return NULL;
|
||||
|
||||
if(self->row_size != self->col_size){
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"matrix.identity: "
|
||||
"only square matrices are supported");
|
||||
return NULL;
|
||||
@@ -1319,21 +1318,20 @@ static PyObject *Matrix_repr(MatrixObject *self)
|
||||
}
|
||||
}
|
||||
switch(self->row_size) {
|
||||
case 2: return PyUnicode_FromFormat("Matrix(%R,\n"
|
||||
" %R)", rows[0], rows[1]);
|
||||
case 2: return PyUnicode_FromFormat("Matrix((%R,\n"
|
||||
" %R))", rows[0], rows[1]);
|
||||
|
||||
case 3: return PyUnicode_FromFormat("Matrix(%R,\n"
|
||||
" %R,\n"
|
||||
" %R)", rows[0], rows[1], rows[2]);
|
||||
case 3: return PyUnicode_FromFormat("Matrix((%R,\n"
|
||||
" %R,\n"
|
||||
" %R))", rows[0], rows[1], rows[2]);
|
||||
|
||||
case 4: return PyUnicode_FromFormat("Matrix(%R,\n"
|
||||
" %R,\n"
|
||||
" %R,\n"
|
||||
" %R)", rows[0], rows[1], rows[2], rows[3]);
|
||||
case 4: return PyUnicode_FromFormat("Matrix((%R,\n"
|
||||
" %R,\n"
|
||||
" %R,\n"
|
||||
" %R))", rows[0], rows[1], rows[2], rows[3]);
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"internal error!");
|
||||
Py_FatalError("Matrix(): invalid row size!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1409,7 +1407,7 @@ static int Matrix_ass_item(MatrixObject *self, int i, PyObject *value)
|
||||
return -1;
|
||||
|
||||
if(i >= self->row_size || i < 0){
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"matrix[attribute] = x: bad column");
|
||||
return -1;
|
||||
}
|
||||
@@ -1473,7 +1471,7 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
|
||||
|
||||
if(PySequence_Fast_GET_SIZE(value_fast) != size) {
|
||||
Py_DECREF(value_fast);
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"matrix[begin:end] = []: "
|
||||
"size mismatch in slice assignment");
|
||||
return -1;
|
||||
@@ -1509,7 +1507,7 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
|
||||
mat2 = (MatrixObject*)m2;
|
||||
|
||||
if(!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Matrix addition: "
|
||||
"arguments not valid for this operation");
|
||||
return NULL;
|
||||
@@ -1519,7 +1517,7 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
|
||||
return NULL;
|
||||
|
||||
if(mat1->row_size != mat2->row_size || mat1->col_size != mat2->col_size){
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Matrix addition: "
|
||||
"matrices must have the same dimensions for this operation");
|
||||
return NULL;
|
||||
@@ -1540,7 +1538,7 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
|
||||
mat2 = (MatrixObject*)m2;
|
||||
|
||||
if(!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Matrix addition: "
|
||||
"arguments not valid for this operation");
|
||||
return NULL;
|
||||
@@ -1550,7 +1548,7 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
|
||||
return NULL;
|
||||
|
||||
if(mat1->row_size != mat2->row_size || mat1->col_size != mat2->col_size){
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Matrix addition: "
|
||||
"matrices must have the same dimensions for this operation");
|
||||
return NULL;
|
||||
@@ -1588,32 +1586,24 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
|
||||
|
||||
if(mat1 && mat2) {
|
||||
/*MATRIX * MATRIX*/
|
||||
if(mat1->row_size != mat2->col_size){
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
"Matrix multiplication: "
|
||||
"matrix A rowsize must equal matrix B colsize");
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
float mat[16]= {0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f};
|
||||
double dot = 0.0f;
|
||||
int x, y, z;
|
||||
float mat[16]= {0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f};
|
||||
double dot = 0.0f;
|
||||
int x, y, z;
|
||||
|
||||
for(x = 0; x < mat2->row_size; x++) {
|
||||
for(y = 0; y < mat1->col_size; y++) {
|
||||
for(z = 0; z < mat1->row_size; z++) {
|
||||
dot += (mat1->matrix[z][y] * mat2->matrix[x][z]);
|
||||
}
|
||||
mat[((x * mat1->col_size) + y)] = (float)dot;
|
||||
dot = 0.0f;
|
||||
for(x = 0; x < mat2->row_size; x++) {
|
||||
for(y = 0; y < mat1->col_size; y++) {
|
||||
for(z = 0; z < mat1->row_size; z++) {
|
||||
dot += (mat1->matrix[z][y] * mat2->matrix[x][z]);
|
||||
}
|
||||
mat[((x * mat1->col_size) + y)] = (float)dot;
|
||||
dot = 0.0f;
|
||||
}
|
||||
|
||||
return newMatrixObject(mat, mat2->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1));
|
||||
}
|
||||
|
||||
return newMatrixObject(mat, mat2->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1));
|
||||
}
|
||||
else if(mat2) {
|
||||
/*FLOAT/INT * MATRIX */
|
||||
@@ -1622,8 +1612,20 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
|
||||
}
|
||||
}
|
||||
else if(mat1) {
|
||||
/*VEC * MATRIX */
|
||||
if(VectorObject_Check(m2)) {
|
||||
VectorObject *vec2= (VectorObject *)m2;
|
||||
float tvec[4];
|
||||
if(BaseMath_ReadCallback(vec2) == -1)
|
||||
return NULL;
|
||||
if(column_vector_multiplication(tvec, vec2, mat1) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return newVectorObject(tvec, vec2->size, Py_NEW, Py_TYPE(m2));
|
||||
}
|
||||
/*FLOAT/INT * MATRIX */
|
||||
if (((scalar= PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred())==0) {
|
||||
else if (((scalar= PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred())==0) {
|
||||
return matrix_mul_float(mat1, scalar);
|
||||
}
|
||||
}
|
||||
@@ -1683,14 +1685,14 @@ static PyObject *Matrix_subscript(MatrixObject* self, PyObject* item)
|
||||
return Matrix_slice(self, start, stop);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"slice steps not supported with matricies");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"vector indices must be integers, not %.200s",
|
||||
"matrix indices must be integers, not %.200s",
|
||||
Py_TYPE(item)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1715,7 +1717,7 @@ static int Matrix_ass_subscript(MatrixObject* self, PyObject* item, PyObject* va
|
||||
if (step == 1)
|
||||
return Matrix_ass_slice(self, start, stop, value);
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"slice steps not supported with matricies");
|
||||
return -1;
|
||||
}
|
||||
@@ -2021,8 +2023,7 @@ PyObject *newMatrixObject(float *mat, const unsigned short rowSize, const unsign
|
||||
self->wrapped = Py_NEW;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Matrix(): invalid type, internal error");
|
||||
Py_FatalError("Matrix(): invalid type!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
2
source/blender/python/generic/mathutils_Matrix.h → source/blender/python/mathutils/mathutils_Matrix.h
Normal file → Executable file
2
source/blender/python/generic/mathutils_Matrix.h → source/blender/python/mathutils/mathutils_Matrix.h
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils_Matrix.h 38409 2011-07-15 04:01:47Z campbellbarton $
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
44
source/blender/python/generic/mathutils_Quaternion.c → source/blender/python/mathutils/mathutils_Quaternion.c
Normal file → Executable file
44
source/blender/python/generic/mathutils_Quaternion.c → source/blender/python/mathutils/mathutils_Quaternion.c
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils_Quaternion.c 38674 2011-07-25 01:44:19Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -248,7 +248,7 @@ static PyObject *Quaternion_slerp(QuaternionObject *self, PyObject *args)
|
||||
return NULL;
|
||||
|
||||
if(fac > 1.0f || fac < 0.0f) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"quat.slerp(): "
|
||||
"interpolation factor must be between 0.0 and 1.0");
|
||||
return NULL;
|
||||
@@ -582,7 +582,7 @@ static int Quaternion_ass_slice(QuaternionObject *self, int begin, int end, PyOb
|
||||
return -1;
|
||||
|
||||
if(size != (end - begin)){
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"quaternion[begin:end] = []: "
|
||||
"size mismatch in slice assignment");
|
||||
return -1;
|
||||
@@ -620,7 +620,7 @@ static PyObject *Quaternion_subscript(QuaternionObject *self, PyObject *item)
|
||||
return Quaternion_slice(self, start, stop);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"slice steps not supported with quaternions");
|
||||
return NULL;
|
||||
}
|
||||
@@ -653,7 +653,7 @@ static int Quaternion_ass_subscript(QuaternionObject *self, PyObject *item, PyOb
|
||||
if (step == 1)
|
||||
return Quaternion_ass_slice(self, start, stop, value);
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"slice steps not supported with quaternion");
|
||||
return -1;
|
||||
}
|
||||
@@ -675,7 +675,7 @@ static PyObject *Quaternion_add(PyObject *q1, PyObject *q2)
|
||||
QuaternionObject *quat1 = NULL, *quat2 = NULL;
|
||||
|
||||
if(!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Quaternion addition: "
|
||||
"arguments not valid for this operation");
|
||||
return NULL;
|
||||
@@ -698,7 +698,7 @@ static PyObject *Quaternion_sub(PyObject *q1, PyObject *q2)
|
||||
QuaternionObject *quat1 = NULL, *quat2 = NULL;
|
||||
|
||||
if(!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Quaternion addition: "
|
||||
"arguments not valid for this operation");
|
||||
return NULL;
|
||||
@@ -753,8 +753,30 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
|
||||
return quat_mul_float(quat2, scalar);
|
||||
}
|
||||
}
|
||||
else if (quat1) { /* QUAT*FLOAT */
|
||||
if((((scalar= PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred())==0)) {
|
||||
else if (quat1) {
|
||||
/* QUAT * VEC */
|
||||
if (VectorObject_Check(q2)) {
|
||||
VectorObject *vec2 = (VectorObject *)q2;
|
||||
float tvec[3];
|
||||
|
||||
if(vec2->size != 3) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Vector multiplication: "
|
||||
"only 3D vector rotations (with quats) "
|
||||
"currently supported");
|
||||
return NULL;
|
||||
}
|
||||
if(BaseMath_ReadCallback(vec2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
copy_v3_v3(tvec, vec2->vec);
|
||||
mul_qt_v3(quat1->quat, tvec);
|
||||
|
||||
return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(vec2));
|
||||
}
|
||||
/* QUAT * FLOAT */
|
||||
else if((((scalar= PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred())==0)) {
|
||||
return quat_mul_float(quat1, scalar);
|
||||
}
|
||||
}
|
||||
@@ -1142,9 +1164,7 @@ PyObject *newQuaternionObject(float *quat, int type, PyTypeObject *base_type)
|
||||
self->wrapped = Py_NEW;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Quaternion(): invalid type, internal error");
|
||||
return NULL;
|
||||
Py_FatalError("Quaternion(): invalid type!");
|
||||
}
|
||||
}
|
||||
return (PyObject *) self;
|
||||
2
source/blender/python/generic/mathutils_Quaternion.h → source/blender/python/mathutils/mathutils_Quaternion.h
Normal file → Executable file
2
source/blender/python/generic/mathutils_Quaternion.h → source/blender/python/mathutils/mathutils_Quaternion.h
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils_Quaternion.h 38409 2011-07-15 04:01:47Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
108
source/blender/python/generic/mathutils_Vector.c → source/blender/python/mathutils/mathutils_Vector.c
Normal file → Executable file
108
source/blender/python/generic/mathutils_Vector.c → source/blender/python/mathutils/mathutils_Vector.c
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils_Vector.c 38674 2011-07-25 01:44:19Z campbellbarton $
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -34,10 +34,11 @@
|
||||
|
||||
#include "mathutils.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
extern void PyC_LineSpit(void);
|
||||
|
||||
#define MAX_DIMENSIONS 4
|
||||
|
||||
/* Swizzle axes get packed into a single value that is used as a closure. Each
|
||||
@@ -442,8 +443,7 @@ static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args)
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
axis_err_msg);
|
||||
PyErr_SetString(PyExc_ValueError, axis_err_msg);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -667,7 +667,7 @@ static PyObject *Vector_rotation_difference(VectorObject *self, PyObject *value)
|
||||
float quat[4], vec_a[3], vec_b[3];
|
||||
|
||||
if(self->size < 3) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"vec.difference(value): "
|
||||
"expects both vectors to be size 3 or 4");
|
||||
return NULL;
|
||||
@@ -1083,7 +1083,7 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2)
|
||||
* note: vector/matrix multiplication IS NOT COMMUTATIVE!!!!
|
||||
* note: assume read callbacks have been done first.
|
||||
*/
|
||||
static int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec, MatrixObject * mat)
|
||||
int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec, MatrixObject * mat)
|
||||
{
|
||||
float vec_cpy[MAX_DIMENSIONS];
|
||||
double dot = 0.0f;
|
||||
@@ -1094,7 +1094,7 @@ static int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject
|
||||
vec_cpy[3] = 1.0f;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"matrix * vector: "
|
||||
"matrix.row_size and len(vector) must be the same, "
|
||||
"except for 3D vector * 4x4 matrix.");
|
||||
@@ -1147,7 +1147,7 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
|
||||
double dot = 0.0f;
|
||||
|
||||
if(vec1->size != vec2->size) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Vector multiplication: "
|
||||
"vectors must have the same dimensions for this operation");
|
||||
return NULL;
|
||||
@@ -1161,8 +1161,29 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
|
||||
}
|
||||
else if (vec1) {
|
||||
if (MatrixObject_Check(v2)) {
|
||||
extern void PyC_LineSpit(void);
|
||||
|
||||
/* VEC * MATRIX */
|
||||
/* this is deprecated!, use the reverse instead */
|
||||
float tvec[MAX_DIMENSIONS];
|
||||
|
||||
|
||||
/* ------ to be removed ------*/
|
||||
#ifndef MATH_STANDALONE
|
||||
#ifdef WITH_ASSERT_ABORT
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"(Vector * Matrix) is now removed, reverse the "
|
||||
"order (promoted to an Error for Debug builds)");
|
||||
return NULL;
|
||||
#else
|
||||
printf("Warning: (Vector * Matrix) is now deprecated, "
|
||||
"reverse the multiplication order in the script.\n");
|
||||
PyC_LineSpit();
|
||||
#endif
|
||||
#endif /* ifndef MATH_STANDALONE */
|
||||
/* ------ to be removed ------*/
|
||||
|
||||
|
||||
if(BaseMath_ReadCallback((MatrixObject *)v2) == -1)
|
||||
return NULL;
|
||||
if(column_vector_multiplication(tvec, vec1, (MatrixObject*)v2) == -1) {
|
||||
@@ -1177,7 +1198,7 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
|
||||
float tvec[3];
|
||||
|
||||
if(vec1->size != 3) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Vector multiplication: "
|
||||
"only 3D vector rotations (with quats) currently supported");
|
||||
return NULL;
|
||||
@@ -1185,6 +1206,24 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
|
||||
if(BaseMath_ReadCallback(quat2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* ------ to be removed ------*/
|
||||
#ifndef MATH_STANDALONE
|
||||
#ifdef WITH_ASSERT_ABORT
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"(Vector * Quat) is now removed, reverse the "
|
||||
"order (promoted to an Error for Debug builds)");
|
||||
return NULL;
|
||||
#else
|
||||
printf("Warning: (Vector * Quat) is now deprecated, "
|
||||
"reverse the multiplication order in the script.\n");
|
||||
PyC_LineSpit();
|
||||
#endif
|
||||
#endif /* ifndef MATH_STANDALONE */
|
||||
/* ------ to be removed ------*/
|
||||
|
||||
|
||||
copy_v3_v3(tvec, vec1->vec);
|
||||
mul_qt_v3(quat2->quat, tvec);
|
||||
return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(vec1));
|
||||
@@ -1228,6 +1267,24 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
|
||||
if(column_vector_multiplication(rvec, vec, (MatrixObject*)v2) == -1)
|
||||
return NULL;
|
||||
|
||||
|
||||
/* ------ to be removed ------*/
|
||||
#ifndef MATH_STANDALONE
|
||||
#ifdef WITH_ASSERT_ABORT
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"(Vector *= Matrix) is now removed, reverse the "
|
||||
"order (promoted to an Error for Debug builds) "
|
||||
"and uses the non in-place multiplication.");
|
||||
return NULL;
|
||||
#else
|
||||
printf("Warning: (Vector *= Matrix) is now deprecated, "
|
||||
"reverse the (non in-place) multiplication order in the script.\n");
|
||||
PyC_LineSpit();
|
||||
#endif
|
||||
#endif /* ifndef MATH_STANDALONE */
|
||||
/* ------ to be removed ------*/
|
||||
|
||||
|
||||
memcpy(vec->vec, rvec, sizeof(float) * vec->size);
|
||||
}
|
||||
else if (QuaternionObject_Check(v2)) {
|
||||
@@ -1235,7 +1292,7 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
|
||||
QuaternionObject *quat2 = (QuaternionObject*)v2;
|
||||
|
||||
if(vec->size != 3) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Vector multiplication: "
|
||||
"only 3D vector rotations (with quats) currently supported");
|
||||
return NULL;
|
||||
@@ -1244,6 +1301,25 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
|
||||
if(BaseMath_ReadCallback(quat2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* ------ to be removed ------*/
|
||||
#ifndef MATH_STANDALONE
|
||||
#ifdef WITH_ASSERT_ABORT
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"(Vector *= Quat) is now removed, reverse the "
|
||||
"order (promoted to an Error for Debug builds) "
|
||||
"and uses the non in-place multiplication.");
|
||||
return NULL;
|
||||
#else
|
||||
printf("Warning: (Vector *= Quat) is now deprecated, "
|
||||
"reverse the (non in-place) multiplication order in the script.\n");
|
||||
PyC_LineSpit();
|
||||
#endif
|
||||
#endif /* ifndef MATH_STANDALONE */
|
||||
/* ------ to be removed ------*/
|
||||
|
||||
|
||||
mul_qt_v3(quat2->quat, vec->vec);
|
||||
}
|
||||
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* VEC *= FLOAT */
|
||||
@@ -1485,7 +1561,7 @@ static PyObject *Vector_subscript(VectorObject* self, PyObject* item)
|
||||
return Vector_slice(self, start, stop);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"slice steps not supported with vectors");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1517,7 +1593,7 @@ static int Vector_ass_subscript(VectorObject* self, PyObject* item, PyObject* va
|
||||
if (step == 1)
|
||||
return Vector_ass_slice(self, start, stop, value);
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"slice steps not supported with vectors");
|
||||
return -1;
|
||||
}
|
||||
@@ -1620,7 +1696,7 @@ static int Vector_setLength(VectorObject *self, PyObject *value)
|
||||
}
|
||||
|
||||
if (param < 0.0) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"cannot set a vectors length to a negative value");
|
||||
return -1;
|
||||
}
|
||||
@@ -2174,7 +2250,7 @@ static int row_vector_multiplication(float rvec[4], VectorObject* vec, MatrixObj
|
||||
|
||||
if(mat->colSize != vec_size){
|
||||
if(mat->colSize == 4 && vec_size != 3){
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"vector * matrix: matrix column size "
|
||||
"and the vector size must be the same");
|
||||
return -1;
|
||||
@@ -2390,9 +2466,7 @@ PyObject *newVectorObject(float *vec, const int size, const int type, PyTypeObje
|
||||
self->wrapped = Py_NEW;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Vector(): invalid type, internal error");
|
||||
return NULL;
|
||||
Py_FatalError("Vector(): invalid type!");
|
||||
}
|
||||
}
|
||||
return (PyObject *) self;
|
||||
2
source/blender/python/generic/mathutils_Vector.h → source/blender/python/mathutils/mathutils_Vector.h
Normal file → Executable file
2
source/blender/python/generic/mathutils_Vector.h → source/blender/python/mathutils/mathutils_Vector.h
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils_Vector.h 38409 2011-07-15 04:01:47Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
654
source/blender/python/generic/mathutils_geometry.c → source/blender/python/mathutils/mathutils_geometry.c
Normal file → Executable file
654
source/blender/python/generic/mathutils_geometry.c → source/blender/python/mathutils/mathutils_geometry.c
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
/*
|
||||
* $Id: mathutils_geometry.c 38409 2011-07-15 04:01:47Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -37,16 +37,16 @@
|
||||
#include "mathutils_geometry.h"
|
||||
|
||||
/* Used for PolyFill */
|
||||
#include "MEM_guardedalloc.h"
|
||||
#ifndef MATH_STANDALONE /* define when building outside blender */
|
||||
# include "MEM_guardedalloc.h"
|
||||
# include "BLI_blenlib.h"
|
||||
# include "BLI_boxpack2d.h"
|
||||
# include "BKE_displist.h"
|
||||
# include "BKE_curve.h"
|
||||
#endif
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_boxpack2d.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_displist.h"
|
||||
|
||||
#include "BKE_curve.h"
|
||||
|
||||
#define SWAP_FLOAT(a, b, tmp) tmp=a; a=b; b=tmp
|
||||
#define eps 0.000001
|
||||
@@ -346,132 +346,6 @@ static PyObject *M_Geometry_area_tri(PyObject *UNUSED(self), PyObject* args)
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------geometry.PolyFill() -------------------*/
|
||||
PyDoc_STRVAR(M_Geometry_tesselate_polygon_doc,
|
||||
".. function:: tesselate_polygon(veclist_list)\n"
|
||||
"\n"
|
||||
" Takes a list of polylines (each point a vector) and returns the point indices for a polyline filled with triangles.\n"
|
||||
"\n"
|
||||
" :arg veclist_list: list of polylines\n"
|
||||
" :rtype: list\n"
|
||||
);
|
||||
/* PolyFill function, uses Blenders scanfill to fill multiple poly lines */
|
||||
static PyObject *M_Geometry_tesselate_polygon(PyObject *UNUSED(self), PyObject *polyLineSeq)
|
||||
{
|
||||
PyObject *tri_list; /*return this list of tri's */
|
||||
PyObject *polyLine, *polyVec;
|
||||
int i, len_polylines, len_polypoints, ls_error= 0;
|
||||
|
||||
/* display listbase */
|
||||
ListBase dispbase={NULL, NULL};
|
||||
DispList *dl;
|
||||
float *fp; /*pointer to the array of malloced dl->verts to set the points from the vectors */
|
||||
int index, *dl_face, totpoints=0;
|
||||
|
||||
if(!PySequence_Check(polyLineSeq)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"expected a sequence of poly lines");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len_polylines= PySequence_Size(polyLineSeq);
|
||||
|
||||
for(i= 0; i < len_polylines; ++i) {
|
||||
polyLine= PySequence_GetItem(polyLineSeq, i);
|
||||
if (!PySequence_Check(polyLine)) {
|
||||
freedisplist(&dispbase);
|
||||
Py_XDECREF(polyLine); /* may be null so use Py_XDECREF*/
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"One or more of the polylines is not a sequence of mathutils.Vector's");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len_polypoints= PySequence_Size(polyLine);
|
||||
if (len_polypoints>0) { /* dont bother adding edges as polylines */
|
||||
#if 0
|
||||
if (EXPP_check_sequence_consistency(polyLine, &vector_Type) != 1) {
|
||||
freedisplist(&dispbase);
|
||||
Py_DECREF(polyLine);
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"A point in one of the polylines is not a mathutils.Vector type");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
dl= MEM_callocN(sizeof(DispList), "poly disp");
|
||||
BLI_addtail(&dispbase, dl);
|
||||
dl->type= DL_INDEX3;
|
||||
dl->nr= len_polypoints;
|
||||
dl->type= DL_POLY;
|
||||
dl->parts= 1; /* no faces, 1 edge loop */
|
||||
dl->col= 0; /* no material */
|
||||
dl->verts= fp= MEM_callocN(sizeof(float)*3*len_polypoints, "dl verts");
|
||||
dl->index= MEM_callocN(sizeof(int)*3*len_polypoints, "dl index");
|
||||
|
||||
for(index= 0; index<len_polypoints; ++index, fp+=3) {
|
||||
polyVec= PySequence_GetItem(polyLine, index);
|
||||
if(VectorObject_Check(polyVec)) {
|
||||
|
||||
if(BaseMath_ReadCallback((VectorObject *)polyVec) == -1)
|
||||
ls_error= 1;
|
||||
|
||||
fp[0]= ((VectorObject *)polyVec)->vec[0];
|
||||
fp[1]= ((VectorObject *)polyVec)->vec[1];
|
||||
if(((VectorObject *)polyVec)->size > 2)
|
||||
fp[2]= ((VectorObject *)polyVec)->vec[2];
|
||||
else
|
||||
fp[2]= 0.0f; /* if its a 2d vector then set the z to be zero */
|
||||
}
|
||||
else {
|
||||
ls_error= 1;
|
||||
}
|
||||
|
||||
totpoints++;
|
||||
Py_DECREF(polyVec);
|
||||
}
|
||||
}
|
||||
Py_DECREF(polyLine);
|
||||
}
|
||||
|
||||
if(ls_error) {
|
||||
freedisplist(&dispbase); /* possible some dl was allocated */
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"A point in one of the polylines "
|
||||
"is not a mathutils.Vector type");
|
||||
return NULL;
|
||||
}
|
||||
else if (totpoints) {
|
||||
/* now make the list to return */
|
||||
filldisplist(&dispbase, &dispbase, 0);
|
||||
|
||||
/* The faces are stored in a new DisplayList
|
||||
thats added to the head of the listbase */
|
||||
dl= dispbase.first;
|
||||
|
||||
tri_list= PyList_New(dl->parts);
|
||||
if(!tri_list) {
|
||||
freedisplist(&dispbase);
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"failed to make a new list");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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]));
|
||||
dl_face+= 3;
|
||||
index++;
|
||||
}
|
||||
freedisplist(&dispbase);
|
||||
}
|
||||
else {
|
||||
/* no points, do this so scripts dont barf */
|
||||
freedisplist(&dispbase); /* possible some dl was allocated */
|
||||
tri_list= PyList_New(0);
|
||||
}
|
||||
|
||||
return tri_list;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(M_Geometry_intersect_line_line_2d_doc,
|
||||
".. function:: intersect_line_line_2d(lineA_p1, lineA_p2, lineB_p1, lineB_p2)\n"
|
||||
@@ -556,7 +430,7 @@ static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObjec
|
||||
}
|
||||
|
||||
if(ELEM4(2, line_a->size, line_b->size, plane_co->size, plane_no->size)) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"geometry.intersect_line_plane(...): "
|
||||
" can't use 2D Vectors");
|
||||
return NULL;
|
||||
@@ -614,7 +488,7 @@ static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObje
|
||||
}
|
||||
|
||||
if(ELEM3(2, line_a->size, line_b->size, sphere_co->size)) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"geometry.intersect_line_sphere(...): "
|
||||
" can't use 2D Vectors");
|
||||
return NULL;
|
||||
@@ -844,187 +718,6 @@ static PyObject *M_Geometry_intersect_point_quad_2d(PyObject *UNUSED(self), PyOb
|
||||
return PyLong_FromLong(isect_point_quad_v2(pt_vec->vec, quad_p1->vec, quad_p2->vec, quad_p3->vec, quad_p4->vec));
|
||||
}
|
||||
|
||||
static int boxPack_FromPyObject(PyObject *value, boxPack **boxarray)
|
||||
{
|
||||
int len, i;
|
||||
PyObject *list_item, *item_1, *item_2;
|
||||
boxPack *box;
|
||||
|
||||
|
||||
/* Error checking must already be done */
|
||||
if(!PyList_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"can only back a list of [x, y, w, h]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
len= PyList_Size(value);
|
||||
|
||||
(*boxarray)= MEM_mallocN(len*sizeof(boxPack), "boxPack box");
|
||||
|
||||
|
||||
for(i= 0; i < len; i++) {
|
||||
list_item= PyList_GET_ITEM(value, i);
|
||||
if(!PyList_Check(list_item) || PyList_Size(list_item) < 4) {
|
||||
MEM_freeN(*boxarray);
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"can only pack a list of [x, y, w, h]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
box= (*boxarray)+i;
|
||||
|
||||
item_1= PyList_GET_ITEM(list_item, 2);
|
||||
item_2= PyList_GET_ITEM(list_item, 3);
|
||||
|
||||
box->w= (float)PyFloat_AsDouble(item_1);
|
||||
box->h= (float)PyFloat_AsDouble(item_2);
|
||||
box->index= i;
|
||||
|
||||
if (box->w < 0.0f || box->h < 0.0f) {
|
||||
MEM_freeN(*boxarray);
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"error parsing width and height values from list: "
|
||||
"[x, y, w, h], not numbers or below zero");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* verts will be added later */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void boxPack_ToPyObject(PyObject *value, boxPack **boxarray)
|
||||
{
|
||||
int len, i;
|
||||
PyObject *list_item;
|
||||
boxPack *box;
|
||||
|
||||
len= PyList_Size(value);
|
||||
|
||||
for(i= 0; i < len; i++) {
|
||||
box= (*boxarray)+i;
|
||||
list_item= PyList_GET_ITEM(value, box->index);
|
||||
PyList_SET_ITEM(list_item, 0, PyFloat_FromDouble(box->x));
|
||||
PyList_SET_ITEM(list_item, 1, PyFloat_FromDouble(box->y));
|
||||
}
|
||||
MEM_freeN(*boxarray);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(M_Geometry_box_pack_2d_doc,
|
||||
".. function:: box_pack_2d(boxes)\n"
|
||||
"\n"
|
||||
" Returns the normal of the 3D tri or quad.\n"
|
||||
"\n"
|
||||
" :arg boxes: list of boxes, each box is a list where the first 4 items are [x, y, width, height, ...] other items are ignored.\n"
|
||||
" :type boxes: list\n"
|
||||
" :return: the width and height of the packed bounding box\n"
|
||||
" :rtype: tuple, pair of floats\n"
|
||||
);
|
||||
static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlist)
|
||||
{
|
||||
float tot_width= 0.0f, tot_height= 0.0f;
|
||||
int len;
|
||||
|
||||
PyObject *ret;
|
||||
|
||||
if(!PyList_Check(boxlist)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"expected a list of boxes [[x, y, w, h], ... ]");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len= PyList_GET_SIZE(boxlist);
|
||||
if (len) {
|
||||
boxPack *boxarray= NULL;
|
||||
if(boxPack_FromPyObject(boxlist, &boxarray) == -1) {
|
||||
return NULL; /* exception set */
|
||||
}
|
||||
|
||||
/* Non Python function */
|
||||
boxPack2D(boxarray, len, &tot_width, &tot_height);
|
||||
|
||||
boxPack_ToPyObject(boxlist, &boxarray);
|
||||
}
|
||||
|
||||
ret= PyTuple_New(2);
|
||||
PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(tot_width));
|
||||
PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_width));
|
||||
return ret;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(M_Geometry_interpolate_bezier_doc,
|
||||
".. function:: interpolate_bezier(knot1, handle1, handle2, knot2, resolution)\n"
|
||||
"\n"
|
||||
" Interpolate a bezier spline segment.\n"
|
||||
"\n"
|
||||
" :arg knot1: First bezier spline point.\n"
|
||||
" :type knot1: :class:`mathutils.Vector`\n"
|
||||
" :arg handle1: First bezier spline handle.\n"
|
||||
" :type handle1: :class:`mathutils.Vector`\n"
|
||||
" :arg handle2: Second bezier spline handle.\n"
|
||||
" :type handle2: :class:`mathutils.Vector`\n"
|
||||
" :arg knot2: Second bezier spline point.\n"
|
||||
" :type knot2: :class:`mathutils.Vector`\n"
|
||||
" :arg resolution: Number of points to return.\n"
|
||||
" :type resolution: int\n"
|
||||
" :return: The interpolated points\n"
|
||||
" :rtype: list of :class:`mathutils.Vector`'s\n"
|
||||
);
|
||||
static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject* args)
|
||||
{
|
||||
VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2;
|
||||
int resolu;
|
||||
int dims;
|
||||
int i;
|
||||
float *coord_array, *fp;
|
||||
PyObject *list;
|
||||
|
||||
float k1[4]= {0.0, 0.0, 0.0, 0.0};
|
||||
float h1[4]= {0.0, 0.0, 0.0, 0.0};
|
||||
float k2[4]= {0.0, 0.0, 0.0, 0.0};
|
||||
float h2[4]= {0.0, 0.0, 0.0, 0.0};
|
||||
|
||||
|
||||
if(!PyArg_ParseTuple(args, "O!O!O!O!i:interpolate_bezier",
|
||||
&vector_Type, &vec_k1,
|
||||
&vector_Type, &vec_h1,
|
||||
&vector_Type, &vec_h2,
|
||||
&vector_Type, &vec_k2, &resolu)
|
||||
) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(resolu <= 1) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"resolution must be 2 or over");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(BaseMath_ReadCallback(vec_k1) == -1 || BaseMath_ReadCallback(vec_h1) == -1 || BaseMath_ReadCallback(vec_k2) == -1 || BaseMath_ReadCallback(vec_h2) == -1)
|
||||
return NULL;
|
||||
|
||||
dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);
|
||||
|
||||
for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i];
|
||||
for(i=0; i < vec_h1->size; i++) h1[i]= vec_h1->vec[i];
|
||||
for(i=0; i < vec_k2->size; i++) k2[i]= vec_k2->vec[i];
|
||||
for(i=0; i < vec_h2->size; i++) h2[i]= vec_h2->vec[i];
|
||||
|
||||
coord_array= MEM_callocN(dims * (resolu) * sizeof(float), "interpolate_bezier");
|
||||
for(i=0; i<dims; i++) {
|
||||
forward_diff_bezier(k1[i], h1[i], h2[i], k2[i], coord_array+i, resolu-1, sizeof(float)*dims);
|
||||
}
|
||||
|
||||
list= PyList_New(resolu);
|
||||
fp= coord_array;
|
||||
for(i=0; i<resolu; i++, fp= fp+dims) {
|
||||
PyList_SET_ITEM(list, i, newVectorObject(fp, dims, Py_NEW, NULL));
|
||||
}
|
||||
MEM_freeN(coord_array);
|
||||
return list;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(M_Geometry_barycentric_transform_doc,
|
||||
".. function:: barycentric_transform(point, tri_a1, tri_a2, tri_a3, tri_b1, tri_b2, tri_b3)\n"
|
||||
"\n"
|
||||
@@ -1075,7 +768,7 @@ static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObje
|
||||
vec_t3_tar->size != 3)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"One of more of the vector arguments wasnt a 3D vector");
|
||||
"One of more of the vector arguments wasn't a 3D vector");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1086,6 +779,321 @@ static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObje
|
||||
return newVectorObject(vec, 3, Py_NEW, NULL);
|
||||
}
|
||||
|
||||
#ifndef MATH_STANDALONE
|
||||
|
||||
PyDoc_STRVAR(M_Geometry_interpolate_bezier_doc,
|
||||
".. function:: interpolate_bezier(knot1, handle1, handle2, knot2, resolution)\n"
|
||||
"\n"
|
||||
" Interpolate a bezier spline segment.\n"
|
||||
"\n"
|
||||
" :arg knot1: First bezier spline point.\n"
|
||||
" :type knot1: :class:`mathutils.Vector`\n"
|
||||
" :arg handle1: First bezier spline handle.\n"
|
||||
" :type handle1: :class:`mathutils.Vector`\n"
|
||||
" :arg handle2: Second bezier spline handle.\n"
|
||||
" :type handle2: :class:`mathutils.Vector`\n"
|
||||
" :arg knot2: Second bezier spline point.\n"
|
||||
" :type knot2: :class:`mathutils.Vector`\n"
|
||||
" :arg resolution: Number of points to return.\n"
|
||||
" :type resolution: int\n"
|
||||
" :return: The interpolated points\n"
|
||||
" :rtype: list of :class:`mathutils.Vector`'s\n"
|
||||
);
|
||||
static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject* args)
|
||||
{
|
||||
VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2;
|
||||
int resolu;
|
||||
int dims;
|
||||
int i;
|
||||
float *coord_array, *fp;
|
||||
PyObject *list;
|
||||
|
||||
float k1[4]= {0.0, 0.0, 0.0, 0.0};
|
||||
float h1[4]= {0.0, 0.0, 0.0, 0.0};
|
||||
float k2[4]= {0.0, 0.0, 0.0, 0.0};
|
||||
float h2[4]= {0.0, 0.0, 0.0, 0.0};
|
||||
|
||||
|
||||
if(!PyArg_ParseTuple(args, "O!O!O!O!i:interpolate_bezier",
|
||||
&vector_Type, &vec_k1,
|
||||
&vector_Type, &vec_h1,
|
||||
&vector_Type, &vec_h2,
|
||||
&vector_Type, &vec_k2, &resolu)
|
||||
) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(resolu <= 1) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"resolution must be 2 or over");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(BaseMath_ReadCallback(vec_k1) == -1 || BaseMath_ReadCallback(vec_h1) == -1 || BaseMath_ReadCallback(vec_k2) == -1 || BaseMath_ReadCallback(vec_h2) == -1)
|
||||
return NULL;
|
||||
|
||||
dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);
|
||||
|
||||
for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i];
|
||||
for(i=0; i < vec_h1->size; i++) h1[i]= vec_h1->vec[i];
|
||||
for(i=0; i < vec_k2->size; i++) k2[i]= vec_k2->vec[i];
|
||||
for(i=0; i < vec_h2->size; i++) h2[i]= vec_h2->vec[i];
|
||||
|
||||
coord_array= MEM_callocN(dims * (resolu) * sizeof(float), "interpolate_bezier");
|
||||
for(i=0; i<dims; i++) {
|
||||
forward_diff_bezier(k1[i], h1[i], h2[i], k2[i], coord_array+i, resolu-1, sizeof(float)*dims);
|
||||
}
|
||||
|
||||
list= PyList_New(resolu);
|
||||
fp= coord_array;
|
||||
for(i=0; i<resolu; i++, fp= fp+dims) {
|
||||
PyList_SET_ITEM(list, i, newVectorObject(fp, dims, Py_NEW, NULL));
|
||||
}
|
||||
MEM_freeN(coord_array);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(M_Geometry_tesselate_polygon_doc,
|
||||
".. function:: tesselate_polygon(veclist_list)\n"
|
||||
"\n"
|
||||
" Takes a list of polylines (each point a vector) and returns the point indices for a polyline filled with triangles.\n"
|
||||
"\n"
|
||||
" :arg veclist_list: list of polylines\n"
|
||||
" :rtype: list\n"
|
||||
);
|
||||
/* PolyFill function, uses Blenders scanfill to fill multiple poly lines */
|
||||
static PyObject *M_Geometry_tesselate_polygon(PyObject *UNUSED(self), PyObject *polyLineSeq)
|
||||
{
|
||||
PyObject *tri_list; /*return this list of tri's */
|
||||
PyObject *polyLine, *polyVec;
|
||||
int i, len_polylines, len_polypoints, ls_error= 0;
|
||||
|
||||
/* display listbase */
|
||||
ListBase dispbase={NULL, NULL};
|
||||
DispList *dl;
|
||||
float *fp; /*pointer to the array of malloced dl->verts to set the points from the vectors */
|
||||
int index, *dl_face, totpoints=0;
|
||||
|
||||
if(!PySequence_Check(polyLineSeq)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"expected a sequence of poly lines");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len_polylines= PySequence_Size(polyLineSeq);
|
||||
|
||||
for(i= 0; i < len_polylines; ++i) {
|
||||
polyLine= PySequence_GetItem(polyLineSeq, i);
|
||||
if (!PySequence_Check(polyLine)) {
|
||||
freedisplist(&dispbase);
|
||||
Py_XDECREF(polyLine); /* may be null so use Py_XDECREF*/
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"One or more of the polylines is not a sequence of mathutils.Vector's");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len_polypoints= PySequence_Size(polyLine);
|
||||
if (len_polypoints>0) { /* dont bother adding edges as polylines */
|
||||
#if 0
|
||||
if (EXPP_check_sequence_consistency(polyLine, &vector_Type) != 1) {
|
||||
freedisplist(&dispbase);
|
||||
Py_DECREF(polyLine);
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"A point in one of the polylines is not a mathutils.Vector type");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
dl= MEM_callocN(sizeof(DispList), "poly disp");
|
||||
BLI_addtail(&dispbase, dl);
|
||||
dl->type= DL_INDEX3;
|
||||
dl->nr= len_polypoints;
|
||||
dl->type= DL_POLY;
|
||||
dl->parts= 1; /* no faces, 1 edge loop */
|
||||
dl->col= 0; /* no material */
|
||||
dl->verts= fp= MEM_callocN(sizeof(float)*3*len_polypoints, "dl verts");
|
||||
dl->index= MEM_callocN(sizeof(int)*3*len_polypoints, "dl index");
|
||||
|
||||
for(index= 0; index<len_polypoints; ++index, fp+=3) {
|
||||
polyVec= PySequence_GetItem(polyLine, index);
|
||||
if(VectorObject_Check(polyVec)) {
|
||||
|
||||
if(BaseMath_ReadCallback((VectorObject *)polyVec) == -1)
|
||||
ls_error= 1;
|
||||
|
||||
fp[0]= ((VectorObject *)polyVec)->vec[0];
|
||||
fp[1]= ((VectorObject *)polyVec)->vec[1];
|
||||
if(((VectorObject *)polyVec)->size > 2)
|
||||
fp[2]= ((VectorObject *)polyVec)->vec[2];
|
||||
else
|
||||
fp[2]= 0.0f; /* if its a 2d vector then set the z to be zero */
|
||||
}
|
||||
else {
|
||||
ls_error= 1;
|
||||
}
|
||||
|
||||
totpoints++;
|
||||
Py_DECREF(polyVec);
|
||||
}
|
||||
}
|
||||
Py_DECREF(polyLine);
|
||||
}
|
||||
|
||||
if(ls_error) {
|
||||
freedisplist(&dispbase); /* possible some dl was allocated */
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"A point in one of the polylines "
|
||||
"is not a mathutils.Vector type");
|
||||
return NULL;
|
||||
}
|
||||
else if (totpoints) {
|
||||
/* now make the list to return */
|
||||
filldisplist(&dispbase, &dispbase, 0);
|
||||
|
||||
/* The faces are stored in a new DisplayList
|
||||
thats added to the head of the listbase */
|
||||
dl= dispbase.first;
|
||||
|
||||
tri_list= PyList_New(dl->parts);
|
||||
if(!tri_list) {
|
||||
freedisplist(&dispbase);
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"failed to make a new list");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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]));
|
||||
dl_face+= 3;
|
||||
index++;
|
||||
}
|
||||
freedisplist(&dispbase);
|
||||
}
|
||||
else {
|
||||
/* no points, do this so scripts dont barf */
|
||||
freedisplist(&dispbase); /* possible some dl was allocated */
|
||||
tri_list= PyList_New(0);
|
||||
}
|
||||
|
||||
return tri_list;
|
||||
}
|
||||
|
||||
|
||||
static int boxPack_FromPyObject(PyObject *value, boxPack **boxarray)
|
||||
{
|
||||
int len, i;
|
||||
PyObject *list_item, *item_1, *item_2;
|
||||
boxPack *box;
|
||||
|
||||
|
||||
/* Error checking must already be done */
|
||||
if(!PyList_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"can only back a list of [x, y, w, h]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
len= PyList_Size(value);
|
||||
|
||||
(*boxarray)= MEM_mallocN(len*sizeof(boxPack), "boxPack box");
|
||||
|
||||
|
||||
for(i= 0; i < len; i++) {
|
||||
list_item= PyList_GET_ITEM(value, i);
|
||||
if(!PyList_Check(list_item) || PyList_Size(list_item) < 4) {
|
||||
MEM_freeN(*boxarray);
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"can only pack a list of [x, y, w, h]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
box= (*boxarray)+i;
|
||||
|
||||
item_1= PyList_GET_ITEM(list_item, 2);
|
||||
item_2= PyList_GET_ITEM(list_item, 3);
|
||||
|
||||
box->w= (float)PyFloat_AsDouble(item_1);
|
||||
box->h= (float)PyFloat_AsDouble(item_2);
|
||||
box->index= i;
|
||||
|
||||
/* accounts for error case too and overwrites with own error */
|
||||
if (box->w < 0.0f || box->h < 0.0f) {
|
||||
MEM_freeN(*boxarray);
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"error parsing width and height values from list: "
|
||||
"[x, y, w, h], not numbers or below zero");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* verts will be added later */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void boxPack_ToPyObject(PyObject *value, boxPack **boxarray)
|
||||
{
|
||||
int len, i;
|
||||
PyObject *list_item;
|
||||
boxPack *box;
|
||||
|
||||
len= PyList_Size(value);
|
||||
|
||||
for(i= 0; i < len; i++) {
|
||||
box= (*boxarray)+i;
|
||||
list_item= PyList_GET_ITEM(value, box->index);
|
||||
PyList_SET_ITEM(list_item, 0, PyFloat_FromDouble(box->x));
|
||||
PyList_SET_ITEM(list_item, 1, PyFloat_FromDouble(box->y));
|
||||
}
|
||||
MEM_freeN(*boxarray);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(M_Geometry_box_pack_2d_doc,
|
||||
".. function:: box_pack_2d(boxes)\n"
|
||||
"\n"
|
||||
" Returns the normal of the 3D tri or quad.\n"
|
||||
"\n"
|
||||
" :arg boxes: list of boxes, each box is a list where the first 4 items are [x, y, width, height, ...] other items are ignored.\n"
|
||||
" :type boxes: list\n"
|
||||
" :return: the width and height of the packed bounding box\n"
|
||||
" :rtype: tuple, pair of floats\n"
|
||||
);
|
||||
static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlist)
|
||||
{
|
||||
float tot_width= 0.0f, tot_height= 0.0f;
|
||||
int len;
|
||||
|
||||
PyObject *ret;
|
||||
|
||||
if(!PyList_Check(boxlist)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"expected a list of boxes [[x, y, w, h], ... ]");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len= PyList_GET_SIZE(boxlist);
|
||||
if (len) {
|
||||
boxPack *boxarray= NULL;
|
||||
if(boxPack_FromPyObject(boxlist, &boxarray) == -1) {
|
||||
return NULL; /* exception set */
|
||||
}
|
||||
|
||||
/* Non Python function */
|
||||
boxPack2D(boxarray, len, &tot_width, &tot_height);
|
||||
|
||||
boxPack_ToPyObject(boxlist, &boxarray);
|
||||
}
|
||||
|
||||
ret= PyTuple_New(2);
|
||||
PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(tot_width));
|
||||
PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_width));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* MATH_STANDALONE */
|
||||
|
||||
|
||||
static PyMethodDef M_Geometry_methods[]= {
|
||||
{"intersect_ray_tri", (PyCFunction) M_Geometry_intersect_ray_tri, METH_VARARGS, M_Geometry_intersect_ray_tri_doc},
|
||||
{"intersect_point_line", (PyCFunction) M_Geometry_intersect_point_line, METH_VARARGS, M_Geometry_intersect_point_line_doc},
|
||||
@@ -1096,12 +1104,14 @@ static PyMethodDef M_Geometry_methods[]= {
|
||||
{"intersect_line_plane", (PyCFunction) M_Geometry_intersect_line_plane, METH_VARARGS, M_Geometry_intersect_line_plane_doc},
|
||||
{"intersect_line_sphere", (PyCFunction) M_Geometry_intersect_line_sphere, METH_VARARGS, M_Geometry_intersect_line_sphere_doc},
|
||||
{"intersect_line_sphere_2d", (PyCFunction) M_Geometry_intersect_line_sphere_2d, METH_VARARGS, M_Geometry_intersect_line_sphere_2d_doc},
|
||||
{"interpolate_bezier", (PyCFunction) M_Geometry_interpolate_bezier, METH_VARARGS, M_Geometry_interpolate_bezier_doc},
|
||||
{"area_tri", (PyCFunction) M_Geometry_area_tri, METH_VARARGS, M_Geometry_area_tri_doc},
|
||||
{"normal", (PyCFunction) M_Geometry_normal, METH_VARARGS, M_Geometry_normal_doc},
|
||||
{"barycentric_transform", (PyCFunction) M_Geometry_barycentric_transform, METH_VARARGS, M_Geometry_barycentric_transform_doc},
|
||||
#ifndef MATH_STANDALONE
|
||||
{"interpolate_bezier", (PyCFunction) M_Geometry_interpolate_bezier, METH_VARARGS, M_Geometry_interpolate_bezier_doc},
|
||||
{"tesselate_polygon", (PyCFunction) M_Geometry_tesselate_polygon, METH_O, M_Geometry_tesselate_polygon_doc},
|
||||
{"box_pack_2d", (PyCFunction) M_Geometry_box_pack_2d, METH_O, M_Geometry_box_pack_2d_doc},
|
||||
{"barycentric_transform", (PyCFunction) M_Geometry_barycentric_transform, METH_VARARGS, M_Geometry_barycentric_transform_doc},
|
||||
#endif
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
@@ -1118,7 +1128,7 @@ static struct PyModuleDef M_Geometry_module_def= {
|
||||
};
|
||||
|
||||
/*----------------------------MODULE INIT-------------------------*/
|
||||
PyMODINIT_FUNC BPyInit_mathutils_geometry(void)
|
||||
PyMODINIT_FUNC PyInit_mathutils_geometry(void)
|
||||
{
|
||||
PyObject *submodule= PyModule_Create(&M_Geometry_module_def);
|
||||
return submodule;
|
||||
4
source/blender/python/generic/mathutils_geometry.h → source/blender/python/mathutils/mathutils_geometry.h
Normal file → Executable file
4
source/blender/python/generic/mathutils_geometry.h → source/blender/python/mathutils/mathutils_geometry.h
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Id: mathutils_geometry.h 38409 2011-07-15 04:01:47Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -38,6 +38,6 @@
|
||||
|
||||
#include "mathutils.h"
|
||||
|
||||
PyMODINIT_FUNC BPyInit_mathutils_geometry(void);
|
||||
PyMODINIT_FUNC PyInit_mathutils_geometry(void);
|
||||
|
||||
#endif /* MATHUTILS_GEOMETRY_H */
|
||||
Reference in New Issue
Block a user