| 330 | | |
|---|
| 331 | | class GLGeometryBin(object): |
|---|
| 332 | | maxcount = 65536 |
|---|
| 333 | | |
|---|
| 334 | | class GeometryBinFull(Exception): pass |
|---|
| 335 | | |
|---|
| 336 | | def __init__(self): |
|---|
| 337 | | self._offset = 0 |
|---|
| 338 | | self._pointslist = [] |
|---|
| 339 | | self._colorslist = [] |
|---|
| 340 | | self._primitives = [] |
|---|
| 341 | | self._traversals = [] |
|---|
| 342 | | |
|---|
| 343 | | def __len__(self): |
|---|
| 344 | | return self._offset |
|---|
| 345 | | |
|---|
| 346 | | def AddData(self, points, colors): |
|---|
| 347 | | assert len(points) == len(colors) |
|---|
| 348 | | newoffset = self._offset + len(points) |
|---|
| 349 | | if newoffset >= self.maxcount: |
|---|
| 350 | | raise self.GeometryBinFull, 'Overflow of OpenGL indexable geometry' |
|---|
| 351 | | self._pointslist.append(points) |
|---|
| 352 | | self._colorslist.append(colors) |
|---|
| 353 | | |
|---|
| 354 | | offset = self._offset |
|---|
| 355 | | self._offset = newoffset |
|---|
| 356 | | return offset |
|---|
| 357 | | |
|---|
| 358 | | def AddTranversals(self, primitives, traversals, offset): |
|---|
| 359 | | assert len(primitives) == len(traversals) |
|---|
| 360 | | offset = Numeric.asarray(offset, Numeric.UInt16) |
|---|
| 361 | | traversals = [Numeric.asarray(traversal, Numeric.UInt16) + offset for traversal in traversals] |
|---|
| 362 | | self._primitives.extend(primitives) |
|---|
| 363 | | self._traversals.extend(traversals) |
|---|
| 364 | | |
|---|
| 365 | | def Commit(self, target): |
|---|
| 366 | | if self and target is not None: |
|---|
| 367 | | points = Numeric.concatenate(self._pointslist) |
|---|
| 368 | | vertices = VertexArrays.VertexArray(points, points.typecode) |
|---|
| 369 | | target.AddRenderable(vertices, False) |
|---|
| 370 | | |
|---|
| 371 | | colors = Numeric.concatenate(self._colorslist) |
|---|
| 372 | | colors = VertexArrays.ColorArray(colors, colors.typecode) |
|---|
| 373 | | target.AddRenderable(colors, False) |
|---|
| 374 | | |
|---|
| 375 | | traversals = ArrayTraversal.IndexedCollectionTraversalRaw(self._primitives, self._traversals) |
|---|
| 376 | | target.AddRenderable(traversals, False) |
|---|
| 377 | | |
|---|
| 378 | | class GLGeometryCollector(object): |
|---|
| 379 | | def __init__(self, groupcount=1, geometrycount=1): |
|---|
| 380 | | self.renderables = [] |
|---|
| 381 | | self.geobin = GLGeometryBin() |
|---|
| 382 | | |
|---|
| 383 | | self._progress = [0,0] |
|---|
| 384 | | self._total = [groupcount, geometrycount] |
|---|
| 385 | | |
|---|
| 386 | | def AddGroupProgress(self): |
|---|
| 387 | | self._progress[0] += 1 |
|---|
| 388 | | def AddGeometryProgress(self): |
|---|
| 389 | | self._progress[1] += 1 |
|---|
| 390 | | |
|---|
| 391 | | def Progress(self): |
|---|
| 392 | | return 0.5 * (float(self._progress[0])/self._total[0] + float(self._progress[1])/self._total[1]) |
|---|
| 393 | | |
|---|
| 394 | | def AddData(self, *args, **kw): |
|---|
| 395 | | try: |
|---|
| 396 | | return self.geobin.AddData(*args, **kw) |
|---|
| 397 | | except GLGeometryBin.GeometryBinFull: |
|---|
| 398 | | # Commit the bin that just overflowed |
|---|
| 399 | | self.geobin.Commit(self) |
|---|
| 400 | | |
|---|
| 401 | | # Create new bin, and add the data again |
|---|
| 402 | | self.geobin = GLGeometryBin() |
|---|
| 403 | | return self.geobin.AddData(*args, **kw) |
|---|
| 404 | | |
|---|
| 405 | | def AddTranversals(self, *args, **kw): |
|---|
| 406 | | return self.geobin.AddTranversals(*args, **kw) |
|---|
| 407 | | |
|---|
| 408 | | def AddRenderable(self, renderable, flushgeometry=True): |
|---|
| 409 | | if flushgeometry and self.geobin: |
|---|
| 410 | | self.geobin.Commit(self) |
|---|
| 411 | | self.geobin = GLGeometryBin() |
|---|
| 412 | | self.renderables.append(renderable) |
|---|
| 413 | | |
|---|
| 414 | | def ExtendRenderables(self, renderables, flushgeometry=True): |
|---|
| 415 | | if flushgeometry and self.geobin: |
|---|
| 416 | | self.geobin.Commit(self) |
|---|
| 417 | | self.geobin = GLGeometryBin() |
|---|
| 418 | | self.renderables.extend(renderables) |
|---|
| 419 | | |
|---|
| 420 | | def GetRenderables(self, *args, **kw): |
|---|
| 421 | | self.Commit(*args, **kw) |
|---|
| 422 | | return self.renderables |
|---|
| 423 | | |
|---|
| 424 | | def Commit(self, target=None): |
|---|
| 425 | | self.geobin.Commit(self) |
|---|
| 426 | | del self.geobin |
|---|
| 427 | | if target is not None: |
|---|
| 428 | | target.ExtendRenderables(self.renderables) |
|---|
| 429 | | |
|---|
| 430 | | class GLGeometryTransaction(object): |
|---|
| 431 | | def __init__(self, points=None, singlecolor=None, colors=None): |
|---|
| 432 | | self.primitives = [] |
|---|
| 433 | | self.traversals = [] |
|---|
| 434 | | if points is not None: |
|---|
| 435 | | self.SetPoints(points) |
|---|
| 436 | | |
|---|
| 437 | | if singlecolor is not None: |
|---|
| 438 | | assert colors is None |
|---|
| 439 | | self.SetSingleColor(singlecolor) |
|---|
| 440 | | elif colors is not None: |
|---|
| 441 | | assert singlecolor is None |
|---|
| 442 | | self.SetColors(colors) |
|---|
| 443 | | |
|---|
| 444 | | def SetPoints(self, points): |
|---|
| 445 | | if isinstance(points, Numeric.ArrayType): |
|---|
| 446 | | self.points = points |
|---|
| 447 | | else: |
|---|
| 448 | | self.points = Numeric.asarray(points, _NumericType) |
|---|
| 449 | | |
|---|
| 450 | | def SetSingleColor(self, color): |
|---|
| 451 | | assert getattr(self, 'points', None), "SetPoints must be called before SetSingleColor" |
|---|
| 452 | | self.SetColors([color]*len(self.points)) |
|---|
| 453 | | |
|---|
| 454 | | def SetColors(self, colors): |
|---|
| 455 | | self.colors = Numeric.asarray(colors, Numeric.UInt8) |
|---|
| 456 | | |
|---|
| 457 | | def Add(self, glmode, indexes): |
|---|
| 458 | | self.primitives.append(glmode) |
|---|
| 459 | | self.traversals.append(indexes) |
|---|
| 460 | | |
|---|
| 461 | | def Commit(self, target): |
|---|
| 462 | | if target is not None and self.primitives and self.traversals: |
|---|
| 463 | | offset = target.AddData(self.points, self.colors) |
|---|
| 464 | | target.AddTranversals(self.primitives, self.traversals, offset) |
|---|
| 465 | | |
|---|
| 466 | | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 467 | | |
|---|
| 468 | | class GLStroke(GLGeometryTransaction): |
|---|
| 469 | | def AddLines(self, indexes): |
|---|
| 470 | | self.Add(GL.GL_LINES, indexes) |
|---|
| 471 | | def AddLineStrip(self, indexes): |
|---|
| 472 | | self.Add(GL.GL_LINE_STRIP, indexes) |
|---|
| 473 | | def AddLineLoop(self, indexes): |
|---|
| 474 | | self.Add(GL.GL_LINE_LOOP, indexes) |
|---|
| 475 | | |
|---|
| 476 | | class GLFill(GLGeometryTransaction): |
|---|
| 477 | | def AddTriangles(self, indexes): |
|---|
| 478 | | self.Add(GL.GL_TRIANGLES, indexes) |
|---|
| 479 | | def AddTriangleStrip(self, indexes): |
|---|
| 480 | | self.Add(GL.GL_TRIANGLE_STRIP, indexes) |
|---|
| 481 | | def AddTriangleFan(self, indexes): |
|---|
| 482 | | self.Add(GL.GL_TRIANGLE_FAN, indexes) |
|---|
| 483 | | |
|---|
| 484 | | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|