Layer.py 4.4 KB

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