Layer.py 4.3 KB

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