root/trunk/RBRapier/RBRapier/Formats/Attic/SVG.old/Renderers/Rapier.py

Revision 656, 10.3 kB (checked in by sholloway, 5 years ago)

*** empty log message ***

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
28 from RBRapier.Renderer.View import Transformations
29 from RBRapier.Renderer.Geometry import VertexArrays
30 from RBRapier.Renderer.Geometry import ArrayTraversal
31 from RBRapier.Renderer import SequenceMgr
32
33 import Abstract
34 import RapierObjects
35
36 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 #~ Definitions
38 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39
40 class RapierContext(object):
41     sequence = None
42     currentColor = None
43     fillcolor = None
44     strokecolor = None
45     fillopacity = 1.
46     strokeopacity = 1.
47
48     resolver = {}
49
50     def __init__(self, *kwin, **kw):
51         for each in kwin:
52             self.__dict__.update(each)
53         self.__dict__.update(kw)
54
55     def Branch(self, **kw):
56         return self.__class__(self.__dict__, **kw)
57
58     def GetFillColor(self, allowstroke=True):
59         result = self.fillcolor
60         if result is not None:
61             return self.fillcolor + (int(255*self.fillopacity),)
62         elif allowstroke:
63             return self.GetStrokeColor(False)
64
65     def GetStrokeColor(self, allowfill=True):
66         result = self.strokecolor
67         if result is not None:
68             return self.strokecolor + (int(255*self.strokeopacity),)
69         elif allowfill:
70             return self.GetFillColor(False)
71
72     def GetColors(self):
73         return {'stroke': self.GetStrokeColor(False), 'fill': self.GetFillColor(False)}
74
75 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
76
77 class RapierRenderer(Abstract.AbstractRenderer):
78     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
79     #~ Constants / Variables / Etc.
80     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81
82     PathFactory = RapierObjects.RapierPathFactory
83     TransformFactory = RapierObjects.RapierTransformFactory
84     SequenceFactory = SequenceMgr.Sequence
85
86     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
87     #~ Public Methods
88     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
89
90     def Display(self, ri):
91         self._debug_points = 0
92         rootsequence = self.SequenceFactory()
93
94         # SVG coordinate system is upside down from OpenGL's , so scale y by -1
95         xform = Transformations.ScaleMgd(GL.GL_PROJECTION, True, (1, -1, 1))
96         rootsequence.AddElement(xform.Select)
97         rootsequence.AddPostElement(xform.Deselect)
98
99         xform = Transformations.IdentityMgd(GL.GL_MODELVIEW, True)
100         rootsequence.AddElement(xform.Select)
101         rootsequence.AddPostElement(xform.Deselect)
102
103         self.contextstack = []
104         self.context = RapierContext()
105         self.context.sequence = rootsequence
106
107         try:
108             ri.DisplayOn(self)
109         finally:
110             del self.context
111             del self.contextstack
112
113         print self._debug_points
114         return rootsequence
115
116     #~ Meta Information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
117
118     def DisplayTitle(self, ri_title):
119         pass
120
121     def DisplayDescription(self, ri_desc):
122         pass
123
124     #~ Groups ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
125
126     def DisplaySVG(self, ri_svg):
127         self.PushContext(ri_svg, True)
128         self.context.resolver = ri_svg.idmapping
129         try:
130             ri_svg.DisplayChildrenOn(self)
131         finally:
132             self.PopContext(ri_svg)
133
134     def DisplayGroup(self, ri_group):
135         self.PushContext(ri_group)
136         try:
137             ri_group.DisplayChildrenOn(self)
138         finally:
139             self.PopContext(ri_group)
140
141     def DisplaySymbol(self, ri_symbol):
142         self.PushContext(ri_symbol, True)
143         try:
144             ri_symbol.DisplayChildrenOn(self)
145         finally:
146             self.PopContext(ri_symbol)
147
148     def DisplayUse(self, ri_use):
149         ri_used = self.ResolveReference(ri_use.usereference)
150         if ri_used is not None:
151             self.PushContext(ri_use)
152             try:
153                 ri_used.DisplayOn(self)
154             finally:
155                 self.PopContext(ri_use)
156
157     #~ Shapes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
158
159     def DisplayLine(self, ri_line):
160         self.PushContext(ri_line)
161         try:
162             self._debug_points += 2
163             ro = RapierObjects.Line((ri_line.x1, ri_line.y1), (ri_line.x2, ri_line.y2))
164             ro.SetColors(**self.context.GetColors())
165             if ro: self.context.sequence.AddElement(ro)
166         finally:
167             self.PopContext(ri_line)
168
169     def DisplayRect(self, ri_rect):
170         self.PushContext(ri_rect)
171         try:
172             self._debug_points += 4
173             ro = RapierObjects.Rect(ri_rect.width, ri_rect.height)
174             ro.SetColors(**self.context.GetColors())
175             if ro: self.context.sequence.AddElement(ro)
176         finally:
177             self.PopContext(ri_rect)
178
179     def DisplayCircle(self, ri_circle):
180         self.PushContext(ri_circle)
181         try:
182             self._debug_points += 4
183             ro = RapierObjects.Circle(ri_circle.cx, ri_circle.cy, ri_circle.r)
184             ro.SetColors(**self.context.GetColors())
185             if ro: self.context.sequence.AddElement(ro)
186         finally:
187             self.PopContext(ri_circle)
188
189     def DisplayEllipse(self, ri_ellipse):
190         self.PushContext(ri_ellipse)
191         try:
192             self._debug_points += 4
193             ro = RapierObjects.Ellipse(ri_ellipse.cx, ri_ellipse.cy, ri_ellipse.rx, ri_ellipse.ry)
194             ro.SetColors(**self.context.GetColors())
195             if ro: self.context.sequence.AddElement(ro)
196         finally:
197             self.PopContext(ri_ellipse)
198
199     def DisplayPolygon(self, ri_polygon):
200         self.PushContext(ri_polygon)
201         try:
202             self._debug_points += len(ri_polygon.points)/2
203             ro = RapierObjects.Polygon(ri_polygon.points)
204             ro.SetColors(**self.context.GetColors())
205             if ro: self.context.sequence.AddElement(ro)
206         finally:
207             self.PopContext(ri_polygon)
208
209     def DisplayPolyline(self, ri_polyline):
210         self.PushContext(ri_polyline)
211         try:
212             self._debug_points += len(ri_polyline.points)/2
213             ro = RapierObjects.Polyline(ri_polyline.points)
214             ro.SetColors(**self.context.GetColors())
215             if ro: self.context.sequence.AddElement(ro)
216         finally:
217             self.PopContext(ri_polyline)
218
219     def DisplayPath(self, ri_path):
220         self.PushContext(ri_path)
221         try:
222             pathlist = ri_path.path.RestoreTo(self.PathFactory()).pathlist
223             self._debug_points += reduce(int.__add__, [len(x) for x in pathlist], 0)
224             ro = RapierObjects.Path(pathlist)
225             ro.SetColors(**self.context.GetColors())
226             if ro: self.context.sequence.AddElement(ro)
227         finally:
228             self.PopContext(ri_path)
229
230     def DisplayText(self, ri_text):
231         self.PushContext(ri_text)
232         try:
233             self._debug_points += 4
234             ro = RapierObjects.Text()
235             ro.SetColors(**self.context.GetColors())
236             if ro: self.context.sequence.AddElement(ro)
237         finally:
238             self.PopContext(ri_text)
239
240     #~ Order management ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
241
242     def ResolveReference(self, reference):
243         base, tag = reference
244         return self.context.resolver.get(tag, None)
245
246     def PushContext(self, ri, extendTransform=False):
247         self.contextstack.append(self.context)
248         self.context = self.context.Branch()
249
250         if extendTransform:
251             self._DoExtendedTransform(ri)
252         else:
253             self._DoTransform(ri)
254         self._DoStyle(ri)
255
256     def PopContext(self, ri):
257         self.context = self.contextstack.pop()
258
259     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
260
261     def PushSequence(self):
262         newsequence = self.SequenceFactory()
263         self.context.sequence.AddElement(newsequence.Execute)
264         self.context.sequence = newsequence
265         return newsequence
266
267     def _DoStyle(self, ri):
268         style = ri.GetStyle()
269         if style:
270             if 'color' in style:
271                 self.context.currentColor = style['color']
272
273             # fill
274             if 'fill' in style:
275                 fillcolor = style['fill']
276                 if fillcolor == 'currentColor':
277                     fillcolor = self.context.currentColor
278                 self.context.fillcolor = fillcolor
279
280             if 'fill-opacity' in style:
281                 self.context.fillopacity = style['fill-opacity']
282
283             # stroke
284             if 'stroke' in style:
285                 strokecolor = style['stroke']
286                 if strokecolor == 'currentColor':
287                     strokecolor = self.context.currentColor
288                 self.context.strokecolor = strokecolor
289
290             if 'stroke-opacity' in style:
291                 self.context.strokeopacity = style['stroke-opacity']
292
293     def _DoTransform(self, ri):
294         x, y, transform = ri.GetX(), ri.GetY(), ri.GetTransform()
295         if not (x or y or transform):
296             return False
297
298         if transform:
299             xform = Transformations.CompositeMgd(None, True)
300             if x or y:
301                 xform.Add(Transformations.Translate((x or 0., y or 0.)))
302             transform.RestoreTo(self.TransformFactory(xform))
303         elif x or y:
304             xform = Transformations.TranslateMgd(None, True, (x or 0., y or 0.))
305
306         sequence = self.PushSequence()
307         sequence.AddElement(xform.Select)
308         sequence.AddPostElement(xform.Deselect)
309
310         return True
311
312     def _DoExtendedTransform(self, ri):
313         x, y, w, h = ri.GetViewBox()
314         xform = Transformations.OrthographicMgd(None, True, x, x+w, y, y+h)
315
316         sequence = self.PushSequence()
317         sequence.AddElement(xform.Select)
318         sequence.AddPostElement(xform.Deselect)
319        
320         return True
321          
Note: See TracBrowser for help on using the browser.