diff --git a/doc/How to build - Mac OS.md b/doc/How to build - Mac OS.md index 670e9fd87..5af755564 100644 --- a/doc/How to build - Mac OS.md +++ b/doc/How to build - Mac OS.md @@ -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. diff --git a/resources/icons/layers.svg b/resources/icons/layers.svg index da5dec21d..cd71fab3a 100644 --- a/resources/icons/layers.svg +++ b/resources/icons/layers.svg @@ -5,13 +5,13 @@ - + - + - + @@ -20,7 +20,7 @@ - + diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index dc017f737..c06d19cb9 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -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(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 extruders = m_writer.extruders(); + if (! extruders.empty()) { + std::pair out_filament_used_mm ("; filament used [mm] = ", 0); + std::pair out_filament_used_cm3("; filament used [cm3] = ", 0); + std::pair out_filament_used_g ("; filament used [g] = ", 0); + std::pair 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 &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(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(region.config().perimeter_extruder.value - 1, 0); // Let's recover vector of extruder overrides: - const ExtruderPerCopy* entity_overrides = const_cast(layer_tools).wiping_extrusions().get_extruder_overrides(fill, correct_extruder_id, layer_to_print.object()->copies().size()); + const ExtruderPerCopy* entity_overrides = const_cast(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) diff --git a/src/libslic3r/GCode/WipeTowerPrusaMM.hpp b/src/libslic3r/GCode/WipeTowerPrusaMM.hpp index 3f904a483..2b5fa2241 100644 --- a/src/libslic3r/GCode/WipeTowerPrusaMM.hpp +++ b/src/libslic3r/GCode/WipeTowerPrusaMM.hpp @@ -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 diff --git a/src/libslic3r/GCodeTimeEstimator.cpp b/src/libslic3r/GCodeTimeEstimator.cpp index 4b4e9f587..60d7a4cdf 100644 --- a/src/libslic3r/GCodeTimeEstimator.cpp +++ b/src/libslic3r/GCodeTimeEstimator.cpp @@ -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(); diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 6b16855e8..5a0558977 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -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); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 0b51f36ec..bb03d1e9d 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1813,6 +1813,7 @@ std::vector PrintObject::_slice_volumes(const std::vector &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 PrintObject::_slice_volume(const std::vector &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(); diff --git a/src/libslic3r/SLA/SLABasePool.cpp b/src/libslic3r/SLA/SLABasePool.cpp index 2aabaa590..94b6c7d9b 100644 --- a/src/libslic3r/SLA/SLABasePool.cpp +++ b/src/libslic3r/SLA/SLABasePool.cpp @@ -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(); diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index bb0e5e007..75f9b0140 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -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 &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); diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index e5a574463..b7191970d 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -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(); diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index 2d603661d..f449ac2b4 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -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); diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 4bf5ce039..60ddcca08 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -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 find_unvisited_neighbors(std::vector &facet_visited) const; - friend class TriangleMeshSlicer; }; enum FacetEdgeType { @@ -159,9 +158,8 @@ class TriangleMeshSlicer public: typedef std::function 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 &z, std::vector* layers, throw_on_cancel_callback_type throw_on_cancel) const; void slice(const std::vector &z, const float closing_radius, std::vector* layers, throw_on_cancel_callback_type throw_on_cancel) const; enum FacetSliceType { diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index dfd72b7a9..21ec3d307 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -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(); diff --git a/src/libslic3r/libslic3r_version.h.in b/src/libslic3r/libslic3r_version.h.in index 2259b2302..7c4a4b294 100644 --- a/src/libslic3r/libslic3r_version.h.in +++ b/src/libslic3r/libslic3r_version.h.in @@ -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@" diff --git a/src/platform/msw/slic3r.rc.in b/src/platform/msw/slic3r.rc.in index 493f9f752..970683e58 100644 --- a/src/platform/msw/slic3r.rc.in +++ b/src/platform/msw/slic3r.rc.in @@ -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" } } diff --git a/src/platform/osx/Info.plist.in b/src/platform/osx/Info.plist.in index 35958acde..9314bdaab 100644 --- a/src/platform/osx/Info.plist.in +++ b/src/platform/osx/Info.plist.in @@ -3,15 +3,15 @@ CFBundleExecutable - Slic3r + @SLIC3R_APP_KEY@ CFBundleGetInfoString - Slic3r Copyright (C) 2011-2017 Alessandro Ranellucci, (C) 2016-2018 Prusa Reseach + @SLIC3R_APP_NAME@ Copyright (C) 2011-2019 Alessandro Ranellucci, (C) 2016-2019 Prusa Reseach CFBundleIconFile Slic3r.icns CFBundleName - Slic3r + @SLIC3R_APP_KEY@ CFBundleShortVersionString - Slic3r @SLIC3R_BUILD_ID@ + @SLIC3R_APP_NAME@ @SLIC3R_BUILD_ID@ CFBundleIdentifier com.prusa3d.slic3r/ CFBundleInfoDictionaryVersion diff --git a/src/slic3r.cpp b/src/slic3r.cpp index ff87b3f6d..c3e69a189 100644 --- a/src/slic3r.cpp +++ b/src/slic3r.cpp @@ -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 */ diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index 44d1972bc..b2b025880 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -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); diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index c6a73864d..e5135ef43 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -16,6 +16,7 @@ #include "libslic3r/Utils.hpp" #include "libslic3r/GCode/PostProcessor.hpp" #include "libslic3r/GCode/PreviewData.hpp" +#include "libslic3r/libslic3r.h" #include #include @@ -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"); diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index 30ccc1ba5..db116a5dd 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -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(); diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 641f1cb72..551a4f739 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -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); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c4f0a3a91..626e9a9ac 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -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); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 42385bd63..a30798790 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -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); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 0a3984d9e..0f3c7cb79 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -543,12 +543,13 @@ void ObjectList::paste_objects_into_list(const std::vector& 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(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 6bf43955f..42be32041 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -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 diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 7cc5b6485..346bf5b06 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -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); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index aa88f9dd5..2285e2520 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -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(); Transform3f instance_matrix_no_translation_no_scaling = vol->get_instance_transformation().get_matrix(true,false,true).cast(); Vec3f scaling = vol->get_instance_scaling_factor().cast(); + 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(); 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(); + 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 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(&m_mesh), [](){}); + m_tms->init(m_mesh, [](){}); } - + std::vector list_of_expolys; m_tms->set_up_direction(up); m_tms->slice(std::vector{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{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(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 m_AABB; - TriangleMesh m_mesh; + const TriangleMesh* m_mesh; + mutable const TriangleMesh* m_supports_mesh; mutable std::vector m_triangles; + mutable std::vector 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 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 m_tms; + mutable std::unique_ptr m_supports_tms; std::vector get_config_options(const std::vector& keys) const; bool is_point_clipped(const Vec3d& point, const Vec3d& direction_to_camera) const; diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 63f331b92..9a4561f07 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -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"))); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index ac4284c12..302ab5a02 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -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) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 93fbe263b..c3ac8738b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -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 Plater::priv::load_files(const std::vector& 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 Plater::priv::load_files(const std::vector& 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& 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(); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index c40e4c309..d2ae72f62 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -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& object_idxs); void schedule_background_process(); void fix_through_netfabb(const int obj_idx, const int vol_idx = -1); void send_gcode(); diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 62bcb9d9b..12d96624c 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -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); diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index 7927006b2..7de8c99aa 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -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 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); } diff --git a/src/slic3r/GUI/PresetBundle.hpp b/src/slic3r/GUI/PresetBundle.hpp index 069ebd784..2309ceecd 100644 --- a/src/slic3r/GUI/PresetBundle.hpp +++ b/src/slic3r/GUI/PresetBundle.hpp @@ -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); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 957c04d69..e014851ab 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -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; diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index a8b0c06dc..87c919680 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -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); diff --git a/src/slic3r/GUI/SysInfoDialog.cpp b/src/slic3r/GUI/SysInfoDialog.cpp index 0067e6438..471ba5486 100644 --- a/src/slic3r/GUI/SysInfoDialog.cpp +++ b/src/slic3r/GUI/SysInfoDialog.cpp @@ -22,7 +22,7 @@ std::string get_main_info(bool format_as_html) std::string line_end = format_as_html ? "
" : "\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); diff --git a/src/slic3r/GUI/UpdateDialogs.cpp b/src/slic3r/GUI/UpdateDialogs.cpp index dccdf3ecd..d3638c1f5 100644 --- a/src/slic3r/GUI/UpdateDialogs.cpp +++ b/src/slic3r/GUI/UpdateDialogs.cpp @@ -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_mapSetBitmap(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); diff --git a/src/slic3r/Utils/Http.cpp b/src/slic3r/Utils/Http.cpp index 02bbc087e..79c4ecfa9 100644 --- a/src/slic3r/Utils/Http.cpp +++ b/src/slic3r/Utils/Http.cpp @@ -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(this)); ::curl_easy_setopt(curl, CURLOPT_READFUNCTION, form_file_read_cb); diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 6924f86de..1128df29c 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -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)); diff --git a/version.inc b/version.inc index 6a3f00e00..cbb2d1ab0 100644 --- a/version.inc +++ b/version.inc @@ -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}") diff --git a/xs/xsp/TriangleMesh.xsp b/xs/xsp/TriangleMesh.xsp index edfb4a198..e519f9210 100644 --- a/xs/xsp/TriangleMesh.xsp +++ b/xs/xsp/TriangleMesh.xsp @@ -180,6 +180,8 @@ SV* TriangleMesh::slice(z) std::vector z CODE: + THIS->require_shared_vertices(); // TriangleMeshSlicer needs this + // convert doubles to floats std::vector z_f = cast(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); diff --git a/xs/xsp/XS.xsp b/xs/xsp/XS.xsp index 04969a7f9..e6f252ca8 100644 --- a/xs/xsp/XS.xsp +++ b/xs/xsp/XS.xsp @@ -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