mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Merge remote-tracking branch 'origin/ys_bug_fixing' into ys_msw_dpi
This commit is contained in:
		
						commit
						de55801e31
					
				
					 44 changed files with 387 additions and 165 deletions
				
			
		| 
						 | 
				
			
			@ -61,3 +61,10 @@ Please note that the `CMAKE_OSX_DEPLOYMENT_TARGET` and `CMAKE_OSX_SYSROOT` optio
 | 
			
		|||
on both the dependencies bundle as well as Slic3r PE itself.
 | 
			
		||||
 | 
			
		||||
Official Mac Slic3r builds are currently built against SDK 10.9 to ensure compatibility with older Macs.
 | 
			
		||||
 | 
			
		||||
_Warning:_ XCode may be set such that it rejects SDKs bellow some version (silently, more or less).
 | 
			
		||||
This is set in the property list file
 | 
			
		||||
 | 
			
		||||
    /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Info.plist
 | 
			
		||||
 | 
			
		||||
To remove the limitation, simply delete the key `MinimumSDKVersion` from that file.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,13 +5,13 @@
 | 
			
		|||
<g id="layers">
 | 
			
		||||
	<g>
 | 
			
		||||
		<g>
 | 
			
		||||
			<rect x="1" y="13" fill="#808080" width="14" height="2"/>
 | 
			
		||||
			<rect x="1" y="13" fill="#FFFFFF" width="14" height="2"/>
 | 
			
		||||
		</g>
 | 
			
		||||
		<g>
 | 
			
		||||
			<rect x="1" y="10.6" fill="#808080" width="14" height="1.74"/>
 | 
			
		||||
			<rect x="1" y="10.6" fill="#FFFFFF" width="14" height="1.74"/>
 | 
			
		||||
		</g>
 | 
			
		||||
		<g>
 | 
			
		||||
			<rect x="1" y="8.19" fill="#808080" width="14" height="1.47"/>
 | 
			
		||||
			<rect x="1" y="8.19" fill="#FFFFFF" width="14" height="1.47"/>
 | 
			
		||||
		</g>
 | 
			
		||||
		<g>
 | 
			
		||||
			<rect x="1" y="5.79" fill="#ED6B21" width="14" height="1.2"/>
 | 
			
		||||
| 
						 | 
				
			
			@ -20,7 +20,7 @@
 | 
			
		|||
			<rect x="1" y="3.39" fill="#ED6B21" width="14" height="0.93"/>
 | 
			
		||||
		</g>
 | 
			
		||||
		<g>
 | 
			
		||||
			<rect x="1" y="0.99" fill="#808080" width="14" height="0.67"/>
 | 
			
		||||
			<rect x="1" y="0.99" fill="#FFFFFF" width="14" height="0.67"/>
 | 
			
		||||
		</g>
 | 
			
		||||
	</g>
 | 
			
		||||
</g>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
		 Before Width: | Height: | Size: 845 B After Width: | Height: | Size: 845 B  | 
| 
						 | 
				
			
			@ -173,7 +173,7 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
 | 
			
		|||
 | 
			
		||||
    // Toolchangeresult.gcode assumes the wipe tower corner is at the origin
 | 
			
		||||
    // We want to rotate and shift all extrusions (gcode postprocessing) and starting and ending position
 | 
			
		||||
    float alpha = m_wipe_tower_rotation/180.f * M_PI;
 | 
			
		||||
    float alpha = m_wipe_tower_rotation/180.f * float(M_PI);
 | 
			
		||||
    WipeTower::xy start_pos = tcr.start_pos;
 | 
			
		||||
    WipeTower::xy end_pos = tcr.end_pos;
 | 
			
		||||
    start_pos.rotate(alpha);
 | 
			
		||||
