| Line | Revision | Contents |
| 1 | 1 | """VPython-style curve object, similar to an IndexedLineSet""" |
| 2 | from OpenGL.GL import * |
|
| 3 | from OpenGLContext import displaylist |
|
| 4 | 139 | from vrml import cache |
| 5 | 1 | from vrml.vrml97 import nodetypes |
| 6 | from vrml import node, field, protofunctions |
|
| 7 | from OpenGLContext.arrays import concatenate, asarray |
|
| 8 | ||
| 9 | class VPCurve( nodetypes.Rendering, nodetypes.Children, node.Node ): |
|
| 10 | """VPython-style curve object, similar to an IndexedLineSet""" |
|
| 11 | color = field.newField( 'color', 'MFColor', 1, [(1,1,1),]) |
|
| 12 | pos = field.newField( 'pos', 'MFVec3f', 1, list) |
|
| 13 | radius = field.newField( 'radius', 'SFFloat', 1, 0.0) |
|
| 14 | def append( self, pos=None, color=None, **arguments ): |
|
| 15 | """Append a single point to the curve""" |
|
| 16 | def merge( main, partials, default ): |
|
| 17 | if main is not None: |
|
| 18 | return main |
|
| 19 | result = [] |
|
| 20 | for a,b in zip(partials, default): |
|
| 21 | if a is None: |
|
| 22 | result.append( b ) |
|
| 23 | else: |
|
| 24 | result.append( a ) |
|
| 25 | return result |
|
| 26 | if len(self.color): |
|
| 27 | last = self.color[-1] |
|
| 28 | else: |
|
| 29 | last = (1,1,1) |
|
| 30 | color = merge( |
|
| 31 | color, |
|
| 32 | [arguments.get(n) for n in ('red','green','blue')], |
|
| 33 | last |
|
| 34 | ) |
|
| 35 | if len( self.pos ): |
|
| 36 | last = self.pos[-1] |
|
| 37 | else: |
|
| 38 | last = (0,0,0) |
|
| 39 | pos = merge( |
|
| 40 | pos, |
|
| 41 | [arguments.get(n) for n in ('x','y','z')], |
|
| 42 | last |
|
| 43 | ) |
|
| 44 | positions = self.pos |
|
| 45 | colors = self.color |
|
| 46 | positions = concatenate( (positions, (pos,))) |
|
| 47 | colors = concatenate( (colors, (color,))) |
|
| 48 | self.color = colors |
|
| 49 | self.pos = positions |
|
| 50 | def Render (self, mode = None): |
|
| 51 | """Do run-time rendering of the Shape for the given mode""" |
|
| 52 | if mode.visible: |
|
| 53 | dl = mode.cache.getData(self) |
|
| 54 | if not dl: |
|
| 55 | dl = self.compile(mode=mode) |
|
| 56 | if dl is None: |
|
| 57 | return None |
|
| 58 | # okay, is now a (cached) display list object |
|
| 59 | dl() |
|
| 60 | return None |
|
| 61 | def compile( self, mode=None ): |
|
| 62 | """Compile the VPCurve into a display-list |
|
| 63 | """ |
|
| 64 | 49 | # This code is not OpenGL 3.1 compatible |
| 65 | 1 | if self.pos.any(): |
| 66 | dl = displaylist.DisplayList() |
|
| 67 | #XXX should do sanity checks here... |
|
| 68 | dl.start() |
|
| 69 | try: |
|
| 70 | pos = self.pos |
|
| 71 | color = self.color |
|
| 72 | colorLen = len(color) |
|
| 73 | killThickness = 0 |
|
| 74 | if self.radius: |
|
| 75 | glLineWidth( self.radius*2 ) |
|
| 76 | killThickness = 1 |
|
| 77 | try: |
|
| 78 | |
|
| 79 | glEnable( GL_COLOR_MATERIAL ) |
|
| 80 | try: |
|
| 81 | glBegin( GL_LINE_STRIP ) |
|
| 82 | try: |
|
| 83 | lastColor = None |
|
| 84 | for index in range(len(pos)): |
|
| 85 | point = pos[index] |
|
| 86 | if index < colorLen: |
|
| 87 | col = tuple(color[index]) |
|
| 88 | if col != lastColor: |
|
| 89 | glColor3dv( col ) |
|
| 90 | lastColor = col |
|
| 91 | glVertex3dv(point) |
|
| 92 | finally: |
|
| 93 | glEnd() |
|
| 94 | finally: |
|
| 95 | glDisable( GL_COLOR_MATERIAL ) |
|
| 96 | finally: |
|
| 97 | if killThickness: |
|
| 98 | glLineWidth( 1 ) |
|
| 99 | finally: |
|
| 100 | dl.end() |
|
| 101 | holder = mode.cache.holder(self, dl) |
|
| 102 | for field in protofunctions.getFields( self ): |
|
| 103 | # change to any field requires a recompile |
|
| 104 | holder.depend( self, field ) |
|
| 105 | return dl |
|
| 106 | return None |
|
| 107 | |
Loggerhead 1.10 is a web-based interface for Bazaar branches