VisPyTesselators.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. def _on_error(self, errno):
  27. print("GLUTess error:", errno)
  28. def _on_end_primitive(self):
  29. pass
  30. def triangulate(self, polygon):
  31. """
  32. Triangulates polygon
  33. :param polygon: shapely.geometry.polygon
  34. Polygon to tessellate
  35. :return: list, list
  36. Array of triangle vertex indices [t0i0, t0i1, t0i2, t1i0, t1i1, ... ]
  37. Array of polygon points [(x0, y0), (x1, y1), ... ]
  38. """
  39. # Create tessellation object
  40. tess = GLU.gluNewTess()
  41. # Setup callbacks
  42. GLU.gluTessCallback(tess, GLU.GLU_TESS_BEGIN, self._on_begin_primitive)
  43. GLU.gluTessCallback(tess, GLU.GLU_TESS_VERTEX, self._on_new_vertex)
  44. GLU.gluTessCallback(tess, GLU.GLU_TESS_EDGE_FLAG, self._on_edge_flag)
  45. GLU.gluTessCallback(tess, GLU.GLU_TESS_COMBINE, self._on_combine)
  46. GLU.gluTessCallback(tess, GLU.GLU_TESS_ERROR, self._on_error)
  47. GLU.gluTessCallback(tess, GLU.GLU_TESS_END, self._on_end_primitive)
  48. # Reset data
  49. del self.tris[:]
  50. del self.pts[:]
  51. self.vertex_index = 0
  52. # Define polygon
  53. GLU.gluTessBeginPolygon(tess, None)
  54. def define_contour(contour):
  55. vertices = list(contour.coords) # Get vertices coordinates
  56. if vertices[0] == vertices[-1]: # Open ring
  57. vertices = vertices[:-1]
  58. self.pts += vertices
  59. GLU.gluTessBeginContour(tess) # Start contour
  60. # Set vertices
  61. for vertex in vertices:
  62. point = (vertex[0], vertex[1], 0)
  63. GLU.gluTessVertex(tess, point, self.vertex_index)
  64. self.vertex_index += 1
  65. GLU.gluTessEndContour(tess) # End contour
  66. # Polygon exterior
  67. define_contour(polygon.exterior)
  68. # Interiors
  69. for interior in polygon.interiors:
  70. define_contour(interior)
  71. # Start tessellation
  72. GLU.gluTessEndPolygon(tess)
  73. # Free resources
  74. GLU.gluDeleteTess(tess)
  75. return self.tris, self.pts