VisPyTesselators.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. # ##########################################################
  2. # FlatCAM: 2D Post-processing for Manufacturing #
  3. # http://flatcam.org #
  4. # File Author: Dennis Hayrullin #
  5. # Date: 2/5/2016 #
  6. # MIT Licence #
  7. # ##########################################################
  8. from OpenGL import GLU
  9. class GLUTess:
  10. def __init__(self):
  11. """
  12. OpenGL GLU triangulation class
  13. """
  14. self.tris = []
  15. self.pts = []
  16. self.vertex_index = 0
  17. def _on_begin_primitive(self, type):
  18. pass
  19. def _on_new_vertex(self, vertex):
  20. self.tris.append(vertex)
  21. # Force GLU to return separate triangles (GLU_TRIANGLES)
  22. def _on_edge_flag(self, flag):
  23. pass
  24. def _on_combine(self, coords, data, weight):
  25. return coords[0], coords[1], coords[2]
  26. @staticmethod
  27. def _on_error(errno):
  28. print("GLUTess error:", errno)
  29. def _on_end_primitive(self):
  30. pass
  31. def triangulate(self, polygon):
  32. """
  33. Triangulates polygon
  34. :param polygon: shapely.geometry.polygon
  35. Polygon to tessellate
  36. :return: list, list
  37. Array of triangle vertex indices [t0i0, t0i1, t0i2, t1i0, t1i1, ... ]
  38. Array of polygon points [(x0, y0), (x1, y1), ... ]
  39. """
  40. # Create tessellation object
  41. tess = GLU.gluNewTess()
  42. # Setup callbacks
  43. GLU.gluTessCallback(tess, GLU.GLU_TESS_BEGIN, self._on_begin_primitive)
  44. GLU.gluTessCallback(tess, GLU.GLU_TESS_VERTEX, self._on_new_vertex)
  45. GLU.gluTessCallback(tess, GLU.GLU_TESS_EDGE_FLAG, self._on_edge_flag)
  46. GLU.gluTessCallback(tess, GLU.GLU_TESS_COMBINE, self._on_combine)
  47. GLU.gluTessCallback(tess, GLU.GLU_TESS_ERROR, self._on_error)
  48. GLU.gluTessCallback(tess, GLU.GLU_TESS_END, self._on_end_primitive)
  49. # Reset data
  50. del self.tris[:]
  51. del self.pts[:]
  52. self.vertex_index = 0
  53. # Define polygon
  54. GLU.gluTessBeginPolygon(tess, None)
  55. def define_contour(contour):
  56. vertices = list(contour.coords) # Get vertices coordinates
  57. if vertices[0] == vertices[-1]: # Open ring
  58. vertices = vertices[:-1]
  59. self.pts += vertices
  60. GLU.gluTessBeginContour(tess) # Start contour
  61. # Set vertices
  62. for vertex in vertices:
  63. point = (vertex[0], vertex[1], 0)
  64. GLU.gluTessVertex(tess, point, self.vertex_index)
  65. self.vertex_index += 1
  66. GLU.gluTessEndContour(tess) # End contour
  67. # Polygon exterior
  68. define_contour(polygon.exterior)
  69. # Interiors
  70. for interior in polygon.interiors:
  71. define_contour(interior)
  72. # Start tessellation
  73. GLU.gluTessEndPolygon(tess)
  74. # Free resources
  75. GLU.gluDeleteTess(tess)
  76. return self.tris, self.pts