mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-16 03:07:53 -06:00
Formulate layerview logic using numpy to speed up. Also changed layer data packets from engine to make it possible.
This commit is contained in:
parent
ac0f743855
commit
f184baadf0
6 changed files with 202 additions and 92 deletions
102
cura/Layer.py
102
cura/Layer.py
|
@ -35,24 +35,31 @@ class Layer:
|
||||||
def setThickness(self, thickness):
|
def setThickness(self, thickness):
|
||||||
self._thickness = thickness
|
self._thickness = thickness
|
||||||
|
|
||||||
def vertexCount(self):
|
def lineMeshVertexCount(self):
|
||||||
result = 0
|
result = 0
|
||||||
for polygon in self._polygons:
|
for polygon in self._polygons:
|
||||||
result += polygon.vertexCount()
|
result += polygon.lineMeshVertexCount()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def build(self, offset, vertices, colors, indices):
|
def lineMeshElementCount(self):
|
||||||
result = offset
|
result = 0
|
||||||
for polygon in self._polygons:
|
for polygon in self._polygons:
|
||||||
if polygon.type == LayerPolygon.InfillType or polygon.type == LayerPolygon.MoveCombingType or polygon.type == LayerPolygon.MoveRetractionType:
|
result += polygon.lineMeshElementCount()
|
||||||
continue
|
|
||||||
|
|
||||||
polygon.build(result, vertices, colors, indices)
|
return result
|
||||||
result += polygon.vertexCount()
|
|
||||||
|
def build(self, vertex_offset, index_offset, vertices, colors, indices):
|
||||||
|
result_vertex_offset = vertex_offset
|
||||||
|
result_index_offset = index_offset
|
||||||
|
self._element_count = 0
|
||||||
|
for polygon in self._polygons:
|
||||||
|
polygon.build(result_vertex_offset, result_index_offset, vertices, colors, indices)
|
||||||
|
result_vertex_offset += polygon.lineMeshVertexCount()
|
||||||
|
result_index_offset += polygon.lineMeshElementCount()
|
||||||
self._element_count += polygon.elementCount
|
self._element_count += polygon.elementCount
|
||||||
|
|
||||||
return result
|
return (result_vertex_offset,result_index_offset)
|
||||||
|
|
||||||
def createMesh(self):
|
def createMesh(self):
|
||||||
return self.createMeshOrJumps(True)
|
return self.createMeshOrJumps(True)
|
||||||
|
@ -61,39 +68,58 @@ class Layer:
|
||||||
return self.createMeshOrJumps(False)
|
return self.createMeshOrJumps(False)
|
||||||
|
|
||||||
def createMeshOrJumps(self, make_mesh):
|
def createMeshOrJumps(self, make_mesh):
|
||||||
builder = MeshBuilder()
|
builder = MeshBuilder() # This is never really used, only the mesh_data inside
|
||||||
|
index_pattern = numpy.array([[0,3,2,0,1,3]],dtype = numpy.int32 )
|
||||||
|
|
||||||
|
line_count = 0
|
||||||
|
if make_mesh:
|
||||||
|
for polygon in self._polygons:
|
||||||
|
line_count += polygon._mesh_line_count
|
||||||
|
else:
|
||||||
|
for polygon in self._polygons:
|
||||||
|
line_count += polygon._jump_count
|
||||||
|
|
||||||
|
|
||||||
|
# Reserve the neccesary space for the data upfront
|
||||||
|
builder.reserveFaceAndVerticeCount( 2*line_count, 4*line_count )
|
||||||
|
|
||||||
for polygon in self._polygons:
|
for polygon in self._polygons:
|
||||||
if make_mesh and (polygon.type == LayerPolygon.MoveCombingType or polygon.type == LayerPolygon.MoveRetractionType):
|
#if make_mesh and (polygon.type == LayerPolygon.MoveCombingType or polygon.type == LayerPolygon.MoveRetractionType):
|
||||||
continue
|
# continue
|
||||||
if not make_mesh and not (polygon.type == LayerPolygon.MoveCombingType or polygon.type == LayerPolygon.MoveRetractionType):
|
#if not make_mesh and not (polygon.type == LayerPolygon.MoveCombingType or polygon.type == LayerPolygon.MoveRetractionType):
|
||||||
continue
|
# continue
|
||||||
|
|
||||||
|
index_mask = numpy.logical_not(polygon._jump_mask) if make_mesh else polygon._jump_mask
|
||||||
|
|
||||||
poly_color = polygon.getColor()
|
# Create an array with rows [p p+1] and only save those we whant to draw based on make_mesh
|
||||||
|
points = numpy.concatenate((polygon.data[:-1],polygon.data[1:]),1)[index_mask.ravel()]
|
||||||
|
# Line types of the points we want to draw
|
||||||
|
line_types = polygon._types[index_mask]
|
||||||
|
|
||||||
|
|
||||||
|
#if polygon.type == LayerPolygon.InfillType or polygon.type == LayerPolygon.SkinType or polygon.type == LayerPolygon.SupportInfillType:
|
||||||
|
# points[:,1] -= 0.01
|
||||||
|
#if polygon.type == LayerPolygon.MoveCombingType or polygon.type == LayerPolygon.MoveRetractionType:
|
||||||
|
# points[:,1] += 0.01
|
||||||
|
# Shift the z-axis according to previous implementation.
|
||||||
|
if make_mesh:
|
||||||
|
points[polygon._orInfillSkin[line_types],1::3] -= 0.01
|
||||||
|
else:
|
||||||
|
points[:,1::3] += 0.01
|
||||||
|
|
||||||
points = numpy.copy(polygon.data)
|
# Create an array with normals and tile 2 copies to match size of points variable
|
||||||
if polygon.type == LayerPolygon.InfillType or polygon.type == LayerPolygon.SkinType or polygon.type == LayerPolygon.SupportInfillType:
|
normals = numpy.tile( polygon.getNormals()[index_mask.ravel()], (1,2))
|
||||||
points[:,1] -= 0.01
|
|
||||||
if polygon.type == LayerPolygon.MoveCombingType or polygon.type == LayerPolygon.MoveRetractionType:
|
|
||||||
points[:,1] += 0.01
|
|
||||||
|
|
||||||
normals = polygon.getNormals()
|
# Scale all normals by the line width of the current line so we can easily offset.
|
||||||
|
normals *= (polygon.lineWidths[index_mask.ravel()] / 2)
|
||||||
|
|
||||||
# Scale all by the line width of the polygon so we can easily offset.
|
# Create 4 points to draw each line segment, points +- normals results in 2 points each. Reshape to one point per line
|
||||||
normals *= (polygon.lineWidth / 2)
|
f_points = numpy.concatenate((points-normals,points+normals),1).reshape((-1,3))
|
||||||
|
# index_pattern defines which points to use to draw the two faces for each lines egment, the following linesegment is offset by 4
|
||||||
|
f_indices = ( index_pattern + numpy.arange(0,4*len(normals),4,dtype=numpy.int32).reshape((-1,1)) ).reshape((-1,3))
|
||||||
|
f_colors = numpy.repeat(polygon._color_map[line_types], 4, 0)
|
||||||
|
|
||||||
#TODO: Use numpy magic to perform the vertex creation to speed up things.
|
builder.addFacesWithColor(f_points, f_indices, f_colors)
|
||||||
for i in range(len(points)):
|
|
||||||
start = points[i - 1]
|
|
||||||
end = points[i]
|
|
||||||
|
|
||||||
normal = normals[i - 1]
|
|
||||||
|
return builder.build()
|
||||||
point1 = Vector(data = start - normal)
|
|
||||||
point2 = Vector(data = start + normal)
|
|
||||||
point3 = Vector(data = end + normal)
|
|
||||||
point4 = Vector(data = end - normal)
|
|
||||||
|
|
||||||
builder.addQuad(point1, point2, point3, point4, color = poly_color)
|
|
||||||
|
|
||||||
return builder.build()
|
|
|
@ -50,18 +50,22 @@ class LayerDataBuilder(MeshBuilder):
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
vertex_count = 0
|
vertex_count = 0
|
||||||
|
index_count = 0
|
||||||
for layer, data in self._layers.items():
|
for layer, data in self._layers.items():
|
||||||
vertex_count += data.vertexCount()
|
vertex_count += data.lineMeshVertexCount()
|
||||||
|
index_count += data.lineMeshElementCount()
|
||||||
|
|
||||||
vertices = numpy.empty((vertex_count, 3), numpy.float32)
|
vertices = numpy.empty((vertex_count, 3), numpy.float32)
|
||||||
colors = numpy.empty((vertex_count, 4), numpy.float32)
|
colors = numpy.empty((vertex_count, 4), numpy.float32)
|
||||||
indices = numpy.empty((vertex_count, 2), numpy.int32)
|
indices = numpy.empty((index_count, 2), numpy.int32)
|
||||||
|
|
||||||
offset = 0
|
vertex_offset = 0
|
||||||
|
index_offset = 0
|
||||||
for layer, data in self._layers.items():
|
for layer, data in self._layers.items():
|
||||||
offset = data.build(offset, vertices, colors, indices)
|
( vertex_offset, index_offset ) = data.build( vertex_offset, index_offset, vertices, colors, indices)
|
||||||
self._element_counts[layer] = data.elementCount
|
self._element_counts[layer] = data.elementCount
|
||||||
|
|
||||||
|
self.clear()
|
||||||
self.addVertices(vertices)
|
self.addVertices(vertices)
|
||||||
self.addColors(colors)
|
self.addColors(colors)
|
||||||
self.addIndices(indices.flatten())
|
self.addIndices(indices.flatten())
|
||||||
|
|
|
@ -14,40 +14,96 @@ class LayerPolygon:
|
||||||
SupportInfillType = 7
|
SupportInfillType = 7
|
||||||
MoveCombingType = 8
|
MoveCombingType = 8
|
||||||
MoveRetractionType = 9
|
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._mesh = mesh
|
||||||
self._type = polygon_type
|
self._types = line_types
|
||||||
self._data = data
|
self._data = data
|
||||||
self._line_width = line_width / 1000
|
self._line_widths = line_widths / 1000
|
||||||
self._begin = 0
|
|
||||||
self._end = 0
|
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])
|
||||||
|
|
||||||
self._color = self.__color_map[polygon_type]
|
# 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, offset, vertices, colors, indices):
|
def build(self, vertex_offset, index_offset, vertices, colors, indices):
|
||||||
self._begin = offset
|
if (self._build_cache_line_mesh_mask == None) or (self._build_cache_needed_points == None ):
|
||||||
self._end = self._begin + len(self._data) - 1
|
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)
|
||||||
|
|
||||||
vertices[self._begin:self._end + 1, :] = self._data[:, :]
|
self._index_begin += index_offset
|
||||||
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)
|
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
|
||||||
|
|
||||||
for i in range(self._begin, self._end):
|
def getColors(self):
|
||||||
indices[i, 0] = i
|
return self._colors
|
||||||
indices[i, 1] = i + 1
|
|
||||||
|
|
||||||
indices[self._end, 0] = self._end
|
def lineMeshVertexCount(self):
|
||||||
indices[self._end, 1] = self._begin
|
return (self._vertex_end - self._vertex_begin)
|
||||||
|
|
||||||
def getColor(self):
|
def lineMeshElementCount(self):
|
||||||
return self._color
|
return (self._index_end - self._index_begin)
|
||||||
|
|
||||||
def vertexCount(self):
|
|
||||||
return len(self._data)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type(self):
|
def types(self):
|
||||||
return self._type
|
return self._types
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def data(self):
|
def data(self):
|
||||||
|
@ -55,11 +111,11 @@ class LayerPolygon:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def elementCount(self):
|
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
|
@property
|
||||||
def lineWidth(self):
|
def lineWidths(self):
|
||||||
return self._line_width
|
return self._line_widths
|
||||||
|
|
||||||
# Calculate normals for the entire polygon using numpy.
|
# Calculate normals for the entire polygon using numpy.
|
||||||
def getNormals(self):
|
def getNormals(self):
|
||||||
|
@ -71,7 +127,8 @@ class LayerPolygon:
|
||||||
# we end up subtracting each next point from the current, wrapping
|
# we end up subtracting each next point from the current, wrapping
|
||||||
# around. This gives us the edges from the next point to the current
|
# around. This gives us the edges from the next point to the current
|
||||||
# point.
|
# point.
|
||||||
normals[:] = normals[:] - numpy.roll(normals, -1, axis = 0)
|
normals = numpy.diff(normals, 1, 0)
|
||||||
|
|
||||||
# Calculate the length of each edge using standard Pythagoras
|
# Calculate the length of each edge using standard Pythagoras
|
||||||
lengths = numpy.sqrt(normals[:, 0] ** 2 + normals[:, 2] ** 2)
|
lengths = numpy.sqrt(normals[:, 0] ** 2 + normals[:, 2] ** 2)
|
||||||
# The normal of a 2D vector is equal to its x and y coordinates swapped
|
# The normal of a 2D vector is equal to its x and y coordinates swapped
|
||||||
|
@ -85,7 +142,7 @@ class LayerPolygon:
|
||||||
|
|
||||||
return normals
|
return normals
|
||||||
|
|
||||||
__color_map = {
|
__color_mapping = {
|
||||||
NoneType: Color(1.0, 1.0, 1.0, 1.0),
|
NoneType: Color(1.0, 1.0, 1.0, 1.0),
|
||||||
Inset0Type: Color(1.0, 0.0, 0.0, 1.0),
|
Inset0Type: Color(1.0, 0.0, 0.0, 1.0),
|
||||||
InsetXType: Color(0.0, 1.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),
|
MoveCombingType: Color(0.0, 0.0, 1.0, 1.0),
|
||||||
MoveRetractionType: Color(0.5, 0.5, 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]])
|
||||||
|
|
|
@ -44,21 +44,9 @@ message Layer {
|
||||||
}
|
}
|
||||||
|
|
||||||
message Polygon {
|
message Polygon {
|
||||||
enum Type {
|
bytes line_type = 1;
|
||||||
NoneType = 0;
|
bytes points = 2;
|
||||||
Inset0Type = 1;
|
bytes line_width = 3;
|
||||||
InsetXType = 2;
|
|
||||||
SkinType = 3;
|
|
||||||
SupportType = 4;
|
|
||||||
SkirtType = 5;
|
|
||||||
InfillType = 6;
|
|
||||||
SupportInfillType = 7;
|
|
||||||
MoveCombingType = 8;
|
|
||||||
MoveRetractionType = 9;
|
|
||||||
}
|
|
||||||
Type type = 1; // Type of move
|
|
||||||
bytes points = 2; // The points of the polygon, or two points if only a line segment (Currently only line segments are used)
|
|
||||||
float line_width = 3; // The width of the line being laid down
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message GCodeLayer {
|
message GCodeLayer {
|
||||||
|
@ -86,4 +74,4 @@ message GCodePrefix {
|
||||||
}
|
}
|
||||||
|
|
||||||
message SlicingFinished {
|
message SlicingFinished {
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ from UM.Math.Vector import Vector
|
||||||
|
|
||||||
from cura import LayerDataBuilder
|
from cura import LayerDataBuilder
|
||||||
from cura import LayerDataDecorator
|
from cura import LayerDataDecorator
|
||||||
|
from cura import LayerPolygon
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
|
@ -38,6 +39,12 @@ class ProcessSlicedLayersJob(Job):
|
||||||
self._abort_requested = True
|
self._abort_requested = True
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
# This is to prevent small models layer data to be cleared by extra invocation of engine
|
||||||
|
# Possibly adds an extra bug of layerdata not being removed if platform is cleared.
|
||||||
|
#TODO: remove need for this check
|
||||||
|
if len(self._layers) == 0:
|
||||||
|
return
|
||||||
|
|
||||||
if Application.getInstance().getController().getActiveView().getPluginId() == "LayerView":
|
if Application.getInstance().getController().getActiveView().getPluginId() == "LayerView":
|
||||||
self._progress = Message(catalog.i18nc("@info:status", "Processing Layers"), 0, False, -1)
|
self._progress = Message(catalog.i18nc("@info:status", "Processing Layers"), 0, False, -1)
|
||||||
self._progress.show()
|
self._progress.show()
|
||||||
|
@ -80,15 +87,22 @@ class ProcessSlicedLayersJob(Job):
|
||||||
abs_layer_number = layer.id + abs(min_layer_number)
|
abs_layer_number = layer.id + abs(min_layer_number)
|
||||||
|
|
||||||
layer_data.addLayer(abs_layer_number)
|
layer_data.addLayer(abs_layer_number)
|
||||||
|
this_layer = layer_data.getLayer(abs_layer_number)
|
||||||
layer_data.setLayerHeight(abs_layer_number, layer.height)
|
layer_data.setLayerHeight(abs_layer_number, layer.height)
|
||||||
layer_data.setLayerThickness(abs_layer_number, layer.thickness)
|
layer_data.setLayerThickness(abs_layer_number, layer.thickness)
|
||||||
|
|
||||||
for p in range(layer.repeatedMessageCount("polygons")):
|
for p in range(layer.repeatedMessageCount("polygons")):
|
||||||
polygon = layer.getRepeatedMessage("polygons", p)
|
polygon = layer.getRepeatedMessage("polygons", p)
|
||||||
|
|
||||||
|
line_types = numpy.fromstring(polygon.line_type, dtype="u1") # Convert bytearray to numpy array
|
||||||
|
line_types = line_types.reshape((-1,1))
|
||||||
|
|
||||||
points = numpy.fromstring(polygon.points, dtype="i8") # Convert bytearray to numpy array
|
points = numpy.fromstring(polygon.points, dtype="i8") # Convert bytearray to numpy array
|
||||||
points = points.reshape((-1,2)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly.
|
points = points.reshape((-1,2)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly.
|
||||||
|
|
||||||
|
line_widths = numpy.fromstring(polygon.line_width, dtype="i4") # Convert bytearray to numpy array
|
||||||
|
line_widths = line_widths.reshape((-1,1)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly.
|
||||||
|
|
||||||
# Create a new 3D-array, copy the 2D points over and insert the right height.
|
# Create a new 3D-array, copy the 2D points over and insert the right height.
|
||||||
# This uses manual array creation + copy rather than numpy.insert since this is
|
# This uses manual array creation + copy rather than numpy.insert since this is
|
||||||
# faster.
|
# faster.
|
||||||
|
@ -99,7 +113,11 @@ class ProcessSlicedLayersJob(Job):
|
||||||
|
|
||||||
new_points /= 1000
|
new_points /= 1000
|
||||||
|
|
||||||
layer_data.addPolygon(abs_layer_number, polygon.type, new_points, polygon.line_width)
|
this_poly = LayerPolygon.LayerPolygon(layer_data, line_types, new_points, line_widths)
|
||||||
|
this_poly.build_cache()
|
||||||
|
|
||||||
|
this_layer.polygons.append(this_poly)
|
||||||
|
|
||||||
Job.yieldThread()
|
Job.yieldThread()
|
||||||
Job.yieldThread()
|
Job.yieldThread()
|
||||||
current_layer += 1
|
current_layer += 1
|
||||||
|
|
|
@ -25,6 +25,8 @@ from . import LayerViewProxy
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
import numpy
|
||||||
|
|
||||||
## View used to display g-code paths.
|
## View used to display g-code paths.
|
||||||
class LayerView(View):
|
class LayerView(View):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -42,7 +44,7 @@ class LayerView(View):
|
||||||
self._top_layers_job = None
|
self._top_layers_job = None
|
||||||
self._activity = False
|
self._activity = False
|
||||||
|
|
||||||
Preferences.getInstance().addPreference("view/top_layer_count", 1)
|
Preferences.getInstance().addPreference("view/top_layer_count", 5)
|
||||||
Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged)
|
Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged)
|
||||||
|
|
||||||
self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count"))
|
self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count"))
|
||||||
|
@ -255,12 +257,14 @@ class _CreateTopLayersJob(Job):
|
||||||
if not layer or layer.getVertices() is None:
|
if not layer or layer.getVertices() is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
layer_mesh.addIndices(layer_mesh._vertex_count+layer.getIndices())
|
||||||
layer_mesh.addVertices(layer.getVertices())
|
layer_mesh.addVertices(layer.getVertices())
|
||||||
|
|
||||||
# Scale layer color by a brightness factor based on the current layer number
|
# Scale layer color by a brightness factor based on the current layer number
|
||||||
# This will result in a range of 0.5 - 1.0 to multiply colors by.
|
# This will result in a range of 0.5 - 1.0 to multiply colors by.
|
||||||
brightness = (2.0 - (i / self._solid_layers)) / 2.0
|
brightness = numpy.ones((1,4),dtype=numpy.float32) * (2.0 - (i / self._solid_layers)) / 2.0
|
||||||
layer_mesh.addColors(layer.getColors() * brightness)
|
brightness[0,3] = 1.0;
|
||||||
|
layer_mesh.addColors(layer.getColors() * brightness )
|
||||||
|
|
||||||
if self._cancel:
|
if self._cancel:
|
||||||
return
|
return
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue