1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
from .LayerPolygon import LayerPolygon
from UM.Math.Vector import Vector
from UM.Mesh.MeshBuilder import MeshBuilder
import numpy
class Layer:
def __init__(self, layer_id):
self._id = layer_id
self._height = 0.0
self._thickness = 0.0
self._polygons = []
self._element_count = 0
@property
def height(self):
return self._height
@property
def thickness(self):
return self._thickness
@property
def polygons(self):
return self._polygons
@property
def elementCount(self):
return self._element_count
def setHeight(self, height):
self._height = height
def setThickness(self, thickness):
self._thickness = thickness
def lineMeshVertexCount(self):
result = 0
for polygon in self._polygons:
result += polygon.lineMeshVertexCount()
return result
def lineMeshElementCount(self):
result = 0
for polygon in self._polygons:
result += polygon.lineMeshElementCount()
return result
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
return (result_vertex_offset, result_index_offset)
def createMesh(self):
return self.createMeshOrJumps(True)
def createJumps(self):
return self.createMeshOrJumps(False)
# Defines the two triplets of local point indices to use to draw the two faces for each line segment in createMeshOrJump
__index_pattern = numpy.array([[0, 3, 2, 0, 1, 3]], dtype = numpy.int32 )
def createMeshOrJumps(self, make_mesh):
builder = MeshBuilder()
line_count = 0
if make_mesh:
for polygon in self._polygons:
line_count += polygon.meshLineCount
else:
for polygon in self._polygons:
line_count += polygon.jumpCount
# Reserve the neccesary space for the data upfront
builder.reserveFaceAndVertexCount(2 * line_count, 4 * line_count)
for polygon in self._polygons:
# Filter out the types of lines we are not interesed in depending on whether we are drawing the mesh or the jumps.
index_mask = numpy.logical_not(polygon.jumpMask) if make_mesh else polygon.jumpMask
# Create an array with rows [p p+1] and only keep 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]
# Shift the z-axis according to previous implementation.
if make_mesh:
points[polygon.isInfillOrSkinType(line_types), 1::3] -= 0.01
else:
points[:, 1::3] += 0.01
# Create an array with normals and tile 2 copies to match size of points variable
normals = numpy.tile( polygon.getNormals()[index_mask.ravel()], (1, 2))
# Scale all normals by the line width of the current line so we can easily offset.
normals *= (polygon.lineWidths[index_mask.ravel()] / 2)
# Create 4 points to draw each line segment, points +- normals results in 2 points each. Reshape to one point per line
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 = ( self.__index_pattern + numpy.arange(0, 4 * len(normals), 4, dtype=numpy.int32).reshape((-1, 1)) ).reshape((-1, 3))
f_colors = numpy.repeat(polygon.mapLineTypeToColor(line_types), 4, 0)
builder.addFacesWithColor(f_points, f_indices, f_colors)
return builder.build()
|