Changeset 666

Show
Ignore:
Timestamp:
08/20/03 21:57:48 (5 years ago)
Author:
sholloway
Message:

New SVG tree works! Well... for the most part...

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/RBRapier/RBRapier/Formats/SVG/RapierRenderItems.py

    r665 r666  
    2424#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    2525 
    26 from __future__ import generators 
    2726from OpenGL import GL 
    28 import Polygon as PolygonModule 
    2927import Numeric 
    3028 
     
    3230from RBRapier.Tools.Geometry import Curves 
    3331from RBRapier.Tools.Geometry.gluPolygonTesselation import PolygonTesselator as _PolygonTesselator 
     32 
     33from RBRapier.Renderer.Geometry import VertexArrays 
     34from RBRapier.Renderer.Geometry import ArrayTraversal 
     35from RBRapier.Renderer.View import Transformations as RenderTransformations 
    3436 
    3537#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     
    5254        result._style = self._style.copy() 
    5355        return result 
    54  
    55     def __iadd__(self, other): 
    56         self._style.update(other._style) 
    57         return self 
    5856 
    5957    def __add__(self, other): 
     
    8179 
    8280class Transform(Transformations2d.Composite): 
     81    def __mul__(self, other): 
     82        if isinstance(other, Transform): 
     83            return Transform(self.collection + other.collection) 
     84        else:  
     85            return Transformations2d.Composite.__mul__(self, other) 
     86 
     87    def __rmul__(self, other): 
     88        if isinstance(other, Transform): 
     89            return Transform(other.collection + self.collection) 
     90        else:  
     91            return Transformations2d.Composite.__rmul__(self, other) 
     92 
    8393    def copy(self): 
    8494        result = self.__class__() 
     
    90100 
    91101    def scale(self, x=1., y=None):  
     102        if y is None: y = x 
    92103        self.Add(Transformations2d.Scale((x,y))) 
    93104 
     
    144155        self.vertexdata.append(vertexdata[:2]) 
    145156 
    146 class PathConnector(object): 
     157class SVGPathConnector(object): 
    147158    pos = (0,0) 
    148159    controlpoint = None 
    149     steps = 32 
     160    beziersteps = 32 
     161    ellipsesteps = 32 
    150162 
    151163    command_table = { 
     
    195207        return self.move(x+dx, y+dy) 
    196208    def move(self, x, y):  
    197         if not self.pathlist or self.pathlist[-1]: 
    198             self.pathlist.append([(x,y)]) 
     209        pathlist = self.pathlist 
     210        if not pathlist or pathlist[-1]: 
     211            pathlist.append([(x,y)]) 
    199212        else: 
    200             self.pathlist[-1][:] = [(x,y)] 
     213            pathlist[-1][:] = [(x,y)] 
    201214        self._savepos((x,y)) 
    202215 
    203216    def closepath(self):  
    204         if self.pathlist[-1]: 
    205             lastpath = self.pathlist[-1] 
    206             pos = lastpath[0] 
    207             lastpath.append(pos) 
    208             self.pathlist.append([]) 
     217        pathlist = self.pathlist 
     218        if len(pathlist[-1]) <= 1: 
     219            pathlist.pop() 
     220        else: 
     221            pos = pathlist[-1][0] 
     222            pathlist[-1].append(pos) 
     223            pathlist.append([]) 
    209224            self._savepos(pos) 
    210225 
     
    236251        return self.cubicbezier(x1+dx, y1+dy, x2+dx, y2+dy, x+dx, y+dy) 
    237252    def cubicbezier(self, x1, y1, x2, y2, x, y):  
    238         bezier = Curves.CubicBezier(self.pos, (x1, y1), (x2, y2), (x, y), steps=self.steps) 
     253        bezier = Curves.CubicBezier(self.pos, (x1, y1), (x2, y2), (x, y), steps=self.beziersteps) 
    239254        self.pathlist[-1].extend(list(bezier)) 
    240255        self._savepos((x,y), (x2, y2)) 
     
    251266        return self.quadraticbezier(x1+dx, y1+dy, x+dx, y+dy) 
    252267    def quadraticbezier(self, x1, y1, x, y):  
    253         bezier = Curves.QuadraticBezier(self.pos, (x1, y1), (x, y), steps=self.steps) 
     268        bezier = Curves.QuadraticBezier(self.pos, (x1, y1), (x, y), steps=self.beziersteps) 
    254269        self.pathlist[-1].extend(list(bezier)) 
    255270        self._savepos((x,y), (x1,y1)) 
     
    268283        startpt, endpt = self.pos, (x,y) 
    269284        if startpt == endpt: return 
    270         ellipse = Curves.Ellipse.fromArc(startpt, endpt, abs(rx), abs(ry), xrotation % 360, bool(largeArcFlag), bool(sweepFlag), inDegrees=True, steps=self.steps) 
     285        ellipse = Curves.Ellipse.fromArc(startpt, endpt, abs(rx), abs(ry), xrotation % 360, bool(largeArcFlag), bool(sweepFlag), inDegrees=True, steps=self.ellipsesteps) 
    271286        self.pathlist[-1].extend(list(ellipse)) 
    272287        self._savepos((x,y)) 
     
    288303#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    289304 
    290 class GLGeometry(object): 
    291     points = () 
    292     colors = () 
    293  
     305class GLGeometryBin(object): 
     306    maxcount = 65536 
     307 
     308    class GeometryBinFull(Exception): pass 
     309 
     310    def __init__(self): 
     311        self._offset = 0 
     312        self._pointslist = [] 
     313        self._colorslist = [] 
     314        self._primitives = [] 
     315        self._traversals = [] 
     316     
     317    def __len__(self): 
     318        return self._offset 
     319 
     320    def AddData(self, points, colors): 
     321        assert len(points) == len(colors) 
     322        newoffset = self._offset + len(points) 
     323        if newoffset >= self.maxcount: 
     324            raise self.GeometryBinFull, 'Overflow of OpenGL indexable geometry' 
     325        self._pointslist.append(points) 
     326        self._colorslist.append(colors) 
     327 
     328        offset = self._offset 
     329        self._offset = newoffset 
     330        return offset 
     331 
     332    def AddTranversals(self, primitives, traversals, offset): 
     333        assert len(primitives) == len(traversals) 
     334        offset = Numeric.asarray(offset, Numeric.UInt16) 
     335        traversals = [Numeric.asarray(traversal, Numeric.UInt16) + offset for traversal in traversals] 
     336        self._primitives.extend(primitives) 
     337        self._traversals.extend(traversals) 
     338     
     339    def Commit(self, target): 
     340        if target is not None: 
     341            points = Numeric.concatenate(self._pointslist) 
     342            vertices = VertexArrays.VertexArray(points, points.typecode) 
     343            target.AddRenderable(vertices, False) 
     344 
     345            colors = Numeric.concatenate(self._colorslist) 
     346            colors = VertexArrays.ColorArray(colors, colors.typecode) 
     347            target.AddRenderable(colors, False) 
     348 
     349            traversals = ArrayTraversal.IndexedCollectionTraversalRaw(self._primitives, self._traversals) 
     350            target.AddRenderable(traversals, False) 
     351 
     352class GLGeometryCollector(object): 
     353    def __init__(self): 
     354        self.renderables = [] 
     355        self.geobin = GLGeometryBin() 
     356 
     357    def AddData(self, *args, **kw): 
     358        try: 
     359            return self.geobin.AddData(*args, **kw) 
     360        except GLGeometryBin.GeometryBinFull: 
     361            # Commit the bin that just overflowed 
     362            self.geobin.Commit(self) 
     363 
     364        # Create new bin, and add the data again 
     365        self.geobin = GLGeometryBin() 
     366        return self.geobin.AddData(*args, **kw) 
     367 
     368    def AddTranversals(self, *args, **kw): 
     369        return self.geobin.AddTranversals(*args, **kw) 
     370 
     371    def AddRenderable(self, renderable, flushgeometry=True): 
     372        if flushgeometry and self.geobin: 
     373            self.geobin.Commit(self) 
     374            self.geobin = GLGeometryBin() 
     375        self.renderables.append(renderable) 
     376 
     377    def ExtendRenderables(self, renderables, flushgeometry=True): 
     378        if flushgeometry and self.geobin: 
     379            self.geobin.Commit(self) 
     380            self.geobin = GLGeometryBin() 
     381        self.renderables.extend(renderables) 
     382 
     383    def GetRenderables(self, *args, **kw): 
     384        self.Commit(*args, **kw) 
     385        return self.renderables 
     386 
     387    def Commit(self, target=None): 
     388        self.geobin.Commit(self) 
     389        del self.geobin 
     390        if target is not None: 
     391            target.ExtendRenderables(self.renderables) 
     392 
     393class GLGeometryTransaction(object): 
    294394    def __init__(self, points=None, singlecolor=None, colors=None): 
     395        self.primitives = [] 
     396        self.traversals = [] 
    295397        if points is not None: 
    296398            self.SetPoints(points) 
     
    303405            self.SetColors(colors) 
    304406 
    305     def SetPoints(self, points, transform=None): 
    306         self.points = points 
     407    def SetPoints(self, points): 
     408        if isinstance(points, Numeric.ArrayType): 
     409            self.points = points 
     410        else: 
     411            self.points = Numeric.asarray(points, _NumericType) 
    307412 
    308413    def SetSingleColor(self, color): 
    309         assert self.points, "SetPoints must be called before SetSingleColor" 
     414        assert getattr(self, 'points', None), "SetPoints must be called before SetSingleColor" 
    310415        self.SetColors([color]*len(self.points)) 
    311416 
    312417    def SetColors(self, colors): 
    313         self.colors = Numeric.asarray(colors, _NumericType
     418        self.colors = Numeric.asarray(colors, Numeric.UInt8
    314419     
    315     def Commit(self): 
    316         raise NotImplementedError 
    317  
    318 class GLStroke(GLGeometry): 
     420    def Add(self, glmode, indexes): 
     421        self.primitives.append(glmode) 
     422        self.traversals.append(indexes) 
     423 
     424    def Commit(self, target): 
     425        if target is not None and self.primitives and self.traversals: 
     426            offset = target.AddData(self.points, self.colors) 
     427            target.AddTranversals(self.primitives, self.traversals, offset) 
     428 
     429#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     430 
     431class GLStroke(GLGeometryTransaction): 
    319432    def AddLines(self, indexes): 
    320433        self.Add(GL.GL_LINES, indexes) 
    321  
    322434    def AddLineStrip(self, indexes): 
    323435        self.Add(GL.GL_LINE_STRIP, indexes) 
    324  
    325436    def AddLineLoop(self, indexes): 
    326437        self.Add(GL.GL_LINE_LOOP, indexes) 
    327438 
    328     def Add(self, glmode, indexes): 
    329         pass 
    330  
    331     def Commit(self): 
    332         raise NotImplementedError 
    333  
    334 class GLFill(GLGeometry): 
     439class GLFill(GLGeometryTransaction): 
    335440    def AddTriangles(self, indexes): 
    336441        self.Add(GL.GL_TRIANGLES, indexes) 
    337  
    338442    def AddTriangleStrip(self, indexes): 
    339443        self.Add(GL.GL_TRIANGLE_STRIP, indexes) 
    340      
    341444    def AddTriangleFan(self, indexes): 
    342445        self.Add(GL.GL_TRIANGLE_FAN, indexes) 
    343  
    344     def Add(self, glmode, indexes): 
    345         pass 
    346  
    347     def Commit(self): 
    348         raise NotImplementedError 
    349446 
    350447#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     
    366463    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    367464 
    368     def Compile(self, style, transform): 
     465    def Compile(self, style, transform, target): 
    369466        #style, transform = self._GetStyleAndTransform(style, transform) 
    370467        pass 
     
    395492                style = self.style.copy() 
    396493        elif self.style is not None: 
    397             style += self.style 
     494            style = style + self.style 
    398495        if transform is None: 
    399496            if self.transform is None: 
     
    402499                transform = self.transform.copy() 
    403500        elif self.transform is not None: 
    404             transform *= self.transform 
     501            transform = transform * self.transform 
    405502        return style, transform 
    406503 
     
    408505 
    409506class GroupRenderItem(RenderItem): 
    410     children = () 
    411  
    412     def Compile(self, style=None, transform=None): 
     507    renderChildren = () 
     508    otherChildren = () 
     509 
     510    def Compile(self, style=None, transform=None, target=None): 
    413511        style, transform = self._GetStyleAndTransform(style, transform) 
    414         for child in self.children: 
    415             for geometry in child.Compile(style, transform): 
    416                 yield geometry 
     512        for child in self.renderChildren: 
     513            child.Compile(style, transform, target) 
    417514 
    418515    def SetChildren(self, children): 
    419         self.allchildren = children 
    420         self.children = [child for child in children if isinstance(child, RenderItem)] 
    421  
    422 class SVGGroupRenderItem(GroupRenderItem): 
    423     #~ SVG Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    424  
    425     def SetRenderOptions(self, text=None, shape=None, image=None): 
    426         pass # TODO: implement 
     516        self.renderChildren = [] 
     517        self.otherChildren = [] 
     518        for child in children: 
     519            if isinstance(child, RenderItem): 
     520                self.renderChildren.append(child) 
     521            else: 
     522                self.otherChildren.append(child) 
     523 
     524class ContainerGroupRenderItem(GroupRenderItem): 
     525    viewbox = None 
     526    dimensions = None 
     527    alignment = None 
     528 
     529    def _GetStyleAndTransform(self, style=None, transform=None): 
     530        if self.viewbox is not None: 
     531            x, y, w, h = self.viewbox 
     532        elif self.dimensions is not None: 
     533            x, y = 0, 0 
     534            w, h = self.dimensions 
     535        else: 
     536            x, y, w, h = 0,0,100,100 
     537 
     538        projection = Transform() 
     539        projection.matrix( 
     540            2./w, 0., -1-2.*x/w,  
     541            0., 2./h, -1-2.*y/h) 
     542 
     543        # TODO: implement alignment 
     544 
     545        if transform is None: 
     546            transform = projection 
     547        else:  
     548            transform = transform * projection 
     549 
     550        return GroupRenderItem._GetStyleAndTransform(self, style, transform) 
     551 
     552    #~ SVG Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     553 
    427554    def SetDimensions(self, width, height): 
    428555        self.dimensions = width, height 
     
    432559        self.alignment = xalign, yalign, alignstyle 
    433560 
     561class SVGGroupRenderItem(ContainerGroupRenderItem): 
     562    def Compile(self, style=None, transform=None, target=None): 
     563        childtarget = GLGeometryCollector() 
     564        # TODO: implement render options 
     565 
     566        ContainerGroupRenderItem.Compile(self, style, transform, childtarget) 
     567 
     568        if target is not None: 
     569            childtarget.Commit(target) 
     570        else: # we're the root... return our goodies 
     571            return childtarget.GetRenderables() 
     572 
     573    #~ SVG Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     574 
     575    def SetRenderOptions(self, text=None, shape=None, image=None): 
     576        pass # TODO: implement 
     577 
    434578#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    435579#~ Shapes 
     
    437581 
    438582class Line(RenderItem): 
    439     def Compile(self, style, transform): 
     583    def Compile(self, style, transform, target): 
    440584        style, transform = self._GetStyleAndTransform(style, transform) 
    441585 
     
    445589            stroke = GLStroke(points, strokecolor) 
    446590            stroke.AddLines(range(2)) 
    447             yield stroke 
     591            stroke.Commit(target) 
    448592 
    449593    #~ SVG Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     
    455599 
    456600class Rect(RenderItem): 
    457     def Compile(self, style, transform): 
     601    def Compile(self, style, transform, target): 
    458602        style, transform = self._GetStyleAndTransform(style, transform) 
    459603        x,y = self.position 
     
    461605 
    462606        # TODO: compute rounded rectangles 
    463         points = [(x,y), (x+w, y), (x+w, y+h), (x, y+h)] 
     607        points = [(x,y), (x, y+h), (x+w, y+h), (x+w, y)] 
    464608        points = transform.TransformPoints(points) 
    465609 
     
    467611        if fillcolor is not None: 
    468612            fill = GLFill(points, fillcolor) 
    469             fill.AddTriangleStrip(range(4)) 
    470             yield fill 
     613            fill.AddTriangleFan(range(4)) 
     614            fill.Commit(target) 
    471615 
    472616        strokecolor = style.GetStrokeColor() 
     
    474618            stroke = GLStroke(points, strokecolor) 
    475619            stroke.AddLineLoop(range(4)) 
    476             yield stroke 
     620            stroke.Commit(target) 
    477621 
    478622    #~ SVG Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     
    492636 
    493637class Ellipse(RenderItem): 
    494     def Compile(self, style, transform): 
     638    def Compile(self, style, transform, target): 
    495639        style, transform = self._GetStyleAndTransform(style, transform) 
    496640 
    497         ellipse = Curves.Ellipse(self.center, self.radiusx, self.radiusy)#, 0., 360., xrotation=self.xrotation) 
     641        ellipse = Curves.Ellipse(self.center, self.radiusx, self.radiusy) 
    498642        points = transform.TransformPoints(ellipse.asCurve()) 
    499643 
     
    503647            fill = GLFill(fillpoints, fillcolor) 
    504648            fill.AddTriangleFan(range(len(points))) 
    505             yield fill 
     649            fill.Commit(target) 
    506650 
    507651        strokecolor = style.GetStrokeColor() 
     
    509653            stroke = GLStroke(points, strokecolor) 
    510654            stroke.AddLineLoop(range(len(points))) 
    511             yield stroke 
    512      
     655            stroke.Commit(target) 
     656 
    513657    #~ SVG Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    514658 
     
    531675 
    532676class Polyline(RenderItem): 
    533     def Compile(self, style, transform): 
     677    def Compile(self, style, transform, target): 
    534678        style, transform = self._GetStyleAndTransform(style, transform) 
    535679 
    536680        fillcolor = style.GetFillColor() 
    537681        if fillcolor is not None and len(self.points) >= 3: 
    538             fillpoints = self.points 
    539             if fillpoints[0] != fillpoints[-1]: 
    540                 # close the polyline so we can fill it 
    541                 fillpoints = fillpoints + fillpoints[0:1] 
    542  
    543             glmodedatalist = SVGTesselator([fillpoints]).results 
     682            glmodedatalist = SVGTesselator([self.points]).results 
    544683            for glmode, fillpoints in glmodedatalist: 
    545684                fillpoints = transform.TransformPoints(fillpoints) 
    546685                fill = GLFill(fillpoints, fillcolor) 
    547686                fill.Add(glmode, range(len(fillpoints))) 
    548                 yield fill 
     687                fill.Commit(target) 
    549688 
    550689        strokecolor = style.GetStrokeColor() 
     
    553692            stroke = GLStroke(points, strokecolor) 
    554693            stroke.AddLineStrip(range(len(points))) 
    555             yield stroke 
     694            stroke.Commit(target) 
    556695 
    557696    #~ SVG Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     
    563702 
    564703class Polygon(Polyline): 
    565     def Compile(self, style, transform): 
     704    def Compile(self, style, transform, target): 
    566705        style, transform = self._GetStyleAndTransform(style, transform) 
    567706 
     
    573712                fill = GLFill(fillpoints, fillcolor) 
    574713                fill.Add(glmode, range(len(fillpoints))) 
    575                 yield fill 
     714                fill.Commit(target) 
    576715 
    577716        strokecolor = style.GetStrokeColor() 
     
    583722                stroke = GLStroke(strokepoints, strokecolor) 
    584723                stroke.Add(glmode, range(len(strokepoints))) 
    585                 yield stroke 
     724                stroke.Commit(target) 
    586725 
    587726    def SetPoints(self, points): 
     
    595734 
    596735class Path(RenderItem): 
    597     def Compile(self, style, transform): 
     736    def Compile(self, style, transform, target): 
     737        contours = SVGPathConnector.fromSVGPath(self.path).GetContours() 
     738        if not contours: return # must be a degenerate path... exit gracefully 
     739 
    598740        style, transform = self._GetStyleAndTransform(style, transform) 
    599  
    600         path = PathConnector.fromSVGPath(self.path) 
    601741 
    602742        fillcolor = style.GetFillColor() 
    603743        if fillcolor is not None: 
    604             # make contour list 
    605             contourlist = [] 
    606             for contour in path.GetContours(): 
    607                 if len(contour) <= 2: 
    608                     continue 
    609                 if contour[0] != contour[-1]: 
    610                     # close the contour so we can fill it 
    611                     contour += contour[0:1] 
    612                 contourlist.append(contour) 
     744            # paths can only be formed when there is more than two points... 
     745            contourlist = [contour for contour in contours if len(contour)>2] 
    613746 
    614747            if contourlist: 
    615                 poly = PolygonModule.Polygon() 
    616                 map(poly.addContour, contourlist) 
    617                 poly.triStrip() 
    618  
    619                 #glmodedatalist = [] #SVGTesselator(contourlist).results 
    620                 #for glmode, fillpoints in glmodedatalist: 
    621                 #    fillpoints = transform.TransformPoints(fillpoints) 
    622                 #    fill = GLFill(fillpoints, fillcolor) 
    623                 #    fill.Add(glmode, range(len(fillpoints))) 
    624                 #    yield fill 
     748                glmodedatalist = [] #SVGTesselator(contourlist).results 
     749                for glmode, fillpoints in glmodedatalist: 
     750                    fillpoints = transform.TransformPoints(fillpoints) 
     751                    fill = GLFill(fillpoints, fillcolor) 
     752                    fill.Add(glmode, range(len(fillpoints))) 
     753                    fill.Commit(target) 
    625754 
    626755        strokecolor = style.GetStrokeColor() 
    627756        if strokecolor is not None: 
    628             for contour in path.GetContours(): 
    629                 points = transform.TransformPoints(contour) 
    630                 stroke = GLStroke(points, strokecolor) 
    631                 stroke.AddLineStrip(range(len(points))) 
    632                 yield stroke 
     757            points = [pt for contour in contours for pt in contour] 
     758            points = transform.TransformPoints(points) 
     759 
     760            stroke = GLStroke(points, strokecolor) 
     761            index = 0 
     762            for count in map(len, contours): 
     763                stroke.AddLineStrip(range(index, index+count)) 
     764                index += count 
     765            stroke.Commit(target) 
    633766 
    634767    #~ SVG Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  • trunk/RBRapier/RBRapier/Renderer/Geometry/ArrayTraversal.py

    r658 r666  
    3737 
    3838    'linelist': GL.GL_LINES, 
     39    'lineloop': GL.GL_LINE_LOOP, 
    3940    'linestrip': GL.GL_LINE_STRIP, 
    4041 
     
    5354    GL.GL_LINES: ('lines', lambda count: count//2), 
    5455    GL.GL_LINE_STRIP: ('lines', lambda count: count-1), 
     56    GL.GL_LINE_LOOP: ('lines', lambda count: count), 
    5557 
    5658    GL.GL_TRIANGLES: ('triangles', lambda count: count//3), 
     
    6668#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    6769 
     70def GetPrimitiveCollection(primitive, count): 
     71    if isinstance(primitive, (list, tuple)): 
     72        assert len(primitive) == count 
     73        return [_PrimitveMap.get(p, p) for p in primitive] 
     74    else: 
     75        return [_PrimitveMap.get(primitive, primitive)]*count 
     76 
    6877def GenerateStatistics(self, context): 
    6978    if context.Statistics: 
     
    7281            except KeyError: context.Statistics[StatName] = StatResults 
    7382 
    74 class RangedTraversal(object): 
    75     """Draws a collection of ranges using one primitive""" 
     83#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     84#~ Ranged Traversals 
     85#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    7686 
    77     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    78     #~ Constants / Variables / Etc.  
    79     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     87class RangedTraversalRaw(object): 
     88    """Draws a collection of ranges using multiple primitives""" 
    8089 
    81     _PrimitiveCount = 0 
     90    def __init__(self, primitives, starts, lengths): 
     91        assert len(primitives) == len(starts) == len(lengths) 
     92        self.primitives = primitives 
     93        self.starts = starts 
     94        self.lengths = lengths 
    8295 
    83     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    84     #~ Public Methods  
    85     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    86  
    87     def __init__(self, primitive, rangecollection): 
    88         self.primitive = _PrimitveMap.get(primitive, primitive) 
    89         self.rangecollection = rangecollection 
    90  
    91         StatName, StatCalc = _PrimitveStatsMap[self.primitive] 
    92         StatResults = 0 
    93         for RangeStart, RangeEnd in self.rangecollection:  
    94             StatResults += StatCalc(RangeEnd - RangeStart) 
    95         self._StatsData = {StatName:StatResults, _ReversePrimitveMap[self.primitive]: len(self.rangecollection)} 
     96        self._StatsData = {} 
     97        for primitive, count in zip(primitives, lengths): 
     98            StatName, StatCalc = _PrimitveStatsMap[primitive] 
     99            self._StatsData[StatName] = self._StatsData.get(StatName, 0) + StatCalc(count) 
     100            ReverseName = _ReversePrimitveMap[primitive] 
     101            self._StatsData[ReverseName] = self._StatsData.get(ReverseName, 0) + 1 
    96102 
    97103    GenerateStatistics = GenerateStatistics 
    98104 
    99105    def Execute(self, context): 
    100         primitive = self.primitive 
    101         for RangeStart, RangeEnd in self.rangecollection: 
    102             GL.glDrawArrays(primitive, RangeStart, RangeEnd) 
    103  
     106        map(GL.glDrawArrays, self.primitives, self.starts, self.lengths) 
    104107        self.GenerateStatistics(context) 
    105108 
    106109#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    107110 
    108 class IndexedCollectionTraversal(object): 
    109     """Draws a collection of index arrays using one primitive""" 
     111class RangedTraversal(RangedTraversalRaw): 
     112    """Draws a collection of ranges using multiple primitives""" 
    110113 
    111     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    112     #~ Constants / Variables / Etc.  
    113     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     114    def __init__(self, primitive, rangecollection): 
     115        primitives = GetPrimitiveCollection(primitive, len(rangecollection)) 
     116        starts, lengths = zip(*rangecollection) 
     117        RangedTraversalRaw.__init__(self, primitives, starts, lengths) 
    114118 
    115     _PrimitiveCount = 0 
    116     _DefaultFormat = Numeric.UInt16 
     119#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     120#~ Indexed Collection Traversals 
     121#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    117122 
    118     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    119     #~ Public Methods  
    120     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     123class IndexedCollectionTraversalRaw(object): 
     124    """Draws a collection of index arrays using multiple primitives""" 
    121125 
    122     def __init__(self, primitive, datacollection, format=None): 
    123         self.primitive = _PrimitveMap.get(primitive, primitive
    124         if format is None: format = self._DefaultFormat 
    125         self.datacollection = [Numeric.asarray(data, format) for data in datacollection] 
     126    def __init__(self, primitives, data): 
     127        assert len(primitives) == len(data
     128        self.primitives = primitives 
     129        self.data = data 
    126130 
    127         StatName, StatCalc = _PrimitveStatsMap[self.primitive] 
    128         StatResults = 0 
    129         for each in self.datacollection:  
    130             StatResults += StatCalc(len(each)) 
    131         self._StatsData = {StatName:StatResults, _ReversePrimitveMap[self.primitive]: len(self.datacollection)} 
     131        self._StatsData = {} 
     132        for primitive, datacoll in zip(primitives, data):  
     133            StatName, StatCalc = _PrimitveStatsMap[primitive] 
     134            self._StatsData[StatName] = self._StatsData.get(StatName, 0) + StatCalc(len(datacoll)) 
     135            ReverseName = _ReversePrimitveMap[primitive] 
     136            self._StatsData[ReverseName] = self._StatsData.get(ReverseName, 0) + 1 
    132137 
    133138    GenerateStatistics = GenerateStatistics 
    134139 
    135140    def Execute(self, context): 
    136         primitive = self.primitive 
    137         DrawElements = NumericVertexArray.DrawElementsArray 
    138         for data in self.datacollection: 
    139             DrawElements(primitive, data) 
     141        map(NumericVertexArray.DrawElementsArray, self.primitives, self.data) 
     142        self.GenerateStatistics(context) 
    140143 
    141         self.GenerateStatistics(context) 
     144#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     145 
     146class IndexedCollectionTraversal(IndexedCollectionTraversalRaw): 
     147    """Draws a collection of index arrays using multiple primitives""" 
     148 
     149    _DefaultFormat = Numeric.UInt16 
     150 
     151    def __init__(self, primitive, data, format=None): 
     152        if format is None: format = self._DefaultFormat 
     153        primitives = GetPrimitiveCollection(primitive, len(data)) 
     154        data = [Numeric.asarray(item, format) for item in data] 
     155        IndexedCollectionTraversalRaw.__init__(self, primitives, data) 
    142156 
    143157#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     
    154168    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    155169 
    156     def __init__(self, primitive, datacollection, format=None): 
    157         IndexedCollectionTraversal.__init__(self, primitive, datacollection, format) 
     170    def __init__(self, primitive, data, format=None): 
     171        IndexedCollectionTraversal.__init__(self, primitive, data, format) 
    158172        self.GenerateColors() 
    159173 
    160174    def GenerateColors(self): 
    161175        import random 
    162         self.colors = [(.3 + .7*random.random(), .3 + .7*random.random(), .3 + .7*random.random()) for x in self.datacollection
     176        self.colors = [(.3 + .7*random.random(), .3 + .7*random.random(), .3 + .7*random.random()) for x in self.data
    163177 
    164178    def Execute(self, context): 
    165         primitive = self.primitive 
    166179        _glDrawElements = NumericVertexArray.DrawElementsArray 
    167         for color, data in zip(self.colors, self.datacollection): 
    168             GL.glColor3f(*color) 
    169             _glDrawElements(primitive, data
     180        for color, primitive, indexes in zip(self.colors, self.primitives, self.data): 
     181            GL.glColor3fv(color) 
     182            _glDrawElements(primitive, indexes
    170183 
    171184        self.GenerateStatistics(context) 
  • trunk/RBRapier/RBRapier/Renderer/Geometry/VertexArrays.py

    r383 r666  
    5353    def __init__(self, data, format=None): 
    5454        if format is None: format = self._DefaultFormat 
    55         self.data = Numeric.asarray(data, format) 
     55        if isinstance(data, Numeric.ArrayType): 
     56            self.data = data 
     57        else: 
     58            self.data = Numeric.asarray(data, format) 
    5659 
    5760    def Select(self, context): 
    5861        context.ClientStateMgr.Enable(self._glArrayType) 
    5962        self._glArrayCall(self.data) 
     63    Execute = Select 
    6064 
    6165    def Deselect(self, context): 
  • trunk/RBRapier/RBRapier/Renderer/SequenceMgr.py

    r634 r666  
    7979        self._AddElement(Element, priority) 
    8080 
    81     def AddElements(self, *args): 
    82         for each in args: 
     81    def AddElements(self, elements): 
     82        for each in elements: 
    8383            if isinstance(each, (tuple, list)): 
    8484                self.AddElement(*each) 
  • trunk/RBRapier/RBRapier/Tools/Transformations2d.py

    r665 r666  
    103103            else: 
    104104                return Composite(self.collection + [other]) 
    105         else: TransformPrimitive2dh.__mul__(self, other) 
     105        else:  
     106            return TransformPrimitive2dh.__mul__(self, other) 
    106107 
    107108    def __rmul__(self, other): 
     
    111112            else: 
    112113                return Composite([other] + self.collection) 
    113         else: TransformPrimitive2dh.__rmul__(self, other) 
     114        else:  
     115            return TransformPrimitive2dh.__rmul__(self, other) 
    114116 
    115117    def Add(self, Transform): 
  • trunk/RBRapier/demo/Cube/cubescene.py

    r643 r666  
    5757        self.viewsetup.StartRendering() 
    5858 
    59     def Initialize(self, subject, canvas): 
     59    def Initialize(self, glviewsetup, canvas): 
    6060        self.viewsetup.OnRender.Remove(self.Initialize) 
    6161        self.root = SequenceMgr.RootSequence() 
     
    7474        self.root.AddElement(self.cube.Draw) 
    7575 
    76     def Render(self, subject, canvas): 
     76    def Render(self, glviewsetup, canvas): 
    7777        self.viewport.SetRectangle(canvas.GetClientRect().asTuple()) 
    7878        self.projection.Dimensions = 2, 2, 2 
  • trunk/RBRapier/demo/Lightwave/scene.py

    r626 r666  
    5454    def __init__(self, skinelement): 
    5555        self.ViewSetup = GLViewSetup(skinelement.parent().object) 
    56         self.ViewSetup.RenderEvent.Add(self.Initialize) 
    57         self.ViewSetup.RenderEvent.Add(self.Render) 
     56        self.ViewSetup.OnRender.Add(self.Initialize) 
     57        self.ViewSetup.OnRender.Add(self.Render) 
    5858 
    59     def Initialize(self, subject, canvas): 
    60         subject.Remove(self.Initialize) 
     59    def Initialize(self, glviewsetup, canvas): 
     60        glviewsetup.OnRender.Remove(self.Initialize) 
     61 
    6162        self.Sequence = SequenceMgr.RootSequence() 
    6263 
     
    168169 
    169170    Animate = 1 
    170     def Render(self, subject, canvas): 
     171    def Render(self, glviewsetup, canvas): 
     172 
    171173        # Recalculate the viewport 
    172174        self.Viewport.SetRectangle(canvas.GetClientRect().asTuple()) 
  • trunk/RBRapier/demo/Wavefront/scene.py

    r626 r666  
    4949    def __init__(self, skinelement): 
    5050        self.ViewSetup = GLViewSetup(skinelement.parent().object) 
    51         self.ViewSetup.RenderEvent.Add(self.Initialize) 
    52         self.ViewSetup.RenderEvent.Add(self.Render) 
     51        self.ViewSetup.OnRender.Add(self.Initialize) 
     52        self.ViewSetup.OnRender.Add(self.Render) 
    5353 
    54     def Initialize(self, subject, canvas): 
    55         subject.Remove(self.Initialize) 
     54    def Initialize(self, glviewsetup, canvas): 
     55        glviewsetup.OnRender.Remove(self.Initialize) 
     56 
    5657        self.Sequence = SequenceMgr.RootSequence() 
    5758 
     
    116117        self.Sequence.AddElement(self.LightXForm.Deselect) 
    117118 
    118         self.GeoObj = self.WavefrontOBJ('data/oldtree.obj', 1, 3) 
     119        #self.GeoObj = self.WavefrontOBJ('data/oldtree.obj', 1, 3) 
    119120        #self.GeoObj = self.StripeColoredWavefrontOBJ('data/oldtree.obj', 0, 0) 
    120         #self.GeoObj = self.WavefrontOBJ('data/x29.obj', 1, 3) 
     121        self.GeoObj = self.WavefrontOBJ('data/x29.obj', 1, 3) 
    121122        #self.GeoObj = self.WavefrontOBJ('data/porsche.obj', 1, 3) 
    122123        #self.GeoObj = self.WavefrontOBJ('data/cessna.obj', 1, 3) 
     
    139140 
    140141    Animate = 1 
    141     def Render(self, subject, canvas): 
     142    def Render(self, glviewsetup, canvas): 
    142143        # Recalculate the viewport 
    143144        self.Viewport.SetRectangle(canvas.GetClientRect().asTuple())