📄 glmodule.c
字号:
/*
Input used to generate the Python module "glmodule.c".
The stub generator is a Python script called "cgen.py".
Each definition must be contained on one line:
<returntype> <name> <type> <arg> <type> <arg>
<returntype> can be: void, short, long (XXX maybe others?)
<type> can be: char, string, short, float, long, or double
string indicates a null terminated string;
if <type> is char and <arg> begins with a *, the * is stripped
and <type> is changed into string
<arg> has the form <mode> or <mode>[<subscript>]
where <mode> can be
s: arg is sent
r: arg is received (arg is a pointer)
and <subscript> can be (N and I are numbers):
N
argI
retval
N*argI
N*I
N*retval
In the case where the subscript consists of two parts
separated by *, the first part is the width of the matrix, and
the second part is the length of the matrix. This order is
opposite from the order used in C to declare a two-dimensional
matrix.
*/
/*
* An attempt has been made to make this module switch threads on qread
* calls. It is far from safe, though.
*/
#include <gl.h>
#include <device.h>
#ifdef __sgi
extern int devport();
extern int textwritemask();
extern int pagewritemask();
extern int gewrite();
extern int gettp();
#endif
#include "Python.h"
#include "cgensupport.h"
/*
Some stubs are too complicated for the stub generator.
We can include manually written versions of them here.
A line starting with '%' gives the name of the function so the stub
generator can include it in the table of functions.
*/
static PyObject *
gl_qread(PyObject *self, PyObject *args)
{
long retval;
short arg1 ;
Py_BEGIN_ALLOW_THREADS
retval = qread( & arg1 );
Py_END_ALLOW_THREADS
{ PyObject *v = PyTuple_New( 2 );
if (v == NULL) return NULL;
PyTuple_SetItem(v, 0, mknewlongobject(retval));
PyTuple_SetItem(v, 1, mknewshortobject(arg1));
return v;
}
}
/*
varray -- an array of v.. calls.
The argument is an array (maybe list or tuple) of points.
Each point must be a tuple or list of coordinates (x, y, z).
The points may be 2- or 3-dimensional but must all have the
same dimension. Float and int values may be mixed however.
The points are always converted to 3D double precision points
by assuming z=0.0 if necessary (as indicated in the man page),
and for each point v3d() is called.
*/
static PyObject *
gl_varray(PyObject *self, PyObject *args)
{
PyObject *v, *w=NULL;
int i, n, width;
double vec[3];
PyObject * (*getitem)(PyObject *, int);
if (!PyArg_GetObject(args, 1, 0, &v))
return NULL;
if (PyList_Check(v)) {
n = PyList_Size(v);
getitem = PyList_GetItem;
}
else if (PyTuple_Check(v)) {
n = PyTuple_Size(v);
getitem = PyTuple_GetItem;
}
else {
PyErr_BadArgument();
return NULL;
}
if (n == 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (n > 0)
w = (*getitem)(v, 0);
width = 0;
if (w == NULL) {
}
else if (PyList_Check(w)) {
width = PyList_Size(w);
}
else if (PyTuple_Check(w)) {
width = PyTuple_Size(w);
}
switch (width) {
case 2:
vec[2] = 0.0;
/* Fall through */
case 3:
break;
default:
PyErr_BadArgument();
return NULL;
}
for (i = 0; i < n; i++) {
w = (*getitem)(v, i);
if (!PyArg_GetDoubleArray(w, 1, 0, width, vec))
return NULL;
v3d(vec);
}
Py_INCREF(Py_None);
return Py_None;
}
/*
vnarray, nvarray -- an array of n3f and v3f calls.
The argument is an array (list or tuple) of pairs of points and normals.
Each pair is a tuple (NOT a list) of a point and a normal for that point.
Each point or normal must be a tuple (NOT a list) of coordinates (x, y, z).
Three coordinates must be given. Float and int values may be mixed.
For each pair, n3f() is called for the normal, and then v3f() is called
for the vector.
vnarray and nvarray differ only in the order of the vector and normal in
the pair: vnarray expects (v, n) while nvarray expects (n, v).
*/
static PyObject *gen_nvarray(); /* Forward */
static PyObject *
gl_nvarray(PyObject *self, PyObject *args)
{
return gen_nvarray(args, 0);
}
static PyObject *
gl_vnarray(PyObject *self, PyObject *args)
{
return gen_nvarray(args, 1);
}
/* Generic, internal version of {nv,nv}array: inorm indicates the
argument order, 0: normal first, 1: vector first. */
static PyObject *
gen_nvarray(PyObject *args, int inorm)
{
PyObject *v, *w, *wnorm, *wvec;
int i, n;
float norm[3], vec[3];
PyObject * (*getitem)(PyObject *, int);
if (!PyArg_GetObject(args, 1, 0, &v))
return NULL;
if (PyList_Check(v)) {
n = PyList_Size(v);
getitem = PyList_GetItem;
}
else if (PyTuple_Check(v)) {
n = PyTuple_Size(v);
getitem = PyTuple_GetItem;
}
else {
PyErr_BadArgument();
return NULL;
}
for (i = 0; i < n; i++) {
w = (*getitem)(v, i);
if (!PyTuple_Check(w) || PyTuple_Size(w) != 2) {
PyErr_BadArgument();
return NULL;
}
wnorm = PyTuple_GetItem(w, inorm);
wvec = PyTuple_GetItem(w, 1 - inorm);
if (!PyArg_GetFloatArray(wnorm, 1, 0, 3, norm) ||
!PyArg_GetFloatArray(wvec, 1, 0, 3, vec))
return NULL;
n3f(norm);
v3f(vec);
}
Py_INCREF(Py_None);
return Py_None;
}
/* nurbssurface(s_knots[], t_knots[], ctl[][], s_order, t_order, type).
The dimensions of ctl[] are computed as follows:
[len(s_knots) - s_order], [len(t_knots) - t_order]
*/
static PyObject *
gl_nurbssurface(PyObject *self, PyObject *args)
{
long arg1 ;
double * arg2 ;
long arg3 ;
double * arg4 ;
double *arg5 ;
long arg6 ;
long arg7 ;
long arg8 ;
long ncoords;
long s_byte_stride, t_byte_stride;
long s_nctl, t_nctl;
long s, t;
PyObject *v, *w, *pt;
double *pnext;
if (!PyArg_GetLongArraySize(args, 6, 0, &arg1))
return NULL;
if ((arg2 = PyMem_NEW(double, arg1 )) == NULL) {
return PyErr_NoMemory();
}
if (!PyArg_GetDoubleArray(args, 6, 0, arg1 , arg2))
return NULL;
if (!PyArg_GetLongArraySize(args, 6, 1, &arg3))
return NULL;
if ((arg4 = PyMem_NEW(double, arg3 )) == NULL) {
return PyErr_NoMemory();
}
if (!PyArg_GetDoubleArray(args, 6, 1, arg3 , arg4))
return NULL;
if (!PyArg_GetLong(args, 6, 3, &arg6))
return NULL;
if (!PyArg_GetLong(args, 6, 4, &arg7))
return NULL;
if (!PyArg_GetLong(args, 6, 5, &arg8))
return NULL;
if (arg8 == N_XYZ)
ncoords = 3;
else if (arg8 == N_XYZW)
ncoords = 4;
else {
PyErr_BadArgument();
return NULL;
}
s_nctl = arg1 - arg6;
t_nctl = arg3 - arg7;
if (!PyArg_GetObject(args, 6, 2, &v))
return NULL;
if (!PyList_Check(v) || PyList_Size(v) != s_nctl) {
PyErr_BadArgument();
return NULL;
}
if ((arg5 = PyMem_NEW(double, s_nctl*t_nctl*ncoords )) == NULL) {
return PyErr_NoMemory();
}
pnext = arg5;
for (s = 0; s < s_nctl; s++) {
w = PyList_GetItem(v, s);
if (w == NULL || !PyList_Check(w) ||
PyList_Size(w) != t_nctl) {
PyErr_BadArgument();
return NULL;
}
for (t = 0; t < t_nctl; t++) {
pt = PyList_GetItem(w, t);
if (!PyArg_GetDoubleArray(pt, 1, 0, ncoords, pnext))
return NULL;
pnext += ncoords;
}
}
s_byte_stride = sizeof(double) * ncoords;
t_byte_stride = s_byte_stride * s_nctl;
nurbssurface( arg1 , arg2 , arg3 , arg4 ,
s_byte_stride , t_byte_stride , arg5 , arg6 , arg7 , arg8 );
PyMem_DEL(arg2);
PyMem_DEL(arg4);
PyMem_DEL(arg5);
Py_INCREF(Py_None);
return Py_None;
}
/* nurbscurve(knots, ctlpoints, order, type).
The length of ctlpoints is len(knots)-order. */
static PyObject *
gl_nurbscurve(PyObject *self, PyObject *args)
{
long arg1 ;
double * arg2 ;
long arg3 ;
double * arg4 ;
long arg5 ;
long arg6 ;
int ncoords, npoints;
int i;
PyObject *v;
double *pnext;
if (!PyArg_GetLongArraySize(args, 4, 0, &arg1))
return NULL;
if ((arg2 = PyMem_NEW(double, arg1 )) == NULL) {
return PyErr_NoMemory();
}
if (!PyArg_GetDoubleArray(args, 4, 0, arg1 , arg2))
return NULL;
if (!PyArg_GetLong(args, 4, 2, &arg5))
return NULL;
if (!PyArg_GetLong(args, 4, 3, &arg6))
return NULL;
if (arg6 == N_ST)
ncoords = 2;
else if (arg6 == N_STW)
ncoords = 3;
else {
PyErr_BadArgument();
return NULL;
}
npoints = arg1 - arg5;
if (!PyArg_GetObject(args, 4, 1, &v))
return NULL;
if (!PyList_Check(v) || PyList_Size(v) != npoints) {
PyErr_BadArgument();
return NULL;
}
if ((arg4 = PyMem_NEW(double, npoints*ncoords )) == NULL) {
return PyErr_NoMemory();
}
pnext = arg4;
for (i = 0; i < npoints; i++) {
if (!PyArg_GetDoubleArray(PyList_GetItem(v, i), 1, 0, ncoords, pnext))
return NULL;
pnext += ncoords;
}
arg3 = (sizeof(double)) * ncoords;
nurbscurve( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
PyMem_DEL(arg2);
PyMem_DEL(arg4);
Py_INCREF(Py_None);
return Py_None;
}
/* pwlcurve(points, type).
Points is a list of points. Type must be N_ST. */
static PyObject *
gl_pwlcurve(PyObject *self, PyObject *args)
{
PyObject *v;
long type;
double *data, *pnext;
long npoints, ncoords;
int i;
if (!PyArg_GetObject(args, 2, 0, &v))
return NULL;
if (!PyArg_GetLong(args, 2, 1, &type))
return NULL;
if (!PyList_Check(v)) {
PyErr_BadArgument();
return NULL;
}
npoints = PyList_Size(v);
if (type == N_ST)
ncoords = 2;
else {
PyErr_BadArgument();
return NULL;
}
if ((data = PyMem_NEW(double, npoints*ncoords)) == NULL) {
return PyErr_NoMemory();
}
pnext = data;
for (i = 0; i < npoints; i++) {
if (!PyArg_GetDoubleArray(PyList_GetItem(v, i), 1, 0, ncoords, pnext))
return NULL;
pnext += ncoords;
}
pwlcurve(npoints, data, sizeof(double)*ncoords, type);
PyMem_DEL(data);
Py_INCREF(Py_None);
return Py_None;
}
/* Picking and Selecting */
static short *pickbuffer = NULL;
static long pickbuffersize;
static PyObject *
pick_select(PyObject *args, void (*func)())
{
if (!PyArg_GetLong(args, 1, 0, &pickbuffersize))
return NULL;
if (pickbuffer != NULL) {
PyErr_SetString(PyExc_RuntimeError,
"pick/gselect: already picking/selecting");
return NULL;
}
if ((pickbuffer = PyMem_NEW(short, pickbuffersize)) == NULL) {
return PyErr_NoMemory();
}
(*func)(pickbuffer, pickbuffersize);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
endpick_select(PyObject *args, long (*func)())
{
PyObject *v, *w;
int i, nhits, n;
if (!PyArg_NoArgs(args))
return NULL;
if (pickbuffer == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"endpick/endselect: not in pick/select mode");
return NULL;
}
nhits = (*func)(pickbuffer);
if (nhits < 0) {
nhits = -nhits; /* How to report buffer overflow otherwise? */
}
/* Scan the buffer to see how many integers */
n = 0;
for (; nhits > 0; nhits--) {
n += 1 + pickbuffer[n];
}
v = PyList_New(n);
if (v == NULL)
return NULL;
/* XXX Could do it nicer and interpret the data structure here,
returning a list of lists. But this can be done in Python... */
for (i = 0; i < n; i++) {
w = PyInt_FromLong((long)pickbuffer[i]);
if (w == NULL) {
Py_DECREF(v);
return NULL;
}
PyList_SetItem(v, i, w);
}
PyMem_DEL(pickbuffer);
pickbuffer = NULL;
return v;
}
extern void pick(), gselect();
extern long endpick(), endselect();
static PyObject *gl_pick(PyObject *self, PyObject *args)
{
return pick_select(args, pick);
}
static PyObject *gl_endpick(PyObject *self, PyObject *args)
{
return endpick_select(args, endpick);
}
static PyObject *gl_gselect(PyObject *self, PyObject *args)
{
return pick_select(args, gselect);
}
static PyObject *gl_endselect(PyObject *self, PyObject *args)
{
return endpick_select(args, endselect);
}
/* XXX The generator botches this one. Here's a quick hack to fix it. */
/* XXX The generator botches this one. Here's a quick hack to fix it. */
static PyObject *
gl_getmatrix(PyObject *self, PyObject *args)
{
Matrix arg1;
PyObject *v, *w;
int i, j;
getmatrix( arg1 );
v = PyList_New(16);
if (v == NULL) {
return PyErr_NoMemory();
}
for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) {
w = mknewfloatobject(arg1[i][j]);
if (w == NULL) {
Py_DECREF(v);
return NULL;
}
PyList_SetItem(v, i*4+j, w);
}
return v;
}
/* Here's an alternate version that returns a 4x4 matrix instead of
a vector. Unfortunately it is incompatible with loadmatrix and
multmatrix... */
static PyObject *
gl_altgetmatrix(PyObject *self, PyObject *args)
{
Matrix arg1;
PyObject *v, *w;
int i, j;
getmatrix( arg1 );
v = PyList_New(4);
if (v == NULL) {
return NULL;
}
for (i = 0; i < 4; i++) {
w = PyList_New(4);
if (w == NULL) {
Py_DECREF(v);
return NULL;
}
PyList_SetItem(v, i, w);
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
w = mknewfloatobject(arg1[i][j]);
if (w == NULL) {
Py_DECREF(v);
return NULL;
}
PyList_SetItem(PyList_GetItem(v, i), j, w);
}
}
return v;
}
static PyObject *
gl_lrectwrite(PyObject *self, PyObject *args)
{
short x1 ;
short y1 ;
short x2 ;
short y2 ;
string parray ;
PyObject *s;
#if 0
int pixcount;
#endif
if (!PyArg_GetShort(args, 5, 0, &x1))
return NULL;
if (!PyArg_GetShort(args, 5, 1, &y1))
return NULL;
if (!PyArg_GetShort(args, 5, 2, &x2))
return NULL;
if (!PyArg_GetShort(args, 5, 3, &y2))
return NULL;
if (!PyArg_GetString(args, 5, 4, &parray))
return NULL;
if (!PyArg_GetObject(args, 5, 4, &s))
return NULL;
#if 0
/* Don't check this, it breaks experiments with pixmode(PM_SIZE, ...) */
pixcount = (long)(x2+1-x1) * (long)(y2+1-y1);
if (!PyString_Check(s) || PyString_Size(s) != pixcount*sizeof(long)) {
PyErr_SetString(PyExc_RuntimeError,
"string arg to lrectwrite has wrong size");
return NULL;
}
#endif
lrectwrite( x1 , y1 , x2 , y2 , (unsigned long *) parray );
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
gl_lrectread(PyObject *self, PyObject *args)
{
short x1 ;
short y1 ;
short x2 ;
short y2 ;
PyObject *parray;
int pixcount;
if (!PyArg_GetShort(args, 4, 0, &x1))
return NULL;
if (!PyArg_GetShort(args, 4, 1, &y1))
return NULL;
if (!PyArg_GetShort(args, 4, 2, &x2))
return NULL;
if (!PyArg_GetShort(args, 4, 3, &y2))
return NULL;
pixcount = (long)(x2+1-x1) * (long)(y2+1-y1);
parray = PyString_FromStringAndSize((char *)NULL, pixcount*sizeof(long));
if (parray == NULL)
return NULL; /* No memory */
lrectread(x1, y1, x2, y2, (unsigned long *) PyString_AsString(parray));
return parray;
}
static PyObject *
gl_readdisplay(PyObject *self, PyObject *args)
{
short x1, y1, x2, y2;
unsigned long *parray, hints;
long size, size_ret;
PyObject *rv;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -