Recreating my GSoC branch.
[blender.git] / source / gameengine / Ketsji / KX_PolyProxy.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 #ifndef DISABLE_PYTHON
30
31 #include "KX_PolyProxy.h"
32 #include "KX_MeshProxy.h"
33 #include "RAS_MeshObject.h"
34 #include "KX_BlenderMaterial.h"
35 #include "KX_PolygonMaterial.h"
36
37 #include "KX_PyMath.h"
38
39 PyTypeObject KX_PolyProxy::Type = {
40         PyVarObject_HEAD_INIT(NULL, 0)
41         "KX_PolyProxy",
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_PolyProxy::Methods[] = {
62         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,getMaterialIndex),
63         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,getNumVertex),
64         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,isVisible),
65         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,isCollider),
66         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,getMaterialName),
67         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,getTextureName),
68         KX_PYMETHODTABLE(KX_PolyProxy,getVertexIndex),
69         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,getMesh),
70         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,getMaterial),
71         {NULL,NULL} //Sentinel
72 };
73
74 PyAttributeDef KX_PolyProxy::Attributes[] = {
75         /* All dummy's so they come up in a dir() */
76         //KX_PYATTRIBUTE_TODO("DummyProps"),
77         KX_PYATTRIBUTE_DUMMY("matname"),
78         KX_PYATTRIBUTE_DUMMY("texture"),
79         KX_PYATTRIBUTE_DUMMY("material"),
80         KX_PYATTRIBUTE_DUMMY("matid"),
81         KX_PYATTRIBUTE_DUMMY("v1"),
82         KX_PYATTRIBUTE_DUMMY("v2"),
83         KX_PYATTRIBUTE_DUMMY("v3"),
84         KX_PYATTRIBUTE_DUMMY("v4"),
85         KX_PYATTRIBUTE_DUMMY("visible"),
86         KX_PYATTRIBUTE_DUMMY("collide"),
87         { NULL }        //Sentinel
88 };
89
90 #if 0
91 PyObject* KX_PolyProxy::py_getattro(PyObject *attr)
92 {
93         char *attr_str= _PyUnicode_AsString(attr);
94         if (!strcmp(attr_str, "matname"))
95         {
96                 return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName());
97         }
98         if (!strcmp(attr_str, "texture"))
99         {
100                 return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName());
101         }
102         if (!strcmp(attr_str, "material"))
103         {
104                 RAS_IPolyMaterial *polymat = m_polygon->GetMaterial()->GetPolyMaterial();
105                 if(polymat->GetFlag() & RAS_BLENDERMAT)
106                 {
107                         KX_BlenderMaterial* mat = static_cast<KX_BlenderMaterial*>(polymat);
108                         return mat->GetProxy();
109                 }
110                 else
111                 {
112                         KX_PolygonMaterial* mat = static_cast<KX_PolygonMaterial*>(polymat);
113                         return mat->GetProxy();
114                 }
115         }
116         if (!strcmp(attr_str, "matid"))
117         {
118                 // we'll have to scan through the material bucket of the mes and compare with 
119                 // the one of the polygon
120                 RAS_MaterialBucket* polyBucket = m_polygon->GetMaterial();
121                 unsigned int matid;
122                 for (matid=0; matid<(unsigned int)m_mesh->NumMaterials(); matid++)
123                 {
124                         RAS_MeshMaterial* meshMat = m_mesh->GetMeshMaterial(matid);
125                         if (meshMat->m_bucket == polyBucket)
126                                 // found it
127                                 break;
128                 }
129                 return PyLong_FromSsize_t(matid);
130         }
131         if (!strcmp(attr_str, "v1"))
132         {
133                 return PyLong_FromSsize_t(m_polygon->GetVertexOffsetAbs(m_mesh, 0));
134         }
135         if (!strcmp(attr_str, "v2"))
136         {
137                 return PyLong_FromSsize_t(m_polygon->GetVertexOffsetAbs(m_mesh, 1));
138         }
139         if (!strcmp(attr_str, "v3"))
140         {
141                 return PyLong_FromSsize_t(m_polygon->GetVertexOffsetAbs(m_mesh, 2));
142         }
143         if (!strcmp(attr_str, "v4"))
144         {
145                 return PyLong_FromSsize_t(((m_polygon->VertexCount()>3)?m_polygon->GetVertexOffsetAbs(m_mesh, 3):0));
146         }
147         if (!strcmp(attr_str, "visible"))
148         {
149                 return PyLong_FromSsize_t(m_polygon->IsVisible());
150         }
151         if (!strcmp(attr_str, "collide"))
152         {
153                 return PyLong_FromSsize_t(m_polygon->IsCollider());
154         }
155         // py_getattro_up(CValue); // XXX -- todo, make all these attributes
156 }
157 #endif
158
159 KX_PolyProxy::KX_PolyProxy(const RAS_MeshObject*mesh, RAS_Polygon* polygon)
160 :       m_polygon(polygon),
161         m_mesh((RAS_MeshObject*)mesh)
162 {
163 }
164
165 KX_PolyProxy::~KX_PolyProxy()
166 {
167 }
168
169
170 // stuff for cvalue related things
171 CValue*         KX_PolyProxy::Calc(VALUE_OPERATOR, CValue *) { return NULL;}
172 CValue*         KX_PolyProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;}      
173 STR_String      sPolyName="polygone";
174 const STR_String &      KX_PolyProxy::GetText() {return sPolyName;};
175 double          KX_PolyProxy::GetNumber() { return -1;}
176 STR_String&     KX_PolyProxy::GetName() { return sPolyName;}
177 void            KX_PolyProxy::SetName(const char *) { };
178 CValue*         KX_PolyProxy::GetReplica() { return NULL;}
179
180 // stuff for python integration
181
182 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialIndex, 
183 "getMaterialIndex() : return the material index of the polygon in the mesh\n")
184 {
185         RAS_MaterialBucket* polyBucket = m_polygon->GetMaterial();
186         unsigned int matid;
187         for (matid=0; matid<(unsigned int)m_mesh->NumMaterials(); matid++)
188         {
189                 RAS_MeshMaterial* meshMat = m_mesh->GetMeshMaterial(matid);
190                 if (meshMat->m_bucket == polyBucket)
191                         // found it
192                         break;
193         }
194         return PyLong_FromSsize_t(matid);
195 }
196
197 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getNumVertex,
198 "getNumVertex() : returns the number of vertex of the polygon, 3 or 4\n")
199 {
200         return PyLong_FromSsize_t(m_polygon->VertexCount());
201 }
202
203 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, isVisible,
204 "isVisible() : returns whether the polygon is visible or not\n")
205 {
206         return PyLong_FromSsize_t(m_polygon->IsVisible());
207 }
208
209 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, isCollider,
210 "isCollider() : returns whether the polygon is receives collision or not\n")
211 {
212         return PyLong_FromSsize_t(m_polygon->IsCollider());
213 }
214
215 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialName,
216 "getMaterialName() : returns the polygon material name, \"NoMaterial\" if no material\n")
217 {
218         return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName());
219 }
220
221 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getTextureName,
222 "getTexturelName() : returns the polygon texture name, \"NULL\" if no texture\n")
223 {
224         return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName());
225 }
226
227 KX_PYMETHODDEF_DOC(KX_PolyProxy, getVertexIndex,
228 "getVertexIndex(vertex) : returns the mesh vertex index of a polygon vertex\n"
229 "vertex: index of the vertex in the polygon: 0->3\n"
230 "return value can be used to retrieve the vertex details through mesh proxy\n"
231 "Note: getVertexIndex(3) on a triangle polygon returns 0\n")
232 {
233         int index;
234         if (!PyArg_ParseTuple(args,"i:getVertexIndex",&index))
235         {
236                 return NULL;
237         }
238         if (index < 0 || index > 3)
239         {
240                 PyErr_SetString(PyExc_AttributeError, "poly.getVertexIndex(int): KX_PolyProxy, expected an index between 0-3");
241                 return NULL;
242         }
243         if (index < m_polygon->VertexCount())
244         {
245                 return PyLong_FromSsize_t(m_polygon->GetVertexOffsetAbs(m_mesh, index));
246         }
247         return PyLong_FromSsize_t(0);
248 }
249
250 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMesh,
251 "getMesh() : returns a mesh proxy\n")
252 {
253         KX_MeshProxy* meshproxy = new KX_MeshProxy((RAS_MeshObject*)m_mesh);
254         return meshproxy->NewProxy(true);
255 }
256
257 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterial,
258 "getMaterial() : returns a material\n")
259 {
260         RAS_IPolyMaterial *polymat = m_polygon->GetMaterial()->GetPolyMaterial();
261         if(polymat->GetFlag() & RAS_BLENDERMAT)
262         {
263                 KX_BlenderMaterial* mat = static_cast<KX_BlenderMaterial*>(polymat);
264                 return mat->GetProxy();
265         }
266         else
267         {
268                 KX_PolygonMaterial* mat = static_cast<KX_PolygonMaterial*>(polymat);
269                 return mat->GetProxy();
270         }
271 }
272
273 #endif // DISABLE_PYTHON