mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-08 07:27:29 -06:00
Rework LayerData mesh generation for improved performance
Rather than using a lot of calls to MeshData::addVertices which is very slow, pre-allocate numpy arrays, fill them with data from the polygons and then assign them to the mesh data's arrays. This greatly increases performance of the layer data calculation. Contributes to #52
This commit is contained in:
parent
049f3c25ff
commit
bc055a8031
1 changed files with 53 additions and 25 deletions
|
@ -8,6 +8,7 @@ from UM.Math.Vector import Vector
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
import math
|
import math
|
||||||
|
import copy
|
||||||
|
|
||||||
class LayerData(MeshData):
|
class LayerData(MeshData):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -48,11 +49,23 @@ class LayerData(MeshData):
|
||||||
self._layers[layer].setThickness(thickness)
|
self._layers[layer].setThickness(thickness)
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
|
vertex_count = 0
|
||||||
for layer, data in self._layers.items():
|
for layer, data in self._layers.items():
|
||||||
data.build()
|
vertex_count += data.vertexCount()
|
||||||
|
|
||||||
|
vertices = numpy.empty((vertex_count, 3), numpy.float32)
|
||||||
|
colors = numpy.empty((vertex_count, 4), numpy.float32)
|
||||||
|
indices = numpy.empty((vertex_count, 2), numpy.int32)
|
||||||
|
|
||||||
|
offset = 0
|
||||||
|
for layer, data in self._layers.items():
|
||||||
|
offset = data.build(offset, vertices, colors, indices)
|
||||||
self._element_counts[layer] = data.elementCount
|
self._element_counts[layer] = data.elementCount
|
||||||
|
|
||||||
|
self.addVertices(vertices)
|
||||||
|
self.addColors(colors)
|
||||||
|
self.addIndices(indices.flatten())
|
||||||
|
|
||||||
class Layer():
|
class Layer():
|
||||||
def __init__(self, id):
|
def __init__(self, id):
|
||||||
self._id = id
|
self._id = id
|
||||||
|
@ -83,20 +96,30 @@ class Layer():
|
||||||
def setThickness(self, thickness):
|
def setThickness(self, thickness):
|
||||||
self._thickness = thickness
|
self._thickness = thickness
|
||||||
|
|
||||||
def build(self):
|
def vertexCount(self):
|
||||||
|
result = 0
|
||||||
|
for polygon in self._polygons:
|
||||||
|
result += polygon.vertexCount()
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def build(self, offset, vertices, colors, indices):
|
||||||
|
result = offset
|
||||||
for polygon in self._polygons:
|
for polygon in self._polygons:
|
||||||
if polygon._type == Polygon.InfillType or polygon._type == Polygon.SupportInfillType:
|
if polygon._type == Polygon.InfillType or polygon._type == Polygon.SupportInfillType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
polygon.build()
|
polygon.build(result, vertices, colors, indices)
|
||||||
|
result += polygon.vertexCount()
|
||||||
self._element_count += polygon.elementCount
|
self._element_count += polygon.elementCount
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def createMesh(self):
|
def createMesh(self):
|
||||||
builder = MeshBuilder()
|
builder = MeshBuilder()
|
||||||
|
|
||||||
for polygon in self._polygons:
|
for polygon in self._polygons:
|
||||||
poly_color = polygon.getColor()
|
poly_color = polygon.getColor()
|
||||||
poly_color = Color(poly_color[0], poly_color[1], poly_color[2], poly_color[3])
|
|
||||||
|
|
||||||
points = numpy.copy(polygon.data)
|
points = numpy.copy(polygon.data)
|
||||||
if polygon.type == Polygon.InfillType or polygon.type == Polygon.SkinType or polygon.type == Polygon.SupportInfillType:
|
if polygon.type == Polygon.InfillType or polygon.type == Polygon.SkinType or polygon.type == Polygon.SupportInfillType:
|
||||||
|
@ -159,43 +182,48 @@ class Polygon():
|
||||||
self._data = data
|
self._data = data
|
||||||
self._line_width = line_width / 1000
|
self._line_width = line_width / 1000
|
||||||
|
|
||||||
def build(self):
|
def build(self, offset, vertices, colors, indices):
|
||||||
self._begin = self._mesh._vertex_count
|
self._begin = offset
|
||||||
self._mesh.addVertices(self._data)
|
|
||||||
self._end = self._begin + len(self._data) - 1
|
|
||||||
|
|
||||||
color = self.getColor()
|
color = self.getColor()
|
||||||
color[3] = 2.0
|
color.setValues(color.r * 0.5, color.g * 0.5, color.b * 0.5, color.a)
|
||||||
|
|
||||||
colors = [color for i in range(len(self._data))]
|
for i in range(len(self._data)):
|
||||||
self._mesh.addColors(numpy.array(colors, dtype=numpy.float32) * 0.5)
|
vertices[offset + i, :] = self._data[i, :]
|
||||||
|
colors[offset + i, 0] = color.r
|
||||||
|
colors[offset + i, 1] = color.g
|
||||||
|
colors[offset + i, 2] = color.b
|
||||||
|
colors[offset + i, 3] = color.a
|
||||||
|
|
||||||
|
self._end = self._begin + len(self._data) - 1
|
||||||
|
|
||||||
indices = []
|
|
||||||
for i in range(self._begin, self._end):
|
for i in range(self._begin, self._end):
|
||||||
indices.append(i)
|
indices[i, 0] = i
|
||||||
indices.append(i + 1)
|
indices[i, 1] = i + 1
|
||||||
|
|
||||||
indices.append(self._end)
|
indices[self._end, 0] = self._end
|
||||||
indices.append(self._begin)
|
indices[self._end, 1] = self._begin
|
||||||
self._mesh.addIndices(numpy.array(indices, dtype=numpy.int32))
|
|
||||||
|
|
||||||
def getColor(self):
|
def getColor(self):
|
||||||
if self._type == self.Inset0Type:
|
if self._type == self.Inset0Type:
|
||||||
return [1.0, 0.0, 0.0, 1.0]
|
return Color(1.0, 0.0, 0.0, 1.0)
|
||||||
elif self._type == self.InsetXType:
|
elif self._type == self.InsetXType:
|
||||||
return [0.0, 1.0, 0.0, 1.0]
|
return Color(0.0, 1.0, 0.0, 1.0)
|
||||||
elif self._type == self.SkinType:
|
elif self._type == self.SkinType:
|
||||||
return [1.0, 1.0, 0.0, 1.0]
|
return Color(1.0, 1.0, 0.0, 1.0)
|
||||||
elif self._type == self.SupportType:
|
elif self._type == self.SupportType:
|
||||||
return [0.0, 1.0, 1.0, 1.0]
|
return Color(0.0, 1.0, 1.0, 1.0)
|
||||||
elif self._type == self.SkirtType:
|
elif self._type == self.SkirtType:
|
||||||
return [0.0, 1.0, 1.0, 1.0]
|
return Color(0.0, 1.0, 1.0, 1.0)
|
||||||
elif self._type == self.InfillType:
|
elif self._type == self.InfillType:
|
||||||
return [1.0, 1.0, 0.0, 1.0]
|
return Color(1.0, 1.0, 0.0, 1.0)
|
||||||
elif self._type == self.SupportInfillType:
|
elif self._type == self.SupportInfillType:
|
||||||
return [0.0, 1.0, 1.0, 1.0]
|
return Color(0.0, 1.0, 1.0, 1.0)
|
||||||
else:
|
else:
|
||||||
return [1.0, 1.0, 1.0, 1.0]
|
return Color(1.0, 1.0, 1.0, 1.0)
|
||||||
|
|
||||||
|
def vertexCount(self):
|
||||||
|
return len(self._data)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type(self):
|
def type(self):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue