def test_multipleItemsRename(self, objects_model): node1 = SceneNode() node2 = SceneNode() result = objects_model._renameNodes( {"zomg": _NodeInfo(nodes_to_rename=[node1, node2])}) assert result == [node1, node2] assert node1.getName() == "zomg(1)" assert node2.getName() == "zomg(2)"
def _subdivide(self, mesh, plane): start_time = time.time() plane_mesh_data = plane.getMeshData() plane_vertices = plane_mesh_data.getVertices() plane_face = [plane_vertices[0], plane_vertices[1], plane_vertices[2]] builders = [MeshBuilder(), MeshBuilder()] mesh_data = mesh.getMeshData() vertices = mesh_data.getVertices() indices = mesh_data.getIndices() faces = [] if indices: for index_array in indices: faces.append([ vertices[index_array[0]], vertices[index_array[1]], vertices[index_array[2]] ]) else: for i in range(0, len(vertices), 3): faces.append([vertices[i], vertices[i + 1], vertices[i + 2]]) for f in faces: intersection_type = self.check_intersection_with_triangle( plane_face, f) if intersection_type is None or ( intersection_type is not None and intersection_type[0] in [IntersectionType.Point, IntersectionType.Edge]): side = self.check_plane_side(plane_face, f) if side is not None: self.add_face_to_builder(builders[side], f) else: Logger.log("w", "Invalid face detected: " + str(f)) elif intersection_type[0] == IntersectionType.Face: self.add_face_to_builder(builders[0], f) self.add_face_to_builder(builders[1], f) elif intersection_type[0] == IntersectionType.Segment: new_faces = self.split_triangle(f, intersection_type[1]) for new_face in new_faces: self.add_face_to_builder( builders[self.check_plane_side(plane_face, new_face)], new_face) elif intersection_type[0] == IntersectionType.PointAndSegment: new_faces = self.split_triangle_in_one_segment( f, intersection_type[1]) for new_face in new_faces: self.add_face_to_builder( builders[self.check_plane_side(plane_face, new_face)], new_face) nodes = [SceneNode(), SceneNode()] for n in range(len(nodes)): builders[n].calculateNormals() nodes[n].setMeshData(builders[n].build()) nodes[n].setSelectable(True) nodes[n].setScale(mesh.getScale()) Logger.log( "w", i18n_catalog.i18n("Subdivision took %f seconds") % (time.time() - start_time)) return nodes[0], nodes[1]
def test_scaleWorld(self): node1 = SceneNode() node2 = SceneNode(node1) node2.scale(Vector(1.5,1.,1.)) node2.translate(Vector(10,10,10)) self.assertEqual(node2.getWorldPosition(), Vector(15,10,10)) node2.scale(Vector(1.5,1,1)) self.assertEqual(node2.getWorldPosition(), Vector(15,10,10))
def test_removeChildren(self): node1 = SceneNode() node2 = SceneNode() node1.addChild(node2) assert node1.hasChildren() node1.removeAllChildren() assert not node1.hasChildren()
def test_getSelectedObject(self): node_1 = SceneNode() node_2 = SceneNode() Selection.add(node_1) Selection.add(node_2) assert Selection.getSelectedObject(0) == node_1 assert Selection.getSelectedObject(1) == node_2 assert Selection.getSelectedObject(3) is None
def test_selectionCount(self): assert self.proxy.selectionCount == 0 node_1 = SceneNode() Selection.add(node_1) assert self.proxy.selectionCount == 1 node_2 = SceneNode() Selection.add(node_2) assert self.proxy.selectionCount == 2
def test_getSelectionCenter(self): node_1 = SceneNode() node_1.getBoundingBox = MagicMock(return_value = AxisAlignedBox(Vector(0, 0, 0), Vector(10, 20, 30))) Selection.add(node_1) assert Selection.getSelectionCenter() == Vector(5, 10, 15) node_2 = SceneNode() node_2.getBoundingBox = MagicMock(return_value=AxisAlignedBox(Vector(0, 0, 0), Vector(20, 30, 40))) Selection.add(node_2) assert Selection.getSelectionCenter() == Vector(10, 15, 20)
def test_clearSelection(self): node_1 = SceneNode() node_2 = SceneNode() Selection.add(node_1) Selection.add(node_2) # Ensure that the objects we want selected are selected assert Selection.getAllSelectedObjects() == [node_1, node_2] Selection.clear() assert Selection.getAllSelectedObjects() == []
def test_SimpleRedoUndo(): node = SceneNode() parent_node = SceneNode() operation = AddSceneNodeOperation(node, parent_node) operation.redo() assert node.getParent() == parent_node operation.undo() assert node.getParent() is None
def test_UndoRedoWithSelection(): node = SceneNode() parent_node = SceneNode() Selection.add(node) operation = AddSceneNodeOperation(node, parent_node) operation.undo() assert not Selection.isSelected(node) operation.redo() assert Selection.isSelected(node)
def setUp(self): # Called before the first testfunction is executed self._scene = Scene() self._scene_object = SceneNode() self._scene_object2 = SceneNode() self._scene_object.addChild(self._scene_object2) self._scene.getRoot().addChild(self._scene_object) temp_matrix = Matrix() temp_matrix.setByTranslation(Vector(10,10,10)) self._scene_object2.setLocalTransformation(deepcopy(temp_matrix)) temp_matrix.setByScaleFactor(0.5) self._scene_object.setLocalTransformation(temp_matrix)
def test_ignoreSceneChanges(): scene = Scene() scene.sceneChanged.emit = MagicMock() scene.setIgnoreSceneChanges(ignore_scene_changes=True) root = scene.getRoot() root.addChild(SceneNode()) assert scene.sceneChanged.emit.call_count == 0 scene.setIgnoreSceneChanges(ignore_scene_changes=False) root.addChild(SceneNode()) assert scene.sceneChanged.emit.call_count == 2
def test_visibility(self): node1 = SceneNode() node1.setVisible(True) assert node1.isVisible() node2 = SceneNode() node1.addChild(node2) node2.setVisible(True) assert node2.isVisible() node1.setVisible(False) assert not node1.isVisible() assert not node2.isVisible()
def test_enabled(self): node1 = SceneNode() node1.setEnabled(True) assert node1.isEnabled() node2 = SceneNode() node1.addChild(node2) node2.setEnabled(True) assert node2.isEnabled() node1.setEnabled(False) assert not node1.isEnabled() assert not node2.isEnabled()
def test_getDepth(self): node1 = SceneNode() node2 = SceneNode() node3 = SceneNode() node4 = SceneNode() node1.addChild(node2) node1.addChild(node3) node2.addChild(node4) assert node1.getDepth() == 0 assert node2.getDepth() == 1 assert node3.getDepth() == 1 assert node4.getDepth() == 2
def test_addRemoveDouble(self): # Adding a child that's already a child of a node should not cause issues. Same for trying to remove one that isn't a child node_1 = SceneNode() node_2 = SceneNode() # Should work node_1.addChild(node_2) # Should still work! node_1.addChild(node_2) # This has already been tested somewhere else, so no problems are expected node_1.removeChild(node_2) # Doing it again shouldn't break. node_1.removeChild(node_2)
def test_deepCopy(self): node_1 = SceneNode() node_2 = SceneNode() node_1.translate(Vector(1, 2, 3)) node_1.scale(Vector(1.5, 1., 1.)) node_1.setMeshData(MeshData()) node_1.addChild(node_2) node_1.addDecorator(GroupDecorator()) copied_node = deepcopy(node_1) assert copied_node.getScale() == Vector(1.5, 1, 1) assert copied_node.getPosition() == Vector(1, 2, 3) assert len(copied_node.getChildren()) == 1 # Ensure that the decorator also got copied assert copied_node.callDecoration("isGroup")
def _addMeshFromData(self, mesh_data, base_name="") -> SceneNode: new_node = SceneNode() new_node.setMeshData(mesh_data) node_name = base_name + hex(id(new_node)) new_node.setName(node_name) return new_node
def test_compute2DConvexHullNoMeshData(convex_hull_decorator): node = SceneNode() with patch("UM.Application.Application.getInstance", MagicMock(return_value=mocked_application)): convex_hull_decorator.setNode(node) assert convex_hull_decorator._compute2DConvexHull() == Polygon([])
def _addMesh(self, mesh_builder, base_name=""): new_node = SceneNode() new_node.setMeshData(mesh_builder.build()) node_name = base_name + hex(id(new_node)) new_node.setName(node_name) return new_node
def test_getConvexHullBoundaryNotPrintingMesh(convex_hull_decorator): node = SceneNode() node.addDecorator(NonPrintingDecorator()) with patch("UM.Application.Application.getInstance", MagicMock(return_value=mocked_application)): convex_hull_decorator.setNode(node) assert convex_hull_decorator.getConvexHullBoundary() is None
def test_singleItemRenameWithIndex(self, objects_model): node = SceneNode() objects_model._renameNodes({ "zomg": _NodeInfo(index_to_node={1: node}, nodes_to_rename=[node]) }) assert node.getName() == "zomg(2)"
def test_addAndMergeOperations(): group_operation_1 = GroupedOperation() group_operation_2 = GroupedOperation() group_operation_3 = GroupedOperation() scene_node = SceneNode() operation_1 = TranslateOperation(scene_node, Vector(10, 10)) operation_2 = TranslateOperation(scene_node, Vector(10, 20)) operation_3 = Operation() operation_1.mergeWith = MagicMock() group_operation_1.addOperation(operation_1) assert group_operation_1.getNumChildrenOperations() == 1 # Length of the grouped operations must be the same. assert not group_operation_1.mergeWith(group_operation_2) group_operation_3.addOperation(operation_3) # The base operation always says it can't be merged (so one child says it can't be merged). This should result # in the parent (grouped) operation also failing. assert not group_operation_3.mergeWith(group_operation_1) group_operation_2.addOperation(operation_2) merged_operation = group_operation_1.mergeWith(group_operation_2) # The merge of the nested operation should have been called once. assert operation_1.mergeWith.call_count == 1 # Number of operations should still be the same. assert merged_operation.getNumChildrenOperations() == 1
def test_findObject(): scene = Scene() node = SceneNode() scene.getRoot().addChild(node) assert scene.findObject(id(node)) == node assert scene.findObject(12) is None
def test_getSelectedObjectsWithoutSelectedAncestors(): scene_node_1 = SceneNode() Selection.add(scene_node_1) test_tool_1 = Tool() assert test_tool_1._getSelectedObjectsWithoutSelectedAncestors() == [ scene_node_1 ]
def read(self, file_name): mesh_builder = MeshBuilder() scene_node = SceneNode() if use_numpystl: self._loadWithNumpySTL(file_name, mesh_builder) else: f = open(file_name, "rb") if not self._loadBinary(mesh_builder, f): f.close() f = open(file_name, "rt") try: self._loadAscii(mesh_builder, f) except UnicodeDecodeError: return None f.close() Job.yieldThread() # Yield somewhat to ensure the GUI has time to update a bit. mesh_builder.calculateNormals(fast = True) mesh_builder.setFileName(file_name) mesh = mesh_builder.build() Logger.log("d", "Loaded a mesh with %s vertices", mesh_builder.getVertexCount()) scene_node.setMeshData(mesh) return scene_node
def _read(self, file_name): """Decide if we need to use ascii or binary in order to read file""" mesh_builder = MeshBuilder() scene_node = SceneNode() self.load_file(file_name, mesh_builder, _use_numpystl = use_numpystl) mesh = mesh_builder.build() if use_numpystl: verts = mesh.getVertices() # In some cases numpy stl reads incorrectly and the result is that the Z values are all 0 # Add new error cases if you find them. if numpy.amin(verts[:, 1]) == numpy.amax(verts[:, 1]): # Something may have gone wrong in numpy stl, start over without numpy stl Logger.log("w", "All Z coordinates are the same using numpystl, trying again without numpy stl.") mesh_builder = MeshBuilder() self.load_file(file_name, mesh_builder, _use_numpystl = False) mesh = mesh_builder.build() verts = mesh.getVertices() if numpy.amin(verts[:, 1]) == numpy.amax(verts[:, 1]): Logger.log("e", "All Z coordinates are still the same without numpy stl... let's hope for the best") if mesh_builder.getVertexCount() == 0: Logger.log("d", "File did not contain valid data, unable to read.") return None # We didn't load anything. scene_node.setMeshData(mesh) Logger.log("d", "Loaded a mesh with %s vertices", mesh_builder.getVertexCount()) return scene_node
def test_print_to_cloud(self): active_machine_mock = self.app.getGlobalContainerStack.return_value active_machine_mock.getMetaDataEntry.side_effect = {"file_formats": "application/x-ufp"}.get request_upload_response = parseFixture("putJobUploadResponse") request_print_response = parseFixture("postJobPrintResponse") self.network.prepareReply("PUT", self.REQUEST_UPLOAD_URL, 201, request_upload_response) self.network.prepareReply("PUT", request_upload_response["data"]["upload_url"], 201, b"{}") self.network.prepareReply("POST", self.PRINT_URL, 200, request_print_response) file_handler = MagicMock() file_handler.getSupportedFileTypesWrite.return_value = [{ "extension": "ufp", "mime_type": "application/x-ufp", "mode": 2 }, { "extension": "gcode.gz", "mime_type": "application/gzip", "mode": 2, }] file_handler.getWriterByMimeType.return_value.write.side_effect = \ lambda stream, nodes: stream.write(str(nodes).encode()) scene_nodes = [SceneNode()] expected_mesh = str(scene_nodes).encode() self.device.requestWrite(scene_nodes, file_handler=file_handler, file_name="FileName") self.network.flushReplies() self.assertEqual( {"data": {"content_type": "application/x-ufp", "file_size": len(expected_mesh), "job_name": "FileName"}}, json.loads(self.network.getRequestBody("PUT", self.REQUEST_UPLOAD_URL).decode()) ) self.assertEqual(expected_mesh, self.network.getRequestBody("PUT", request_upload_response["data"]["upload_url"])) self.assertIsNone(self.network.getRequestBody("POST", self.PRINT_URL))
def test_getSetSelectable(self): node = SceneNode() node.setSelectable(True) assert node.isSelectable() node.setEnabled(False) assert not node.isSelectable( ) # Node is disabled, can't select it anymore
def test_SceneNodeDecorator(): test_node = SceneNode() test_decorator = SceneNodeDecorator() amazing_decorator = TheAmazingTestDecorator() less_amazing_decorator = TheLessAmazingTestDecorator() not_amazing_decorator = TheNotSoAmazingTestDecorator() # Replace emit with mock object test_node.decoratorsChanged.emit = MagicMock() test_decorator.clear = MagicMock() # First actual change test_node.addDecorator(test_decorator) assert len(test_node.getDecorators()) == 1 assert test_node.decoratorsChanged.emit.call_count == 1 # Adding a decorator of the same type (SceneNodeDecorator) again should not do anything. test_node.addDecorator(test_decorator) assert len(test_node.getDecorators()) == 1 assert test_node.decoratorsChanged.emit.call_count == 1 assert test_node.getDecorator(type(test_decorator)) == test_decorator # Remove the decorator again! test_node.removeDecorator(SceneNodeDecorator) assert len(test_node.getDecorators()) == 0 assert test_node.decoratorsChanged.emit.call_count == 2 assert test_decorator.clear.call_count == 1 # Ensure that the clear of the test decorator is called. # Add a number of decorators! test_node.addDecorator(amazing_decorator) test_node.addDecorator(less_amazing_decorator) test_node.addDecorator(not_amazing_decorator) assert test_node.decoratorsChanged.emit.call_count == 5 assert len(test_node.getDecorators()) == 3 assert test_node.hasDecoration("zomg") == False assert test_node.hasDecoration("theOkayDecoration") assert test_node.hasDecoration("theAmazingDecoration") # Calling the decorations with args / kwargs assert test_node.callDecoration("theOkayDecoration", None) is None assert test_node.callDecoration("theEvenMoreAmazingDecoration", "beep") == ("beep", "Wow", "so wow") assert test_node.callDecoration("theEvenMoreAmazingDecoration", "beep", much_test="Wow") == ("beep", "Wow", "Wow") # Calling decoration that is "double" assert test_node.callDecoration("theAmazingDecoration") == "Amazing!" test_node.removeDecorator(TheAmazingTestDecorator) assert test_node.callDecoration("theAmazingDecoration") == "amazing" not_amazing_decorator.clear = MagicMock() test_node.removeDecorators() # Also assure that removing all decorators also triggers the clear assert not_amazing_decorator.clear.call_count == 1 assert len(test_node.getDecorators()) == 0 assert test_node.decoratorsChanged.emit.call_count == 7 assert test_node.getDecorator(type(test_decorator)) is None