jexzeb's picture
Upload folder using huggingface_hub
b6068b4
"""Wrapper/Implementation of the GLU tessellator objects for PyOpenGL"""
from OpenGL.raw import GLU as _simple
from OpenGL.raw.GL.VERSION import GL_1_1
from OpenGL.platform import createBaseFunction
from OpenGL.GLU import glustruct
from OpenGL import arrays, wrapper
from OpenGL.platform import PLATFORM
GLU = PLATFORM.GLU
from OpenGL.lazywrapper import lazy as _lazy
import ctypes
class GLUtesselator(glustruct.GLUStruct, _simple.GLUtesselator):
"""Implementation class for GLUTessellator structures in OpenGL-ctypes"""
FUNCTION_TYPE = PLATFORM.functionTypeFor(PLATFORM.GLU)
CALLBACK_TYPES = {
# mapping from "which" GLU enumeration to a ctypes function type
_simple.GLU_TESS_BEGIN: FUNCTION_TYPE(None, _simple.GLenum),
_simple.GLU_TESS_BEGIN_DATA: FUNCTION_TYPE(
None, _simple.GLenum, ctypes.c_void_p
),
_simple.GLU_TESS_EDGE_FLAG: FUNCTION_TYPE(None, _simple.GLboolean),
_simple.GLU_TESS_EDGE_FLAG_DATA: FUNCTION_TYPE(
None, _simple.GLboolean, ctypes.c_void_p
),
_simple.GLU_TESS_VERTEX: FUNCTION_TYPE(None, ctypes.c_void_p),
_simple.GLU_TESS_VERTEX_DATA: FUNCTION_TYPE(
None, ctypes.c_void_p, ctypes.c_void_p
),
_simple.GLU_TESS_END: FUNCTION_TYPE(None),
_simple.GLU_TESS_END_DATA: FUNCTION_TYPE(None, ctypes.c_void_p),
_simple.GLU_TESS_COMBINE: FUNCTION_TYPE(
None,
ctypes.POINTER(_simple.GLdouble),
ctypes.POINTER(ctypes.c_void_p),
ctypes.POINTER(_simple.GLfloat),
ctypes.POINTER(ctypes.c_void_p),
),
_simple.GLU_TESS_COMBINE_DATA: FUNCTION_TYPE(
None,
ctypes.POINTER(_simple.GLdouble),
ctypes.POINTER(ctypes.c_void_p),
ctypes.POINTER(_simple.GLfloat),
ctypes.POINTER(ctypes.c_void_p),
ctypes.c_void_p,
),
_simple.GLU_TESS_ERROR: FUNCTION_TYPE(None, _simple.GLenum),
_simple.GLU_TESS_ERROR_DATA: FUNCTION_TYPE(
None, _simple.GLenum, ctypes.c_void_p
),
_simple.GLU_ERROR: FUNCTION_TYPE(None, _simple.GLenum),
}
WRAPPER_METHODS = {
_simple.GLU_TESS_BEGIN_DATA: 'dataWrapper',
_simple.GLU_TESS_EDGE_FLAG_DATA: 'dataWrapper',
_simple.GLU_TESS_VERTEX: 'vertexWrapper',
_simple.GLU_TESS_VERTEX_DATA: 'vertexWrapper',
_simple.GLU_TESS_END_DATA: 'dataWrapper',
_simple.GLU_TESS_COMBINE: 'combineWrapper',
_simple.GLU_TESS_COMBINE_DATA: 'combineWrapper',
_simple.GLU_TESS_ERROR_DATA: 'dataWrapper',
}
def gluTessVertex(self, location, data=None):
"""Add a vertex to this tessellator, storing data for later lookup"""
vertexCache = getattr(self, 'vertexCache', None)
if vertexCache is None:
self.vertexCache = []
vertexCache = self.vertexCache
location = arrays.GLdoubleArray.asArray(location, GL_1_1.GL_DOUBLE)
if arrays.GLdoubleArray.arraySize(location) != 3:
raise ValueError(
"""Require 3 doubles for array location, got: %s""" % (location,)
)
oorValue = self.noteObject(data)
vp = ctypes.c_void_p(oorValue)
self.vertexCache.append(location)
return gluTessVertexBase(self, location, vp)
def gluTessBeginPolygon(self, data):
"""Note the object pointer to return it as a Python object"""
return _simple.gluTessBeginPolygon(self, ctypes.c_void_p(self.noteObject(data)))
def combineWrapper(self, function):
"""Wrap a Python function with ctypes-compatible wrapper for combine callback
For a Python combine callback, the signature looks like this:
def combine(
GLdouble coords[3],
void *vertex_data[4],
GLfloat weight[4]
):
return data
While the C signature looks like this:
void combine(
GLdouble coords[3],
void *vertex_data[4],
GLfloat weight[4],
void **outData
)
"""
if (function is not None) and (not hasattr(function, '__call__')):
raise TypeError("""Require a callable callback, got: %s""" % (function,))
def wrap(coords, vertex_data, weight, outData, *args):
"""The run-time wrapper around the function"""
coords = self.ptrAsArray(coords, 3, arrays.GLdoubleArray)
weight = self.ptrAsArray(weight, 4, arrays.GLfloatArray)
# find the original python objects for vertex data
vertex_data = [self.originalObject(vertex_data[i]) for i in range(4)]
args = tuple([self.originalObject(x) for x in args])
try:
result = function(coords, vertex_data, weight, *args)
except Exception as err:
raise err.__class__(
"""Failure during combine callback %r with args( %s,%s,%s,*%s):\n%s"""
% (
function,
coords,
vertex_data,
weight,
args,
str(err),
)
)
outP = ctypes.c_void_p(self.noteObject(result))
if outData:
outData[0] = outP
else:
raise RuntimeError("Null outData passed to callback")
return None
return wrap
def dataWrapper(self, function):
"""Wrap a function which only has the one data-pointer as last arg"""
if (function is not None) and (not hasattr(function, '__call__')):
raise TypeError("""Require a callable callback, got: %s""" % (function,))
def wrap(*args):
"""Just return the original object for polygon_data"""
args = args[:-1] + (self.originalObject(args[-1]),)
try:
return function(*args)
except Exception as err:
err.args += (function, args)
raise
return wrap
def dataWrapper2(self, function):
"""Wrap a function which has two data-pointers as last args"""
if (function is not None) and (not hasattr(function, '__call__')):
raise TypeError("""Require a callable callback, got: %s""" % (function,))
def wrap(*args):
"""Just return the original object for polygon_data"""
args = args[:-2] + (
self.originalObject(args[-2]),
self.originalObject(args[-1]),
)
try:
return function(*args)
except Exception as err:
err.args += (function, args)
raise
return wrap
def vertexWrapper(self, function):
"""Converts a vertex-pointer into an OOR vertex for processing"""
if (function is not None) and (not hasattr(function, '__call__')):
raise TypeError("""Require a callable callback, got: %s""" % (function,))
def wrap(vertex, data=None):
"""Just return the original object for polygon_data"""
vertex = self.originalObject(vertex)
try:
if data is not None:
data = self.originalObject(data)
return function(vertex, data)
else:
return function(vertex)
except Exception as err:
err.args += (function, (vertex, data))
raise
return wrap
c = funcType = None
GLUtesselator.CALLBACK_FUNCTION_REGISTRARS = dict(
[
(
c,
createBaseFunction(
'gluTessCallback',
dll=GLU,
resultType=None,
argTypes=[ctypes.POINTER(GLUtesselator), _simple.GLenum, funcType],
doc='gluTessCallback( POINTER(GLUtesselator)(tess), GLenum(which), _GLUfuncptr(CallBackFunc) ) -> None',
argNames=('tess', 'which', 'CallBackFunc'),
),
)
for (c, funcType) in GLUtesselator.CALLBACK_TYPES.items()
]
)
try:
del c, funcType
except NameError as err:
pass
def gluTessCallback(tess, which, function):
"""Set a given gluTessellator callback for the given tessellator"""
return tess.addCallback(which, function)
def gluTessBeginPolygon(tess, data):
"""Start definition of polygon in the tessellator"""
return tess.gluTessBeginPolygon(data)
def gluTessVertex(tess, location, data=None):
"""Add a vertex to the tessellator's current polygon"""
return tess.gluTessVertex(location, data)
# /usr/include/GL/glu.h 293
@_lazy(
createBaseFunction(
'gluNewTess',
dll=GLU,
resultType=ctypes.POINTER(GLUtesselator),
doc='gluNewTess( ) -> POINTER(GLUtesselator)',
)
)
def gluNewTess(baseFunction):
"""Get a new tessellator object (just unpacks the pointer for you)"""
return baseFunction()[0]
@_lazy(_simple.gluGetTessProperty)
def gluGetTessProperty(baseFunction, tess, which, data=None):
"""Retrieve single double for a tessellator property"""
if data is None:
data = _simple.GLdouble(0.0)
baseFunction(tess, which, data)
return data.value
else:
return baseFunction(tess, which, data)
gluTessVertexBase = wrapper.wrapper(_simple.gluTessVertex).setInputArraySize(
'location',
3,
)
__all__ = (
'gluNewTess',
'gluGetTessProperty',
'gluTessBeginPolygon',
'gluTessCallback',
'gluTessVertex',
)