4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
/**********************************************
20
* Copyright (C) 2002-2003 Bertrand 'blam' LAMY
21
**********************************************/
23
/*================================*
24
* FACE: Python object definition *
25
*================================*/
27
void P3_face_raypick (PyObject* face, P3_raypick_data* data, P3_raypickable* parent) {
28
PyObject* o; PyObject* w; PyObject* c;
35
int double_sided = P3_FALSE;
36
o = PyObject_GetAttrString (face, "vertices");
37
nb = PySequence_Size (o);
39
option = data->option;
40
w = PyObject_GetAttrString (face, "double_sided");
41
if (PyObject_IsTrue (w) == 1) {
42
option &= ~P3_RAYPICK_CULL_FACE;
43
double_sided = P3_TRUE;
46
/* get vertices coordinates */
47
c = PyObject_GetAttrString (face, "parent");
48
p = (GLfloat*) malloc (nb * 3 * sizeof (GLfloat));
49
for (i = 0; i < nb; i++) {
50
PyP3_GetPositionInto (PySequence_Fast_GET_ITEM (o, i), (P3_coordsys*) c, p + i * 3);
52
P3_face_normal (normal, p, p + 3, p + 6);
53
P3_vector_normalize (normal);
54
raydata = P3_raypickable_get_raypick_data ((P3_raypickable*) c, data);
56
i = P3_triangle_raypick (raydata, p, p + 3, p + 6, normal, option, &r);
58
i = P3_quad_raypick (raydata, p, p + 3, p + 6, p + 9, normal, option, &r);
61
P3_error ("raypicking on face with more than 4 vertices is not supported");
64
if (data->ret_csys == NULL || fabs (r) < fabs (data->result)) {
65
if (i == P3_RAYPICK_DIRECT) {
68
memcpy (data->normal, normal, 3 * sizeof (GLfloat));
69
} else if (i == P3_RAYPICK_INDIRECT) {
72
if (double_sided == P3_TRUE) {
73
data->normal[0] = -normal[0];
74
data->normal[1] = -normal[1];
75
data->normal[2] = -normal[2];
77
memcpy (data->normal, normal, 3 * sizeof (GLfloat));
86
int P3_face_raypick_b (PyObject* face, P3_raypick_data* data, P3_raypickable* parent) {
87
PyObject* o; PyObject* w; PyObject* c;
90
GLfloat r; GLfloat normal[3];
93
o = PyObject_GetAttrString (face, "vertices");
94
nb = PySequence_Size (o);
95
if (nb < 3) { return P3_FALSE; }
96
option = data->option;
97
if (option & P3_RAYPICK_CULL_FACE) {
98
w = PyObject_GetAttrString (face, "double_sided");
99
if (PyObject_IsTrue (w) == 1) option &= ~P3_RAYPICK_CULL_FACE;
102
/* get vertices coordinates */
103
p = (GLfloat*) malloc (nb * 3 * sizeof (GLfloat));
104
c = PyObject_GetAttrString (face, "parent");
105
for (i = 0; i < nb; i++) {
106
PyP3_GetPositionInto (PySequence_Fast_GET_ITEM (o, i), (P3_coordsys*) c, p + i * 3);
108
P3_face_normal (normal, p, p + 3, p + 6);
109
P3_vector_normalize (normal);
110
raydata = P3_raypickable_get_raypick_data (parent, data);
112
i = P3_triangle_raypick (raydata, p, p + 3, p + 6, normal, option, &r);
113
} else if (nb == 4) {
114
i = P3_quad_raypick (raydata, p, p + 3, p + 6, p + 9, normal, option, &r);
117
P3_error ("raypicking on face with more than 4 vertices is not supported");
125
P3_class P3_class_face = {
127
(batch_func) P3_shape_batch,
128
(render_func) P3_shape_render,
130
(raypick_func) P3_face_raypick,
131
(raypick_b_func) P3_face_raypick_b,
134
static int PyP3Face_Init (PyObject* self, PyObject* args, PyObject* kwds) {
135
((P3_any_object*) self)->class = &P3_class_face;
139
PyTypeObject PyP3Face_Type = {
140
PyObject_HEAD_INIT(NULL)
143
sizeof(P3_any_object),
145
(destructor) PyP3Object_Dealloc,/* tp_dealloc */
152
0,/* tp_as_sequence */
153
0,/* tp_as_mapping */
157
PYP3_GENERIC_GETATTR,/* tp_getattro */
160
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,/* tp_flags */
162
(traverseproc) 0,/* tp_traverse */
163
(inquiry) 0,/* tp_clear */
164
0,/* tp_richcompare */
165
0,/* tp_weaklistoffset */
168
(PyMethodDef*) 0,//&PyP3Renderable_Methods,/* tp_methods */
170
(PyGetSetDef*) 0,/* tp_getset */
175
0,/* tp_dictoffset */
176
(initproc) PyP3Face_Init,/* tp_init */
177
PYP3_GENERIC_ALLOC,/* tp_alloc */
178
(newfunc) PyP3Object_New,/* tp_new */
179
PYP3_GENERIC_FREE,/* tp_free */
183
/*=====================================*
184
* FACE: C functions about Python face *
185
*=====================================*/
188
int P3_face_get_option (P3_face* f1) {
191
if (P3_face_is_smoothlit (f1)) { opt |= P3_R_SMOOTHLIT; }
192
if (P3_face_is_alpha (f1)) { opt |= P3_R_ALPHA; }
193
if (P3_face_is_double_sided (f1)) { opt |= P3_R_FRONT_AND_BACK; }
194
if (P3_face_is_static_lit (f1)) { opt |= P3_R_STATIC_LIT; }
195
if (P3_face_is_colored (f1)) { opt |= P3_R_COLORED; }
196
if (!(P3_face_is_solid (f1))) { opt |= P3_OBJECT_NON_SOLID; }
197
if (!(P3_face_can_be_lit (f1))) { opt |= P3_R_NEVER_LIT; }
198
if (P3_face_get_material (f1) != NULL) { opt |= P3_R_TEXTURED; }
203
P3_material* P3_face_get_material (PyObject* face) {
205
m = PyObject_GetAttrString (face, "material");
210
return (P3_material*) m;
214
P3_coordsys* P3_face_get_coordsys (PyObject* face) {
216
c = (P3_coordsys*) PyObject_GetAttrString (face, "parent");
218
if ((PyObject*) c == Py_None) {
225
void P3_face_get_box (PyObject* face, GLfloat* box, int* edited) {
231
nbv = P3_face_get_vertices_number (face);
232
for (i = 0; i < nbv; i++) {
233
vertex = P3_face_get_vertex (face, i);
234
csys = P3_vertex_get_coordsys (vertex);
235
P3_vertex_get_coord (vertex, coord);
236
P3_point_by_matrix (coord, P3_coordsys_get_root_matrix (csys));
237
if (*edited == P3_FALSE) {
239
memcpy (box, coord, 3 * sizeof (GLfloat));
240
memcpy (box + 3, coord, 3 * sizeof (GLfloat));
242
if (coord[0] < box[0]) { box[0] = coord[0]; }
243
if (coord[1] < box[1]) { box[1] = coord[1]; }
244
if (coord[2] < box[2]) { box[2] = coord[2]; }
245
if (coord[0] > box[3]) { box[3] = coord[0]; }
246
if (coord[1] > box[4]) { box[4] = coord[1]; }
247
if (coord[2] > box[5]) { box[5] = coord[2]; }
252
P3_coordsys* P3_vertex_get_coordsys (PyObject* vertex) {
254
c = (P3_coordsys*) PyObject_GetAttrString (vertex, "parent");
256
if ((PyObject*) c == Py_None) {
263
void P3_vertex_set_diffuse (PyObject* o, GLfloat* c) {
265
tuple = PyTuple_New (4);
266
PyTuple_SET_ITEM (tuple, 0, PyFloat_FromDouble ((double) c[0]));
267
PyTuple_SET_ITEM (tuple, 1, PyFloat_FromDouble ((double) c[1]));
268
PyTuple_SET_ITEM (tuple, 2, PyFloat_FromDouble ((double) c[2]));
269
PyTuple_SET_ITEM (tuple, 3, PyFloat_FromDouble ((double) c[3]));
270
PyObject_SetAttrString (o, "color", tuple);
274
void P3_vertex_set_emissive (PyObject* o, GLfloat* c) {
276
tuple = PyTuple_New (4);
277
PyTuple_SET_ITEM (tuple, 0, PyFloat_FromDouble ((double) c[0]));
278
PyTuple_SET_ITEM (tuple, 1, PyFloat_FromDouble ((double) c[1]));
279
PyTuple_SET_ITEM (tuple, 2, PyFloat_FromDouble ((double) c[2]));
280
PyTuple_SET_ITEM (tuple, 3, PyFloat_FromDouble ((double) c[3]));
281
PyObject_SetAttrString (o, "emissive", tuple);
285
PyObject* P3_face_new (P3_world* w, P3_material* material, int nb_v, ...) {
291
if (material == NULL) { material = (P3_material*) Py_None; }
292
list = PyList_New (0);
293
for (i = 0; i < nb_v; i++) {
294
PyList_Append (list, va_arg (ap, PyObject*));
296
f = PyObject_CallMethod (P3Module, "new_face", "OOO", w, list, material);
298
if (PyErr_Occurred () != NULL) { PyErr_Print (); }
299
#endif /* SAFE_MODE */
304
PyObject* P3_vertex_new (P3_world* w, GLfloat x, GLfloat y, GLfloat z) {
306
v = PyObject_CallMethod (P3Module, "new_vertex", "Offf", w, x, y, z);
307
PyObject_SetAttrString (v, "color", Py_None);
309
if (PyErr_Occurred () != NULL) { PyErr_Print (); }
310
#endif /* SAFE_MODE */
314
#define FUNC_FACE_GET(name, attr) \
315
int P3_face_##name (PyObject* face) { \
318
o = PyObject_GetAttrString (face, attr); \
320
i = (PyObject_IsTrue (o) == 1); \
325
#define FUNC_FACE_IS(name, attr) \
326
int P3_face_##name (PyObject* face) { \
329
o = PyObject_CallMethod (face, attr, NULL); \
331
i = (PyObject_IsTrue (o) == 1); \
336
#define FUNC_FACE_SET(name, attr) \
337
void P3_face_set_##name (PyObject* face, int value) { \
339
o = PyInt_FromLong ((long) value); \
340
PyObject_SetAttrString (face, attr, o); \
343
#define FUNC_FACE_TRY(name, attr) \
344
int P3_face_##name (PyObject* face) { \
347
if (PyObject_HasAttrString (face, attr)) { \
348
o = PyObject_GetAttrString (face, attr); \
349
i = PyObject_IsTrue (o); \
355
FUNC_FACE_GET (is_smoothlit, "smooth_lit")
356
FUNC_FACE_GET (is_double_sided, "double_sided")
357
FUNC_FACE_GET (is_solid, "solid")
358
FUNC_FACE_GET (is_static_lit, "static_lit")
359
FUNC_FACE_GET (can_be_lit, "lit")
360
FUNC_FACE_IS (is_alpha, "is_alpha")
361
FUNC_FACE_IS (is_colored, "is_colored")
362
FUNC_FACE_SET (smoothlit, "smooth_lit")
363
FUNC_FACE_SET (double_sided, "double_sided")
364
FUNC_FACE_SET (solid, "solid")
365
FUNC_FACE_SET (static_lit, "static_lit")
366
FUNC_FACE_SET (can_be_lit, "lit")
367
FUNC_FACE_SET (cell_shading, "cell_shading")
368
FUNC_FACE_TRY (cell_shading, "cell_shading")
375
int P3_face_get_vertices_number (PyObject* face) {
378
o = PyObject_GetAttrString (face, "vertices");
380
i = PySequence_Size (o);
386
PyObject* P3_face_get_vertex (PyObject* face, int index) {
389
o = PyObject_GetAttrString (face, "vertices");
391
v = PySequence_Fast_GET_ITEM (o, index);
397
void P3_face_add_vertex (PyObject* face, PyObject* vertex) {
399
o = PyObject_GetAttrString (face, "vertices");
402
PyList_Append (o, vertex);
407
void P3_vertex_get_coord (PyObject* v, GLfloat* ptr) {
409
o = PyObject_GetAttrString (v, "x");
411
ptr[0] = (GLfloat) PyFloat_AS_DOUBLE (o);
414
o = PyObject_GetAttrString (v, "y");
416
ptr[1] = (GLfloat) PyFloat_AS_DOUBLE (o);
419
o = PyObject_GetAttrString (v, "z");
421
ptr[2] = (GLfloat) PyFloat_AS_DOUBLE (o);
426
void P3_vertex_get_texcoord (PyObject* v, GLfloat* ptr) {
428
o = PyObject_GetAttrString (v, "tex_x");
430
ptr[0] = (GLfloat) PyFloat_AS_DOUBLE (o);
433
o = PyObject_GetAttrString (v, "tex_y");
435
ptr[1] = (GLfloat) PyFloat_AS_DOUBLE (o);
440
void P3_vertex_get_diffuse (PyObject* v, GLfloat* ptr) {
442
o = PyObject_GetAttrString (v, "color");
443
if (o != NULL && o != Py_None) {
444
PY_TUPLE_FLOAT_TO_ARRAY_4 (ptr, o);
454
void P3_vertex_get_emissive (PyObject* v, GLfloat* ptr) {
456
if (PyObject_HasAttrString (v, "emissive")) {
457
o = PyObject_GetAttrString (v, "emissive");
458
if (o != NULL && o != Py_None) {
459
PY_TUPLE_FLOAT_TO_ARRAY_4 (ptr, o);
470
int P3_vertex_is_morphing (PyObject* v) {
473
if (PyObject_HasAttrString (v, "morphing") == 1) {
474
o = PyObject_GetAttrString (v, "morphing");
475
i = PyInt_AS_LONG (o);
482
P3_material* P3_vertex_get_material (PyObject* v) {
484
if (!PyObject_HasAttrString (v, "material")) {
487
m = PyObject_GetAttrString (v, "material");
492
return (P3_material*) m;
496
void P3_vertex_set_texcoord (PyObject* v, GLfloat* uv) {
498
o = PyFloat_FromDouble ((double) uv[0]);
499
PyObject_SetAttrString (v, "tex_x", o);
501
o = PyFloat_FromDouble ((double) uv[1]);
502
PyObject_SetAttrString (v, "tex_y", o);