root/trunk/RBRapier/RBRapier/Formats/SVG/RapierGeometry.py

Revision 734, 7.0 kB (checked in by sholloway, 4 years ago)

Added support for a precompile step

Line 
1 #!/usr/bin/env python
2 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 ##~ License
4 ##~
5 ##- The RuneBlade Foundation library is intended to ease some
6 ##- aspects of writing intricate Jabber, XML, and User Interface (wxPython, etc.)
7 ##- applications, while providing the flexibility to modularly change the
8 ##- architecture. Enjoy.
9 ##~
10 ##~ Copyright (C) 2002  TechGame Networks, LLC.
11 ##~
12 ##~ This library is free software; you can redistribute it and/or
13 ##~ modify it under the terms of the BSD style License as found in the
14 ##~ LICENSE file included with this distribution.
15 ##~
16 ##~ TechGame Networks, LLC can be reached at:
17 ##~ 3578 E. Hartsel Drive #211
18 ##~ Colorado Springs, Colorado, USA, 80920
19 ##~
20 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21
22 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 #~ Imports
24 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25
26 from OpenGL import GL
27 import Numeric
28
29 from RBRapier.Renderer.Geometry import VertexArrays
30 from RBRapier.Renderer.Geometry import ArrayTraversal
31 #from RBRapier.Renderer.View import Transformations as RenderTransformations
32
33 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
34 #~ Definitions
35 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
36
37 class GLGeometryBin(object):
38     maxcount = 65536
39
40     class GeometryBinFull(Exception): pass
41
42     def __init__(self):
43         self._offset = 0
44         self._pointslist = []
45         self._colorslist = []
46         self._primitives = []
47         self._traversals = []
48    
49     def __len__(self):
50         return self._offset
51
52     def AddData(self, points, colors):
53         assert len(points) == len(colors)
54         newoffset = self._offset + len(points)
55         if newoffset >= self.maxcount:
56             raise self.GeometryBinFull, 'Overflow of OpenGL indexable geometry'
57         self._pointslist.append(points)
58         self._colorslist.append(colors)
59
60         offset = self._offset
61         self._offset = newoffset
62         return offset
63
64     def AddTranversals(self, primitives, traversals, offset):
65         assert len(primitives) == len(traversals)
66         offset = Numeric.asarray(offset, Numeric.UInt16)
67         traversals = [Numeric.asarray(traversal, Numeric.UInt16) + offset for traversal in traversals]
68         self._primitives.extend(primitives)
69         self._traversals.extend(traversals)
70    
71     def Commit(self, target):
72         if self and target is not None:
73             points = Numeric.concatenate(self._pointslist)
74             vertices = VertexArrays.VertexArray(points, points.typecode)
75             target.AddRenderable(vertices, False)
76
77             colors = Numeric.concatenate(self._colorslist)
78             colors = VertexArrays.ColorArray(colors, colors.typecode)
79             target.AddRenderable(colors, False)
80
81             traversals = ArrayTraversal.IndexedCollectionTraversalRaw(self._primitives, self._traversals)
82             target.AddRenderable(traversals, False)
83
84 class BaseGeometryCollector(object):
85     def __init__(self, groupcount=1, geometrycount=1):
86         self._progress = [0,0]
87         self._total = [groupcount, geometrycount]
88
89     def AddGroupProgress(self):
90         self._progress[0] += 1
91     def AddGeometryProgress(self):
92         self._progress[1] += 1
93
94     def Progress(self):
95         items = float(self._progress[0])/self._total[0]
96         groups = float(self._progress[1])/self._total[1]
97         return 0.5*(groups+items)
98
99 class NullGeometryCollector(BaseGeometryCollector):
100     def AddData(self, *args, **kw): pass
101     def AddTranversals(self, *args, **kw): pass
102     def AddRenderable(self, renderable, flushgeometry=True): pass
103     def ExtendRenderables(self, renderables, flushgeometry=True): pass
104
105     def GetRenderables(self, *args, **kw): return []
106     def Commit(self, target=None): pass
107
108 class GLGeometryCollector(BaseGeometryCollector):
109     def __init__(self, *args, **kw):
110         BaseGeometryCollector.__init__(self, *args, **kw)
111         self.renderables = []
112         self.geobin = GLGeometryBin()
113
114     def AddData(self, *args, **kw):
115         try:
116             return self.geobin.AddData(*args, **kw)
117         except GLGeometryBin.GeometryBinFull:
118             # Commit the bin that just overflowed
119             self.geobin.Commit(self)
120
121         # Create new bin, and add the data again
122         self.geobin = GLGeometryBin()
123         return self.geobin.AddData(*args, **kw)
124
125     def AddTranversals(self, *args, **kw):
126         return self.geobin.AddTranversals(*args, **kw)
127
128     def AddRenderable(self, renderable, flushgeometry=True):
129         if flushgeometry and self.geobin:
130             self.geobin.Commit(self)
131             self.geobin = GLGeometryBin()
132         self.renderables.append(renderable)
133
134     def ExtendRenderables(self, renderables, flushgeometry=True):
135         if flushgeometry and self.geobin:
136             self.geobin.Commit(self)
137             self.geobin = GLGeometryBin()
138         self.renderables.extend(renderables)
139
140     def GetRenderables(self, *args, **kw):
141         self.Commit(*args, **kw)
142         return [r for r in self.renderables if r is not None]
143
144     def Commit(self, target=None):
145         self.geobin.Commit(self)
146         del self.geobin
147         if target is not None:
148             target.ExtendRenderables(self.renderables)
149
150 class GLGeometryTransaction(object):
151     _NumericType = Numeric.Float16
152
153     def __init__(self, points=None, singlecolor=None, colors=None):
154         self.primitives = []
155         self.traversals = []
156         if points is not None:
157             self.SetPoints(points)
158
159         if singlecolor is not None:
160             assert colors is None
161             self.SetSingleColor(singlecolor)
162         elif colors is not None:
163             assert singlecolor is None
164             self.SetColors(colors)
165
166     def SetPoints(self, points):
167         if isinstance(points, Numeric.ArrayType):
168             self.points = points
169         else:
170             self.points = Numeric.asarray(points, self._NumericType)
171
172     def SetSingleColor(self, color):
173         assert getattr(self, 'points', None), "SetPoints must be called before SetSingleColor"
174         self.SetColors([color]*len(self.points))
175
176     def SetColors(self, colors):
177         self.colors = Numeric.asarray(colors, Numeric.UInt8)
178    
179     def Add(self, glmode, indexes):
180         self.primitives.append(glmode)
181         self.traversals.append(indexes)
182
183     def Commit(self, target):
184         if target is not None and self.primitives and self.traversals:
185             offset = target.AddData(self.points, self.colors)
186             target.AddTranversals(self.primitives, self.traversals, offset)
187
188 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
189
190 class GLStroke(GLGeometryTransaction):
191     def AddLines(self, indexes):
192         self.Add(GL.GL_LINES, indexes)
193     def AddLineStrip(self, indexes):
194         self.Add(GL.GL_LINE_STRIP, indexes)
195     def AddLineLoop(self, indexes):
196         self.Add(GL.GL_LINE_LOOP, indexes)
197
198 class GLFill(GLGeometryTransaction):
199     def AddTriangles(self, indexes):
200         self.Add(GL.GL_TRIANGLES, indexes)
201     def AddTriangleStrip(self, indexes):
202         self.Add(GL.GL_TRIANGLE_STRIP, indexes)
203     def AddTriangleFan(self, indexes):
204         self.Add(GL.GL_TRIANGLE_FAN, indexes)
205
Note: See TracBrowser for help on using the browser.