diff options
author | Johan K <johan@3dverkstan.se> | 2016-06-14 19:08:35 +0300 |
---|---|---|
committer | Johan Kristensen <johan@3dverkstan.se> | 2016-06-28 23:29:29 +0300 |
commit | f184baadf0a396743268b29027a1d4031d73991d (patch) | |
tree | f540a0cf093b58d573e7f2bc4469269c71afe55c /cura/LayerPolygon.py | |
parent | ac0f743855ed2df9d9542724b911a8f3a43dd07c (diff) |
Formulate layerview logic using numpy to speed up. Also changed layer data packets from engine to make it possible.
Diffstat (limited to 'cura/LayerPolygon.py')
-rw-r--r-- | cura/LayerPolygon.py | 140 |
1 files changed, 105 insertions, 35 deletions
diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index c4dc5d4954..f2c84e0d57 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -14,40 +14,96 @@ class LayerPolygon: SupportInfillType = 7 MoveCombingType = 8 MoveRetractionType = 9 - - def __init__(self, mesh, polygon_type, data, line_width): + + __jump_map = numpy.logical_or( numpy.arange(10) == NoneType, numpy.arange(10) >= MoveCombingType ) + + def __init__(self, mesh, line_types, data, line_widths): self._mesh = mesh - self._type = polygon_type + self._types = line_types self._data = data - self._line_width = line_width / 1000 - self._begin = 0 - self._end = 0 - - self._color = self.__color_map[polygon_type] - - def build(self, offset, vertices, colors, indices): - self._begin = offset - self._end = self._begin + len(self._data) - 1 - - vertices[self._begin:self._end + 1, :] = self._data[:, :] - colors[self._begin:self._end + 1, :] = numpy.array([self._color.r * 0.5, self._color.g * 0.5, self._color.b * 0.5, self._color.a], numpy.float32) - - for i in range(self._begin, self._end): - indices[i, 0] = i - indices[i, 1] = i + 1 - - indices[self._end, 0] = self._end - indices[self._end, 1] = self._begin - - def getColor(self): - return self._color - - def vertexCount(self): - return len(self._data) + self._line_widths = line_widths / 1000 + + self._vertex_begin = 0 + self._vertex_end = 0 + self._index_begin = 0 + self._index_end = 0 + + self._jump_mask = self.__jump_map[self._types] + self._jump_count = numpy.sum(self._jump_mask) + self._mesh_line_count = len(self._types)-self._jump_count + self._vertex_count = self._mesh_line_count + numpy.sum( self._types[1:] == self._types[:-1]) + + # Buffering the colors shouldn't be necessary as it is not + # re-used and can save alot of memory usage. + self._colors = self.__color_map[self._types] + self._color_map = self.__color_map + + # type == LayerPolygon.InfillType or type == LayerPolygon.SkinType or type == LayerPolygon.SupportInfillType + # Should be generated in better way, not hardcoded. + self._orInfillSkin = numpy.array([0,0,0,1,0,0,1,1,0,0],dtype=numpy.bool) + + self._build_cache_line_mesh_mask = None + self._build_cache_needed_points = None + + def build_cache(self): + #if polygon.type == LayerPolygon.InfillType or polygon.type == LayerPolygon.MoveCombingType or polygon.type == LayerPolygon.MoveRetractionType: + # continue + self._build_cache_line_mesh_mask = numpy.logical_not(numpy.logical_or(self._jump_mask,self._types == LayerPolygon.InfillType )) + mesh_line_count = numpy.sum(self._build_cache_line_mesh_mask) + self._index_begin = 0 + self._index_end = mesh_line_count + + self._build_cache_needed_points = numpy.ones((len(self._types),2), dtype=numpy.bool) + # Only if the type of line segment changes do we need to add an extra vertex to change colors + self._build_cache_needed_points[1:,0][:,numpy.newaxis] = self._types[1:] != self._types[:-1] + # Remove points of types we don't want in the line mesh + numpy.logical_and(self._build_cache_needed_points, self._build_cache_line_mesh_mask, self._build_cache_needed_points ) + + self._vertex_begin = 0 + self._vertex_end = numpy.sum( self._build_cache_needed_points ) + + + def build(self, vertex_offset, index_offset, vertices, colors, indices): + if (self._build_cache_line_mesh_mask == None) or (self._build_cache_needed_points == None ): + self.build_cache() + + line_mesh_mask = self._build_cache_line_mesh_mask + needed_points_list = self._build_cache_needed_points + + index_list = ( numpy.arange(len(self._types)).reshape((-1,1)) + numpy.array([[0,1]]) ).reshape((-1,1))[needed_points_list.reshape((-1,1))] + + self._vertex_begin += vertex_offset + self._vertex_end += vertex_offset + + vertices[self._vertex_begin:self._vertex_end, :] = self._data[index_list, :] + colors[self._vertex_begin:self._vertex_end, :] = numpy.tile(self._colors,(1,2)).reshape((-1,4))[needed_points_list.ravel()] + colors[self._vertex_begin:self._vertex_end, :] *= numpy.array([[0.5, 0.5, 0.5, 1.0]], numpy.float32) + + self._index_begin += index_offset + self._index_end += index_offset + + indices[self._index_begin:self._index_end,:] = numpy.arange(self._index_end-self._index_begin, dtype=numpy.int32).reshape((-1,1)) + # When the line type changes the index needs to be increased by 2. + indices[self._index_begin:self._index_end,:] += numpy.cumsum(needed_points_list[line_mesh_mask.ravel(),0],dtype=numpy.int32).reshape((-1,1)) + # Each line segment goes from it's starting point p to p+1, offset by the vertex index. + # The -1 is to compensate for the neccecarily True value of needed_points_list[0,0] which causes an unwanted +1 in cumsum above. + indices[self._index_begin:self._index_end,:] += numpy.array([self._vertex_begin - 1,self._vertex_begin]) + + self._build_cache_line_mesh_mask = None + self._build_cache_needed_points = None + + def getColors(self): + return self._colors + + def lineMeshVertexCount(self): + return (self._vertex_end - self._vertex_begin) + + def lineMeshElementCount(self): + return (self._index_end - self._index_begin) @property - def type(self): - return self._type + def types(self): + return self._types @property def data(self): @@ -55,11 +111,11 @@ class LayerPolygon: @property def elementCount(self): - return ((self._end - self._begin) + 1) * 2 # The range of vertices multiplied by 2 since each vertex is used twice + return (self._index_end - self._index_begin) * 2 # The range of vertices multiplied by 2 since each vertex is used twice @property - def lineWidth(self): - return self._line_width + def lineWidths(self): + return self._line_widths # Calculate normals for the entire polygon using numpy. def getNormals(self): @@ -71,7 +127,8 @@ class LayerPolygon: # we end up subtracting each next point from the current, wrapping # around. This gives us the edges from the next point to the current # point. - normals[:] = normals[:] - numpy.roll(normals, -1, axis = 0) + normals = numpy.diff(normals, 1, 0) + # Calculate the length of each edge using standard Pythagoras lengths = numpy.sqrt(normals[:, 0] ** 2 + normals[:, 2] ** 2) # The normal of a 2D vector is equal to its x and y coordinates swapped @@ -85,7 +142,7 @@ class LayerPolygon: return normals - __color_map = { + __color_mapping = { NoneType: Color(1.0, 1.0, 1.0, 1.0), Inset0Type: Color(1.0, 0.0, 0.0, 1.0), InsetXType: Color(0.0, 1.0, 0.0, 1.0), @@ -97,3 +154,16 @@ class LayerPolygon: MoveCombingType: Color(0.0, 0.0, 1.0, 1.0), MoveRetractionType: Color(0.5, 0.5, 1.0, 1.0), } + + # Should be generated in better way, not hardcoded. + __color_map = numpy.array([ + [1.0, 1.0, 1.0, 1.0], + [1.0, 0.0, 0.0, 1.0], + [0.0, 1.0, 0.0, 1.0], + [1.0, 1.0, 0.0, 1.0], + [0.0, 1.0, 1.0, 1.0], + [0.0, 1.0, 1.0, 1.0], + [1.0, 0.74, 0.0, 1.0], + [0.0, 1.0, 1.0, 1.0], + [0.0, 0.0, 1.0, 1.0], + [0.5, 0.5, 1.0, 1.0]]) |