def test_nurbs_raw_arrays( self ): """Test nurbs rendering using raw API calls with arrays""" from OpenGL.raw import GLU import numpy knots = numpy.array( ( 0,0,0,0,1,1,1,1 ), 'f' ) ctlpoints = numpy.array( [[[-3., -3., -3.], [-3., -1., -3.], [-3., 1., -3.], [-3., 3., -3.]], [[-1., -3., -3.], [-1., -1., 3.], [-1., 1., 3.], [-1., 3., -3.]], [[ 1., -3., -3.], [ 1., -1., 3.], [ 1., 1., 3.], [ 1., 3., -3.]], [[ 3., -3., -3.], [ 3., -1., -3.], [ 3., 1., -3.], [ 3., 3., -3.]]], 'f' ) theNurb = GLU.gluNewNurbsRenderer() GLU.gluBeginSurface(theNurb) GLU.gluNurbsSurface( theNurb, 8, knots, 8, knots, 4 * 3, 3, ctlpoints , 4, 4, GL_MAP2_VERTEX_3 ) GLU.gluEndSurface(theNurb)
def test_nurbs_raw( self ): """Test nurbs rendering using raw API calls""" from OpenGL.raw import GLU knots = (constants.GLfloat* 8) ( 0,0,0,0,1,1,1,1 ) ctlpoints = (constants.GLfloat*(3*4*4))( -3., -3., -3., -3., -1., -3., -3., 1., -3., -3., 3., -3., -1., -3., -3., -1., -1., 3., -1., 1., 3., -1., 3., -3., 1., -3., -3., 1., -1., 3., 1., 1., 3., 1., 3., -3., 3., -3., -3., 3., -1., -3., 3., 1., -3., 3., 3., -3. ) theNurb = gluNewNurbsRenderer() GLU.gluBeginSurface(theNurb) GLU.gluNurbsSurface( theNurb, 8, ctypes.byref(knots), 8, ctypes.byref(knots), 4 * 3, 3, ctypes.byref( ctlpoints ), 4, 4, GL_MAP2_VERTEX_3 ) GLU.gluEndSurface(theNurb)
def test_nurbs(self): """Test nurbs rendering""" def buildControlPoints(): ctlpoints = np.zeros((4, 4, 3), "f") for u in range(4): for v in range(4): ctlpoints[u][v][0] = 2.0 * (u - 1.5) ctlpoints[u][v][1] = 2.0 * (v - 1.5) if (u == 1 or u == 2) and (v == 1 or v == 2): ctlpoints[u][v][2] = 3.0 else: ctlpoints[u][v][2] = -3.0 return ctlpoints controlPoints = buildControlPoints() theNurb = GLU.gluNewNurbsRenderer() GLU.gluNurbsProperty(theNurb, GLU.GLU_SAMPLING_TOLERANCE, 25.0) GLU.gluNurbsProperty(theNurb, GLU.GLU_DISPLAY_MODE, GLU.GLU_FILL) knots = np.array([0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0], "f") glPushMatrix() try: glRotatef(330.0, 1., 0., 0.) glScalef(0.5, 0.5, 0.5) GLU.gluBeginSurface(theNurb) try: GLU.gluNurbsSurface(theNurb, knots, knots, controlPoints, GL_MAP2_VERTEX_3) finally: GLU.gluEndSurface(theNurb) finally: glPopMatrix()
def drawNurbsSurfaces(x,sknots,tknots,color=None,alpha=1.0,normals='auto',samplingTolerance=20.0): """Draw a collection of Nurbs surfaces. x: (ns,nt,ndim) or (nsurf,ns,nt,ndim) float array: (ns,nt) shaped control points array, specifying either a single surface or nsurf surfaces defined by the same number of control points. ndim can be 3 or 4. If 4, the 4-th coordinate is interpreted as a weight for that point. sknots: (nsk) or (nsurf,nsk) float array: knot vector, containing the parameter values to be used in the s direction of the surface. Remark that nsk must be larger than ns. The order of the surface in s-direction is nsk-ns and the degree of the s-curves is nsk-ns-1. If a single sknot vector is given, the same is used for all surfaces. Otherwise, the number of sknot vectors must match the number of nurbs surfaces. tknots: (ntk) or (nsurf,ntk) float array: knot vector, containing the parameter values to be used in the t direction of the surface. Remark that ntk must be larger than nt. The order of the surface in t-direction is ntk-nt and the degree of the t-curves is ntk-nt-1. If a single sknot vector is given, the same is used for all surfaces. Otherwise, the number of sknot vectors must match the number of nurbs surfaces. If color is given it is an (nsurf,3) array of RGB values. """ import timer t = timer.Timer() ns,nt,ndim = x.shape[-3:] nsk = asarray(sknots).shape[-1] ntk = asarray(tknots).shape[-1] sorder = nsk-ns torder = ntk-nt if sorder > 8 or torder > 8: utils.warn('Nurbs surfaces of degree > 7 can currently not be drawn! You can approximate the surface by a lower order surface.') return if x.ndim == 3: x = x.reshape(-1,ns,nt,ndim) if color is not None and color.ndim == 3: color = color.reshape(-1,ns,nt,color.shape[-1]) if color is not None: pf.debug('Coords shape: %s' % str(x.shape),pf.DEBUG.DRAW) pf.debug('Color shape: %s' % str(color.shape),pf.DEBUG.DRAW) if color.ndim == 1: pf.debug('Single color',pf.DEBUG.DRAW) elif color.ndim == 2 and color.shape[0] == x.shape[0]: pf.debug('Element color: %s' % color.shape[0],pf.DEBUG.DRAW) elif color.shape == x.shape[:-1] + (3,): pf.debug('Vertex color: %s' % str(color.shape[:-1]),pf.DEBUG.DRAW) else: raise ValueError,"Number of colors (%s) should equal 1 or the number of faces(%s) or the number of faces * number of vertices" % (color.shape[0],x.shape[0]) pf.debug("Color shape = %s" % str(color.shape),pf.DEBUG.DRAW) if color.shape[-1] not in (3,4): raise ValueError,"Expected 3 or 4 color components" if normals == 'auto': GL.glEnable(GL.GL_AUTO_NORMAL) else: GL.glDisable(GL.GL_AUTO_NORMAL) # The following uses: # x: (nsurf,ns,nt,4) # sknots: (nsknots) or (nsurf,nsknots) # tknots: (ntknots) or (nsurf,ntknots) # color: None or (4) or (nsurf,4) or (nsurf,ns,nt,4) # samplingTolerance if pf.options.fastnurbs: alpha=0.5 x = x.astype(float32) sknots = sknots.astype(float32) tknots = tknots.astype(float32) if color is not None: color = color.astype(float32) if color.shape[-1] == 3: # gluNurbs always wants 4 colors color = growAxis(color,3,axis=-1,fill=alpha) nb = drawgl.draw_nurbs_surfaces(x,sknots,tknots,color,alpha,samplingTolerance) else: nurb = GLU.gluNewNurbsRenderer() if not nurb: raise RuntimeError,"Could not create a new NURBS renderer" GLU.gluNurbsProperty(nurb,GLU.GLU_SAMPLING_TOLERANCE,samplingTolerance) mode = {3:GL.GL_MAP2_VERTEX_3, 4:GL.GL_MAP2_VERTEX_4}[ndim] if color is not None and color.ndim == 1: # Handle single color pf.debug('Set single color: OK',pf.DEBUG.DRAW) glColor(color) color = None si = sknots ti = tknots for i,xi in enumerate(x): if color is not None and color.ndim == 2: # Handle element color glColor(color[i]) if sknots.ndim > 1: si = sknots[i] if tknots.ndim > 1: ti = tknots[i] GLU.gluBeginSurface(nurb) if color is not None and color.ndim == 4: # Handle vertex color ci = color[i] if ci.shape[-1] == 3: # gluNurbs always wants 4 colors ci = growAxis(ci,1,axis=-1,fill=alpha) GLU.gluNurbsSurface(nurb,si,ti,ci,GL.GL_MAP2_COLOR_4) GLU.gluNurbsSurface(nurb,si,ti,xi,mode) GLU.gluEndSurface(nurb) GLU.gluDeleteNurbsRenderer(nurb) print("drawNurbsSurfaces: %s seconds" % t.seconds())
def drawNurbsSurfaces(x, sknots, tknots, color=None, normals="auto", samplingTolerance=10.0): """Draw a collection of Nurbs surfaces. x: (ns,nt,ndim) or (nsurf,ns,nt,ndim) float array: (ns,nt) shaped control points array, specifying either a single surface or nsurf surfaces defined by the same number of control points. ndim can be 3 or 4. If 4, the 4-th coordinate is interpreted as a weight for that point. sknots: (nsk) or (nsurf,nsk) float array: knot vector, containing the parameter values to be used in the s direction of the surface. Remark that nsk must be larger than ns. The order of the surface in s-direction is nsk-ns and the degree of the s-curves is nsk-ns-1. If a single sknot vector is given, the same is used for all surfaces. Otherwise, the number of sknot vectors must match the number of nurbs surfaces. tknots: (ntk) or (nsurf,ntk) float array: knot vector, containing the parameter values to be used in the t direction of the surface. Remark that ntk must be larger than nt. The order of the surface in t-direction is ntk-nt and the degree of the t-curves is ntk-nt-1. If a single sknot vector is given, the same is used for all surfaces. Otherwise, the number of sknot vectors must match the number of nurbs surfaces. If color is given it is an (nsurf,3) array of RGB values. """ if normals == "auto": GL.glEnable(GL.GL_AUTO_NORMAL) else: GL.glDisable(GL.GL_AUTO_NORMAL) nurb = GLU.gluNewNurbsRenderer() if not nurb: raise RuntimeError, "Could not create a new NURBS renderer" ns, nt, ndim = x.shape[-3:] nsk = asarray(sknots).shape[-1] ntk = asarray(tknots).shape[-1] sorder = nsk - ns torder = ntk - nt if sorder > 8 or torder > 8: import warnings warnings.warn( "Nurbs surfaces of degree > 7 can currently not be drawn! You can approximate the surface by a lower order surface." ) return mode = {3: GL.GL_MAP2_VERTEX_3, 4: GL.GL_MAP2_VERTEX_4}[ndim] # x = x.reshape(-1,ns,nt,ndim) if color is not None: pf.debug("Color shape: %s" % str(color.shape)) pf.debug("Coords shape: %s" % str(x.shape)) # color = color.reshape(-1,3) if color.ndim == 1: # Handle single color pf.debug("Set single color: OK") GL.glColor3fv(color) color = None elif color.ndim == 2 and color.shape[0] == x.shape[0]: pf.debug("Element color: %s" % color.shape[0]) elif color.shape == x.shape[:-1] + (3,): pf.debug("Vertex color: %s" % str(color.shape[:-1])) else: raise ValueError, "Number of colors (%s) should equal 1 or the number of faces(%s) or the number of faces * number of vertices" % ( color.shape[0], x.shape[0], ) si = sknots ti = tknots GLU.gluNurbsProperty(nurb, GLU.GLU_SAMPLING_TOLERANCE, samplingTolerance) if x.ndim == 3: x = x.reshape(-1, ns, nt, ndim) if color is not None and color.ndim == 3: from plugins.nurbs import Coords4 color = Coords4(color) color = color.reshape(-1, ns, nt, ndim) for i, xi in enumerate(x): if color is not None and color.ndim == 2: # Handle element color pf.debug("Set element color: OK") GL.glColor3fv(color[i]) if sknots.ndim > 1: si = sknots[i] if tknots.ndim > 1: ti = tknots[i] GLU.gluBeginSurface(nurb) if color is not None and color.ndim == 4: GLU.gluNurbsSurface(nurb, si, ti, color[i], GL.GL_MAP2_COLOR_4) GLU.gluNurbsSurface(nurb, si, ti, xi, mode) GLU.gluEndSurface(nurb)
def draw(self): glu.gluBeginSurface(self.glID) glu.gluNurbsSurface(self.glID, self.uKnot, self.vKnot, self.controlPoints, self.target) glu.gluEndSurface(self.glID)