| 
						 | 
				
			
			@ -519,43 +519,43 @@ void GCode::_do_export(Print &print, FILE *file)
 | 
			
		|||
    // this->print_machine_envelope(file, print);
 | 
			
		||||
    // shall be adjusted as well to produce a G-code block compatible with the particular firmware flavor.
 | 
			
		||||
    if (print.config().gcode_flavor.value == gcfMarlin) {
 | 
			
		||||
        m_normal_time_estimator.set_max_acceleration(print.config().machine_max_acceleration_extruding.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_retract_acceleration(print.config().machine_max_acceleration_retracting.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_minimum_feedrate(print.config().machine_min_extruding_rate.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_minimum_travel_feedrate(print.config().machine_min_travel_rate.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, print.config().machine_max_acceleration_x.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, print.config().machine_max_acceleration_y.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, print.config().machine_max_acceleration_z.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, print.config().machine_max_acceleration_e.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, print.config().machine_max_feedrate_x.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, print.config().machine_max_feedrate_y.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, print.config().machine_max_feedrate_z.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, print.config().machine_max_feedrate_e.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, print.config().machine_max_jerk_x.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, print.config().machine_max_jerk_y.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config().machine_max_jerk_z.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config().machine_max_jerk_e.values[0]);
 | 
			
		||||
        m_normal_time_estimator.set_max_acceleration((float)print.config().machine_max_acceleration_extruding.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_retract_acceleration((float)print.config().machine_max_acceleration_retracting.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_minimum_feedrate((float)print.config().machine_min_extruding_rate.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_minimum_travel_feedrate((float)print.config().machine_min_travel_rate.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)print.config().machine_max_acceleration_x.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)print.config().machine_max_acceleration_y.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)print.config().machine_max_acceleration_z.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)print.config().machine_max_acceleration_e.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)print.config().machine_max_feedrate_x.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)print.config().machine_max_feedrate_y.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)print.config().machine_max_feedrate_z.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)print.config().machine_max_feedrate_e.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)print.config().machine_max_jerk_x.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)print.config().machine_max_jerk_y.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)print.config().machine_max_jerk_z.values[0]);
 | 
			
		||||
		m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)print.config().machine_max_jerk_e.values[0]);
 | 
			
		||||
 | 
			
		||||
        if (m_silent_time_estimator_enabled)
 | 
			
		||||
        {
 | 
			
		||||
            m_silent_time_estimator.reset();
 | 
			
		||||
            m_silent_time_estimator.set_dialect(print.config().gcode_flavor);
 | 
			
		||||
            m_silent_time_estimator.set_max_acceleration(print.config().machine_max_acceleration_extruding.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_retract_acceleration(print.config().machine_max_acceleration_retracting.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_minimum_feedrate(print.config().machine_min_extruding_rate.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_minimum_travel_feedrate(print.config().machine_min_travel_rate.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, print.config().machine_max_acceleration_x.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, print.config().machine_max_acceleration_y.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, print.config().machine_max_acceleration_z.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, print.config().machine_max_acceleration_e.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, print.config().machine_max_feedrate_x.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, print.config().machine_max_feedrate_y.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, print.config().machine_max_feedrate_z.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, print.config().machine_max_feedrate_e.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, print.config().machine_max_jerk_x.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, print.config().machine_max_jerk_y.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config().machine_max_jerk_z.values[1]);
 | 
			
		||||
            m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config().machine_max_jerk_e.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_max_acceleration((float)print.config().machine_max_acceleration_extruding.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_retract_acceleration((float)print.config().machine_max_acceleration_retracting.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_minimum_feedrate((float)print.config().machine_min_extruding_rate.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_minimum_travel_feedrate((float)print.config().machine_min_travel_rate.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)print.config().machine_max_acceleration_x.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)print.config().machine_max_acceleration_y.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)print.config().machine_max_acceleration_z.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)print.config().machine_max_acceleration_e.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)print.config().machine_max_feedrate_x.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)print.config().machine_max_feedrate_y.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)print.config().machine_max_feedrate_z.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)print.config().machine_max_feedrate_e.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)print.config().machine_max_jerk_x.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)print.config().machine_max_jerk_y.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)print.config().machine_max_jerk_z.values[1]);
 | 
			
		||||
			m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)print.config().machine_max_jerk_e.values[1]);
 | 
			
		||||
            if (print.config().single_extruder_multi_material) {
 | 
			
		||||
                // As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they
 | 
			
		||||
                // are considered to be active for the single extruder multi-material printers only.
 | 
			
		||||
| 
						 | 
				
			
			@ -1054,26 +1054,54 @@ void GCode::_do_export(Print &print, FILE *file)
 | 
			
		|||
    print.m_print_statistics.clear();
 | 
			
		||||
    print.m_print_statistics.estimated_normal_print_time = m_normal_time_estimator.get_time_dhms();
 | 
			
		||||
    print.m_print_statistics.estimated_silent_print_time = m_silent_time_estimator_enabled ? m_silent_time_estimator.get_time_dhms() : "N/A";
 | 
			
		||||
    for (const Extruder &extruder : m_writer.extruders()) {
 | 
			
		||||
        double used_filament   = extruder.used_filament() + (has_wipe_tower ? print.wipe_tower_data().used_filament[extruder.id()] : 0.f);
 | 
			
		||||
        double extruded_volume = extruder.extruded_volume() + (has_wipe_tower ? print.wipe_tower_data().used_filament[extruder.id()] * 2.4052f : 0.f); // assumes 1.75mm filament diameter
 | 
			
		||||
        double filament_weight = extruded_volume * extruder.filament_density() * 0.001;
 | 
			
		||||
        double filament_cost   = filament_weight * extruder.filament_cost()    * 0.001;
 | 
			
		||||
        print.m_print_statistics.filament_stats.insert(std::pair<size_t, float>(extruder.id(), (float)used_filament));
 | 
			
		||||
        _write_format(file, "; filament used = %.1lfmm (%.1lfcm3)\n", used_filament, extruded_volume * 0.001);
 | 
			
		||||
        if (filament_weight > 0.) {
 | 
			
		||||
            print.m_print_statistics.total_weight = print.m_print_statistics.total_weight + filament_weight;
 | 
			
		||||
            _write_format(file, "; filament used = %.1lf\n", filament_weight);
 | 
			
		||||
            if (filament_cost > 0.) {
 | 
			
		||||
                print.m_print_statistics.total_cost = print.m_print_statistics.total_cost + filament_cost;
 | 
			
		||||
                _write_format(file, "; filament cost = %.1lf\n", filament_cost);
 | 
			
		||||
    std::vector<Extruder> extruders = m_writer.extruders();
 | 
			
		||||
    if (! extruders.empty()) {
 | 
			
		||||
        std::pair<std::string, unsigned int> out_filament_used_mm ("; filament used [mm] = ", 0);
 | 
			
		||||
        std::pair<std::string, unsigned int> out_filament_used_cm3("; filament used [cm3] = ", 0);
 | 
			
		||||
        std::pair<std::string, unsigned int> out_filament_used_g  ("; filament used [g] = ", 0);
 | 
			
		||||
        std::pair<std::string, unsigned int> out_filament_cost    ("; filament cost = ", 0);
 | 
			
		||||
        for (const Extruder &extruder : extruders) {
 | 
			
		||||
            double used_filament   = extruder.used_filament() + (has_wipe_tower ? print.wipe_tower_data().used_filament[extruder.id()] : 0.f);
 | 
			
		||||
            double extruded_volume = extruder.extruded_volume() + (has_wipe_tower ? print.wipe_tower_data().used_filament[extruder.id()] * 2.4052f : 0.f); // assumes 1.75mm filament diameter
 | 
			
		||||
            double filament_weight = extruded_volume * extruder.filament_density() * 0.001;
 | 
			
		||||
            double filament_cost   = filament_weight * extruder.filament_cost()    * 0.001;
 | 
			
		||||
            auto append = [&extruder, &extruders](std::pair<std::string, unsigned int> &dst, const char *tmpl, double value) {
 | 
			
		||||
                while (dst.second < extruder.id()) {
 | 
			
		||||
                    // Fill in the non-printing extruders with zeros.
 | 
			
		||||
                    dst.first += (dst.second > 0) ? ", 0" : "0";
 | 
			
		||||
                    ++ dst.second;
 | 
			
		||||
                }
 | 
			
		||||
                if (dst.second > 0)
 | 
			
		||||
                    dst.first += ", ";
 | 
			
		||||
                char buf[64];
 | 
			
		||||
				sprintf(buf, tmpl, value);
 | 
			
		||||
                dst.first += buf;
 | 
			
		||||
                ++ dst.second;
 | 
			
		||||
            };
 | 
			
		||||
            print.m_print_statistics.filament_stats.insert(std::pair<size_t, float>(extruder.id(), (float)used_filament));
 | 
			
		||||
            append(out_filament_used_mm,  "%.1lf", used_filament);
 | 
			
		||||
            append(out_filament_used_cm3, "%.1lf", extruded_volume * 0.001);
 | 
			
		||||
            if (filament_weight > 0.) {
 | 
			
		||||
                print.m_print_statistics.total_weight = print.m_print_statistics.total_weight + filament_weight;
 | 
			
		||||
                append(out_filament_used_g, "%.1lf", filament_weight);
 | 
			
		||||
                if (filament_cost > 0.) {
 | 
			
		||||
                    print.m_print_statistics.total_cost = print.m_print_statistics.total_cost + filament_cost;
 | 
			
		||||
                    append(out_filament_cost, "%.1lf", filament_cost);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            print.m_print_statistics.total_used_filament += used_filament;
 | 
			
		||||
            print.m_print_statistics.total_extruded_volume += extruded_volume;
 | 
			
		||||
            print.m_print_statistics.total_wipe_tower_filament += has_wipe_tower ? used_filament - extruder.used_filament() : 0.;
 | 
			
		||||
            print.m_print_statistics.total_wipe_tower_cost += has_wipe_tower ? (extruded_volume - extruder.extruded_volume())* extruder.filament_density() * 0.001 * extruder.filament_cost() * 0.001 : 0.;
 | 
			
		||||
        }
 | 
			
		||||
        print.m_print_statistics.total_used_filament += used_filament;
 | 
			
		||||
        print.m_print_statistics.total_extruded_volume += extruded_volume;
 | 
			
		||||
        print.m_print_statistics.total_wipe_tower_filament += has_wipe_tower ? used_filament - extruder.used_filament() : 0.;
 | 
			
		||||
        print.m_print_statistics.total_wipe_tower_cost += has_wipe_tower ? (extruded_volume - extruder.extruded_volume())* extruder.filament_density() * 0.001 * extruder.filament_cost() * 0.001 : 0.;
 | 
			
		||||
        _writeln(file, out_filament_used_mm.first);
 | 
			
		||||
		_writeln(file, out_filament_used_cm3.first);
 | 
			
		||||
		if (out_filament_used_g.second)
 | 
			
		||||
			_writeln(file, out_filament_used_g.first);
 | 
			
		||||
		if (out_filament_cost.second)
 | 
			
		||||
			_writeln(file, out_filament_cost.first);
 | 
			
		||||
    }
 | 
			
		||||
    _write_format(file, "; total filament used [g] = %.1lf\n", print.m_print_statistics.total_weight);
 | 
			
		||||
    _write_format(file, "; total filament cost = %.1lf\n", print.m_print_statistics.total_cost);
 | 
			
		||||
    _write_format(file, "; estimated printing time (normal mode) = %s\n", m_normal_time_estimator.get_time_dhms().c_str());
 | 
			
		||||
    if (m_silent_time_estimator_enabled)
 | 
			
		||||
| 
						 | 
				
			
			@ -1528,7 +1556,7 @@ void GCode::process_layer(
 | 
			
		|||
                            std::max<int>(region.config().perimeter_extruder.value - 1, 0);
 | 
			
		||||
 | 
			
		||||
                        // Let's recover vector of extruder overrides:
 | 
			
		||||
                        const ExtruderPerCopy* entity_overrides = const_cast<LayerTools&>(layer_tools).wiping_extrusions().get_extruder_overrides(fill, correct_extruder_id, layer_to_print.object()->copies().size());
 | 
			
		||||
                        const ExtruderPerCopy* entity_overrides = const_cast<LayerTools&>(layer_tools).wiping_extrusions().get_extruder_overrides(fill, correct_extruder_id, (int)layer_to_print.object()->copies().size());
 | 
			
		||||
 | 
			
		||||
                        // Now we must add this extrusion into the by_extruder map, once for each extruder that will print it:
 | 
			
		||||
                        for (unsigned int extruder : layer_tools.extruders)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -197,7 +197,7 @@ private:
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
    const bool  m_peters_wipe_tower   = false; // sparse wipe tower inspired by Peter's post processor - not finished yet
 | 
			
		||||
    const float Filament_Area         = M_PI * 1.75f * 1.75f / 4.f; // filament area in mm^2
 | 
			
		||||
    const float Filament_Area         = float(M_PI * 1.75f * 1.75f / 4.f); // filament area in mm^2
 | 
			
		||||
    const float Width_To_Nozzle_Ratio = 1.25f; // desired line width (oval) in multiples of nozzle diameter - may not be actually neccessary to adjust
 | 
			
		||||
    const float WT_EPSILON            = 1e-3f;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -224,8 +224,8 @@ private:
 | 
			
		|||
    bool 			m_retain_speed_override		= true;
 | 
			
		||||
    bool            m_adhesion                  = true;
 | 
			
		||||
 | 
			
		||||
	float m_perimeter_width = 0.4 * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill.
 | 
			
		||||
	float m_extrusion_flow = 0.038; //0.029f;// Extrusion flow is derived from m_perimeter_width, layer height and filament diameter.
 | 
			
		||||
	float m_perimeter_width = 0.4f * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill.
 | 
			
		||||
	float m_extrusion_flow = 0.038f; //0.029f;// Extrusion flow is derived from m_perimeter_width, layer height and filament diameter.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    struct FilamentParameters {
 | 
			
		||||
| 
						 | 
				
			
			@ -269,12 +269,12 @@ private:
 | 
			
		|||
	{
 | 
			
		||||
		if ( layer_height < 0 )
 | 
			
		||||
			return m_extrusion_flow;
 | 
			
		||||
		return layer_height * ( m_perimeter_width - layer_height * (1-M_PI/4.f)) / Filament_Area;
 | 
			
		||||
		return layer_height * ( m_perimeter_width - layer_height * (1.f-float(M_PI)/4.f)) / Filament_Area;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Calculates length of extrusion line to extrude given volume
 | 
			
		||||
	float volume_to_length(float volume, float line_width, float layer_height) const {
 | 
			
		||||
		return std::max(0., volume / (layer_height * (line_width - layer_height * (1. - M_PI / 4.))));
 | 
			
		||||
		return std::max(0.f, volume / (layer_height * (line_width - layer_height * (1.f - float(M_PI) / 4.f))));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Calculates depth for all layers and propagates them downwards
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,7 +38,6 @@ static const std::string MOVE_TYPE_STR[Slic3r::GCodeTimeEstimator::Block::Num_Ty
 | 
			
		|||
#endif // ENABLE_MOVE_STATS
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
    void GCodeTimeEstimator::Feedrates::reset()
 | 
			
		||||
    {
 | 
			
		||||
        feedrate = 0.0f;
 | 
			
		||||
| 
						 | 
				
			
			@ -695,6 +694,8 @@ namespace Slic3r {
 | 
			
		|||
        set_axis_position(X, 0.0f);
 | 
			
		||||
        set_axis_position(Y, 0.0f);
 | 
			
		||||
        set_axis_position(Z, 0.0f);
 | 
			
		||||
        if (get_e_local_positioning_type() == Absolute)
 | 
			
		||||
            set_axis_position(E, 0.0f);
 | 
			
		||||
 | 
			
		||||
        set_additional_time(0.0f);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -715,7 +716,6 @@ namespace Slic3r {
 | 
			
		|||
        _blocks.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    void GCodeTimeEstimator::_calculate_time()
 | 
			
		||||
    {
 | 
			
		||||
        PROFILE_FUNC();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1189,6 +1189,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, b
 | 
			
		|||
            volume->mesh.transform(instance_matrix * volume_matrix, true);
 | 
			
		||||
 | 
			
		||||
            // Perform cut
 | 
			
		||||
            volume->mesh.require_shared_vertices(); // TriangleMeshSlicer needs this
 | 
			
		||||
            TriangleMeshSlicer tms(&volume->mesh);
 | 
			
		||||
            tms.cut(float(z), &upper_mesh, &lower_mesh);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1813,6 +1813,7 @@ std::vector<ExPolygons> PrintObject::_slice_volumes(const std::vector<float> &z,
 | 
			
		|||
            TriangleMeshSlicer mslicer;
 | 
			
		||||
            const Print *print = this->print();
 | 
			
		||||
            auto callback = TriangleMeshSlicer::throw_on_cancel_callback_type([print](){print->throw_if_canceled();});
 | 
			
		||||
            mesh.require_shared_vertices(); // TriangleMeshSlicer needs this
 | 
			
		||||
            mslicer.init(&mesh, callback);
 | 
			
		||||
			mslicer.slice(z, float(m_config.slice_closing_radius.value), &layers, callback);
 | 
			
		||||
            m_print->throw_if_canceled();
 | 
			
		||||
| 
						 | 
				
			
			@ -1840,6 +1841,7 @@ std::vector<ExPolygons> PrintObject::_slice_volume(const std::vector<float> &z,
 | 
			
		|||
        TriangleMeshSlicer mslicer;
 | 
			
		||||
        const Print *print = this->print();
 | 
			
		||||
        auto callback = TriangleMeshSlicer::throw_on_cancel_callback_type([print](){print->throw_if_canceled();});
 | 
			
		||||
        mesh.require_shared_vertices(); // TriangleMeshSlicer needs this
 | 
			
		||||
        mslicer.init(&mesh, callback);
 | 
			
		||||
        mslicer.slice(z, float(m_config.slice_closing_radius.value), &layers, callback);
 | 
			
		||||
        m_print->throw_if_canceled();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -552,6 +552,7 @@ void base_plate(const TriangleMesh &mesh, ExPolygons &output, float h,
 | 
			
		|||
                float layerh, ThrowOnCancel thrfn)
 | 
			
		||||
{
 | 
			
		||||
    TriangleMesh m = mesh;
 | 
			
		||||
    m.require_shared_vertices(); // TriangleMeshSlicer needs this
 | 
			
		||||
    TriangleMeshSlicer slicer(&m);
 | 
			
		||||
 | 
			
		||||
    auto bb = mesh.bounding_box();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -817,6 +817,10 @@ public:
 | 
			
		|||
 | 
			
		||||
        meshcache = mesh(merged);
 | 
			
		||||
 | 
			
		||||
        // The mesh will be passed by const-pointer to TriangleMeshSlicer,
 | 
			
		||||
        // which will need this.
 | 
			
		||||
        meshcache.require_shared_vertices();
 | 
			
		||||
 | 
			
		||||
        // TODO: Is this necessary?
 | 
			
		||||
        //meshcache.repair();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2231,6 +2235,7 @@ SlicedSupports SLASupportTree::slice(float layerh, float init_layerh) const
 | 
			
		|||
 | 
			
		||||
    TriangleMesh fullmesh = m_impl->merged_mesh();
 | 
			
		||||
    fullmesh.merge(get_pad());
 | 
			
		||||
    fullmesh.require_shared_vertices(); // TriangleMeshSlicer needs this
 | 
			
		||||
    TriangleMeshSlicer slicer(&fullmesh);
 | 
			
		||||
    SlicedSupports ret;
 | 
			
		||||
    slicer.slice(heights, 0.f, &ret, get().ctl().cancelfn);
 | 
			
		||||
| 
						 | 
				
			
			@ -2243,6 +2248,7 @@ SlicedSupports SLASupportTree::slice(const std::vector<float> &heights,
 | 
			
		|||
{
 | 
			
		||||
    TriangleMesh fullmesh = m_impl->merged_mesh();
 | 
			
		||||
    fullmesh.merge(get_pad());
 | 
			
		||||
    fullmesh.require_shared_vertices(); // TriangleMeshSlicer needs this
 | 
			
		||||
    TriangleMeshSlicer slicer(&fullmesh);
 | 
			
		||||
    SlicedSupports ret;
 | 
			
		||||
    slicer.slice(heights, cr, &ret, get().ctl().cancelfn);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -706,6 +706,7 @@ void SLAPrint::process()
 | 
			
		|||
            po.m_model_height_levels.emplace_back(it->slice_level());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mesh.require_shared_vertices(); // TriangleMeshSlicer needs this
 | 
			
		||||
        TriangleMeshSlicer slicer(&mesh);
 | 
			
		||||
 | 
			
		||||
        po.m_model_slices.clear();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -607,10 +607,12 @@ void TriangleMesh::require_shared_vertices()
 | 
			
		|||
    BOOST_LOG_TRIVIAL(trace) << "TriangleMeshSlicer::require_shared_vertices - end";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriangleMeshSlicer::init(TriangleMesh *_mesh, throw_on_cancel_callback_type throw_on_cancel)
 | 
			
		||||
void TriangleMeshSlicer::init(const TriangleMesh *_mesh, throw_on_cancel_callback_type throw_on_cancel)
 | 
			
		||||
{
 | 
			
		||||
    mesh = _mesh;
 | 
			
		||||
    _mesh->require_shared_vertices();
 | 
			
		||||
    if (! mesh->has_shared_vertices())
 | 
			
		||||
        throw std::invalid_argument("TriangleMeshSlicer was passed a mesh without shared vertices.");
 | 
			
		||||
 | 
			
		||||
    throw_on_cancel();
 | 
			
		||||
    facets_edges.assign(_mesh->stl.stats.number_of_facets * 3, -1);
 | 
			
		||||
    v_scaled_shared.assign(_mesh->stl.v_shared, _mesh->stl.v_shared + _mesh->stl.stats.shared_vertices);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,18 +67,17 @@ public:
 | 
			
		|||
    TriangleMesh convex_hull_3d() const;
 | 
			
		||||
    void reset_repair_stats();
 | 
			
		||||
    bool needed_repair() const;
 | 
			
		||||
    void require_shared_vertices();
 | 
			
		||||
    bool   has_shared_vertices() const { return stl.v_shared != NULL; }
 | 
			
		||||
    size_t facets_count() const { return this->stl.stats.number_of_facets; }
 | 
			
		||||
    bool   empty() const { return this->facets_count() == 0; }
 | 
			
		||||
 | 
			
		||||
    bool is_splittable() const;
 | 
			
		||||
 | 
			
		||||
    stl_file stl;
 | 
			
		||||
    bool repaired;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void require_shared_vertices();
 | 
			
		||||
    std::deque<uint32_t> find_unvisited_neighbors(std::vector<unsigned char> &facet_visited) const;
 | 
			
		||||
    friend class TriangleMeshSlicer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum FacetEdgeType { 
 | 
			
		||||
| 
						 | 
				
			
			@ -159,9 +158,8 @@ class TriangleMeshSlicer
 | 
			
		|||
public:
 | 
			
		||||
    typedef std::function<void()> throw_on_cancel_callback_type;
 | 
			
		||||
    TriangleMeshSlicer() : mesh(nullptr) {}
 | 
			
		||||
    // Not quite nice, but the constructor and init() methods require non-const mesh pointer to be able to call mesh->require_shared_vertices()
 | 
			
		||||
	TriangleMeshSlicer(TriangleMesh* mesh) { this->init(mesh, [](){}); }
 | 
			
		||||
    void init(TriangleMesh *mesh, throw_on_cancel_callback_type throw_on_cancel);
 | 
			
		||||
	TriangleMeshSlicer(const TriangleMesh* mesh) { this->init(mesh, [](){}); }
 | 
			
		||||
    void init(const TriangleMesh *mesh, throw_on_cancel_callback_type throw_on_cancel);
 | 
			
		||||
    void slice(const std::vector<float> &z, std::vector<Polygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const;
 | 
			
		||||
    void slice(const std::vector<float> &z, const float closing_radius, std::vector<ExPolygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const;
 | 
			
		||||
    enum FacetSliceType {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,7 +88,7 @@ std::string string_printf(const char *format, ...);
 | 
			
		|||
extern std::string timestamp_str();
 | 
			
		||||
// Standard "generated by Slic3r version xxx timestamp xxx" header string, 
 | 
			
		||||
// to be placed at the top of Slic3r generated files.
 | 
			
		||||
inline std::string header_slic3r_generated() { return std::string("generated by " SLIC3R_FORK_NAME " " SLIC3R_VERSION " " ) + timestamp_str(); }
 | 
			
		||||
inline std::string header_slic3r_generated() { return std::string("generated by " SLIC3R_APP_NAME " " SLIC3R_VERSION " " ) + timestamp_str(); }
 | 
			
		||||
 | 
			
		||||
// getpid platform wrapper
 | 
			
		||||
extern unsigned get_current_pid();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,8 @@
 | 
			
		|||
#ifndef __SLIC3R_VERSION_H
 | 
			
		||||
#define __SLIC3R_VERSION_H
 | 
			
		||||
 | 
			
		||||
#define SLIC3R_FORK_NAME "@SLIC3R_FORK_NAME@"
 | 
			
		||||
#define SLIC3R_APP_NAME "@SLIC3R_APP_NAME@"
 | 
			
		||||
#define SLIC3R_APP_KEY "@SLIC3R_APP_KEY@"
 | 
			
		||||
#define SLIC3R_VERSION "@SLIC3R_VERSION@"
 | 
			
		||||
#define SLIC3R_BUILD "@SLIC3R_BUILD@"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,12 +7,12 @@ PRODUCTVERSION @SLIC3R_RC_VERSION@
 | 
			
		|||
  BLOCK "040904E4"
 | 
			
		||||
  {
 | 
			
		||||
   VALUE "CompanyName", "Prusa Research"
 | 
			
		||||
   VALUE "FileDescription", "Slic3r Prusa Edition"
 | 
			
		||||
   VALUE "FileDescription", "@SLIC3R_APP_NAME@"
 | 
			
		||||
   VALUE "FileVersion", "@SLIC3R_BUILD_ID@"
 | 
			
		||||
   VALUE "ProductName", "Slic3r Prusa Edition"
 | 
			
		||||
   VALUE "ProductName", "@SLIC3R_APP_NAME@"
 | 
			
		||||
   VALUE "ProductVersion", "@SLIC3R_BUILD_ID@"
 | 
			
		||||
   VALUE "InternalName", "Slic3r Prusa Edition"
 | 
			
		||||
   VALUE "LegalCopyright", "Copyright \251 2011-2017 Alessandro Ranelucci, \251 2016 Prusa Research"
 | 
			
		||||
   VALUE "InternalName", "@SLIC3R_APP_NAME@"
 | 
			
		||||
   VALUE "LegalCopyright", "Copyright \251 2011-2019 Alessandro Ranelucci, \251 2016-2019 Prusa Research"
 | 
			
		||||
   VALUE "OriginalFilename", "slic3r.exe"
 | 
			
		||||
  }
 | 
			
		||||
 }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,15 +3,15 @@
 | 
			
		|||
<plist version="1.0">
 | 
			
		||||
<dict>
 | 
			
		||||
  <key>CFBundleExecutable</key>
 | 
			
		||||
  <string>Slic3r</string>
 | 
			
		||||
  <string>@SLIC3R_APP_KEY@</string>
 | 
			
		||||
  <key>CFBundleGetInfoString</key>
 | 
			
		||||
  <string>Slic3r Copyright (C) 2011-2017 Alessandro Ranellucci, (C) 2016-2018 Prusa Reseach</string>
 | 
			
		||||
  <string>@SLIC3R_APP_NAME@ Copyright (C) 2011-2019 Alessandro Ranellucci, (C) 2016-2019 Prusa Reseach</string>
 | 
			
		||||
  <key>CFBundleIconFile</key>
 | 
			
		||||
  <string>Slic3r.icns</string>
 | 
			
		||||
  <key>CFBundleName</key>
 | 
			
		||||
  <string>Slic3r</string>
 | 
			
		||||
  <string>@SLIC3R_APP_KEY@</string>
 | 
			
		||||
  <key>CFBundleShortVersionString</key>
 | 
			
		||||
  <string>Slic3r @SLIC3R_BUILD_ID@</string>
 | 
			
		||||
  <string>@SLIC3R_APP_NAME@ @SLIC3R_BUILD_ID@</string>
 | 
			
		||||
  <key>CFBundleIdentifier</key>
 | 
			
		||||
  <string>com.prusa3d.slic3r/</string>
 | 
			
		||||
  <key>CFBundleInfoDictionaryVersion</key>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -568,7 +568,7 @@ bool CLI::setup(int argc, char **argv)
 | 
			
		|||
void CLI::print_help(bool include_print_options, PrinterTechnology printer_technology) const 
 | 
			
		||||
{
 | 
			
		||||
    boost::nowide::cout
 | 
			
		||||
		<< "Slic3r Prusa Edition " << SLIC3R_BUILD 
 | 
			
		||||
		<< SLIC3R_APP_NAME << " " << SLIC3R_BUILD 
 | 
			
		||||
#ifdef SLIC3R_GUI
 | 
			
		||||
        << " (with GUI support)"
 | 
			
		||||
#else /* SLIC3R_GUI */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ void AboutDialogLogo::onRepaint(wxEvent &event)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
AboutDialog::AboutDialog()
 | 
			
		||||
    : DPIDialog(NULL, wxID_ANY, _(L("About Slic3r")), wxDefaultPosition, 
 | 
			
		||||
    : DPIDialog(NULL, wxID_ANY, wxString::Format(_(L("About %s")), SLIC3R_APP_NAME), wxDefaultPosition, 
 | 
			
		||||
                wxDefaultSize, /*wxCAPTION*/wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
 | 
			
		||||
{
 | 
			
		||||
    SetFont(wxGetApp().normal_font());
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ AboutDialog::AboutDialog()
 | 
			
		|||
 | 
			
		||||
    // title
 | 
			
		||||
    {
 | 
			
		||||
        wxStaticText* title = new wxStaticText(this, wxID_ANY, "Slic3r Prusa Edition", wxDefaultPosition, wxDefaultSize);
 | 
			
		||||
        wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_APP_NAME, wxDefaultPosition, wxDefaultSize);
 | 
			
		||||
        wxFont title_font = GUI::wxGetApp().bold_font();// wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
 | 
			
		||||
//         title_font.SetWeight(wxFONTWEIGHT_BOLD);
 | 
			
		||||
        title_font.SetFamily(wxFONTFAMILY_ROMAN);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@
 | 
			
		|||
#include "libslic3r/Utils.hpp"
 | 
			
		||||
#include "libslic3r/GCode/PostProcessor.hpp"
 | 
			
		||||
#include "libslic3r/GCode/PreviewData.hpp"
 | 
			
		||||
#include "libslic3r/libslic3r.h"
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
| 
						 | 
				
			
			@ -390,7 +391,7 @@ void BackgroundSlicingProcess::prepare_upload()
 | 
			
		|||
 | 
			
		||||
	// Generate a unique temp path to which the gcode/zip file is copied/exported
 | 
			
		||||
	boost::filesystem::path source_path = boost::filesystem::temp_directory_path()
 | 
			
		||||
		/ boost::filesystem::unique_path(".Slic3rPE.upload.%%%%-%%%%-%%%%-%%%%");
 | 
			
		||||
		/ boost::filesystem::unique_path("." SLIC3R_APP_KEY ".upload.%%%%-%%%%-%%%%-%%%%");
 | 
			
		||||
 | 
			
		||||
	if (m_print == m_fff_print) {
 | 
			
		||||
		m_print->set_status(95, "Running post-processing scripts");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -261,9 +261,6 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_
 | 
			
		|||
 | 
			
		||||
wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency)
 | 
			
		||||
{
 | 
			
		||||
    width = width * 0.1f * Slic3r::GUI::wxGetApp().em_unit() + 0.5f;
 | 
			
		||||
    height = height * 0.1f * Slic3r::GUI::wxGetApp().em_unit() + 0.5f;
 | 
			
		||||
 | 
			
		||||
    wxImage image(width, height);
 | 
			
		||||
    image.InitAlpha();
 | 
			
		||||
    unsigned char* imgdata = image.GetData();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -281,13 +281,14 @@ void ConfigWizardPage::append_spacer(int space)
 | 
			
		|||
// Wizard pages
 | 
			
		||||
 | 
			
		||||
PageWelcome::PageWelcome(ConfigWizard *parent)
 | 
			
		||||
    : ConfigWizardPage(parent, wxString::Format(_(L("Welcome to the Slic3r %s")), ConfigWizard::name()), _(L("Welcome")))
 | 
			
		||||
    : ConfigWizardPage(parent, wxString::Format(_(L("Welcome to the %s %s")), SLIC3R_APP_NAME, ConfigWizard::name()), _(L("Welcome")))
 | 
			
		||||
    , cbox_reset(nullptr)
 | 
			
		||||
{
 | 
			
		||||
    if (wizard_p()->run_reason == ConfigWizard::RR_DATA_EMPTY) {
 | 
			
		||||
        wxString::Format(_(L("Run %s")), ConfigWizard::name());
 | 
			
		||||
        append_text(wxString::Format(
 | 
			
		||||
            _(L("Hello, welcome to Slic3r Prusa Edition! This %s helps you with the initial configuration; just a few settings and you will be ready to print.")),
 | 
			
		||||
            _(L("Hello, welcome to %s! This %s helps you with the initial configuration; just a few settings and you will be ready to print.")),
 | 
			
		||||
            SLIC3R_APP_NAME,
 | 
			
		||||
            ConfigWizard::name())
 | 
			
		||||
        );
 | 
			
		||||
    } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -398,7 +399,9 @@ PageUpdate::PageUpdate(ConfigWizard *parent)
 | 
			
		|||
    auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _(L("Check for application updates")));
 | 
			
		||||
    box_slic3r->SetValue(app_config->get("version_check") == "1");
 | 
			
		||||
    append(box_slic3r);
 | 
			
		||||
    append_text(_(L("If enabled, Slic3r checks for new versions of Slic3r PE online. When a new version becomes available a notification is displayed at the next application startup (never during program usage). This is only a notification mechanisms, no automatic installation is done.")));
 | 
			
		||||
    append_text(wxString::Format(_(L("If enabled, Slic3r checks for new versions of %s online. When a new version becomes available, "
 | 
			
		||||
                                     "a notification is displayed at the next application startup (never during program usage). "
 | 
			
		||||
                                     "This is only a notification mechanisms, no automatic installation is done.")), SLIC3R_APP_NAME));
 | 
			
		||||
 | 
			
		||||
    append_spacer(VERTICAL_SPACING);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -420,7 +423,7 @@ PageUpdate::PageUpdate(ConfigWizard *parent)
 | 
			
		|||
PageVendors::PageVendors(ConfigWizard *parent)
 | 
			
		||||
    : ConfigWizardPage(parent, _(L("Other Vendors")), _(L("Other Vendors")))
 | 
			
		||||
{
 | 
			
		||||
    append_text(_(L("Pick another vendor supported by Slic3r PE:")));
 | 
			
		||||
    append_text(wxString::Format(_(L("Pick another vendor supported by %s:")), SLIC3R_APP_NAME));
 | 
			
		||||
 | 
			
		||||
    auto boldfont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
 | 
			
		||||
    boldfont.SetWeight(wxFONTWEIGHT_BOLD);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1486,6 +1486,8 @@ void GLCanvas3D::enable_layers_editing(bool enable)
 | 
			
		|||
        if (v->is_modifier)
 | 
			
		||||
            v->force_transparent = enable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set_as_dirty();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLCanvas3D::enable_legend_texture(bool enable)
 | 
			
		||||
| 
						 | 
				
			
			@ -1654,7 +1656,7 @@ void GLCanvas3D::render()
 | 
			
		|||
#endif // !ENABLE_SVG_ICONS
 | 
			
		||||
    _render_toolbar();
 | 
			
		||||
    _render_view_toolbar();
 | 
			
		||||
    if (m_layers_editing.last_object_id >= 0)
 | 
			
		||||
    if ((m_layers_editing.last_object_id >= 0) && (m_layers_editing.object_max_z() > 0.0f))
 | 
			
		||||
        m_layers_editing.render_overlay(*this);
 | 
			
		||||
 | 
			
		||||
    wxGetApp().imgui()->render();
 | 
			
		||||
| 
						 | 
				
			
			@ -2254,6 +2256,22 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
 | 
			
		|||
#endif /* __APPLE__ */
 | 
			
		||||
                post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL));
 | 
			
		||||
        break;
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
        case 'c':
 | 
			
		||||
        case 'C':
 | 
			
		||||
#else /* __APPLE__ */
 | 
			
		||||
        case WXK_CONTROL_C:
 | 
			
		||||
#endif /* __APPLE__ */
 | 
			
		||||
            post_event(SimpleEvent(EVT_GLTOOLBAR_COPY));
 | 
			
		||||
        break;
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
        case 'v':
 | 
			
		||||
        case 'V':
 | 
			
		||||
#else /* __APPLE__ */
 | 
			
		||||
        case WXK_CONTROL_V:
 | 
			
		||||
#endif /* __APPLE__ */
 | 
			
		||||
            post_event(SimpleEvent(EVT_GLTOOLBAR_PASTE));
 | 
			
		||||
        break;
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
        case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead.
 | 
			
		||||
#else /* __APPLE__ */
 | 
			
		||||
| 
						 | 
				
			
			@ -2596,7 +2614,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
 | 
			
		|||
                        m_selection.remove(m_hover_volume_id);
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        m_selection.add(m_hover_volume_id, !ctrl_down);
 | 
			
		||||
                        m_selection.add(m_hover_volume_id, !ctrl_down, true);
 | 
			
		||||
                        m_mouse.drag.move_requires_threshold = !already_selected;
 | 
			
		||||
                        if (already_selected)
 | 
			
		||||
                            m_mouse.set_move_start_threshold_position_2D_as_invalid();
 | 
			
		||||
| 
						 | 
				
			
			@ -3676,8 +3694,8 @@ void GLCanvas3D::_render_objects() const
 | 
			
		|||
        m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data());
 | 
			
		||||
 | 
			
		||||
        m_shader.start_using();
 | 
			
		||||
        if (m_picking_enabled && m_layers_editing.is_enabled() && m_layers_editing.last_object_id != -1) {
 | 
			
		||||
			int object_id = m_layers_editing.last_object_id;
 | 
			
		||||
        if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) {
 | 
			
		||||
            int object_id = m_layers_editing.last_object_id;
 | 
			
		||||
            m_volumes.render_VBOs(GLVolumeCollection::Opaque, false, m_camera.get_view_matrix(), [object_id](const GLVolume &volume) {
 | 
			
		||||
                // Which volume to paint without the layer height profile shader?
 | 
			
		||||
                return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,8 +149,8 @@ bool GUI_App::on_init_inner()
 | 
			
		|||
    wxCHECK_MSG(wxDirExists(resources_dir), false,
 | 
			
		||||
        wxString::Format("Resources path does not exist or is not a directory: %s", resources_dir));
 | 
			
		||||
 | 
			
		||||
    SetAppName("Slic3rPE-beta");
 | 
			
		||||
    SetAppDisplayName("Slic3r Prusa Edition");
 | 
			
		||||
    SetAppName(SLIC3R_APP_KEY "-beta");
 | 
			
		||||
    SetAppDisplayName(SLIC3R_APP_NAME);
 | 
			
		||||
 | 
			
		||||
// Enable this to get the default Win32 COMCTRL32 behavior of static boxes.
 | 
			
		||||
//    wxSystemOptions::SetOption("msw.staticbox.optimized-paint", 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -381,7 +381,7 @@ void GUI_App::recreate_GUI()
 | 
			
		|||
        topwindow->Destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dlg.Update(80, _(L("Loading of a current presets")) + dots);
 | 
			
		||||
    dlg.Update(80, _(L("Loading of current presets")) + dots);
 | 
			
		||||
 | 
			
		||||
    m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg()));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -513,7 +513,7 @@ bool GUI_App::select_language(  wxArrayString & names,
 | 
			
		|||
        m_wxLocale = new wxLocale;
 | 
			
		||||
        m_wxLocale->Init(identifiers[index]);
 | 
			
		||||
		m_wxLocale->AddCatalogLookupPathPrefix(from_u8(localization_dir()));
 | 
			
		||||
        m_wxLocale->AddCatalog(/*GetAppName()*/"Slic3rPE");
 | 
			
		||||
        m_wxLocale->AddCatalog("Slic3rPE");
 | 
			
		||||
		//FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only.
 | 
			
		||||
		wxSetlocale(LC_NUMERIC, "C");
 | 
			
		||||
        Preset::update_suffix_modified();
 | 
			
		||||
| 
						 | 
				
			
			@ -542,7 +542,7 @@ bool GUI_App::load_language()
 | 
			
		|||
            m_wxLocale = new wxLocale;
 | 
			
		||||
            m_wxLocale->Init(identifiers[i]);
 | 
			
		||||
			m_wxLocale->AddCatalogLookupPathPrefix(from_u8(localization_dir()));
 | 
			
		||||
            m_wxLocale->AddCatalog(/*GetAppName()*/"Slic3rPE");
 | 
			
		||||
            m_wxLocale->AddCatalog("Slic3rPE");
 | 
			
		||||
			//FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only.
 | 
			
		||||
            wxSetlocale(LC_NUMERIC, "C");
 | 
			
		||||
			Preset::update_suffix_modified();
 | 
			
		||||
| 
						 | 
				
			
			@ -586,9 +586,7 @@ void GUI_App::get_installed_languages(wxArrayString & names, wxArrayLong & ident
 | 
			
		|||
        if (langinfo != NULL)
 | 
			
		||||
        {
 | 
			
		||||
            auto full_file_name = dir.GetName() + wxFileName::GetPathSeparator() +
 | 
			
		||||
                filename + wxFileName::GetPathSeparator() +
 | 
			
		||||
                /*GetAppName()*/"Slic3rPE" + 
 | 
			
		||||
                wxT(".mo");
 | 
			
		||||
                filename + wxFileName::GetPathSeparator() + "Slic3rPE" + wxT(".mo");
 | 
			
		||||
            if (wxFileExists(full_file_name))
 | 
			
		||||
            {
 | 
			
		||||
                names.Add(langinfo->Description);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -543,12 +543,13 @@ void ObjectList::paste_objects_into_list(const std::vector<size_t>& object_idxs)
 | 
			
		|||
    for (const size_t object : object_idxs)
 | 
			
		||||
    {
 | 
			
		||||
        add_object_to_list(object);
 | 
			
		||||
        m_parts_changed = true;
 | 
			
		||||
        parts_changed(object);
 | 
			
		||||
 | 
			
		||||
        items.Add(m_objects_model->GetItemById(object));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_parts_changed = true;
 | 
			
		||||
    wxGetApp().plater()->changed_objects(object_idxs);
 | 
			
		||||
    m_parts_changed = false;
 | 
			
		||||
 | 
			
		||||
    select_items(items);
 | 
			
		||||
#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
 | 
			
		||||
    selection_changed();
 | 
			
		||||
| 
						 | 
				
			
			@ -644,6 +645,10 @@ void ObjectList::key_event(wxKeyEvent& event)
 | 
			
		|||
    }
 | 
			
		||||
    else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL/*WXK_SHIFT*/))
 | 
			
		||||
        select_item_all_children();
 | 
			
		||||
    else if (wxGetKeyState(wxKeyCode('C')) && wxGetKeyState(WXK_CONTROL))
 | 
			
		||||
        wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_COPY));
 | 
			
		||||
    else if (wxGetKeyState(wxKeyCode('V')) && wxGetKeyState(WXK_CONTROL))
 | 
			
		||||
        wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_PASTE));
 | 
			
		||||
    else
 | 
			
		||||
        event.Skip();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@
 | 
			
		|||
namespace Slic3r {
 | 
			
		||||
namespace GUI {
 | 
			
		||||
 | 
			
		||||
const float GLGizmoBase::Grabber::SizeFactor = 0.025f;
 | 
			
		||||
    const float GLGizmoBase::Grabber::SizeFactor = 0.05f;
 | 
			
		||||
const float GLGizmoBase::Grabber::MinHalfSize = 1.5f;
 | 
			
		||||
const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ float GLGizmoBase::Grabber::get_half_size(float size) const
 | 
			
		|||
 | 
			
		||||
float GLGizmoBase::Grabber::get_dragging_half_size(float size) const
 | 
			
		||||
{
 | 
			
		||||
    return std::max(size * SizeFactor * DraggingScaleFactor, MinHalfSize);
 | 
			
		||||
    return get_half_size(size) * DraggingScaleFactor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLGizmoBase::Grabber::render(float size, const float* render_color, bool use_lighting) const
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,7 +150,8 @@ void GLGizmoMove3D::on_render(const Selection& selection) const
 | 
			
		|||
        glsafe(::glEnd());
 | 
			
		||||
 | 
			
		||||
        // draw grabber
 | 
			
		||||
        m_grabbers[m_hover_id].render(true, box.max_size());
 | 
			
		||||
        float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0);
 | 
			
		||||
        m_grabbers[m_hover_id].render(true, mean_size);
 | 
			
		||||
        render_grabber_extension((Axis)m_hover_id, box, false);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,6 +51,9 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m_model_object != model_object)
 | 
			
		||||
        m_print_object_idx = -1;
 | 
			
		||||
 | 
			
		||||
    m_model_object = model_object;
 | 
			
		||||
    m_active_instance = selection.get_instance_idx();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -111,32 +114,92 @@ void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection, const
 | 
			
		|||
    if (m_clipping_plane_distance == 0.f)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    // First cache instance transformation to be used later.
 | 
			
		||||
    const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
 | 
			
		||||
    Transform3f instance_matrix = vol->get_instance_transformation().get_matrix().cast<float>();
 | 
			
		||||
    Transform3f instance_matrix_no_translation_no_scaling = vol->get_instance_transformation().get_matrix(true,false,true).cast<float>();
 | 
			
		||||
    Vec3f scaling = vol->get_instance_scaling_factor().cast<float>();
 | 
			
		||||
    Vec3d instance_offset = vol->get_instance_offset();
 | 
			
		||||
 | 
			
		||||
    // Calculate distance from mesh origin to the clipping plane (in mesh coordinates).
 | 
			
		||||
    Vec3f up_noscale = instance_matrix_no_translation_no_scaling.inverse() * direction_to_camera.cast<float>();
 | 
			
		||||
    Vec3f up = Vec3f(up_noscale(0)*scaling(0), up_noscale(1)*scaling(1), up_noscale(2)*scaling(2));
 | 
			
		||||
    float height_mesh = (m_active_instance_bb_radius - m_clipping_plane_distance * 2*m_active_instance_bb_radius) * (up_noscale.norm()/up.norm());
 | 
			
		||||
 | 
			
		||||
    // Get transformation of the supports and calculate how far from its origin the clipping plane is.
 | 
			
		||||
    Transform3d supports_trafo = Transform3d::Identity();
 | 
			
		||||
    supports_trafo = supports_trafo.rotate(Eigen::AngleAxisd(vol->get_instance_rotation()(2), Vec3d::UnitZ()));
 | 
			
		||||
    Vec3f up_supports = (supports_trafo.inverse() * direction_to_camera).cast<float>();
 | 
			
		||||
    supports_trafo = supports_trafo.pretranslate(Vec3d(instance_offset(0), instance_offset(1), vol->get_sla_shift_z()));
 | 
			
		||||
    // Instance and supports origin do not coincide, so the following is quite messy:
 | 
			
		||||
    float height_supports = height_mesh * (up.norm() / up_supports.norm()) + instance_offset(2) * (direction_to_camera(2) / direction_to_camera.norm());
 | 
			
		||||
 | 
			
		||||
    // In case either of these was recently changed, the cached triangulated ExPolygons are invalid now.
 | 
			
		||||
    // We are gonna recalculate them both for the object and for the support structures.
 | 
			
		||||
    if (m_clipping_plane_distance != m_old_clipping_plane_distance
 | 
			
		||||
     || m_old_direction_to_camera != direction_to_camera) {
 | 
			
		||||
 | 
			
		||||
        std::vector<ExPolygons> list_of_expolys;
 | 
			
		||||
        m_old_direction_to_camera = direction_to_camera;
 | 
			
		||||
        m_old_clipping_plane_distance = m_clipping_plane_distance;
 | 
			
		||||
 | 
			
		||||
        // Now initialize the TMS for the object, perform the cut and save the result.
 | 
			
		||||
        if (! m_tms) {
 | 
			
		||||
            m_tms.reset(new TriangleMeshSlicer);
 | 
			
		||||
            m_tms->init(const_cast<TriangleMesh*>(&m_mesh), [](){});
 | 
			
		||||
            m_tms->init(m_mesh, [](){});
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::vector<ExPolygons> list_of_expolys;
 | 
			
		||||
        m_tms->set_up_direction(up);
 | 
			
		||||
        m_tms->slice(std::vector<float>{height_mesh}, 0.f, &list_of_expolys, [](){});
 | 
			
		||||
        m_triangles = triangulate_expolygons_2f(list_of_expolys[0]);
 | 
			
		||||
 | 
			
		||||
        m_old_direction_to_camera = direction_to_camera;
 | 
			
		||||
        m_old_clipping_plane_distance = m_clipping_plane_distance;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // Next, ask the backend if supports are already calculated. If so, we are gonna cut them too.
 | 
			
		||||
        // First we need a pointer to the respective SLAPrintObject. The index into objects vector is
 | 
			
		||||
        // cached so we don't have todo it on each render. We only search for the po if needed:
 | 
			
		||||
        if (m_print_object_idx < 0 || (int)m_parent.sla_print()->objects().size() != m_print_objects_count) {
 | 
			
		||||
            m_print_objects_count = m_parent.sla_print()->objects().size();
 | 
			
		||||
            m_print_object_idx = -1;
 | 
			
		||||
            for (const SLAPrintObject* po : m_parent.sla_print()->objects()) {
 | 
			
		||||
                ++m_print_object_idx;
 | 
			
		||||
                if (po->model_object()->id() == m_model_object->id())
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (m_print_object_idx >= 0) {
 | 
			
		||||
            const SLAPrintObject* print_object = m_parent.sla_print()->objects()[m_print_object_idx];
 | 
			
		||||
 | 
			
		||||
            if (print_object->is_step_done(slaposSupportTree)) {
 | 
			
		||||
                // If the supports are already calculated, save the timestamp of the respective step
 | 
			
		||||
                // so we can later tell they were recalculated.
 | 
			
		||||
                size_t timestamp = print_object->step_state_with_timestamp(slaposSupportTree).timestamp;
 | 
			
		||||
 | 
			
		||||
                if (!m_supports_tms || (int)timestamp != m_old_timestamp) {
 | 
			
		||||
                    // The timestamp has changed - stash the mesh and initialize the TMS.
 | 
			
		||||
                    m_supports_mesh = &print_object->support_mesh();
 | 
			
		||||
                    m_supports_tms.reset(new TriangleMeshSlicer);
 | 
			
		||||
                    // The mesh should already have the shared vertices calculated.
 | 
			
		||||
                    m_supports_tms->init(m_supports_mesh, [](){});
 | 
			
		||||
                    m_old_timestamp = timestamp;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // The TMS is initialized - let's do the cutting:
 | 
			
		||||
                list_of_expolys.clear();
 | 
			
		||||
                m_supports_tms->set_up_direction(up_supports);
 | 
			
		||||
                m_supports_tms->slice(std::vector<float>{height_supports}, 0.f, &list_of_expolys, [](){});
 | 
			
		||||
                m_supports_triangles = triangulate_expolygons_2f(list_of_expolys[0]);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                // The supports are not valid. We better dump the cached data.
 | 
			
		||||
                m_supports_tms.reset();
 | 
			
		||||
                m_supports_triangles.clear();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // At this point we have the triangulated cuts for both the object and supports - let's render.
 | 
			
		||||
    ::glColor3f(1.0f, 0.37f, 0.0f);
 | 
			
		||||
 | 
			
		||||
	if (! m_triangles.empty()) {
 | 
			
		||||
		::glPushMatrix();
 | 
			
		||||
		::glTranslated(0.0, 0.0, m_z_shift);
 | 
			
		||||
| 
						 | 
				
			
			@ -146,11 +209,26 @@ void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection, const
 | 
			
		|||
		Eigen::AngleAxisf aa(q);
 | 
			
		||||
		::glRotatef(aa.angle() * (180./M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2));
 | 
			
		||||
		::glTranslatef(0.f, 0.f, -0.001f); // to make sure the cut is safely beyond the near clipping plane
 | 
			
		||||
		::glColor3f(1.0f, 0.37f, 0.0f);
 | 
			
		||||
        ::glBegin(GL_TRIANGLES);
 | 
			
		||||
        ::glColor3f(1.0f, 0.37f, 0.0f);
 | 
			
		||||
        for (const Vec2f& point : m_triangles)
 | 
			
		||||
            ::glVertex3f(point(0), point(1), height_mesh);
 | 
			
		||||
 | 
			
		||||
        ::glEnd();
 | 
			
		||||
		::glPopMatrix();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    if (! m_supports_triangles.empty()) {
 | 
			
		||||
		::glPushMatrix();
 | 
			
		||||
        ::glMultMatrixd(supports_trafo.data());
 | 
			
		||||
        Eigen::Quaternionf q;
 | 
			
		||||
		q.setFromTwoVectors(Vec3f::UnitZ(), up_supports);
 | 
			
		||||
		Eigen::AngleAxisf aa(q);
 | 
			
		||||
		::glRotatef(aa.angle() * (180./M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2));
 | 
			
		||||
		::glTranslatef(0.f, 0.f, -0.001f); // to make sure the cut is safely beyond the near clipping plane
 | 
			
		||||
        ::glBegin(GL_TRIANGLES);
 | 
			
		||||
        for (const Vec2f& point : m_supports_triangles)
 | 
			
		||||
            ::glVertex3f(point(0), point(1), height_supports);
 | 
			
		||||
 | 
			
		||||
        ::glEnd();
 | 
			
		||||
		::glPopMatrix();
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -332,9 +410,12 @@ void GLGizmoSlaSupports::update_mesh()
 | 
			
		|||
    wxBusyCursor wait;
 | 
			
		||||
    Eigen::MatrixXf& V = m_V;
 | 
			
		||||
    Eigen::MatrixXi& F = m_F;
 | 
			
		||||
    // We rely on SLA model object having a single volume,
 | 
			
		||||
    // this way we can use that mesh directly.
 | 
			
		||||
    // This mesh does not account for the possible Z up SLA offset.
 | 
			
		||||
    m_mesh = m_model_object->raw_mesh();
 | 
			
		||||
    const stl_file& stl = m_mesh.stl;
 | 
			
		||||
    m_mesh = &m_model_object->volumes.front()->mesh;
 | 
			
		||||
    const_cast<TriangleMesh*>(m_mesh)->require_shared_vertices(); // TriangleMeshSlicer needs this
 | 
			
		||||
    const stl_file& stl = m_mesh->stl;
 | 
			
		||||
    V.resize(3 * stl.stats.number_of_facets, 3);
 | 
			
		||||
    F.resize(stl.stats.number_of_facets, 3);
 | 
			
		||||
    for (unsigned int i=0; i<stl.stats.number_of_facets; ++i) {
 | 
			
		||||
| 
						 | 
				
			
			@ -972,12 +1053,12 @@ void GLGizmoSlaSupports::on_set_state()
 | 
			
		|||
                m_editing_mode = false; // so it is not active next time the gizmo opens
 | 
			
		||||
                m_editing_mode_cache.clear();
 | 
			
		||||
                m_clipping_plane_distance = 0.f;
 | 
			
		||||
                // Release copy of the mesh, triangle slicer and the AABB spatial search structure.
 | 
			
		||||
				m_mesh.clear();
 | 
			
		||||
                // Release triangle mesh slicer and the AABB spatial search structure.
 | 
			
		||||
                m_AABB.deinit();
 | 
			
		||||
				m_V = Eigen::MatrixXf();
 | 
			
		||||
				m_F = Eigen::MatrixXi();
 | 
			
		||||
                m_tms.reset(nullptr);
 | 
			
		||||
                m_tms.reset();
 | 
			
		||||
                m_supports_tms.reset();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        m_old_state = m_state;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,8 +36,13 @@ private:
 | 
			
		|||
    Eigen::MatrixXf m_V; // vertices
 | 
			
		||||
    Eigen::MatrixXi m_F; // facets indices
 | 
			
		||||
    igl::AABB<Eigen::MatrixXf,3> m_AABB;
 | 
			
		||||
    TriangleMesh m_mesh;
 | 
			
		||||
    const TriangleMesh* m_mesh;
 | 
			
		||||
    mutable const TriangleMesh* m_supports_mesh;
 | 
			
		||||
    mutable std::vector<Vec2f> m_triangles;
 | 
			
		||||
    mutable std::vector<Vec2f> m_supports_triangles;
 | 
			
		||||
    mutable int m_old_timestamp = -1;
 | 
			
		||||
    mutable int m_print_object_idx = -1;
 | 
			
		||||
    mutable int m_print_objects_count = -1;
 | 
			
		||||
 | 
			
		||||
    class CacheEntry {
 | 
			
		||||
    public:
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +84,6 @@ private:
 | 
			
		|||
    bool m_old_editing_state = false;       // To keep track of whether the user toggled between the modes (needed for imgui refreshes).
 | 
			
		||||
    float m_new_point_head_diameter;        // Size of a new point.
 | 
			
		||||
    float m_minimal_point_distance = 20.f;
 | 
			
		||||
    float m_density = 100.f;
 | 
			
		||||
    mutable std::vector<CacheEntry> m_editing_mode_cache; // a support point and whether it is currently selected
 | 
			
		||||
    float m_clipping_plane_distance = 0.f;
 | 
			
		||||
    mutable float m_old_clipping_plane_distance = 0.f;
 | 
			
		||||
| 
						 | 
				
			
			@ -101,6 +105,7 @@ private:
 | 
			
		|||
    int m_canvas_height;
 | 
			
		||||
 | 
			
		||||
    mutable std::unique_ptr<TriangleMeshSlicer> m_tms;
 | 
			
		||||
    mutable std::unique_ptr<TriangleMeshSlicer> m_supports_tms;
 | 
			
		||||
 | 
			
		||||
    std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const;
 | 
			
		||||
    bool is_point_clipped(const Vec3d& point, const Vec3d& direction_to_camera) const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ namespace Slic3r {
 | 
			
		|||
namespace GUI {
 | 
			
		||||
 | 
			
		||||
KBShortcutsDialog::KBShortcutsDialog()
 | 
			
		||||
    : DPIDialog(NULL, wxID_ANY, _(L("Slic3r Prusa Edition - Keyboard Shortcuts")), 
 | 
			
		||||
    : DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("Keyboard Shortcuts")), 
 | 
			
		||||
     wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
 | 
			
		||||
{
 | 
			
		||||
	SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
 | 
			
		||||
| 
						 | 
				
			
			@ -136,6 +136,8 @@ void KBShortcutsDialog::fill_shortcuts()
 | 
			
		|||
    plater_shortcuts.push_back(Shortcut(ctrl+"A",   L("Select All objects")));
 | 
			
		||||
    plater_shortcuts.push_back(Shortcut("Del",      L("Delete selected")));
 | 
			
		||||
    plater_shortcuts.push_back(Shortcut(ctrl+"Del", L("Delete All")));
 | 
			
		||||
    plater_shortcuts.push_back(Shortcut(ctrl+"C",   L("Copy to clipboard")));
 | 
			
		||||
    plater_shortcuts.push_back(Shortcut(ctrl+"V",   L("Paste from clipboard")));
 | 
			
		||||
    plater_shortcuts.push_back(Shortcut("M",        L("Gizmo move")));
 | 
			
		||||
    plater_shortcuts.push_back(Shortcut("S",        L("Gizmo scale")));
 | 
			
		||||
    plater_shortcuts.push_back(Shortcut("R",        L("Gizmo rotate")));
 | 
			
		||||
| 
						 | 
				
			
			@ -177,8 +179,8 @@ void KBShortcutsDialog::fill_shortcuts()
 | 
			
		|||
    Shortcuts layers_slider_shortcuts;
 | 
			
		||||
    layers_slider_shortcuts.reserve(6);
 | 
			
		||||
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut(L("Arrow Up"),   L("Move current slider thump Up")));
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut(L("Arrow Down"), L("Move current slider thump Down")));
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut(L("Arrow Up"),   L("Move current slider thumb Up")));
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut(L("Arrow Down"), L("Move current slider thumb Down")));
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut(L("Arrow Left"), L("Set upper thumb to current slider thumb")));
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut(L("Arrow Right"),L("Set lower thumb to current slider thumb")));
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut("+",             L("Add color change marker for current layer")));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -403,9 +403,9 @@ void MainFrame::init_menubar()
 | 
			
		|||
 | 
			
		||||
        editMenu->AppendSeparator();
 | 
			
		||||
 | 
			
		||||
        wxMenuItem* item_copy = append_menu_item(editMenu, wxID_ANY, _(L("&Copy")) + "\tCtrl+C", _(L("Copy selection to clipboard")),
 | 
			
		||||
        wxMenuItem* item_copy = append_menu_item(editMenu, wxID_ANY, _(L("&Copy")) + sep + GUI::shortkey_ctrl_prefix() + sep_space + "C", _(L("Copy selection to clipboard")),
 | 
			
		||||
            [this](wxCommandEvent&) { m_plater->copy_selection_to_clipboard(); }, "copy_menu");
 | 
			
		||||
        wxMenuItem* item_paste = append_menu_item(editMenu, wxID_ANY, _(L("&Paste")) + "\tCtrl+V", _(L("Paste clipboard")),
 | 
			
		||||
        wxMenuItem* item_paste = append_menu_item(editMenu, wxID_ANY, _(L("&Paste")) + sep + GUI::shortkey_ctrl_prefix() + sep_space + "V", _(L("Paste clipboard")),
 | 
			
		||||
            [this](wxCommandEvent&) { m_plater->paste_from_clipboard(); }, "paste_menu");
 | 
			
		||||
 | 
			
		||||
        Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_select()); }, item_select_all->GetId());
 | 
			
		||||
| 
						 | 
				
			
			@ -505,9 +505,9 @@ void MainFrame::init_menubar()
 | 
			
		|||
            [this](wxCommandEvent&) { wxGetApp().system_info(); });
 | 
			
		||||
        append_menu_item(helpMenu, wxID_ANY, _(L("Show &Configuration Folder")), _(L("Show user configuration folder (datadir)")),
 | 
			
		||||
            [this](wxCommandEvent&) { Slic3r::GUI::desktop_open_datadir_folder(); });
 | 
			
		||||
        append_menu_item(helpMenu, wxID_ANY, _(L("Report an I&ssue")), _(L("Report an issue on the Slic3r Prusa Edition")), 
 | 
			
		||||
        append_menu_item(helpMenu, wxID_ANY, _(L("Report an I&ssue")), wxString::Format(_(L("Report an issue on %s")), SLIC3R_APP_NAME), 
 | 
			
		||||
            [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r/issues/new"); });
 | 
			
		||||
        append_menu_item(helpMenu, wxID_ANY, _(L("&About Slic3r")), _(L("Show about dialog")),
 | 
			
		||||
        append_menu_item(helpMenu, wxID_ANY, wxString::Format(_(L("&About %s")), SLIC3R_APP_NAME), _(L("Show about dialog")),
 | 
			
		||||
            [this](wxCommandEvent&) { Slic3r::GUI::about(); });
 | 
			
		||||
        helpMenu->AppendSeparator();
 | 
			
		||||
        append_menu_item(helpMenu, wxID_ANY, _(L("Keyboard Shortcuts")) + sep + "&?", _(L("Show the list of the keyboard shortcuts")),
 | 
			
		||||
| 
						 | 
				
			
			@ -776,7 +776,7 @@ void MainFrame::export_configbundle()
 | 
			
		|||
    // Ask user for a file name.
 | 
			
		||||
    auto dlg = new wxFileDialog(this, _(L("Save presets bundle as:")),
 | 
			
		||||
        !m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
 | 
			
		||||
        "Slic3r_config_bundle.ini",
 | 
			
		||||
        SLIC3R_APP_KEY "_config_bundle.ini",
 | 
			
		||||
        file_wildcards(FT_INI), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
 | 
			
		||||
    wxString file;
 | 
			
		||||
    if (dlg->ShowModal() == wxID_OK)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -280,7 +280,7 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 *
 | 
			
		|||
                cfg.set_key_value("extruder_colour", colors);
 | 
			
		||||
 | 
			
		||||
                wxGetApp().get_tab(Preset::TYPE_PRINTER)->load_config(cfg);
 | 
			
		||||
                wxGetApp().preset_bundle->update_platter_filament_ui(extruder_idx, this);
 | 
			
		||||
                wxGetApp().preset_bundle->update_platter_filament_ui(extruder_idx, this, wxGetApp().em_unit());
 | 
			
		||||
                wxGetApp().plater()->on_config_change(cfg);
 | 
			
		||||
            }
 | 
			
		||||
            dialog->Destroy();
 | 
			
		||||
| 
						 | 
				
			
			@ -813,7 +813,7 @@ void Sidebar::update_all_preset_comboboxes()
 | 
			
		|||
    // update the dirty flags.
 | 
			
		||||
    if (print_tech == ptFFF) {
 | 
			
		||||
        for (size_t i = 0; i < p->combos_filament.size(); ++i)
 | 
			
		||||
            preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]);
 | 
			
		||||
            preset_bundle.update_platter_filament_ui(i, p->combos_filament[i], wxGetApp().em_unit());
 | 
			
		||||
    }
 | 
			
		||||
    p->show_preset_comboboxes();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -837,7 +837,7 @@ void Sidebar::update_presets(Preset::Type preset_type)
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        for (size_t i = 0; i < filament_cnt; i++) {
 | 
			
		||||
            preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]);
 | 
			
		||||
            preset_bundle.update_platter_filament_ui(i, p->combos_filament[i], wxGetApp().em_unit());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
| 
						 | 
				
			
			@ -872,7 +872,7 @@ void Sidebar::update_presets(Preset::Type preset_type)
 | 
			
		|||
// 		// update the dirty flags.
 | 
			
		||||
//         if (print_tech == ptFFF) {
 | 
			
		||||
//             for (size_t i = 0; i < p->combos_filament.size(); ++ i)
 | 
			
		||||
//                 preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]);
 | 
			
		||||
//                 preset_bundle.update_platter_filament_ui(i, p->combos_filament[i], wxGetApp().em_unit());
 | 
			
		||||
// 		}
 | 
			
		||||
// 		p->show_preset_comboboxes();
 | 
			
		||||
        update_all_preset_comboboxes();
 | 
			
		||||
| 
						 | 
				
			
			@ -1703,6 +1703,14 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
 | 
			
		|||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // is there any advanced config data ?
 | 
			
		||||
                    auto opt_keys = model_object->config.keys();
 | 
			
		||||
                    if (!opt_keys.empty() && !((opt_keys.size() == 1) && (opt_keys[0] == "extruder")))
 | 
			
		||||
                    {
 | 
			
		||||
                        advanced = true;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // is there any modifier ?
 | 
			
		||||
                    for (const ModelVolume* model_volume : model_object->volumes)
 | 
			
		||||
                    {
 | 
			
		||||
| 
						 | 
				
			
			@ -1711,6 +1719,14 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
 | 
			
		|||
                            advanced = true;
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // is there any advanced config data ?
 | 
			
		||||
                        opt_keys = model_volume->config.keys();
 | 
			
		||||
                        if (!opt_keys.empty() && !((opt_keys.size() == 1) && (opt_keys[0] == "extruder")))
 | 
			
		||||
                        {
 | 
			
		||||
                            advanced = true;
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (advanced)
 | 
			
		||||
| 
						 | 
				
			
			@ -2650,7 +2666,7 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt)
 | 
			
		|||
    // TODO: ?
 | 
			
		||||
    if (preset_type == Preset::TYPE_FILAMENT && sidebar->is_multifilament()) {
 | 
			
		||||
        // Only update the platter UI for the 2nd and other filaments.
 | 
			
		||||
        wxGetApp().preset_bundle->update_platter_filament_ui(idx, combo);
 | 
			
		||||
        wxGetApp().preset_bundle->update_platter_filament_ui(idx, combo, wxGetApp().em_unit());
 | 
			
		||||
    } 
 | 
			
		||||
    else {
 | 
			
		||||
        wxWindowUpdateLocker noUpdates(sidebar->presets_panel());
 | 
			
		||||
| 
						 | 
				
			
			@ -3618,7 +3634,7 @@ void Plater::on_extruders_change(int num_extruders)
 | 
			
		|||
        choices.push_back(choice);
 | 
			
		||||
 | 
			
		||||
        // initialize selection
 | 
			
		||||
        wxGetApp().preset_bundle->update_platter_filament_ui(i, choice);
 | 
			
		||||
        wxGetApp().preset_bundle->update_platter_filament_ui(i, choice, wxGetApp().em_unit());
 | 
			
		||||
        ++i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3768,6 +3784,36 @@ void Plater::changed_object(int obj_idx)
 | 
			
		|||
    this->p->schedule_background_process();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Plater::changed_objects(const std::vector<size_t>& object_idxs)
 | 
			
		||||
{
 | 
			
		||||
    if (object_idxs.empty())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    auto list = wxGetApp().obj_list();
 | 
			
		||||
    wxASSERT(list != nullptr);
 | 
			
		||||
    if (list == nullptr)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (list->is_parts_changed()) {
 | 
			
		||||
        for (int obj_idx : object_idxs)
 | 
			
		||||
        {
 | 
			
		||||
            if (obj_idx < p->model.objects.size())
 | 
			
		||||
                // recenter and re - align to Z = 0
 | 
			
		||||
                p->model.objects[obj_idx]->ensure_on_bed();
 | 
			
		||||
        }
 | 
			
		||||
        if (this->p->printer_technology == ptSLA) {
 | 
			
		||||
            // Update the SLAPrint from the current Model, so that the reload_scene()
 | 
			
		||||
            // pulls the correct data, update the 3D scene.
 | 
			
		||||
            this->p->update_restart_background_process(true, false);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            p->view3D->reload_scene(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // update print
 | 
			
		||||
    this->p->schedule_background_process();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Plater::schedule_background_process()
 | 
			
		||||
{
 | 
			
		||||
    this->p->schedule_background_process();    
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -167,6 +167,7 @@ public:
 | 
			
		|||
    void reslice();
 | 
			
		||||
    void reslice_SLA_supports(const ModelObject &object);
 | 
			
		||||
    void changed_object(int obj_idx);
 | 
			
		||||
    void changed_objects(const std::vector<size_t>& object_idxs);
 | 
			
		||||
    void schedule_background_process();
 | 
			
		||||
    void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
 | 
			
		||||
    void send_gcode();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,7 +60,7 @@ void PreferencesDialog::build()
 | 
			
		|||
	// Please keep in sync with ConfigWizard
 | 
			
		||||
	def.label = L("Check for application updates");
 | 
			
		||||
	def.type = coBool;
 | 
			
		||||
	def.tooltip = L("If enabled, Slic3r checks for new versions of Slic3r PE online. When a new version becomes available a notification is displayed at the next application startup (never during program usage). This is only a notification mechanisms, no automatic installation is done.");
 | 
			
		||||
	def.tooltip = L("If enabled, Slic3r checks for new versions of " SLIC3R_APP_NAME " online. When a new version becomes available a notification is displayed at the next application startup (never during program usage). This is only a notification mechanisms, no automatic installation is done.");
 | 
			
		||||
	def.default_value = new ConfigOptionBool(app_config->get("version_check") == "1");
 | 
			
		||||
	option = Option (def, "version_check");
 | 
			
		||||
	m_optgroup->append_single_option_line(option);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1451,7 +1451,7 @@ void PresetBundle::load_default_preset_bitmaps(wxWindow *window)
 | 
			
		|||
    this->load_compatible_bitmaps(window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui)
 | 
			
		||||
void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui, const int em/* = 10*/)
 | 
			
		||||
{
 | 
			
		||||
    if (ui == nullptr || this->printers.get_edited_preset().printer_technology() == ptSLA ||
 | 
			
		||||
        this->filament_presets.size() <= idx_extruder )
 | 
			
		||||
| 
						 | 
				
			
			@ -1476,6 +1476,18 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr
 | 
			
		|||
	wxString selected_str = "";
 | 
			
		||||
	if (!this->filaments().front().is_visible)
 | 
			
		||||
        ui->set_label_marker(ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap));
 | 
			
		||||
 | 
			
		||||
    /* It's supposed that standard size of an icon is 16px*16px for 100% scaled display.
 | 
			
		||||
     * So set sizes for solid_colored icons used for filament preset 
 | 
			
		||||
     * and scale then in respect to em_unit value
 | 
			
		||||
     */
 | 
			
		||||
    const float scale_f = em * 0.1f;
 | 
			
		||||
    const int icon_height       = 16 * scale_f + 0.5f;
 | 
			
		||||
    const int normal_icon_width = 16 * scale_f + 0.5f;
 | 
			
		||||
    const int space_icon_width  = 2  * scale_f + 0.5f;
 | 
			
		||||
    const int wide_icon_width   = 24 * scale_f + 0.5f;
 | 
			
		||||
    const int thin_icon_width   = 8  * scale_f + 0.5f;
 | 
			
		||||
 | 
			
		||||
	for (int i = this->filaments().front().is_visible ? 0 : 1; i < int(this->filaments().size()); ++i) {
 | 
			
		||||
        const Preset &preset    = this->filaments.preset(i);
 | 
			
		||||
        bool          selected  = this->filament_presets[idx_extruder] == preset.name;
 | 
			
		||||
| 
						 | 
				
			
			@ -1499,17 +1511,17 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr
 | 
			
		|||
            std::vector<wxBitmap> bmps;
 | 
			
		||||
            if (wide_icons)
 | 
			
		||||
                // Paint a red flag for incompatible presets.
 | 
			
		||||
                bmps.emplace_back(preset.is_compatible ? m_bitmapCache->mkclear(16, 16) : *m_bitmapIncompatible);
 | 
			
		||||
                bmps.emplace_back(preset.is_compatible ? m_bitmapCache->mkclear(normal_icon_width, icon_height) : *m_bitmapIncompatible);
 | 
			
		||||
            // Paint the color bars.
 | 
			
		||||
            parse_color(filament_rgb, rgb);
 | 
			
		||||
            bmps.emplace_back(m_bitmapCache->mksolid(single_bar ? 24 : 16, 16, rgb));
 | 
			
		||||
            bmps.emplace_back(m_bitmapCache->mksolid(single_bar ? wide_icon_width : normal_icon_width, icon_height, rgb));
 | 
			
		||||
            if (! single_bar) {
 | 
			
		||||
                parse_color(extruder_rgb, rgb);
 | 
			
		||||
                bmps.emplace_back(m_bitmapCache->mksolid(8,  16, rgb));
 | 
			
		||||
                bmps.emplace_back(m_bitmapCache->mksolid(thin_icon_width, icon_height, rgb));
 | 
			
		||||
            }
 | 
			
		||||
            // Paint a lock at the system presets.
 | 
			
		||||
            bmps.emplace_back(m_bitmapCache->mkclear(2, 16));
 | 
			
		||||
			bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(16, 16));
 | 
			
		||||
            bmps.emplace_back(m_bitmapCache->mkclear(space_icon_width, icon_height));
 | 
			
		||||
            bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(normal_icon_width, icon_height));
 | 
			
		||||
//                 (preset.is_dirty ? *m_bitmapLockOpen : *m_bitmapLock) : m_bitmapCache->mkclear(16, 16));
 | 
			
		||||
            bitmap = m_bitmapCache->insert(bitmap_key, bmps);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ public:
 | 
			
		|||
    void                        export_configbundle(const std::string &path, bool export_system_settings = false);
 | 
			
		||||
 | 
			
		||||
    // Update a filament selection combo box on the platter for an idx_extruder.
 | 
			
		||||
    void                        update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui);
 | 
			
		||||
    void                        update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui, const int em = 10);
 | 
			
		||||
 | 
			
		||||
    // Enable / disable the "- default -" preset.
 | 
			
		||||
    void                        set_default_suppressed(bool default_suppressed);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ void Selection::set_model(Model* model)
 | 
			
		|||
    update_valid();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Selection::add(unsigned int volume_idx, bool as_single_selection)
 | 
			
		||||
void Selection::add(unsigned int volume_idx, bool as_single_selection, bool check_for_already_contained)
 | 
			
		||||
{
 | 
			
		||||
    if (!m_valid || ((unsigned int)m_volumes->size() <= volume_idx))
 | 
			
		||||
        return;
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +110,7 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection)
 | 
			
		|||
        return;
 | 
			
		||||
 | 
			
		||||
    bool keep_instance_mode = (m_mode == Instance) && !as_single_selection;
 | 
			
		||||
    bool already_contained = contains_volume(volume_idx);
 | 
			
		||||
    bool already_contained = check_for_already_contained && contains_volume(volume_idx);
 | 
			
		||||
 | 
			
		||||
    // resets the current list if needed
 | 
			
		||||
    bool needs_reset = as_single_selection && !already_contained;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -210,7 +210,7 @@ public:
 | 
			
		|||
    EMode get_mode() const { return m_mode; }
 | 
			
		||||
    void set_mode(EMode mode) { m_mode = mode; }
 | 
			
		||||
 | 
			
		||||
    void add(unsigned int volume_idx, bool as_single_selection = true);
 | 
			
		||||
    void add(unsigned int volume_idx, bool as_single_selection = true, bool check_for_already_contained = false);
 | 
			
		||||
    void remove(unsigned int volume_idx);
 | 
			
		||||
 | 
			
		||||
    void add_object(unsigned int object_idx, bool as_single_selection = true);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ std::string get_main_info(bool format_as_html)
 | 
			
		|||
    std::string line_end = format_as_html ? "<br>" : "\n";
 | 
			
		||||
 | 
			
		||||
    if (!format_as_html)
 | 
			
		||||
        out << b_start << SLIC3R_FORK_NAME << b_end << line_end;
 | 
			
		||||
        out << b_start << SLIC3R_APP_NAME << b_end << line_end;
 | 
			
		||||
    out << b_start << "Version:   "             << b_end << SLIC3R_VERSION << line_end;
 | 
			
		||||
    out << b_start << "Build:     "             << b_end << SLIC3R_BUILD << line_end;
 | 
			
		||||
    out << line_end;
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ std::string get_main_info(bool format_as_html)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
SysInfoDialog::SysInfoDialog()
 | 
			
		||||
    : DPIDialog(NULL, wxID_ANY, _(L("Slic3r Prusa Edition - System Information")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
 | 
			
		||||
    : DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("System Information")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
 | 
			
		||||
{
 | 
			
		||||
	wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
 | 
			
		||||
	SetBackgroundColour(bgr_clr);
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +64,7 @@ SysInfoDialog::SysInfoDialog()
 | 
			
		|||
 | 
			
		||||
    // title
 | 
			
		||||
    {
 | 
			
		||||
        wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_FORK_NAME, wxDefaultPosition, wxDefaultSize);
 | 
			
		||||
        wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_APP_NAME, wxDefaultPosition, wxDefaultSize);
 | 
			
		||||
        wxFont title_font = wxGetApp().bold_font();//wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
 | 
			
		||||
//         title_font.SetWeight(wxFONTWEIGHT_BOLD);
 | 
			
		||||
        title_font.SetFamily(wxFONTFAMILY_ROMAN);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ static const std::string CONFIG_UPDATE_WIKI_URL("https://github.com/prusa3d/Slic
 | 
			
		|||
// MsgUpdateSlic3r
 | 
			
		||||
 | 
			
		||||
MsgUpdateSlic3r::MsgUpdateSlic3r(const Semver &ver_current, const Semver &ver_online) :
 | 
			
		||||
	MsgDialog(nullptr, _(L("Update available")), _(L("New version of Slic3r PE is available"))),
 | 
			
		||||
	MsgDialog(nullptr, _(L("Update available")), wxString::Format(_(L("New version of % is available")), SLIC3R_APP_NAME)),
 | 
			
		||||
	ver_current(ver_current),
 | 
			
		||||
	ver_online(ver_online)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -113,17 +113,17 @@ MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map<std::string, w
 | 
			
		|||
{
 | 
			
		||||
	logo->SetBitmap(create_scaled_bitmap(this, "Slic3r_192px_grayscale.png", 192));
 | 
			
		||||
 | 
			
		||||
	auto *text = new wxStaticText(this, wxID_ANY, _(L(
 | 
			
		||||
		"This version of Slic3r PE is not compatible with currently installed configuration bundles.\n"
 | 
			
		||||
		"This probably happened as a result of running an older Slic3r PE after using a newer one.\n\n"
 | 
			
		||||
	auto *text = new wxStaticText(this, wxID_ANY, wxString::Format(_(L(
 | 
			
		||||
		"This version of %s is not compatible with currently installed configuration bundles.\n"
 | 
			
		||||
		"This probably happened as a result of running an older %s after using a newer one.\n\n"
 | 
			
		||||
 | 
			
		||||
		"You may either exit Slic3r and try again with a newer version, or you may re-run the initial configuration. "
 | 
			
		||||
		"Doing so will create a backup snapshot of the existing configuration before installing files compatible with this Slic3r.\n"
 | 
			
		||||
	)));
 | 
			
		||||
		)), SLIC3R_APP_NAME, SLIC3R_APP_NAME));
 | 
			
		||||
	text->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
 | 
			
		||||
	content_sizer->Add(text);
 | 
			
		||||
 | 
			
		||||
	auto *text2 = new wxStaticText(this, wxID_ANY, wxString::Format(_(L("This Slic3r PE version: %s")), SLIC3R_VERSION));
 | 
			
		||||
	auto *text2 = new wxStaticText(this, wxID_ANY, wxString::Format(_(L("This %s version: %s")), SLIC3R_APP_NAME, SLIC3R_VERSION));
 | 
			
		||||
	text2->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
 | 
			
		||||
	content_sizer->Add(text2);
 | 
			
		||||
	content_sizer->AddSpacer(VERT_SPACING);
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +168,7 @@ MsgDataLegacy::MsgDataLegacy() :
 | 
			
		|||
{
 | 
			
		||||
	auto *text = new wxStaticText(this, wxID_ANY, wxString::Format(
 | 
			
		||||
		_(L(
 | 
			
		||||
			"Slic3r PE now uses an updated configuration structure.\n\n"
 | 
			
		||||
			"%s now uses an updated configuration structure.\n\n"
 | 
			
		||||
 | 
			
		||||
			"So called 'System presets' have been introduced, which hold the built-in default settings for various "
 | 
			
		||||
			"printers. These System presets cannot be modified, instead, users now may create their "
 | 
			
		||||
| 
						 | 
				
			
			@ -178,7 +178,7 @@ MsgDataLegacy::MsgDataLegacy() :
 | 
			
		|||
			"Please proceed with the %s that follows to set up the new presets "
 | 
			
		||||
			"and to choose whether to enable automatic preset updates."
 | 
			
		||||
		)),
 | 
			
		||||
		ConfigWizard::name()
 | 
			
		||||
		SLIC3R_APP_NAME, ConfigWizard::name()
 | 
			
		||||
	));
 | 
			
		||||
	text->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
 | 
			
		||||
	content_sizer->Add(text);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,7 +88,7 @@ Http::priv::priv(const std::string &url)
 | 
			
		|||
 | 
			
		||||
	set_timeout_connect(DEFAULT_TIMEOUT_CONNECT);
 | 
			
		||||
	::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());   // curl makes a copy internally
 | 
			
		||||
	::curl_easy_setopt(curl, CURLOPT_USERAGENT, SLIC3R_FORK_NAME "/" SLIC3R_VERSION);
 | 
			
		||||
	::curl_easy_setopt(curl, CURLOPT_USERAGENT, SLIC3R_APP_NAME "/" SLIC3R_VERSION);
 | 
			
		||||
	::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer.front());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -228,6 +228,7 @@ std::string Http::priv::body_size_error()
 | 
			
		|||
void Http::priv::http_perform()
 | 
			
		||||
{
 | 
			
		||||
	::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
 | 
			
		||||
	::curl_easy_setopt(curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
 | 
			
		||||
	::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb);
 | 
			
		||||
	::curl_easy_setopt(curl, CURLOPT_WRITEDATA, static_cast<void*>(this));
 | 
			
		||||
	::curl_easy_setopt(curl, CURLOPT_READFUNCTION, form_file_read_cb);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -208,7 +208,7 @@ void PresetUpdater::priv::sync_version() const
 | 
			
		|||
{
 | 
			
		||||
	if (! enabled_version_check) { return; }
 | 
			
		||||
 | 
			
		||||
	BOOST_LOG_TRIVIAL(info) << boost::format("Downloading Slic3rPE online version from: `%1%`") % version_check_url;
 | 
			
		||||
	BOOST_LOG_TRIVIAL(info) << boost::format("Downloading %1% online version from: `%2%`") % SLIC3R_APP_NAME % version_check_url;
 | 
			
		||||
 | 
			
		||||
	Http::get(version_check_url)
 | 
			
		||||
		.size_limit(SLIC3R_VERSION_BODY_MAX)
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +224,7 @@ void PresetUpdater::priv::sync_version() const
 | 
			
		|||
		})
 | 
			
		||||
		.on_complete([&](std::string body, unsigned /* http_status */) {
 | 
			
		||||
			boost::trim(body);
 | 
			
		||||
			BOOST_LOG_TRIVIAL(info) << boost::format("Got Slic3rPE online version: `%1%`. Sending to GUI thread...") % body;
 | 
			
		||||
			BOOST_LOG_TRIVIAL(info) << boost::format("Got %1% online version: `%2%`. Sending to GUI thread...") % SLIC3R_APP_NAME % body;
 | 
			
		||||
 | 
			
		||||
			wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_VERSION_ONLINE);
 | 
			
		||||
			evt->SetString(GUI::from_u8(body));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,8 @@
 | 
			
		|||
# Included by CMakeLists, edited by the build script
 | 
			
		||||
# (the version numbers are generated by the build script from the git current label)
 | 
			
		||||
 | 
			
		||||
set(SLIC3R_FORK_NAME "Slic3r Prusa Edition")
 | 
			
		||||
set(SLIC3R_APP_NAME "Slic3r Prusa Edition")
 | 
			
		||||
set(SLIC3R_APP_KEY "Slic3rPE")
 | 
			
		||||
set(SLIC3R_VERSION "1.42.0-beta2")
 | 
			
		||||
set(SLIC3R_BUILD "${SLIC3R_VERSION}+UNKNOWN")
 | 
			
		||||
set(SLIC3R_BUILD_ID "${SLIC3R_BUILD_ID}")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -180,6 +180,8 @@ SV*
 | 
			
		|||
TriangleMesh::slice(z)
 | 
			
		||||
    std::vector<double> z
 | 
			
		||||
    CODE:
 | 
			
		||||
        THIS->require_shared_vertices(); // TriangleMeshSlicer needs this
 | 
			
		||||
 | 
			
		||||
        // convert doubles to floats
 | 
			
		||||
        std::vector<float> z_f = cast<float>(z);
 | 
			
		||||
        
 | 
			
		||||
| 
						 | 
				
			
			@ -210,6 +212,7 @@ TriangleMesh::cut(z, upper, lower)
 | 
			
		|||
    TriangleMesh*   upper;
 | 
			
		||||
    TriangleMesh*   lower;
 | 
			
		||||
    CODE:
 | 
			
		||||
        THIS->require_shared_vertices(); // TriangleMeshSlicer needs this
 | 
			
		||||
        TriangleMeshSlicer mslicer(THIS);
 | 
			
		||||
        mslicer.cut(z, upper, lower);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ DEBUG_OUT_PATH_PREFIX()
 | 
			
		|||
SV*
 | 
			
		||||
FORK_NAME()
 | 
			
		||||
    CODE:
 | 
			
		||||
        RETVAL = newSVpv(SLIC3R_FORK_NAME, 0);
 | 
			
		||||
        RETVAL = newSVpv(SLIC3R_APP_NAME, 0);
 | 
			
		||||
    OUTPUT: RETVAL
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue