def test_slice_single_model(self):
        """
        tries to slice a single model with 0.2mm layer height and checks to see
        if the file exists. Not a really robust check, but it works
        """
        try:
            os.remove('test/models/gcodes/bulbasaur-0.2mm.gcode')
        except FileNotFoundError:
            pass

        expected_commands = [[
            # 'bin/slic3r-pe.AppImage',
            mpp.BINARY,
            '--slice', '--load',
            'profiles/default-profile.ini', '--first-layer-height', '0.25',
            '--layer-height', '0.2',
            '--center', str(int(TestCoreFunctions.print_bed_width/2)) + ',' + \
            str(int(TestCoreFunctions.print_bed_height/2)),
            'test/models/bulbasaur.stl',
            '--output', 'test/models/gcodes/bulbasaur-0.2mm.gcode'
            ]]
        self.assertEqual(expected_commands,
                         mpp.slice_models(0.2, False, \
                                         ['test/' + 'models/bulbasaur.stl']))
        self.assertTrue(
            os.path.isfile('test/models/gcodes/bulbasaur-0.2mm.gcode'))

        try:
            os.remove('test/models/gcodes/bulbasaur-0.2mm.gcode')
        except FileNotFoundError:
            pass
    def test_slice_model_that_isnt_centered(self):
        """
        models that were not centered would fail with an unhelpful message.
        This test ensures that non-centered models get fixed first
        """
        try:
            os.remove('test/models/gcodes/crank-0.3mm.gcode')
        except FileNotFoundError:
            pass

        expected_commands = [
            [
                # 'bin/slic3r-pe.AppImage',
                mpp.BINARY,
                '--slice', '--load',
                'profiles/default-profile.ini', '--first-layer-height',
                '0.35', '--layer-height', '0.3', '--center',
                str(int(TestCoreFunctions.print_bed_width/2)) + ',' + \
                str(int(TestCoreFunctions.print_bed_height/2)),
                'test/models/crank.stl', '--output',
                'test/models/gcodes/crank-0.3mm.gcode'
            ]]
        self.assertEqual(
            expected_commands,
            mpp.slice_models(0.3, False, ['test/' + 'models/crank.stl']))
        self.assertTrue(os.path.isfile('test/models/gcodes/crank-0.3mm.gcode'))

        try:
            os.remove('test/models/gcodes/crank-0.3mm.gcode')
        except FileNotFoundError:
            pass
    def test_slice_single_model_with_supports(self):
        """
        slices with supports and checks the generated time/usage estimates,
        which will be greater because of the support material
        """
        try:
            os.remove('test/models/gcodes/support-test-0.1mm.gcode')
        except FileNotFoundError:
            pass

        expected_commands = [[
            # 'bin/slic3r-pe.AppImage',
            mpp.BINARY,
            '--slice', '--load',
            'profiles/default-profile.ini', '--first-layer-height', '0.15',
            '--layer-height', '0.1', '--support-material',
            '--center', str(int(TestCoreFunctions.print_bed_width/2)) + ',' + \
            str(int(TestCoreFunctions.print_bed_height/2)),
            'test/models/support-test.stl',
            '--output', 'test/models/gcodes/support-test-0.1mm.gcode'
            ]]
        self.assertEqual(
            expected_commands,
            mpp.slice_models(0.1, True, ['test/' + 'models/support-test.stl']))
        self.assertTrue(
            os.path.isfile('test/models/gcodes/support-test-0.1mm.gcode'))

        try:
            os.remove('test/models/gcodes/support-test-0.1mm.gcode')
        except FileNotFoundError:
            pass
    def test_slice_three_models_simultaneously(self):
        """
        slices multiple models to ensure behavior is still the same as when
        slicing one
        """
        try:
            os.remove('test/models/gcodes/1cm-cube-0.2mm.gcode')
            os.remove('test/models/gcodes/2cm-cube-0.2mm.gcode')
            os.remove('test/models/gcodes/3cm-cube-0.2mm.gcode')
        except FileNotFoundError:
            pass

        expected_commands = [
            [
                # 'bin/slic3r-pe.AppImage',
                mpp.BINARY,
                '--slice', '--load',
                'profiles/default-profile.ini', '--first-layer-height',
                '0.25', '--layer-height', '0.2',
                '--center', str(int(TestCoreFunctions.print_bed_width/2)) \
                + ',' + str(int(TestCoreFunctions.print_bed_height/2)),
                'test/models/1cm-cube.stl',
                '--output', 'test/models/gcodes/1cm-cube-0.2mm.gcode'
            ],
            [
                # 'bin/slic3r-pe.AppImage',
                mpp.BINARY,
                '--slice', '--load',
                'profiles/default-profile.ini', '--first-layer-height',
                '0.25', '--layer-height', '0.2',
                '--center', str(int(TestCoreFunctions.print_bed_width/2)) + \
                ',' + str(int(TestCoreFunctions.print_bed_height/2)),
                'test/models/2cm-cube.stl',
                '--output', 'test/models/gcodes/2cm-cube-0.2mm.gcode'
            ],
            [
                # 'bin/slic3r-pe.AppImage',
                mpp.BINARY,
                '--slice', '--load',
                'profiles/default-profile.ini', '--first-layer-height',
                '0.25', '--layer-height', '0.2',
                '--center', str(int(TestCoreFunctions.print_bed_width/2)) \
                + ',' + str(int(TestCoreFunctions.print_bed_height/2)),
                'test/models/3cm-cube.stl',
                '--output', 'test/models/gcodes/3cm-cube-0.2mm.gcode'
            ]]
        self.assertEqual(
            expected_commands,
            mpp.slice_models(0.2, False, [
                'test/models/1cm-cube.stl',
                'test/models/2cm-cube.stl',
                'test/models/3cm-cube.stl',
            ]))
        self.assertTrue(
            os.path.isfile('test/models/gcodes/1cm-cube-0.2mm.gcode'))
        self.assertTrue(
            os.path.isfile('test/models/gcodes/2cm-cube-0.2mm.gcode'))
        self.assertTrue(
            os.path.isfile('test/models/gcodes/3cm-cube-0.2mm.gcode'))

        try:
            os.remove('test/models/gcodes/1cm-cube-0.2mm.gcode')
            os.remove('test/models/gcodes/2cm-cube-0.2mm.gcode')
            os.remove('test/models/gcodes/3cm-cube-0.2mm.gcode')
        except FileNotFoundError:
            pass
Exemple #5
0
def main():
    gray = '#444444'
    sg.SetOptions(background_color='black',
                  element_background_color='black',
                  text_element_background_color='black',
                  input_elements_background_color=gray,
                  text_color='white',
                  element_text_color='white',
                  input_text_color='white',
                  button_color=('white', gray),
                  window_location=(600, 200),
                  font='Fixedsys')

    main_window_layout = [
                 [sg.Text('Broswe for .stl files (Hold shift to select '\
                          + 'multiple)')],
                 [sg.InputText(key='_STL_FILES_'), sg.FilesBrowse()],
                 [sg.Text('Select where the output data should be stored')],
                 [sg.InputText(key='_OUTPUT_FILE_DIR_'), sg.FolderBrowse()],
                 [sg.Text('Layer height')],
                 [sg.Slider(range=(0.05, 0.35), default_value=(0.2),
                     resolution=(0.05), orientation='horizontal',
                     key='_LAYER_HEIGHT_')],
                 [sg.Checkbox('Generate supports', default=False,
                     key='_GENERATE_SUPPORTS?_')],
                 [sg.Button(button_text='Get Estimates', visible=True)],
             ]

    progress_bar_window_layout = [[sg.Text('')],
                                  [
                                      sg.ProgressBar(max_value=10000,
                                                     orientation='h',
                                                     size=(20, 20),
                                                     key='progressbar'),
                                      sg.Text('', key='num_completed'),
                                      sg.Text('/'),
                                      sg.Text('', key='num_total')
                                  ], [sg.Cancel()]]

    window = sg.Window('Multi Part Print Calculator', main_window_layout)

    while True:  # Event Loop
        event, values = window.Read(timeout=100)
        if event is None or event == 'Exit':
            break
        if event == 'Get Estimates':
            if validate_input(values['_STL_FILES_'],
                              values['_OUTPUT_FILE_DIR_']):
                window.Element('Get Estimates').Update(visible=False)

                layer_height = values['_LAYER_HEIGHT_']
                supports = values['_GENERATE_SUPPORTS?_']
                models = values['_STL_FILES_'].split(';')

                result = ''
                gcode_file_names = []
                num_models = len(models)
                for i in range(num_models):
                    mpp.slice_models(layer_height, supports, [models[i]])
                    gcode_file_names.append(
                        mpp.get_gcode_output_path(models[i], layer_height))
                    if sg.OneLineProgressMeter('Slicing models...', i + 1,
                                               num_models, 'single') is False:
                        if num_models != i + 1:
                            result += 'Slicing was cancelled, not all ' + \
                                      'selected models are included.\n'
                        break

                estimates = []
                num_gcode_files = len(gcode_file_names)
                for i in range(num_gcode_files):
                    # the scraper function returns a list and we just want the
                    # first element
                    estimates.append(
                        mpp.scrape_time_and_usage_estimates(
                            [gcode_file_names[i]])[0])
                    if sg.OneLineProgressMeter('Scraping .gcode files ' + \
                                               'for estimates...', i+1,
                                               num_gcode_files,
                                               'scraping_progress') is False:
                        if num_models != i + 1:
                            result += 'Data scraping was cancelled, not ' + \
                                      'all selected models are included.\n'
                        break

                estimates.insert(0, mpp.aggregate_data(estimates))

                output_file = values['_OUTPUT_FILE_DIR_'] \
                    + '/_print_estimates.txt'
                result += 'Estimates have also been output to ' + output_file \
                    + '\n\n'
                result += mpp.output_results(estimates, output_file)

                window.Element('Get Estimates').Update(visible=True)
                sg.PopupScrolled(result, size=(120, 35))
            else:
                sg.Popup('You must input at least one .stl file and a place ' \
                         + 'to store the output!')

    window.Close()