remove python2.x support
[blender.git] / source / gameengine / Ketsji / KX_VertexProxy.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33 #include "KX_VertexProxy.h"
34 #include "KX_MeshProxy.h"
35 #include "RAS_TexVert.h"
36
37 #include "KX_PyMath.h"
38
39 PyTypeObject KX_VertexProxy::Type = {
40         PyVarObject_HEAD_INIT(NULL, 0)
41         "KX_VertexProxy",
42         sizeof(PyObjectPlus_Proxy),
43         0,
44         py_base_dealloc,
45         0,
46         0,
47         0,
48         0,
49         py_base_repr,
50         0,0,0,0,0,0,0,0,0,
51         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
52         0,0,0,0,0,0,0,
53         Methods,
54         0,
55         0,
56         &CValue::Type,
57         0,0,0,0,0,0,
58         py_base_new
59 };
60
61 PyMethodDef KX_VertexProxy::Methods[] = {
62 {"getXYZ", (PyCFunction)KX_VertexProxy::sPyGetXYZ,METH_NOARGS},
63 {"setXYZ", (PyCFunction)KX_VertexProxy::sPySetXYZ,METH_O},
64 {"getUV", (PyCFunction)KX_VertexProxy::sPyGetUV,METH_NOARGS},
65 {"setUV", (PyCFunction)KX_VertexProxy::sPySetUV,METH_O},
66
67 {"getUV2", (PyCFunction)KX_VertexProxy::sPyGetUV2,METH_NOARGS},
68 {"setUV2", (PyCFunction)KX_VertexProxy::sPySetUV2,METH_VARARGS},
69
70 {"getRGBA", (PyCFunction)KX_VertexProxy::sPyGetRGBA,METH_NOARGS},
71 {"setRGBA", (PyCFunction)KX_VertexProxy::sPySetRGBA,METH_O},
72 {"getNormal", (PyCFunction)KX_VertexProxy::sPyGetNormal,METH_NOARGS},
73 {"setNormal", (PyCFunction)KX_VertexProxy::sPySetNormal,METH_O},
74   {NULL,NULL} //Sentinel
75 };
76
77 PyAttributeDef KX_VertexProxy::Attributes[] = {
78         //KX_PYATTRIBUTE_TODO("DummyProps"),
79
80         KX_PYATTRIBUTE_DUMMY("x"),
81         KX_PYATTRIBUTE_DUMMY("y"),
82         KX_PYATTRIBUTE_DUMMY("z"),
83
84         KX_PYATTRIBUTE_DUMMY("r"),
85         KX_PYATTRIBUTE_DUMMY("g"),
86         KX_PYATTRIBUTE_DUMMY("b"),
87         KX_PYATTRIBUTE_DUMMY("a"),
88
89         KX_PYATTRIBUTE_DUMMY("u"),
90         KX_PYATTRIBUTE_DUMMY("v"),
91
92         KX_PYATTRIBUTE_DUMMY("u2"),
93         KX_PYATTRIBUTE_DUMMY("v2"),
94
95         KX_PYATTRIBUTE_DUMMY("XYZ"),
96         KX_PYATTRIBUTE_DUMMY("UV"),
97
98         KX_PYATTRIBUTE_DUMMY("color"),
99         KX_PYATTRIBUTE_DUMMY("colour"),
100
101         KX_PYATTRIBUTE_DUMMY("normal"),
102
103         { NULL }        //Sentinel
104 };
105
106 #if 0
107 PyObject*
108 KX_VertexProxy::py_getattro(PyObject *attr)
109 {
110   char *attr_str= _PyUnicode_AsString(attr);
111   if (attr_str[1]=='\0') { // Group single letters
112     // pos
113     if (attr_str[0]=='x')
114         return PyFloat_FromDouble(m_vertex->getXYZ()[0]);
115     if (attr_str[0]=='y')
116         return PyFloat_FromDouble(m_vertex->getXYZ()[1]);
117     if (attr_str[0]=='z')
118         return PyFloat_FromDouble(m_vertex->getXYZ()[2]);
119
120     // Col
121     if (attr_str[0]=='r')
122         return PyFloat_FromDouble(m_vertex->getRGBA()[0]/255.0);
123     if (attr_str[0]=='g')
124         return PyFloat_FromDouble(m_vertex->getRGBA()[1]/255.0);
125     if (attr_str[0]=='b')
126         return PyFloat_FromDouble(m_vertex->getRGBA()[2]/255.0);
127     if (attr_str[0]=='a')
128         return PyFloat_FromDouble(m_vertex->getRGBA()[3]/255.0);
129
130     // UV
131     if (attr_str[0]=='u')
132         return PyFloat_FromDouble(m_vertex->getUV1()[0]);
133     if (attr_str[0]=='v')
134         return PyFloat_FromDouble(m_vertex->getUV1()[1]);
135   }
136
137
138   if (!strcmp(attr_str, "XYZ"))
139         return PyObjectFrom(MT_Vector3(m_vertex->getXYZ()));
140
141   if (!strcmp(attr_str, "UV"))
142         return PyObjectFrom(MT_Point2(m_vertex->getUV1()));
143
144   if (!strcmp(attr_str, "color") || !strcmp(attr_str, "colour"))
145   {
146         const unsigned char *colp = m_vertex->getRGBA();
147         MT_Vector4 color(colp[0], colp[1], colp[2], colp[3]);
148         color /= 255.0;
149         return PyObjectFrom(color);
150   }
151
152   if (!strcmp(attr_str, "normal"))
153   {
154         return PyObjectFrom(MT_Vector3(m_vertex->getNormal()));
155   }
156
157   py_getattro_up(CValue);
158 }
159 #endif
160
161
162 #if 0
163 int    KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue)
164 {
165   char *attr_str= _PyUnicode_AsString(attr);
166   if (PySequence_Check(pyvalue))
167   {
168         if (!strcmp(attr_str, "XYZ"))
169         {
170                 MT_Point3 vec;
171                 if (PyVecTo(pyvalue, vec))
172                 {
173                         m_vertex->SetXYZ(vec);
174                         m_mesh->SetMeshModified(true);
175                         return PY_SET_ATTR_SUCCESS;
176                 }
177                 return PY_SET_ATTR_FAIL;
178         }
179
180         if (!strcmp(attr_str, "UV"))
181         {
182                 MT_Point2 vec;
183                 if (PyVecTo(pyvalue, vec))
184                 {
185                         m_vertex->SetUV(vec);
186                         m_mesh->SetMeshModified(true);
187                         return PY_SET_ATTR_SUCCESS;
188                 }
189                 return PY_SET_ATTR_FAIL;
190         }
191
192         if (!strcmp(attr_str, "color") || !strcmp(attr_str, "colour"))
193         {
194                 MT_Vector4 vec;
195                 if (PyVecTo(pyvalue, vec))
196                 {
197                         m_vertex->SetRGBA(vec);
198                         m_mesh->SetMeshModified(true);
199                         return PY_SET_ATTR_SUCCESS;
200                 }
201                 return PY_SET_ATTR_FAIL;
202         }
203
204         if (!strcmp(attr_str, "normal"))
205         {
206                 MT_Vector3 vec;
207                 if (PyVecTo(pyvalue, vec))
208                 {
209                         m_vertex->SetNormal(vec);
210                         m_mesh->SetMeshModified(true);
211                         return PY_SET_ATTR_SUCCESS;
212                 }
213                 return PY_SET_ATTR_FAIL;
214         }
215   }
216
217   if (PyFloat_Check(pyvalue))
218   {
219         float val = PyFloat_AsDouble(pyvalue);
220         // pos
221         MT_Point3 pos(m_vertex->getXYZ());
222         if (!strcmp(attr_str, "x"))
223         {
224                 pos.x() = val;
225                 m_vertex->SetXYZ(pos);
226                 m_mesh->SetMeshModified(true);
227                 return PY_SET_ATTR_SUCCESS;
228         }
229
230         if (!strcmp(attr_str, "y"))
231         {
232                 pos.y() = val;
233                 m_vertex->SetXYZ(pos);
234                 m_mesh->SetMeshModified(true);
235                 return PY_SET_ATTR_SUCCESS;
236         }
237
238         if (!strcmp(attr_str, "z"))
239         {
240                 pos.z() = val;
241                 m_vertex->SetXYZ(pos);
242                 m_mesh->SetMeshModified(true);
243                 return PY_SET_ATTR_SUCCESS;
244         }
245
246         // uv
247         MT_Point2 uv = m_vertex->getUV1();
248         if (!strcmp(attr_str, "u"))
249         {
250                 uv[0] = val;
251                 m_vertex->SetUV(uv);
252                 m_mesh->SetMeshModified(true);
253                 return PY_SET_ATTR_SUCCESS;
254         }
255
256         if (!strcmp(attr_str, "v"))
257         {
258                 uv[1] = val;
259                 m_vertex->SetUV(uv);
260                 m_mesh->SetMeshModified(true);
261                 return PY_SET_ATTR_SUCCESS;
262         }
263
264         // uv
265         MT_Point2 uv2 = m_vertex->getUV2();
266         if (!strcmp(attr_str, "u2"))
267         {
268                 uv[0] = val;
269                 m_vertex->SetUV2(uv);
270                 m_mesh->SetMeshModified(true);
271                 return 0;
272         }
273
274         if (!strcmp(attr_str, "v2"))
275         {
276                 uv[1] = val;
277                 m_vertex->SetUV2(uv);
278                 m_mesh->SetMeshModified(true);
279                 return PY_SET_ATTR_SUCCESS;
280         }
281
282         // col
283         unsigned int icol = *((const unsigned int *)m_vertex->getRGBA());
284         unsigned char *cp = (unsigned char*) &icol;
285         val *= 255.0;
286         if (!strcmp(attr_str, "r"))
287         {
288                 cp[0] = (unsigned char) val;
289                 m_vertex->SetRGBA(icol);
290                 m_mesh->SetMeshModified(true);
291                 return PY_SET_ATTR_SUCCESS;
292         }
293         if (!strcmp(attr_str, "g"))
294         {
295                 cp[1] = (unsigned char) val;
296                 m_vertex->SetRGBA(icol);
297                 m_mesh->SetMeshModified(true);
298                 return PY_SET_ATTR_SUCCESS;
299         }
300         if (!strcmp(attr_str, "b"))
301         {
302                 cp[2] = (unsigned char) val;
303                 m_vertex->SetRGBA(icol);
304                 m_mesh->SetMeshModified(true);
305                 return PY_SET_ATTR_SUCCESS;
306         }
307         if (!strcmp(attr_str, "a"))
308         {
309                 cp[3] = (unsigned char) val;
310                 m_vertex->SetRGBA(icol);
311                 m_mesh->SetMeshModified(true);
312                 return PY_SET_ATTR_SUCCESS;
313         }
314   }
315
316   return CValue::py_setattro(attr, pyvalue);
317 }
318 #endif
319
320 KX_VertexProxy::KX_VertexProxy(KX_MeshProxy*mesh, RAS_TexVert* vertex)
321 :       m_vertex(vertex),
322         m_mesh(mesh)
323 {
324 }
325
326 KX_VertexProxy::~KX_VertexProxy()
327 {
328 }
329
330
331
332 // stuff for cvalue related things
333 CValue*         KX_VertexProxy::Calc(VALUE_OPERATOR, CValue *) { return NULL;}
334 CValue*         KX_VertexProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;}
335 STR_String      sVertexName="vertex";
336 const STR_String &      KX_VertexProxy::GetText() {return sVertexName;};
337 double          KX_VertexProxy::GetNumber() { return -1;}
338 STR_String&     KX_VertexProxy::GetName() { return sVertexName;}
339 void            KX_VertexProxy::SetName(const char *) { };
340 CValue*         KX_VertexProxy::GetReplica() { return NULL;}
341
342 // stuff for python integration
343
344 PyObject* KX_VertexProxy::PyGetXYZ()
345 {
346         return PyObjectFrom(MT_Point3(m_vertex->getXYZ()));
347 }
348
349 PyObject* KX_VertexProxy::PySetXYZ(PyObject* value)
350 {
351         MT_Point3 vec;
352         if (!PyVecTo(value, vec))
353                 return NULL;
354
355         m_vertex->SetXYZ(vec);
356         m_mesh->SetMeshModified(true);
357         Py_RETURN_NONE;
358 }
359
360 PyObject* KX_VertexProxy::PyGetNormal()
361 {
362         return PyObjectFrom(MT_Vector3(m_vertex->getNormal()));
363 }
364
365 PyObject* KX_VertexProxy::PySetNormal(PyObject* value)
366 {
367         MT_Vector3 vec;
368         if (!PyVecTo(value, vec))
369                 return NULL;
370
371         m_vertex->SetNormal(vec);
372         m_mesh->SetMeshModified(true);
373         Py_RETURN_NONE;
374 }
375
376
377 PyObject* KX_VertexProxy::PyGetRGBA()
378 {
379         int *rgba = (int *) m_vertex->getRGBA();
380         return PyLong_FromSsize_t(*rgba);
381 }
382
383 PyObject* KX_VertexProxy::PySetRGBA(PyObject* value)
384 {
385         if PyLong_Check(value) {
386                 int rgba = PyLong_AsSsize_t(value);
387                 m_vertex->SetRGBA(rgba);
388                 m_mesh->SetMeshModified(true);
389                 Py_RETURN_NONE;
390         }
391         else {
392                 MT_Vector4 vec;
393                 if (PyVecTo(value, vec))
394                 {
395                         m_vertex->SetRGBA(vec);
396                         m_mesh->SetMeshModified(true);
397                         Py_RETURN_NONE;
398                 }
399         }
400
401         PyErr_SetString(PyExc_TypeError, "vert.setRGBA(value): KX_VertexProxy, expected a 4D vector or an int");
402         return NULL;
403 }
404
405
406 PyObject* KX_VertexProxy::PyGetUV()
407 {
408         return PyObjectFrom(MT_Vector2(m_vertex->getUV1()));
409 }
410
411 PyObject* KX_VertexProxy::PySetUV(PyObject* value)
412 {
413         MT_Point2 vec;
414         if (!PyVecTo(value, vec))
415                 return NULL;
416
417         m_vertex->SetUV(vec);
418         m_mesh->SetMeshModified(true);
419         Py_RETURN_NONE;
420 }
421
422 PyObject* KX_VertexProxy::PyGetUV2()
423 {
424         return PyObjectFrom(MT_Vector2(m_vertex->getUV2()));
425 }
426
427 PyObject* KX_VertexProxy::PySetUV2(PyObject* args)
428 {
429         MT_Point2 vec;
430         unsigned int unit= RAS_TexVert::SECOND_UV;
431
432         PyObject* list= NULL;
433         if(!PyArg_ParseTuple(args, "O|i:setUV2", &list, &unit))
434                 return NULL;
435
436         if (!PyVecTo(list, vec))
437                 return NULL;
438
439         m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV));
440         m_vertex->SetUnit(unit);
441         m_vertex->SetUV2(vec);
442         m_mesh->SetMeshModified(true);
443         Py_RETURN_NONE;
444 }