def createHullMesh(self, hull_points): # Input checking. if len(hull_points) < 3: return None mesh_builder = MeshBuilder() point_first = Vector(hull_points[0][0], self._mesh_height, hull_points[0][1]) point_previous = Vector(hull_points[1][0], self._mesh_height, hull_points[1][1]) for point in hull_points[2:]: # Add the faces in the order of a triangle fan. point_new = Vector(point[0], self._mesh_height, point[1]) mesh_builder.addFace(point_first, point_previous, point_new, color = self._color) point_previous = point_new # Prepare point_previous for the next triangle. return mesh_builder.build()
def createHullMesh(self, hull_points): # Input checking. if len(hull_points) < 3: return None mesh_builder = MeshBuilder() point_first = Vector(hull_points[0][0], self._mesh_height, hull_points[0][1]) point_previous = Vector(hull_points[1][0], self._mesh_height, hull_points[1][1]) for point in hull_points[2:]: # Add the faces in the order of a triangle fan. point_new = Vector(point[0], self._mesh_height, point[1]) mesh_builder.addFace(point_first, point_previous, point_new, color = self._color) point_previous = point_new # Prepare point_previous for the next triangle. return mesh_builder.getData()
def setMeshDataFromPywimTriangles(self, face: pywim.geom.tri.Face, axis: pywim.geom.Vector = None): if len(face.triangles) == 0: return self.face = face self.axis = axis mb = MeshBuilder() for tri in self.face.triangles: mb.addFace(tri.v1, tri.v2, tri.v3) mb.calculateNormals() self.setMeshData(mb.build()) self._setupTools()
def drawSelection(self): if self._tri is None: return ph = self._connector.propertyHandler if ph._selection_mode is SelectionMode.AnchorMode: self.setFace(ph._anchoredTris) else: self.setFace(ph._loadedTris) # Construct Edges using MeshBuilder Cubes mb = MeshBuilder() for tri in self._tri: mb.addFace(tri.v1, tri.v2, tri.v3, color=self._selected_color) if self._connector.propertyHandler._selection_mode == SelectionMode.LoadMode: self.paintArrow(self._tri, mb) # Add to Cura Scene self.setSolidMesh(mb.build())
def rebuild(self): if self._width == 0 or self._height == 0 or self._depth == 0: return min_w = -self._width / 2 max_w = self._width / 2 min_h = 0.0 max_h = self._height min_d = -self._depth / 2 max_d = self._depth / 2 mb = MeshBuilder() mb.addLine(Vector(min_w, min_h, min_d), Vector(max_w, min_h, min_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, max_h, min_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, min_d), Vector(max_w, max_h, min_d), color=self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, max_h, min_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, max_d), Vector(max_w, min_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, max_d), Vector(min_w, max_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, max_d), Vector(max_w, max_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, max_d), Vector(max_w, max_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, min_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, min_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, min_d), Vector(min_w, max_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(max_w, max_h, min_d), Vector(max_w, max_h, max_d), color=self.VolumeOutlineColor) self.setMeshData(mb.getData()) mb = MeshBuilder() mb.addQuad(Vector(min_w, min_h - 0.2, min_d), Vector(max_w, min_h - 0.2, min_d), Vector(max_w, min_h - 0.2, max_d), Vector(min_w, min_h - 0.2, max_d)) self._grid_mesh = mb.getData() for n in range(0, 6): v = self._grid_mesh.getVertex(n) self._grid_mesh.setVertexUVCoordinates(n, v[0], v[2]) disallowed_area_height = 0.1 disallowed_area_size = 0 if self._disallowed_areas: mb = MeshBuilder() color = Color(0.0, 0.0, 0.0, 0.15) for polygon in self._disallowed_areas: points = polygon.getPoints() first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) previous_point = Vector( self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) for point in points: new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height, self._clamp(point[1], min_d, max_d)) mb.addFace(first, previous_point, new_point, color=color) previous_point = new_point # Find the largest disallowed area to exclude it from the maximum scale bounds. # This is a very nasty hack. This pretty much only works for UM machines. This disallowed area_size needs # A -lot- of rework at some point in the future: TODO if numpy.min( points[:, 1] ) >= 0: # This filters out all areas that have points to the left of the centre. This is done to filter the skirt area. size = abs( numpy.max(points[:, 1]) - numpy.min(points[:, 1])) else: size = 0 disallowed_area_size = max(size, disallowed_area_size) self._disallowed_area_mesh = mb.getData() else: self._disallowed_area_mesh = None self._aabb = AxisAlignedBox(minimum=Vector(min_w, min_h - 1.0, min_d), maximum=Vector(max_w, max_h, max_d)) skirt_size = 0.0 profile = Application.getInstance().getMachineManager( ).getWorkingProfile() if profile: skirt_size = self._getSkirtSize(profile) # As this works better for UM machines, we only add the dissallowed_area_size for the z direction. # This is probably wrong in all other cases. TODO! # The +1 and -1 is added as there is always a bit of extra room required to work properly. scale_to_max_bounds = AxisAlignedBox( minimum=Vector(min_w + skirt_size + 1, min_h, min_d + disallowed_area_size - skirt_size + 1), maximum=Vector(max_w - skirt_size - 1, max_h, max_d - disallowed_area_size + skirt_size - 1)) Application.getInstance().getController().getScene( )._maximum_bounds = scale_to_max_bounds
def rebuild(self): if not self._width or not self._height or not self._depth: return min_w = -self._width / 2 max_w = self._width / 2 min_h = 0.0 max_h = self._height min_d = -self._depth / 2 max_d = self._depth / 2 z_fight_distance = 0.2 # Distance between buildplate and disallowed area meshes to prevent z-fighting if self._shape != "elliptic": # Outline 'cube' of the build volume mb = MeshBuilder() mb.addLine(Vector(min_w, min_h, min_d), Vector(max_w, min_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, max_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, min_d), Vector(max_w, max_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, max_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, max_d), Vector(max_w, min_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, max_d), Vector(min_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, max_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, max_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, min_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, min_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, min_d), Vector(min_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, max_h, min_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) self.setMeshData(mb.build()) # Build plate grid mesh mb = MeshBuilder() mb.addQuad( Vector(min_w, min_h - z_fight_distance, min_d), Vector(max_w, min_h - z_fight_distance, min_d), Vector(max_w, min_h - z_fight_distance, max_d), Vector(min_w, min_h - z_fight_distance, max_d) ) for n in range(0, 6): v = mb.getVertex(n) mb.setVertexUVCoordinates(n, v[0], v[2]) self._grid_mesh = mb.build() else: # Bottom and top 'ellipse' of the build volume aspect = 1.0 scale_matrix = Matrix() if self._width != 0: # Scale circular meshes by aspect ratio if width != height aspect = self._height / self._width scale_matrix.compose(scale = Vector(1, 1, aspect)) mb = MeshBuilder() mb.addArc(max_w, Vector.Unit_Y, center = (0, min_h - z_fight_distance, 0), color = self.VolumeOutlineColor) mb.addArc(max_w, Vector.Unit_Y, center = (0, max_h, 0), color = self.VolumeOutlineColor) self.setMeshData(mb.build().getTransformed(scale_matrix)) # Build plate grid mesh mb = MeshBuilder() mb.addVertex(0, min_h - z_fight_distance, 0) mb.addArc(max_w, Vector.Unit_Y, center = Vector(0, min_h - z_fight_distance, 0)) sections = mb.getVertexCount() - 1 # Center point is not an arc section indices = [] for n in range(0, sections - 1): indices.append([0, n + 2, n + 1]) mb.addIndices(numpy.asarray(indices, dtype = numpy.int32)) mb.calculateNormals() for n in range(0, mb.getVertexCount()): v = mb.getVertex(n) mb.setVertexUVCoordinates(n, v[0], v[2] * aspect) self._grid_mesh = mb.build().getTransformed(scale_matrix) # Indication of the machine origin if self._global_container_stack.getProperty("machine_center_is_zero", "value"): origin = (Vector(min_w, min_h, min_d) + Vector(max_w, min_h, max_d)) / 2 else: origin = Vector(min_w, min_h, max_d) mb = MeshBuilder() mb.addCube( width = self._origin_line_length, height = self._origin_line_width, depth = self._origin_line_width, center = origin + Vector(self._origin_line_length / 2, 0, 0), color = self.XAxisColor ) mb.addCube( width = self._origin_line_width, height = self._origin_line_length, depth = self._origin_line_width, center = origin + Vector(0, self._origin_line_length / 2, 0), color = self.YAxisColor ) mb.addCube( width = self._origin_line_width, height = self._origin_line_width, depth = self._origin_line_length, center = origin - Vector(0, 0, self._origin_line_length / 2), color = self.ZAxisColor ) self._origin_mesh = mb.build() disallowed_area_height = 0.1 disallowed_area_size = 0 if self._disallowed_areas: mb = MeshBuilder() color = Color(0.0, 0.0, 0.0, 0.15) for polygon in self._disallowed_areas: points = polygon.getPoints() first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) for point in points: new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height, self._clamp(point[1], min_d, max_d)) mb.addFace(first, previous_point, new_point, color = color) previous_point = new_point # Find the largest disallowed area to exclude it from the maximum scale bounds. # This is a very nasty hack. This pretty much only works for UM machines. # This disallowed area_size needs a -lot- of rework at some point in the future: TODO if numpy.min(points[:, 1]) >= 0: # This filters out all areas that have points to the left of the centre. This is done to filter the skirt area. size = abs(numpy.max(points[:, 1]) - numpy.min(points[:, 1])) else: size = 0 disallowed_area_size = max(size, disallowed_area_size) self._disallowed_area_mesh = mb.build() else: self._disallowed_area_mesh = None if self._error_areas: mb = MeshBuilder() for error_area in self._error_areas: color = Color(1.0, 0.0, 0.0, 0.5) points = error_area.getPoints() first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) for point in points: new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height, self._clamp(point[1], min_d, max_d)) mb.addFace(first, previous_point, new_point, color=color) previous_point = new_point self._error_mesh = mb.build() else: self._error_mesh = None self._volume_aabb = AxisAlignedBox( minimum = Vector(min_w, min_h - 1.0, min_d), maximum = Vector(max_w, max_h - self._raft_thickness, max_d)) bed_adhesion_size = self._getEdgeDisallowedSize() # As this works better for UM machines, we only add the disallowed_area_size for the z direction. # This is probably wrong in all other cases. TODO! # The +1 and -1 is added as there is always a bit of extra room required to work properly. scale_to_max_bounds = AxisAlignedBox( minimum = Vector(min_w + bed_adhesion_size + 1, min_h, min_d + disallowed_area_size - bed_adhesion_size + 1), maximum = Vector(max_w - bed_adhesion_size - 1, max_h - self._raft_thickness, max_d - disallowed_area_size + bed_adhesion_size - 1) ) Application.getInstance().getController().getScene()._maximum_bounds = scale_to_max_bounds
def rebuild(self): if not self._width or not self._height or not self._depth: return min_w = -self._width / 2 max_w = self._width / 2 min_h = 0.0 max_h = self._height min_d = -self._depth / 2 max_d = self._depth / 2 mb = MeshBuilder() # Outline 'cube' of the build volume mb.addLine(Vector(min_w, min_h, min_d), Vector(max_w, min_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, max_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, min_d), Vector(max_w, max_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, max_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, max_d), Vector(max_w, min_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, max_d), Vector(min_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, max_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, max_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, min_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, min_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, min_d), Vector(min_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, max_h, min_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) self.setMeshData(mb.build()) mb = MeshBuilder() mb.addQuad( Vector(min_w, min_h - 0.2, min_d), Vector(max_w, min_h - 0.2, min_d), Vector(max_w, min_h - 0.2, max_d), Vector(min_w, min_h - 0.2, max_d) ) for n in range(0, 6): v = mb.getVertex(n) mb.setVertexUVCoordinates(n, v[0], v[2]) self._grid_mesh = mb.build() disallowed_area_height = 0.1 disallowed_area_size = 0 if self._disallowed_areas: mb = MeshBuilder() color = Color(0.0, 0.0, 0.0, 0.15) for polygon in self._disallowed_areas: points = polygon.getPoints() first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) for point in points: new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height, self._clamp(point[1], min_d, max_d)) mb.addFace(first, previous_point, new_point, color = color) previous_point = new_point # Find the largest disallowed area to exclude it from the maximum scale bounds. # This is a very nasty hack. This pretty much only works for UM machines. # This disallowed area_size needs a -lot- of rework at some point in the future: TODO if numpy.min(points[:, 1]) >= 0: # This filters out all areas that have points to the left of the centre. This is done to filter the skirt area. size = abs(numpy.max(points[:, 1]) - numpy.min(points[:, 1])) else: size = 0 disallowed_area_size = max(size, disallowed_area_size) self._disallowed_area_mesh = mb.build() else: self._disallowed_area_mesh = None if self._prime_tower_area: mb = MeshBuilder() color = Color(1.0, 0.0, 0.0, 0.5) points = self._prime_tower_area.getPoints() first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) for point in points: new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height, self._clamp(point[1], min_d, max_d)) mb.addFace(first, previous_point, new_point, color=color) previous_point = new_point self._prime_tower_area_mesh = mb.build() else: self._prime_tower_area_mesh = None self._volume_aabb = AxisAlignedBox( minimum = Vector(min_w, min_h - 1.0, min_d), maximum = Vector(max_w, max_h - self._raft_thickness, max_d)) bed_adhesion_size = 0.0 container_stack = Application.getInstance().getGlobalContainerStack() if container_stack: bed_adhesion_size = self._getBedAdhesionSize(container_stack) # As this works better for UM machines, we only add the disallowed_area_size for the z direction. # This is probably wrong in all other cases. TODO! # The +1 and -1 is added as there is always a bit of extra room required to work properly. scale_to_max_bounds = AxisAlignedBox( minimum = Vector(min_w + bed_adhesion_size + 1, min_h, min_d + disallowed_area_size - bed_adhesion_size + 1), maximum = Vector(max_w - bed_adhesion_size - 1, max_h - self._raft_thickness, max_d - disallowed_area_size + bed_adhesion_size - 1) ) Application.getInstance().getController().getScene()._maximum_bounds = scale_to_max_bounds
def setNode(self, node): super().setNode(node) aabb = node.getBoundingBox() if not aabb.isValid(): return if not self._body: self._body = ode.Body(self._world) self._body.setMaxAngularSpeed(0) mass = ode.Mass() mass.setBox(5.0, Helpers.toODE(aabb.width), Helpers.toODE(aabb.height), Helpers.toODE(aabb.depth)) self._body.setMass(mass) if not self._geom: if node.getMeshData(): scale_matrix = Matrix() scale_matrix.setByScaleFactor(1.01) mesh = node.getMeshData().getTransformed(scale_matrix) self._trimesh = ode.TriMeshData() debug_builder = MeshBuilder() vertices = mesh.getVertices() indices = mesh.getConvexHull().simplices _fixWindingOrder(vertices, indices, debug_builder) self._trimesh.build(vertices / Helpers.ScaleFactor, indices) self._geom = ode.GeomTriMesh(self._trimesh, self._space) mb = MeshBuilder() for i in range(self._geom.getTriangleCount()): tri = self._geom.getTriangle(i) v0 = Helpers.fromODE(tri[0]) v1 = Helpers.fromODE(tri[1]) v2 = Helpers.fromODE(tri[2]) mb.addFace(v0=v0, v1=v1, v2=v2, color=Color(1.0, 0.0, 0.0, 0.5)) chn = SceneNode(node) chn.setMeshData(mb.build()) def _renderConvexHull(renderer): renderer.queueNode(chn, transparent=True) return True chn.render = _renderConvexHull n = SceneNode(node) n.setMeshData(debug_builder.build()) def _renderNormals(renderer): renderer.queueNode(n, mode=1, overlay=True) return True n.render = _renderNormals else: self._geom = ode.GeomBox(self._space, lengths=(Helpers.toODE(aabb.width), Helpers.toODE(aabb.height), Helpers.toODE(aabb.depth))) self._geom.setBody(self._body) self._body.setPosition(Helpers.toODE(node.getWorldPosition())) node.transformationChanged.connect(self._onTransformationChanged)
def rebuild(self): if self._width == 0 or self._height == 0 or self._depth == 0: return min_w = -self._width / 2 max_w = self._width / 2 min_h = 0.0 max_h = self._height min_d = -self._depth / 2 max_d = self._depth / 2 mb = MeshBuilder() mb.addLine(Vector(min_w, min_h, min_d), Vector(max_w, min_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, max_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, min_d), Vector(max_w, max_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, max_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, max_d), Vector(max_w, min_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, max_d), Vector(min_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, max_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, max_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, min_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, min_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, min_d), Vector(min_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, max_h, min_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) self.setMeshData(mb.getData()) mb = MeshBuilder() mb.addQuad( Vector(min_w, min_h - 0.2, min_d), Vector(max_w, min_h - 0.2, min_d), Vector(max_w, min_h - 0.2, max_d), Vector(min_w, min_h - 0.2, max_d) ) self._grid_mesh = mb.getData() for n in range(0, 6): v = self._grid_mesh.getVertex(n) self._grid_mesh.setVertexUVCoordinates(n, v[0], v[2]) disallowed_area_height = 0.1 disallowed_area_size = 0 if self._disallowed_areas: mb = MeshBuilder() color = Color(0.0, 0.0, 0.0, 0.15) for polygon in self._disallowed_areas: points = polygon.getPoints() first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) for point in points: new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height, self._clamp(point[1], min_d, max_d)) mb.addFace(first, previous_point, new_point, color = color) previous_point = new_point # Find the largest disallowed area to exclude it from the maximum scale bounds size = abs(numpy.max(points[:, 1]) - numpy.min(points[:, 1])) disallowed_area_size = max(size, disallowed_area_size) self._disallowed_area_mesh = mb.getData() else: self._disallowed_area_mesh = None self._aabb = AxisAlignedBox(minimum = Vector(min_w, min_h - 1.0, min_d), maximum = Vector(max_w, max_h, max_d)) skirt_size = 0.0 profile = Application.getInstance().getMachineManager().getActiveProfile() if profile: skirt_size = self._getSkirtSize(profile) scale_to_max_bounds = AxisAlignedBox( minimum = Vector(min_w + skirt_size, min_h, min_d + skirt_size + disallowed_area_size), maximum = Vector(max_w - skirt_size, max_h, max_d - skirt_size - disallowed_area_size) ) Application.getInstance().getController().getScene()._maximum_bounds = scale_to_max_bounds
def _rebuild(self): if not self._build_volume._width or not self._build_volume._height or not self._build_volume._depth: return if not self._build_volume._engine_ready: return if not self._build_volume._volume_outline_color: theme = Application.getInstance().getTheme() self._build_volume._volume_outline_color = Color( *theme.getColor("volume_outline").getRgb()) self._build_volume._x_axis_color = Color( *theme.getColor("x_axis").getRgb()) self._build_volume._y_axis_color = Color( *theme.getColor("y_axis").getRgb()) self._build_volume._z_axis_color = Color( *theme.getColor("z_axis").getRgb()) self._build_volume._disallowed_area_color = Color( *theme.getColor("disallowed_area").getRgb()) self._build_volume._error_area_color = Color( *theme.getColor("error_area").getRgb()) ### START PATCH # Get a dict from the machine metadata optionally overriding the build volume # Note that CuraEngine is blissfully unaware of this; it is just what the user is shown in Cura limit_buildvolume = self._build_volume._global_container_stack.getMetaDataEntry( "limit_buildvolume", {}) if not isinstance(limit_buildvolume, dict): limit_buildvolume = {} min_w = limit_buildvolume.get("width", {}).get("minimum", -self._build_volume._width / 2) max_w = limit_buildvolume.get("width", {}).get("maximum", self._build_volume._width / 2) min_h = limit_buildvolume.get("height", {}).get("minimum", 0.0) max_h = limit_buildvolume.get("height", {}).get("maximum", self._build_volume._height) min_d = limit_buildvolume.get("depth", {}).get("minimum", -self._build_volume._depth / 2) max_d = limit_buildvolume.get("depth", {}).get("maximum", self._build_volume._depth / 2) ### END PATCH z_fight_distance = 0.2 # Distance between buildplate and disallowed area meshes to prevent z-fighting if self._build_volume._shape != "elliptic": # Outline 'cube' of the build volume mb = MeshBuilder() mb.addLine(Vector(min_w, min_h, min_d), Vector(max_w, min_h, min_d), color=self._build_volume._volume_outline_color) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, max_h, min_d), color=self._build_volume._volume_outline_color) mb.addLine(Vector(min_w, max_h, min_d), Vector(max_w, max_h, min_d), color=self._build_volume._volume_outline_color) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, max_h, min_d), color=self._build_volume._volume_outline_color) mb.addLine(Vector(min_w, min_h, max_d), Vector(max_w, min_h, max_d), color=self._build_volume._volume_outline_color) mb.addLine(Vector(min_w, min_h, max_d), Vector(min_w, max_h, max_d), color=self._build_volume._volume_outline_color) mb.addLine(Vector(min_w, max_h, max_d), Vector(max_w, max_h, max_d), color=self._build_volume._volume_outline_color) mb.addLine(Vector(max_w, min_h, max_d), Vector(max_w, max_h, max_d), color=self._build_volume._volume_outline_color) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, min_h, max_d), color=self._build_volume._volume_outline_color) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, min_h, max_d), color=self._build_volume._volume_outline_color) mb.addLine(Vector(min_w, max_h, min_d), Vector(min_w, max_h, max_d), color=self._build_volume._volume_outline_color) mb.addLine(Vector(max_w, max_h, min_d), Vector(max_w, max_h, max_d), color=self._build_volume._volume_outline_color) self._build_volume.setMeshData(mb.build()) # Build plate grid mesh mb = MeshBuilder() mb.addQuad(Vector(min_w, min_h - z_fight_distance, min_d), Vector(max_w, min_h - z_fight_distance, min_d), Vector(max_w, min_h - z_fight_distance, max_d), Vector(min_w, min_h - z_fight_distance, max_d)) for n in range(0, 6): v = mb.getVertex(n) mb.setVertexUVCoordinates(n, v[0], v[2]) self._build_volume._grid_mesh = mb.build() else: # Bottom and top 'ellipse' of the build volume aspect = 1.0 scale_matrix = Matrix() if self._build_volume._width != 0: # Scale circular meshes by aspect ratio if width != height aspect = self._build_volume._depth / self._build_volume._width scale_matrix.compose(scale=Vector(1, 1, aspect)) mb = MeshBuilder() mb.addArc(max_w, Vector.Unit_Y, center=(0, min_h - z_fight_distance, 0), color=self._build_volume._volume_outline_color) mb.addArc(max_w, Vector.Unit_Y, center=(0, max_h, 0), color=self._build_volume._volume_outline_color) self._build_volume.setMeshData( mb.build().getTransformed(scale_matrix)) # Build plate grid mesh mb = MeshBuilder() mb.addVertex(0, min_h - z_fight_distance, 0) mb.addArc(max_w, Vector.Unit_Y, center=Vector(0, min_h - z_fight_distance, 0)) sections = mb.getVertexCount( ) - 1 # Center point is not an arc section indices = [] for n in range(0, sections - 1): indices.append([0, n + 2, n + 1]) mb.addIndices(numpy.asarray(indices, dtype=numpy.int32)) mb.calculateNormals() for n in range(0, mb.getVertexCount()): v = mb.getVertex(n) mb.setVertexUVCoordinates(n, v[0], v[2] * aspect) self._build_volume._grid_mesh = mb.build().getTransformed( scale_matrix) # Indication of the machine origin if self._build_volume._global_container_stack.getProperty( "machine_center_is_zero", "value"): origin = (Vector(min_w, min_h, min_d) + Vector(max_w, min_h, max_d)) / 2 else: origin = Vector(min_w, min_h, max_d) mb = MeshBuilder() mb.addCube(width=self._build_volume._origin_line_length, height=self._build_volume._origin_line_width, depth=self._build_volume._origin_line_width, center=origin + Vector(self._build_volume._origin_line_length / 2, 0, 0), color=self._build_volume._x_axis_color) mb.addCube(width=self._build_volume._origin_line_width, height=self._build_volume._origin_line_length, depth=self._build_volume._origin_line_width, center=origin + Vector(0, self._build_volume._origin_line_length / 2, 0), color=self._build_volume._y_axis_color) mb.addCube(width=self._build_volume._origin_line_width, height=self._build_volume._origin_line_width, depth=self._build_volume._origin_line_length, center=origin - Vector(0, 0, self._build_volume._origin_line_length / 2), color=self._build_volume._z_axis_color) self._build_volume._origin_mesh = mb.build() disallowed_area_height = 0.1 disallowed_area_size = 0 if self._build_volume._disallowed_areas: mb = MeshBuilder() color = self._build_volume._disallowed_area_color for polygon in self._build_volume._disallowed_areas: points = polygon.getPoints() if len(points) == 0: continue first = Vector( self._build_volume._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._build_volume._clamp(points[0][1], min_d, max_d)) previous_point = Vector( self._build_volume._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._build_volume._clamp(points[0][1], min_d, max_d)) for point in points: new_point = Vector( self._build_volume._clamp(point[0], min_w, max_w), disallowed_area_height, self._build_volume._clamp(point[1], min_d, max_d)) mb.addFace(first, previous_point, new_point, color=color) previous_point = new_point # Find the largest disallowed area to exclude it from the maximum scale bounds. # This is a very nasty hack. This pretty much only works for UM machines. # This disallowed area_size needs a -lot- of rework at some point in the future: TODO if numpy.min( points[:, 1] ) >= 0: # This filters out all areas that have points to the left of the centre. This is done to filter the skirt area. size = abs( numpy.max(points[:, 1]) - numpy.min(points[:, 1])) else: size = 0 disallowed_area_size = max(size, disallowed_area_size) self._build_volume._disallowed_area_mesh = mb.build() else: self._build_volume._disallowed_area_mesh = None if self._build_volume._error_areas: mb = MeshBuilder() for error_area in self._build_volume._error_areas: color = self._build_volume._error_area_color points = error_area.getPoints() first = Vector( self._build_volume._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._build_volume._clamp(points[0][1], min_d, max_d)) previous_point = Vector( self._build_volume._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._build_volume._clamp(points[0][1], min_d, max_d)) for point in points: new_point = Vector( self._build_volume._clamp(point[0], min_w, max_w), disallowed_area_height, self._build_volume._clamp(point[1], min_d, max_d)) mb.addFace(first, previous_point, new_point, color=color) previous_point = new_point self._build_volume._error_mesh = mb.build() else: self._build_volume._error_mesh = None self._build_volume._volume_aabb = AxisAlignedBox( minimum=Vector(min_w, min_h - 1.0, min_d), maximum=Vector( max_w, max_h - self._build_volume._raft_thickness - self._build_volume._extra_z_clearance, max_d)) bed_adhesion_size = self._build_volume.getEdgeDisallowedSize() # As this works better for UM machines, we only add the disallowed_area_size for the z direction. # This is probably wrong in all other cases. TODO! # The +1 and -1 is added as there is always a bit of extra room required to work properly. scale_to_max_bounds = AxisAlignedBox( minimum=Vector( min_w + bed_adhesion_size + 1, min_h, min_d + disallowed_area_size - bed_adhesion_size + 1), maximum=Vector( max_w - bed_adhesion_size - 1, max_h - self._build_volume._raft_thickness - self._build_volume._extra_z_clearance, max_d - disallowed_area_size + bed_adhesion_size - 1)) Application.getInstance().getController().getScene( )._maximum_bounds = scale_to_max_bounds self._build_volume.updateNodeBoundaryCheck()
def rebuild(self): if self._width == 0 or self._height == 0 or self._depth == 0: return minW = -self._width / 2 maxW = self._width / 2 minH = 0.0 maxH = self._height minD = -self._depth / 2 maxD = self._depth / 2 mb = MeshBuilder() mb.addLine(Vector(minW, minH, minD), Vector(maxW, minH, minD), color=self.VolumeOutlineColor) mb.addLine(Vector(minW, minH, minD), Vector(minW, maxH, minD), color=self.VolumeOutlineColor) mb.addLine(Vector(minW, maxH, minD), Vector(maxW, maxH, minD), color=self.VolumeOutlineColor) mb.addLine(Vector(maxW, minH, minD), Vector(maxW, maxH, minD), color=self.VolumeOutlineColor) mb.addLine(Vector(minW, minH, maxD), Vector(maxW, minH, maxD), color=self.VolumeOutlineColor) mb.addLine(Vector(minW, minH, maxD), Vector(minW, maxH, maxD), color=self.VolumeOutlineColor) mb.addLine(Vector(minW, maxH, maxD), Vector(maxW, maxH, maxD), color=self.VolumeOutlineColor) mb.addLine(Vector(maxW, minH, maxD), Vector(maxW, maxH, maxD), color=self.VolumeOutlineColor) mb.addLine(Vector(minW, minH, minD), Vector(minW, minH, maxD), color=self.VolumeOutlineColor) mb.addLine(Vector(maxW, minH, minD), Vector(maxW, minH, maxD), color=self.VolumeOutlineColor) mb.addLine(Vector(minW, maxH, minD), Vector(minW, maxH, maxD), color=self.VolumeOutlineColor) mb.addLine(Vector(maxW, maxH, minD), Vector(maxW, maxH, maxD), color=self.VolumeOutlineColor) self.setMeshData(mb.getData()) mb = MeshBuilder() mb.addQuad(Vector(minW, minH, minD), Vector(maxW, minH, minD), Vector(maxW, minH, maxD), Vector(minW, minH, maxD)) self._grid_mesh = mb.getData() for n in range(0, 6): v = self._grid_mesh.getVertex(n) self._grid_mesh.setVertexUVCoordinates(n, v[0], v[2]) disallowed_area_height = 0.2 disallowed_area_size = 0 if self._disallowed_areas: mb = MeshBuilder() color = Color(0.0, 0.0, 0.0, 0.15) for polygon in self._disallowed_areas: points = polygon.getPoints() first = Vector(self._clamp(points[0][0], minW, maxW), disallowed_area_height, self._clamp(points[0][1], minD, maxD)) previous_point = Vector(self._clamp(points[0][0], minW, maxW), disallowed_area_height, self._clamp(points[0][1], minD, maxD)) for point in points: new_point = Vector(self._clamp(point[0], minW, maxW), disallowed_area_height, self._clamp(point[1], minD, maxD)) mb.addFace(first, previous_point, new_point, color=color) previous_point = new_point # Find the largest disallowed area to exclude it from the maximum scale bounds size = abs(numpy.max(points[:, 1]) - numpy.min(points[:, 1])) disallowed_area_size = max(size, disallowed_area_size) self._disallowed_area_mesh = mb.getData() else: self._disallowed_area_mesh = None self._aabb = AxisAlignedBox(minimum=Vector(minW, minH - 1.0, minD), maximum=Vector(maxW, maxH, maxD)) skirt_size = 0.0 profile = Application.getInstance().getMachineManager( ).getActiveProfile() if profile: skirt_size = self._getSkirtSize(profile) scale_to_max_bounds = AxisAlignedBox( minimum=Vector(minW + skirt_size, minH, minD + skirt_size + disallowed_area_size), maximum=Vector(maxW - skirt_size, maxH, maxD - skirt_size - disallowed_area_size)) Application.getInstance().getController().getScene( )._maximum_bounds = scale_to_max_bounds
def rebuild(self): if not self._width or not self._height or not self._depth: return min_w = -self._width / 2 max_w = self._width / 2 min_h = 0.0 max_h = self._height min_d = -self._depth / 2 max_d = self._depth / 2 mb = MeshBuilder() # Outline 'cube' of the build volume mb.addLine(Vector(min_w, min_h, min_d), Vector(max_w, min_h, min_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, max_h, min_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, min_d), Vector(max_w, max_h, min_d), color=self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, max_h, min_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, max_d), Vector(max_w, min_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, max_d), Vector(min_w, max_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, max_d), Vector(max_w, max_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, max_d), Vector(max_w, max_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, min_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, min_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, min_d), Vector(min_w, max_h, max_d), color=self.VolumeOutlineColor) mb.addLine(Vector(max_w, max_h, min_d), Vector(max_w, max_h, max_d), color=self.VolumeOutlineColor) self.setMeshData(mb.build()) mb = MeshBuilder() # Indication of the machine origin if self._global_container_stack.getProperty("machine_center_is_zero", "value"): origin = (Vector(min_w, min_h, min_d) + Vector(max_w, min_h, max_d)) / 2 else: origin = Vector(min_w, min_h, max_d) mb.addCube(width=self._origin_line_length, height=self._origin_line_width, depth=self._origin_line_width, center=origin + Vector(self._origin_line_length / 2, 0, 0), color=self.XAxisColor) mb.addCube(width=self._origin_line_width, height=self._origin_line_length, depth=self._origin_line_width, center=origin + Vector(0, self._origin_line_length / 2, 0), color=self.YAxisColor) mb.addCube(width=self._origin_line_width, height=self._origin_line_width, depth=self._origin_line_length, center=origin - Vector(0, 0, self._origin_line_length / 2), color=self.ZAxisColor) self._origin_mesh = mb.build() mb = MeshBuilder() mb.addQuad(Vector(min_w, min_h - 0.2, min_d), Vector(max_w, min_h - 0.2, min_d), Vector(max_w, min_h - 0.2, max_d), Vector(min_w, min_h - 0.2, max_d)) for n in range(0, 6): v = mb.getVertex(n) mb.setVertexUVCoordinates(n, v[0], v[2]) self._grid_mesh = mb.build() disallowed_area_height = 0.1 disallowed_area_size = 0 if self._disallowed_areas: mb = MeshBuilder() color = Color(0.0, 0.0, 0.0, 0.15) for polygon in self._disallowed_areas: points = polygon.getPoints() first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) previous_point = Vector( self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) for point in points: new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height, self._clamp(point[1], min_d, max_d)) mb.addFace(first, previous_point, new_point, color=color) previous_point = new_point # Find the largest disallowed area to exclude it from the maximum scale bounds. # This is a very nasty hack. This pretty much only works for UM machines. # This disallowed area_size needs a -lot- of rework at some point in the future: TODO if numpy.min( points[:, 1] ) >= 0: # This filters out all areas that have points to the left of the centre. This is done to filter the skirt area. size = abs( numpy.max(points[:, 1]) - numpy.min(points[:, 1])) else: size = 0 disallowed_area_size = max(size, disallowed_area_size) self._disallowed_area_mesh = mb.build() else: self._disallowed_area_mesh = None if self._error_areas: mb = MeshBuilder() for error_area in self._error_areas: color = Color(1.0, 0.0, 0.0, 0.5) points = error_area.getPoints() first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) previous_point = Vector( self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) for point in points: new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height, self._clamp(point[1], min_d, max_d)) mb.addFace(first, previous_point, new_point, color=color) previous_point = new_point self._error_mesh = mb.build() else: self._error_mesh = None self._volume_aabb = AxisAlignedBox( minimum=Vector(min_w, min_h - 1.0, min_d), maximum=Vector(max_w, max_h - self._raft_thickness, max_d)) bed_adhesion_size = self._getEdgeDisallowedSize() # As this works better for UM machines, we only add the disallowed_area_size for the z direction. # This is probably wrong in all other cases. TODO! # The +1 and -1 is added as there is always a bit of extra room required to work properly. scale_to_max_bounds = AxisAlignedBox( minimum=Vector( min_w + bed_adhesion_size + 1, min_h, min_d + disallowed_area_size - bed_adhesion_size + 1), maximum=Vector( max_w - bed_adhesion_size - 1, max_h - self._raft_thickness, max_d - disallowed_area_size + bed_adhesion_size - 1)) Application.getInstance().getController().getScene( )._maximum_bounds = scale_to_max_bounds
def _arrow(self, start: Vector, tail_width, tail_length, head_width, color) -> MeshBuilder: mb = MeshBuilder() p_head = Vector( start.x + self.direction.x * LoadToolHandle.ARROW_TOTAL_LENGTH, start.y + self.direction.y * LoadToolHandle.ARROW_TOTAL_LENGTH, start.z + self.direction.z * LoadToolHandle.ARROW_TOTAL_LENGTH) p_base0 = Vector(start.x + self.direction.x * tail_length, start.y + self.direction.y * tail_length, start.z + self.direction.z * tail_length) p_tail0 = start p_base1 = Vector(p_base0.x, p_base0.y + head_width, p_base0.z) p_base2 = Vector(p_base0.x, p_base0.y - head_width, p_base0.z) p_base3 = Vector(p_base0.x + head_width, p_base0.y, p_base0.z) p_base4 = Vector(p_base0.x - head_width, p_base0.y, p_base0.z) p_base5 = Vector(p_base0.x, p_base0.y, p_base0.z + head_width) p_base6 = Vector(p_base0.x, p_base0.y, p_base0.z - head_width) mb.addFace(p_base1, p_head, p_base3, color=color) mb.addFace(p_base3, p_head, p_base2, color=color) mb.addFace(p_base2, p_head, p_base4, color=color) mb.addFace(p_base4, p_head, p_base1, color=color) mb.addFace(p_base5, p_head, p_base1, color=color) mb.addFace(p_base6, p_head, p_base1, color=color) mb.addFace(p_base6, p_head, p_base2, color=color) mb.addFace(p_base2, p_head, p_base5, color=color) mb.addFace(p_base3, p_head, p_base5, color=color) mb.addFace(p_base5, p_head, p_base4, color=color) mb.addFace(p_base4, p_head, p_base6, color=color) mb.addFace(p_base6, p_head, p_base3, color=color) p_tail1 = Vector(p_tail0.x, p_tail0.y + tail_width, p_tail0.z) p_tail2 = Vector(p_tail0.x, p_tail0.y - tail_width, p_tail0.z) p_tail3 = Vector(p_tail0.x + tail_width, p_tail0.y, p_tail0.z) p_tail4 = Vector(p_tail0.x - tail_width, p_tail0.y, p_tail0.z) p_tail5 = Vector(p_tail0.x, p_tail0.y, p_tail0.z + tail_width) p_tail6 = Vector(p_tail0.x, p_tail0.y, p_tail0.z - tail_width) p_tail_base1 = Vector(p_base0.x, p_base0.y + tail_width, p_base0.z) p_tail_base2 = Vector(p_base0.x, p_base0.y - tail_width, p_base0.z) p_tail_base3 = Vector(p_base0.x + tail_width, p_base0.y, p_base0.z) p_tail_base4 = Vector(p_base0.x - tail_width, p_base0.y, p_base0.z) p_tail_base5 = Vector(p_base0.x, p_base0.y, p_base0.z + tail_width) p_tail_base6 = Vector(p_base0.x, p_base0.y, p_base0.z - tail_width) mb.addFace(p_tail1, p_tail_base1, p_tail3, color=color) mb.addFace(p_tail3, p_tail_base3, p_tail2, color=color) mb.addFace(p_tail2, p_tail_base2, p_tail4, color=color) mb.addFace(p_tail4, p_tail_base4, p_tail1, color=color) mb.addFace(p_tail5, p_tail_base5, p_tail1, color=color) mb.addFace(p_tail6, p_tail_base6, p_tail1, color=color) mb.addFace(p_tail6, p_tail_base6, p_tail2, color=color) mb.addFace(p_tail2, p_tail_base2, p_tail5, color=color) mb.addFace(p_tail3, p_tail_base3, p_tail5, color=color) mb.addFace(p_tail5, p_tail_base5, p_tail4, color=color) mb.addFace(p_tail4, p_tail_base4, p_tail6, color=color) mb.addFace(p_tail6, p_tail_base6, p_tail3, color=color) mb.addFace(p_tail_base1, p_tail_base3, p_tail3, color=color) mb.addFace(p_tail_base3, p_tail_base2, p_tail2, color=color) mb.addFace(p_tail_base2, p_tail_base4, p_tail4, color=color) mb.addFace(p_tail_base4, p_tail_base1, p_tail1, color=color) mb.addFace(p_tail_base5, p_tail_base1, p_tail1, color=color) mb.addFace(p_tail_base6, p_tail_base1, p_tail1, color=color) mb.addFace(p_tail_base6, p_tail_base2, p_tail2, color=color) mb.addFace(p_tail_base2, p_tail_base5, p_tail5, color=color) mb.addFace(p_tail_base3, p_tail_base5, p_tail5, color=color) mb.addFace(p_tail_base5, p_tail_base4, p_tail4, color=color) mb.addFace(p_tail_base4, p_tail_base6, p_tail6, color=color) mb.addFace(p_tail_base6, p_tail_base3, p_tail3, color=color) return mb