Cura/cura/LayerDataBuilder.py
2017-03-22 11:38:55 +01:00

117 lines
4.5 KiB
Python
Executable File

# Copyright (c) 2015 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
from .Layer import Layer
from .LayerPolygon import LayerPolygon
from UM.Mesh.MeshBuilder import MeshBuilder
from .LayerData import LayerData
import numpy
## Builder class for constructing a LayerData object
class LayerDataBuilder(MeshBuilder):
def __init__(self):
super().__init__()
self._layers = {}
self._element_counts = {}
def addLayer(self, layer):
if layer not in self._layers:
self._layers[layer] = Layer(layer)
def addPolygon(self, layer, polygon_type, data, line_width):
if layer not in self._layers:
self.addLayer(layer)
p = LayerPolygon(self, polygon_type, data, line_width)
self._layers[layer].polygons.append(p)
def getLayer(self, layer):
if layer in self._layers:
return self._layers[layer]
def getLayers(self):
return self._layers
def getElementCounts(self):
return self._element_counts
def setLayerHeight(self, layer, height):
if layer not in self._layers:
self.addLayer(layer)
self._layers[layer].setHeight(height)
def setLayerThickness(self, layer, thickness):
if layer not in self._layers:
self.addLayer(layer)
self._layers[layer].setThickness(thickness)
## Return the layer data as LayerData.
#
# \param material_color_map: [r, g, b, a] for each extruder row.
# \param line_type_brightness: compatibility layer view uses line type brightness of 0.5
def build(self, material_color_map, line_type_brightness = 1.0):
vertex_count = 0
index_count = 0
for layer, data in self._layers.items():
vertex_count += data.lineMeshVertexCount()
index_count += data.lineMeshElementCount()
vertices = numpy.empty((vertex_count, 3), numpy.float32)
line_dimensions = numpy.empty((vertex_count, 2), numpy.float32)
colors = numpy.empty((vertex_count, 4), numpy.float32)
indices = numpy.empty((index_count, 2), numpy.int32)
extruders = numpy.empty((vertex_count), numpy.float32)
line_types = numpy.empty((vertex_count), numpy.float32)
vertex_offset = 0
index_offset = 0
for layer, data in self._layers.items():
( vertex_offset, index_offset ) = data.build( vertex_offset, index_offset, vertices, colors, line_dimensions, extruders, line_types, indices)
self._element_counts[layer] = data.elementCount
self.addVertices(vertices)
colors[:, 0:3] *= line_type_brightness
self.addColors(colors)
self.addIndices(indices.flatten())
# Note: we're using numpy indexing here.
# See also: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
material_colors = numpy.zeros((line_dimensions.shape[0], 4), dtype=numpy.float32)
for extruder_nr in range(material_color_map.shape[0]):
material_colors[extruders == extruder_nr] = material_color_map[extruder_nr]
# Set material_colors with indices where line_types (also numpy array) == MoveCombingType
material_colors[line_types == LayerPolygon.MoveCombingType] = colors[line_types == LayerPolygon.MoveCombingType]
material_colors[line_types == LayerPolygon.MoveRetractionType] = colors[line_types == LayerPolygon.MoveRetractionType]
attributes = {
"line_dimensions": {
"value": line_dimensions,
"opengl_name": "a_line_dim",
"opengl_type": "vector2f"
},
"extruders": {
"value": extruders,
"opengl_name": "a_extruder",
"opengl_type": "float" # Strangely enough, the type has to be float while it is actually an int.
},
"colors": {
"value": material_colors,
"opengl_name": "a_material_color",
"opengl_type": "vector4f"
},
"line_types": {
"value": line_types,
"opengl_name": "a_line_type",
"opengl_type": "float"
}
}
return LayerData(vertices=self.getVertices(), normals=self.getNormals(), indices=self.getIndices(),
colors=self.getColors(), uvs=self.getUVCoordinates(), file_name=self.getFileName(),
center_position=self.getCenterPosition(), layers=self._layers,
element_counts=self._element_counts, attributes=attributes)