e7f562bda8e367ce6de921c7b224aff0e2da02cd
[blender.git] / source / gameengine / Ketsji / KX_MeshProxy.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_MeshProxy.h"
34 #include "RAS_IPolygonMaterial.h"
35 #include "RAS_MeshObject.h"
36
37 #include "KX_VertexProxy.h"
38 #include "KX_PolyProxy.h"
39
40 #include "KX_PolygonMaterial.h"
41 #include "KX_BlenderMaterial.h"
42
43 #include "KX_PyMath.h"
44 #include "KX_ConvertPhysicsObject.h"
45
46 #include "PyObjectPlus.h" 
47
48 PyTypeObject KX_MeshProxy::Type = {
49         PyObject_HEAD_INIT(NULL)
50         0,
51         "KX_MeshProxy",
52         sizeof(KX_MeshProxy),
53         0,
54         PyDestructor,
55         0,
56         0,
57         0,
58         0,
59         py_base_repr,
60         0,0,0,0,0,0,
61         py_base_getattro,
62         py_base_setattro,
63         0,0,0,0,0,0,0,0,0,
64         Methods
65 };
66
67 PyParentObject KX_MeshProxy::Parents[] = {
68         &KX_MeshProxy::Type,
69         &SCA_IObject::Type,
70         &CValue::Type,
71         &PyObjectPlus::Type,
72         NULL
73 };
74
75 PyMethodDef KX_MeshProxy::Methods[] = {
76 {"getNumMaterials", (PyCFunction)KX_MeshProxy::sPyGetNumMaterials,METH_VARARGS},
77 {"getNumPolygons", (PyCFunction)KX_MeshProxy::sPyGetNumPolygons,METH_NOARGS},
78 {"getMaterialName", (PyCFunction)KX_MeshProxy::sPyGetMaterialName,METH_VARARGS},
79 {"getTextureName", (PyCFunction)KX_MeshProxy::sPyGetTextureName,METH_VARARGS},
80 {"getVertexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetVertexArrayLength,METH_VARARGS},
81 {"getVertex", (PyCFunction)KX_MeshProxy::sPyGetVertex,METH_VARARGS},
82 {"getPolygon", (PyCFunction)KX_MeshProxy::sPyGetPolygon,METH_VARARGS},
83 KX_PYMETHODTABLE(KX_MeshProxy, reinstancePhysicsMesh),
84 //{"getIndexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetIndexArrayLength,METH_VARARGS},
85
86   {NULL,NULL} //Sentinel
87 };
88
89 PyAttributeDef KX_MeshProxy::Attributes[] = {
90         KX_PYATTRIBUTE_RO_FUNCTION("materials",         KX_MeshProxy, pyattr_get_materials),
91         { NULL }        //Sentinel
92 };
93
94 void KX_MeshProxy::SetMeshModified(bool v)
95 {
96         m_meshobj->SetMeshModified(v);
97 }
98
99
100 PyObject* KX_MeshProxy::py_getattro(PyObject *attr)
101 {
102         py_getattro_up(SCA_IObject);
103 }
104
105
106
107 KX_MeshProxy::KX_MeshProxy(RAS_MeshObject* mesh)
108         : SCA_IObject(&Type), m_meshobj(mesh)
109 {
110 }
111
112 KX_MeshProxy::~KX_MeshProxy()
113 {
114 }
115
116
117
118 // stuff for cvalue related things
119 CValue*         KX_MeshProxy::Calc(VALUE_OPERATOR op, CValue *val) { return NULL;}
120 CValue*         KX_MeshProxy::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val) { return NULL;}  
121
122 const STR_String &      KX_MeshProxy::GetText() {return m_meshobj->GetName();};
123 double          KX_MeshProxy::GetNumber() { return -1;}
124 STR_String      KX_MeshProxy::GetName() { return m_meshobj->GetName();}
125 void            KX_MeshProxy::SetName(STR_String name) { };
126 CValue*         KX_MeshProxy::GetReplica() { return NULL;}
127 void            KX_MeshProxy::ReplicaSetName(STR_String name) {};
128
129
130 // stuff for python integration
131         
132 PyObject* KX_MeshProxy::PyGetNumMaterials(PyObject* self, 
133                                PyObject* args, 
134                                PyObject* kwds)
135 {
136         int num = m_meshobj->NumMaterials();
137         return PyInt_FromLong(num);
138 }
139
140 PyObject* KX_MeshProxy::PyGetNumPolygons(PyObject* self)
141 {
142         int num = m_meshobj->NumPolygons();
143         return PyInt_FromLong(num);
144 }
145
146 PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* self, 
147                                PyObject* args, 
148                                PyObject* kwds)
149 {
150     int matid= 1;
151         STR_String matname;
152
153         if (PyArg_ParseTuple(args,"i:getMaterialName",&matid))
154         {
155                 matname = m_meshobj->GetMaterialName(matid);
156         }
157         else {
158                 return NULL;
159         }
160
161         return PyString_FromString(matname.Ptr());
162                 
163 }
164         
165
166 PyObject* KX_MeshProxy::PyGetTextureName(PyObject* self, 
167                                PyObject* args, 
168                                PyObject* kwds)
169 {
170     int matid= 1;
171         STR_String matname;
172
173         if (PyArg_ParseTuple(args,"i:getTextureName",&matid))
174         {
175                 matname = m_meshobj->GetTextureName(matid);
176         }
177         else {
178                 return NULL;
179         }
180
181         return PyString_FromString(matname.Ptr());
182                 
183 }
184
185 PyObject* KX_MeshProxy::PyGetVertexArrayLength(PyObject* self, 
186                                PyObject* args, 
187                                PyObject* kwds)
188 {
189     int matid= 0;
190         int length = 0;
191
192         
193         if (!PyArg_ParseTuple(args,"i:getVertexArrayLength",&matid))
194                 return NULL;
195         
196
197         RAS_MeshMaterial *mmat = m_meshobj->GetMeshMaterial(matid); /* can be NULL*/
198         
199         if (mmat)
200         {
201                 RAS_IPolyMaterial* mat = mmat->m_bucket->GetPolyMaterial();
202                 if (mat)
203                         length = m_meshobj->NumVertices(mat);
204         }
205         
206         return PyInt_FromLong(length);
207 }
208
209
210 PyObject* KX_MeshProxy::PyGetVertex(PyObject* self, 
211                                PyObject* args, 
212                                PyObject* kwds)
213 {
214     int vertexindex= 1;
215         int matindex= 1;
216         PyObject* vertexob = NULL;
217
218         if (PyArg_ParseTuple(args,"ii:getVertex",&matindex,&vertexindex))
219         {
220                 RAS_TexVert* vertex = m_meshobj->GetVertex(matindex,vertexindex);
221                 if (vertex)
222                 {
223                         vertexob = new KX_VertexProxy(this, vertex);
224                 }
225         }
226         else {
227                 return NULL;
228         }
229
230         return vertexob;
231                 
232 }
233
234 PyObject* KX_MeshProxy::PyGetPolygon(PyObject* self,
235                                PyObject* args, 
236                                PyObject* kwds)
237 {
238     int polyindex= 1;
239         PyObject* polyob = NULL;
240
241         if (!PyArg_ParseTuple(args,"i:getPolygon",&polyindex))
242                 return NULL;
243         
244         if (polyindex<0 || polyindex >= m_meshobj->NumPolygons())
245         {
246                 PyErr_SetString(PyExc_AttributeError, "Invalid polygon index");
247                 return NULL;
248         }
249                 
250
251         RAS_Polygon* polygon = m_meshobj->GetPolygon(polyindex);
252         if (polygon)
253         {
254                 polyob = new KX_PolyProxy(m_meshobj, polygon);
255         }
256         else {
257                 PyErr_SetString(PyExc_AttributeError, "polygon is NULL, unknown reason");
258         }
259         return polyob;
260 }
261
262 KX_PYMETHODDEF_DOC(KX_MeshProxy, reinstancePhysicsMesh,
263 "Reinstance the physics mesh.")
264 {
265         //this needs to be reviewed, it is dependend on Sumo/Solid. Who is using this ?
266         Py_RETURN_NONE;//(KX_ReInstanceShapeFromMesh(m_meshobj)) ? Py_RETURN_TRUE : Py_RETURN_FALSE;
267 }
268
269 PyObject* KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
270 {
271         KX_MeshProxy* self= static_cast<KX_MeshProxy*>(self_v);
272         
273         int tot= self->m_meshobj->NumMaterials();
274         int i;
275         
276         PyObject *materials = PyList_New( tot );
277         
278         list<RAS_MeshMaterial>::iterator mit= self->m_meshobj->GetFirstMaterial();
279         
280         
281         for(i=0; i<tot; mit++, i++) {
282                 RAS_IPolyMaterial *polymat = mit->m_bucket->GetPolyMaterial();   
283                 
284                 /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */
285                 if(polymat->GetFlag() & RAS_BLENDERMAT)          
286                 {        
287                         KX_BlenderMaterial *mat = static_cast<KX_BlenderMaterial*>(polymat);     
288                         PyList_SET_ITEM(materials, i, mat);
289                         Py_INCREF(mat);
290                 }
291                 else {  
292                         KX_PolygonMaterial *mat = static_cast<KX_PolygonMaterial*>(polymat);
293                         PyList_SET_ITEM(materials, i, mat);
294                         Py_INCREF(mat);
295                 }
296         }       
297         return materials;
298 }