# Path: PyOpenGLng/HighLevelApi/PrimitiveVertexArray.py
# class TriangleVertexArray(GlVertexArrayObject):
# 
#     """ Base class to draw primitives as triangles. """
# 
#     # Fixme: 3d
# 
#     ##############################################
# 
#     def __init__(self, items=None):
# 
#         super(TriangleVertexArray, self).__init__()
# 
#         self._number_of_items = 0
#         self._positions_buffer = GlArrayBuffer()
#         self._normals_buffer = GlArrayBuffer()
#         self._colours_buffer = GlArrayBuffer()
# 
#         if items is not None:
#             self.set(*items)
# 
#     ##############################################
# 
#     def set(self, positions, normals, colours):
# 
#         """ Set the vertex array from an iterable of triangles. """
# 
#         self._number_of_items = positions.shape[0]
# 
#         # Fixme:
#         #  - set from high level primitive: slow
#         #  - set from Numpy array: fast but check for mistake
# 
#         # vertex = np.zeros((self._number_of_objects, 3), dtype='f') # dtype=np.float
# 
#         self._positions_buffer.set(positions)
#         self._normals_buffer.set(normals)
#         self._colours_buffer.set(colours)
# 
#     ##############################################
# 
#     def bind_to_shader(self, shader_program_interface):
# 
#         """ Bind the vertex array to the shader program interface attribute.
#         """
# 
#         # Fixme: we cannot reuse the vbo
# 
#         self.bind()
#         shader_program_interface.position.bind_to_buffer(self._positions_buffer)
#         shader_program_interface.normal.bind_to_buffer(self._normals_buffer)
#         shader_program_interface.colour.bind_to_buffer(self._colours_buffer)
#         self.unbind()
# 
#     ##############################################
# 
#     def draw(self):
# 
#         """ Draw the vertex array as lines. """
# 
#         self.bind()
#         GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3*self._number_of_items)
#         self.unbind()
# 
# Path: PyOpenGLng/Tools/EnumFactory.py
# def EnumFactory(enum_name, enum_tuple):
# 
#     """ Return an :class:`EnumMetaClass` instance, where *enum_name* is the class name and
#     *enum_tuple* is an iterable of constant's names.
#     """
# 
#     obj_dict = {}
#     obj_dict['_size'] = len(enum_tuple)
#     for value, name in enumerate(enum_tuple):
#         obj_dict[name] = EnumConstant(name, value)
# 
#     return EnumMetaClass(enum_name, (), obj_dict)


import mmap
import struct
import numpy as np
from .PrimitiveVertexArray import TriangleVertexArray
from PyOpenGLng.Tools.EnumFactory import EnumFactory

        with(open(path, 'r')) as file_handle:
            stream = mmap.mmap(file_handle.fileno(), length=0, access=mmap.ACCESS_READ)
            text_stl = stream.read(6) == 'solid '
            stream.seek(0)
            if text_stl:
                self._read_text(file_handle)
            else:
                self._read_binary(file_handle, stream)

    ##############################################

    def _read_text(self, file_handle):

        # solid OpenSCAD_Model
        #   facet normal -1 0 0
        #     outer loop
        #       vertex 0 0 1
        #       vertex 0 1 1
        #       vertex 0 0 0
        #     endloop
        #   endfacet
        #   ...
        # endsolid OpenSCAD_Model

        vertexes = []
        normals = []
        states = self.stl_parser_state
        state = states.start
        normal = None

# Path: PyOpenGLng/HighLevelApi/PrimitiveVertexArray.py
# class TriangleVertexArray(GlVertexArrayObject):
# 
#     """ Base class to draw primitives as triangles. """
# 
#     # Fixme: 3d
# 
#     ##############################################
# 
#     def __init__(self, items=None):
# 
#         super(TriangleVertexArray, self).__init__()
# 
#         self._number_of_items = 0
#         self._positions_buffer = GlArrayBuffer()
#         self._normals_buffer = GlArrayBuffer()
#         self._colours_buffer = GlArrayBuffer()
# 
#         if items is not None:
#             self.set(*items)
# 
#     ##############################################
# 
#     def set(self, positions, normals, colours):
# 
#         """ Set the vertex array from an iterable of triangles. """
# 
#         self._number_of_items = positions.shape[0]
# 
#         # Fixme:
#         #  - set from high level primitive: slow
#         #  - set from Numpy array: fast but check for mistake
# 
#         # vertex = np.zeros((self._number_of_objects, 3), dtype='f') # dtype=np.float
# 
#         self._positions_buffer.set(positions)
#         self._normals_buffer.set(normals)
#         self._colours_buffer.set(colours)
# 
#     ##############################################
# 
#     def bind_to_shader(self, shader_program_interface):
# 
#         """ Bind the vertex array to the shader program interface attribute.
#         """
# 
#         # Fixme: we cannot reuse the vbo
# 
#         self.bind()
#         shader_program_interface.position.bind_to_buffer(self._positions_buffer)
#         shader_program_interface.normal.bind_to_buffer(self._normals_buffer)
#         shader_program_interface.colour.bind_to_buffer(self._colours_buffer)
#         self.unbind()
# 
#     ##############################################
# 
#     def draw(self):
# 
#         """ Draw the vertex array as lines. """
# 
#         self.bind()
#         GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3*self._number_of_items)
#         self.unbind()
# 
# Path: PyOpenGLng/Tools/EnumFactory.py
# def EnumFactory(enum_name, enum_tuple):
# 
#     """ Return an :class:`EnumMetaClass` instance, where *enum_name* is the class name and
#     *enum_tuple* is an iterable of constant's names.
#     """
# 
#     obj_dict = {}
#     obj_dict['_size'] = len(enum_tuple)
#     for value, name in enumerate(enum_tuple):
#         obj_dict[name] = EnumConstant(name, value)
# 
#     return EnumMetaClass(enum_name, (), obj_dict)


# Path: PyOpenGLng/HighLevelApi/STL.py
import mmap
import struct
import numpy as np
from .PrimitiveVertexArray import TriangleVertexArray
from PyOpenGLng.Tools.EnumFactory import EnumFactory


        with(open(path, 'r')) as file_handle:
            stream = mmap.mmap(file_handle.fileno(), length=0, access=mmap.ACCESS_READ)
            text_stl = stream.read(6) == 'solid '
            stream.seek(0)
            if text_stl:
                self._read_text(file_handle)
            else:
                self._read_binary(file_handle, stream)

    ##############################################

    def _read_text(self, file_handle):

        # solid OpenSCAD_Model
        #   facet normal -1 0 0
        #     outer loop
        #       vertex 0 0 1
        #       vertex 0 1 1
        #       vertex 0 0 0
        #     endloop
        #   endfacet
        #   ...
        # endsolid OpenSCAD_Model

        vertexes = []
        normals = []
        states = self.stl_parser_state
        state = states.start
        normal = None

        for line in file_handle: