Merging r39652 through r39842 from trunk into vgroup_modifiers.
[blender.git] / source / gameengine / VideoTexture / ImageMix.cpp
1 /** \file gameengine/VideoTexture/ImageMix.cpp
2  *  \ingroup bgevideotex
3  */
4 /* $Id$
5 -----------------------------------------------------------------------------
6 This source file is part of VideoTexture library
7
8 Copyright (c) 2007 The Zdeno Ash Miklas
9
10 This program is free software; you can redistribute it and/or modify it under
11 the terms of the GNU Lesser General Public License as published by the Free Software
12 Foundation; either version 2 of the License, or (at your option) any later
13 version.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22 http://www.gnu.org/copyleft/lesser.txt.
23 -----------------------------------------------------------------------------
24 */
25
26 // implementation
27
28 #include <PyObjectPlus.h>
29 #include <structmember.h>
30
31 #include "ImageMix.h"
32
33 #include "ImageBase.h"
34
35 #include "Exception.h"
36
37
38 // cast ImageSource pointer to ImageSourceMix
39 inline ImageSourceMix * getImageSourceMix (ImageSource * src)
40 { return static_cast<ImageSourceMix*>(src); }
41
42
43 // get weight
44 short ImageMix::getWeight (const char * id)
45 {
46         // find source
47         ImageSourceList::iterator src = findSource(id);
48         // if found, return its weight
49         return src != m_sources.end() ? getImageSourceMix(*src)->getWeight() : 0;
50 }
51
52 // set weight
53 bool ImageMix::setWeight (const char * id, short weight)
54 {
55         // find source
56         ImageSourceList::iterator src = findSource(id);
57         // if source isn't found, report it
58         if (src == m_sources.end()) return false;
59         // set its weight
60         getImageSourceMix(*src)->setWeight(weight);
61         return true;
62 }
63
64 ExceptionID ImageSizesNotMatch;
65
66 ExpDesc ImageSizesNotMatchDesc (ImageSizesNotMatch, "Image sizes of sources are different");
67
68 // calculate image from sources and set its availability
69 void ImageMix::calcImage (unsigned int texId, double ts)
70 {
71         // check source sizes
72         if (!checkSourceSizes()) THRWEXCP(ImageSizesNotMatch, S_OK);
73         // set offsets to image buffers
74         for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
75                 // if image buffer is available
76                 if ((*it)->getImageBuf() != NULL)
77                         // set its offset
78                         getImageSourceMix(*it)->setOffset(m_sources[0]->getImageBuf());
79                 // otherwise don't calculate image
80                 else 
81                         return;
82         // if there is only single source
83         if (m_sources.size() == 1)
84         {
85                 // use single filter
86                 FilterBase mixFilt;
87                 // fiter and convert image
88                 filterImage(mixFilt, m_sources[0]->getImageBuf(), m_sources[0]->getSize());
89         }
90         // otherwise use mix filter to merge source images
91         else
92         {
93                 FilterImageMix mixFilt (m_sources);
94                 // fiter and convert image
95                 filterImage(mixFilt, m_sources[0]->getImageBuf(), m_sources[0]->getSize());
96         }
97 }
98
99
100
101 // cast Image pointer to ImageMix
102 inline ImageMix * getImageMix (PyImage * self)
103 { return static_cast<ImageMix*>(self->m_image); }
104
105
106 // python methods
107
108 // get source weight
109 PyObject * getWeight (PyImage * self, PyObject * args)
110 {
111         // weight
112         short weight = 0;
113         // get arguments
114         char * id;
115         if (!PyArg_ParseTuple(args, "s:getWeight", &id))
116                 return NULL;
117         if (self->m_image != NULL)
118                 // get weight
119                 weight = getImageMix(self)->getWeight(id);
120         // return weight
121         return Py_BuildValue("h", weight);
122 }
123
124
125 // set source weight
126 PyObject * setWeight (PyImage * self, PyObject * args)
127 {
128         // get arguments
129         char * id;
130         short weight = 0;
131         if (!PyArg_ParseTuple(args, "sh:setWeight", &id, &weight))
132                 return NULL;
133         if (self->m_image != NULL)
134                 // set weight
135                 if (!getImageMix(self)->setWeight(id, weight))
136                 {
137                         // if not set, report error
138                         PyErr_SetString(PyExc_RuntimeError, "Invalid id of source");
139                         return NULL;
140                 }
141         // return none
142         Py_RETURN_NONE;
143 }
144
145
146 // methods structure
147 static PyMethodDef imageMixMethods[] =
148
149         {"getSource", (PyCFunction)Image_getSource, METH_VARARGS, "get image source"},
150         {"setSource", (PyCFunction)Image_setSource, METH_VARARGS, "set image source"},
151         {"getWeight", (PyCFunction)getWeight, METH_VARARGS, "get image source weight"},
152         {"setWeight", (PyCFunction)setWeight, METH_VARARGS, "set image source weight"},
153         // methods from ImageBase class
154         {"refresh", (PyCFunction)Image_refresh, METH_NOARGS, "Refresh image - invalidate its current content"},
155         {NULL}
156 };
157 // attributes structure
158 static PyGetSetDef imageMixGetSets[] =
159 { // attributes from ImageBase class
160         {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
161         {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
162         {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
163         {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
164         {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL},
165         {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL},
166         {NULL}
167 };
168
169
170 // define python type
171 PyTypeObject ImageMixType =
172
173         PyVarObject_HEAD_INIT(NULL, 0)
174         "VideoTexture.ImageMix",   /*tp_name*/
175         sizeof(PyImage),          /*tp_basicsize*/
176         0,                         /*tp_itemsize*/
177         (destructor)Image_dealloc, /*tp_dealloc*/
178         0,                         /*tp_print*/
179         0,                         /*tp_getattr*/
180         0,                         /*tp_setattr*/
181         0,                         /*tp_compare*/
182         0,                         /*tp_repr*/
183         0,                         /*tp_as_number*/
184         0,                         /*tp_as_sequence*/
185         0,                         /*tp_as_mapping*/
186         0,                         /*tp_hash */
187         0,                         /*tp_call*/
188         0,                         /*tp_str*/
189         0,                         /*tp_getattro*/
190         0,                         /*tp_setattro*/
191         &imageBufferProcs,         /*tp_as_buffer*/
192         Py_TPFLAGS_DEFAULT,        /*tp_flags*/
193         "Image mixer",       /* tp_doc */
194         0,                             /* tp_traverse */
195         0,                             /* tp_clear */
196         0,                             /* tp_richcompare */
197         0,                             /* tp_weaklistoffset */
198         0,                             /* tp_iter */
199         0,                             /* tp_iternext */
200         imageMixMethods,    /* tp_methods */
201         0,                   /* tp_members */
202         imageMixGetSets,          /* tp_getset */
203         0,                         /* tp_base */
204         0,                         /* tp_dict */
205         0,                         /* tp_descr_get */
206         0,                         /* tp_descr_set */
207         0,                         /* tp_dictoffset */
208         (initproc)Image_init<ImageMix>,     /* tp_init */
209         0,                         /* tp_alloc */
210         Image_allocNew,           /* tp_new */
211 };
212