diff --git a/resources/profiles/PrusaResearch/MK3S_thumbnail.png b/resources/profiles/PrusaResearch/MK3S_thumbnail.png index 5fa1a665b5..8a859b82e7 100644 Binary files a/resources/profiles/PrusaResearch/MK3S_thumbnail.png and b/resources/profiles/PrusaResearch/MK3S_thumbnail.png differ diff --git a/resources/shaders/gouraud_light.fs b/resources/shaders/gouraud_light.fs index d1bb2f55bb..970185a00e 100644 --- a/resources/shaders/gouraud_light.fs +++ b/resources/shaders/gouraud_light.fs @@ -1,11 +1,12 @@ #version 110 uniform vec4 uniform_color; +uniform float emission_factor; // x = tainted, y = specular; varying vec2 intensity; void main() { - gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); + gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); } diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index f4b38e2ec6..1e302c6563 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -29,6 +29,11 @@ static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 static const float DEFAULT_TRAVEL_ACCELERATION = 1250.0f; +static const size_t MIN_EXTRUDERS_COUNT = 5; +static const float DEFAULT_FILAMENT_DIAMETER = 1.75f; +static const float DEFAULT_FILAMENT_DENSITY = 1.245f; +static const Slic3r::Vec3f DEFAULT_EXTRUDER_OFFSET = Slic3r::Vec3f::Zero(); + namespace Slic3r { #if ENABLE_VALIDATE_CUSTOM_GCODE @@ -187,72 +192,6 @@ void GCodeProcessor::TimeMachine::CustomGCodeTime::reset() times = std::vector>(); } -void GCodeProcessor::UsedFilaments::reset() -{ - color_change_cache = 0.0f; - volumes_per_color_change = std::vector(); - - tool_change_cache = 0.0f; - volumes_per_extruder.clear(); - - role_cache = 0.0f; - filaments_per_role.clear(); -} - -void GCodeProcessor::UsedFilaments::increase_caches(double extruded_volume) -{ - color_change_cache += extruded_volume; - tool_change_cache += extruded_volume; - role_cache += extruded_volume; -} - -void GCodeProcessor::UsedFilaments::process_color_change_cache() -{ - if (color_change_cache != 0.0f) { - volumes_per_color_change.push_back(color_change_cache); - color_change_cache = 0.0f; - } -} - -void GCodeProcessor::UsedFilaments::process_extruder_cache(GCodeProcessor* processor) -{ - size_t active_extruder_id = processor->m_extruder_id; - if (tool_change_cache != 0.0f) { - if (volumes_per_extruder.find(active_extruder_id) != volumes_per_extruder.end()) - volumes_per_extruder[active_extruder_id] += tool_change_cache; - else - volumes_per_extruder[active_extruder_id] = tool_change_cache; - tool_change_cache = 0.0f; - } -} - -void GCodeProcessor::UsedFilaments::process_role_cache(GCodeProcessor* processor) -{ - if (role_cache != 0.0f) { - std::pair filament = { 0.0f, 0.0f }; - - double s = PI * sqr(0.5 * processor->m_filament_diameters[processor->m_extruder_id]); - filament.first = role_cache/s * 0.001; - filament.second = role_cache * processor->m_filament_densities[processor->m_extruder_id] * 0.001; - - ExtrusionRole active_role = processor->m_extrusion_role; - if (filaments_per_role.find(active_role) != filaments_per_role.end()) { - filaments_per_role[active_role].first += filament.first; - filaments_per_role[active_role].second += filament.second; - } - else - filaments_per_role[active_role] = filament; - role_cache = 0.0f; - } -} - -void GCodeProcessor::UsedFilaments::process_caches(GCodeProcessor* processor) -{ - process_color_change_cache(); - process_extruder_cache(processor); - process_role_cache(processor); -} - void GCodeProcessor::TimeMachine::reset() { enabled = false; @@ -785,6 +724,95 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) "Is " + out_path + " locked?" + '\n'); } +void GCodeProcessor::UsedFilaments::reset() +{ + color_change_cache = 0.0f; + volumes_per_color_change = std::vector(); + + tool_change_cache = 0.0f; + volumes_per_extruder.clear(); + + role_cache = 0.0f; + filaments_per_role.clear(); +} + +void GCodeProcessor::UsedFilaments::increase_caches(double extruded_volume) +{ + color_change_cache += extruded_volume; + tool_change_cache += extruded_volume; + role_cache += extruded_volume; +} + +void GCodeProcessor::UsedFilaments::process_color_change_cache() +{ + if (color_change_cache != 0.0f) { + volumes_per_color_change.push_back(color_change_cache); + color_change_cache = 0.0f; + } +} + +void GCodeProcessor::UsedFilaments::process_extruder_cache(GCodeProcessor* processor) +{ + size_t active_extruder_id = processor->m_extruder_id; + if (tool_change_cache != 0.0f) { + if (volumes_per_extruder.find(active_extruder_id) != volumes_per_extruder.end()) + volumes_per_extruder[active_extruder_id] += tool_change_cache; + else + volumes_per_extruder[active_extruder_id] = tool_change_cache; + tool_change_cache = 0.0f; + } +} + +void GCodeProcessor::UsedFilaments::process_role_cache(GCodeProcessor* processor) +{ + if (role_cache != 0.0f) { + std::pair filament = { 0.0f, 0.0f }; + + double s = PI * sqr(0.5 * processor->m_result.filament_diameters[processor->m_extruder_id]); + filament.first = role_cache / s * 0.001; + filament.second = role_cache * processor->m_result.filament_densities[processor->m_extruder_id] * 0.001; + + ExtrusionRole active_role = processor->m_extrusion_role; + if (filaments_per_role.find(active_role) != filaments_per_role.end()) { + filaments_per_role[active_role].first += filament.first; + filaments_per_role[active_role].second += filament.second; + } + else + filaments_per_role[active_role] = filament; + role_cache = 0.0f; + } +} + +void GCodeProcessor::UsedFilaments::process_caches(GCodeProcessor* processor) +{ + process_color_change_cache(); + process_extruder_cache(processor); + process_role_cache(processor); +} + +#if ENABLE_GCODE_VIEWER_STATISTICS +void GCodeProcessor::Result::reset() { + moves = std::vector(); + bed_shape = Pointfs(); + settings_ids.reset(); + extruders_count = 0; + extruder_colors = std::vector(); + filament_diameters = std::vector(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER); + filament_densities = std::vector(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY); + time = 0; +} +#else +void GCodeProcessor::Result::reset() { + moves = std::vector(); + bed_shape = Pointfs(); + settings_ids.reset(); + extruders_count = 0; + extruder_colors = std::vector(); + filament_diameters = std::vector(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER); + filament_densities = std::vector(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY); +} +#endif // ENABLE_GCODE_VIEWER_STATISTICS + const std::vector> GCodeProcessor::Producers = { { EProducer::PrusaSlicer, "PrusaSlicer" }, { EProducer::Slic3rPE, "Slic3r Prusa Edition" }, @@ -886,14 +914,14 @@ void GCodeProcessor::apply_config(const PrintConfig& config) m_extruder_temps.resize(extruders_count); - m_filament_diameters.resize(config.filament_diameter.values.size()); + m_result.filament_diameters.resize(config.filament_diameter.values.size()); for (size_t i = 0; i < config.filament_diameter.values.size(); ++i) { - m_filament_diameters[i] = static_cast(config.filament_diameter.values[i]); + m_result.filament_diameters[i] = static_cast(config.filament_diameter.values[i]); } - m_filament_densities.resize(config.filament_density.values.size()); + m_result.filament_densities.resize(config.filament_density.values.size()); for (size_t i = 0; i < config.filament_density.values.size(); ++i) { - m_filament_densities[i] = static_cast(config.filament_density.values[i]); + m_result.filament_densities[i] = static_cast(config.filament_density.values[i]); } if ((m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware) && config.machine_limits_usage.value != MachineLimitsUsage::Ignore) { @@ -959,21 +987,37 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) if (printer_settings_id != nullptr) m_result.settings_ids.printer = printer_settings_id->value; + m_result.extruders_count = config.option("nozzle_diameter")->values.size(); + const ConfigOptionFloats* filament_diameters = config.option("filament_diameter"); if (filament_diameters != nullptr) { - for (double diam : filament_diameters->values) { - m_filament_diameters.push_back(static_cast(diam)); + m_result.filament_diameters.clear(); + m_result.filament_diameters.resize(filament_diameters->values.size()); + for (size_t i = 0; i < filament_diameters->values.size(); ++i) { + m_result.filament_diameters[i] = static_cast(filament_diameters->values[i]); + } + } + + if (m_result.filament_diameters.size() < m_result.extruders_count) { + for (size_t i = m_result.filament_diameters.size(); i < m_result.extruders_count; ++i) { + m_result.filament_diameters.emplace_back(DEFAULT_FILAMENT_DIAMETER); } } const ConfigOptionFloats* filament_densities = config.option("filament_density"); if (filament_densities != nullptr) { - for (double dens : filament_densities->values) { - m_filament_densities.push_back(static_cast(dens)); + m_result.filament_densities.clear(); + m_result.filament_densities.resize(filament_densities->values.size()); + for (size_t i = 0; i < filament_densities->values.size(); ++i) { + m_result.filament_densities[i] = static_cast(filament_densities->values[i]); } } - m_result.extruders_count = config.option("nozzle_diameter")->values.size(); + if (m_result.filament_densities.size() < m_result.extruders_count) { + for (size_t i = m_result.filament_densities.size(); i < m_result.extruders_count; ++i) { + m_result.filament_densities.emplace_back(DEFAULT_FILAMENT_DENSITY); + } + } const ConfigOptionPoints* extruder_offset = config.option("extruder_offset"); if (extruder_offset != nullptr) { @@ -983,6 +1027,12 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) m_extruder_offsets[i] = { offset(0), offset(1), 0.0f }; } } + + if (m_extruder_offsets.size() < m_result.extruders_count) { + for (size_t i = m_extruder_offsets.size(); i < m_result.extruders_count; ++i) { + m_extruder_offsets.emplace_back(DEFAULT_EXTRUDER_OFFSET); + } + } const ConfigOptionStrings* extruder_colour = config.option("extruder_colour"); if (extruder_colour != nullptr) { @@ -998,6 +1048,12 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) } } + if (m_result.extruder_colors.size() < m_result.extruders_count) { + for (size_t i = m_result.extruder_colors.size(); i < m_result.extruders_count; ++i) { + m_result.extruder_colors.emplace_back(std::string()); + } + } + // replace missing values with default std::string default_color = "#FF8000"; for (size_t i = 0; i < m_result.extruder_colors.size(); ++i) { @@ -1133,12 +1189,10 @@ void GCodeProcessor::enable_stealth_time_estimator(bool enabled) void GCodeProcessor::reset() { - static const size_t Min_Extruder_Count = 5; - m_units = EUnits::Millimeters; m_global_positioning_type = EPositioningType::Absolute; m_e_local_positioning_type = EPositioningType::Absolute; - m_extruder_offsets = std::vector(Min_Extruder_Count, Vec3f::Zero()); + m_extruder_offsets = std::vector(MIN_EXTRUDERS_COUNT, Vec3f::Zero()); m_flavor = gcfRepRapSprinter; m_start_position = { 0.0f, 0.0f, 0.0f, 0.0f }; @@ -1163,17 +1217,15 @@ void GCodeProcessor::reset() m_extrusion_role = erNone; m_extruder_id = 0; - m_extruder_colors.resize(Min_Extruder_Count); - for (size_t i = 0; i < Min_Extruder_Count; ++i) { + m_extruder_colors.resize(MIN_EXTRUDERS_COUNT); + for (size_t i = 0; i < MIN_EXTRUDERS_COUNT; ++i) { m_extruder_colors[i] = static_cast(i); } - m_extruder_temps.resize(Min_Extruder_Count); - for (size_t i = 0; i < Min_Extruder_Count; ++i) { + m_extruder_temps.resize(MIN_EXTRUDERS_COUNT); + for (size_t i = 0; i < MIN_EXTRUDERS_COUNT; ++i) { m_extruder_temps[i] = 0.0f; } - m_filament_diameters = std::vector(Min_Extruder_Count, 1.75f); - m_filament_densities = std::vector(Min_Extruder_Count, 1.245f); m_extruded_last_z = 0.0f; #if ENABLE_START_GCODE_VISUALIZATION m_first_layer_height = 0.0f; @@ -2205,7 +2257,7 @@ void GCodeProcessor::process_G0(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) { - float filament_diameter = (static_cast(m_extruder_id) < m_filament_diameters.size()) ? m_filament_diameters[m_extruder_id] : m_filament_diameters.back(); + float filament_diameter = (static_cast(m_extruder_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[m_extruder_id] : m_result.filament_diameters.back(); float filament_radius = 0.5f * filament_diameter; float area_filament_cross_section = static_cast(M_PI) * sqr(filament_radius); auto absolute_position = [this, area_filament_cross_section](Axis axis, const GCodeReader::GCodeLine& lineG1) { @@ -2307,7 +2359,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) m_width = delta_pos[E] * static_cast(M_PI * sqr(1.05f * filament_radius)) / (delta_xyz * m_height); else if (m_extrusion_role == erBridgeInfill || m_extrusion_role == erNone) // cross section: circle - m_width = static_cast(m_filament_diameters[m_extruder_id]) * std::sqrt(delta_pos[E] / delta_xyz); + m_width = static_cast(m_result.filament_diameters[m_extruder_id]) * std::sqrt(delta_pos[E] / delta_xyz); else // cross section: rectangle + 2 semicircles m_width = delta_pos[E] * static_cast(M_PI * sqr(filament_radius)) / (delta_xyz * m_height) + static_cast(1.0 - 0.25 * M_PI) * m_height; @@ -2945,8 +2997,7 @@ void GCodeProcessor::process_T(const std::string_view command) } else { unsigned char id = static_cast(eid); if (m_extruder_id != id) { - unsigned char extruders_count = static_cast(m_extruder_offsets.size()); - if (id >= extruders_count) + if (id >= m_result.extruders_count) BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange, maybe from a custom gcode."; else { unsigned char old_extruder_id = m_extruder_id; diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 8975255ecf..616731b498 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -343,7 +343,6 @@ namespace Slic3r { std::map volumes_per_extruder; double role_cache; - // ExtrusionRole : std::map> filaments_per_role; void reset(); @@ -403,27 +402,14 @@ namespace Slic3r { SettingsIds settings_ids; size_t extruders_count; std::vector extruder_colors; + std::vector filament_diameters; + std::vector filament_densities; PrintEstimatedStatistics print_statistics; #if ENABLE_GCODE_VIEWER_STATISTICS int64_t time{ 0 }; - void reset() { - time = 0; - moves = std::vector(); - bed_shape = Pointfs(); - extruder_colors = std::vector(); - extruders_count = 0; - settings_ids.reset(); - } -#else - void reset() { - moves = std::vector(); - bed_shape = Pointfs(); - extruder_colors = std::vector(); - extruders_count = 0; - settings_ids.reset(); - } #endif // ENABLE_GCODE_VIEWER_STATISTICS + void reset(); }; #if ENABLE_SEAMS_VISUALIZATION @@ -549,8 +535,6 @@ namespace Slic3r { unsigned char m_extruder_id; ExtruderColors m_extruder_colors; ExtruderTemps m_extruder_temps; - std::vector m_filament_diameters; - std::vector m_filament_densities; float m_extruded_last_z; #if ENABLE_START_GCODE_VISUALIZATION float m_first_layer_height; // mm diff --git a/src/libslic3r/Point.hpp b/src/libslic3r/Point.hpp index e5ce68420e..ceb2352443 100644 --- a/src/libslic3r/Point.hpp +++ b/src/libslic3r/Point.hpp @@ -27,6 +27,7 @@ using Vec2crd = Eigen::Matrix; using Vec3crd = Eigen::Matrix; using Vec2i = Eigen::Matrix; using Vec3i = Eigen::Matrix; +using Vec4i = Eigen::Matrix; using Vec2i32 = Eigen::Matrix; using Vec2i64 = Eigen::Matrix; using Vec3i32 = Eigen::Matrix; @@ -50,12 +51,15 @@ using Matrix2f = Eigen::Matrix; using Matrix2d = Eigen::Matrix; using Matrix3f = Eigen::Matrix; using Matrix3d = Eigen::Matrix; +using Matrix4f = Eigen::Matrix; +using Matrix4d = Eigen::Matrix; using Transform2f = Eigen::Transform; using Transform2d = Eigen::Transform; using Transform3f = Eigen::Transform; using Transform3d = Eigen::Transform; + inline bool operator<(const Vec2d &lhs, const Vec2d &rhs) { return lhs(0) < rhs(0) || (lhs(0) == rhs(0) && lhs(1) < rhs(1)); } template diff --git a/src/libslic3r/SLA/Hollowing.cpp b/src/libslic3r/SLA/Hollowing.cpp index 1d3016bde8..32a8810375 100644 --- a/src/libslic3r/SLA/Hollowing.cpp +++ b/src/libslic3r/SLA/Hollowing.cpp @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/src/libslic3r/SLA/SupportTreeBuildsteps.hpp b/src/libslic3r/SLA/SupportTreeBuildsteps.hpp index 013666f074..478e2df1fe 100644 --- a/src/libslic3r/SLA/SupportTreeBuildsteps.hpp +++ b/src/libslic3r/SLA/SupportTreeBuildsteps.hpp @@ -2,6 +2,7 @@ #define SLASUPPORTTREEALGORITHM_H #include +#include #include #include diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index fba1429ea2..99f2c96419 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -1014,6 +1014,33 @@ TriangleMesh make_cylinder(double r, double h, double fa) return mesh; } + +TriangleMesh make_cone(double r, double h, double fa) +{ + Pointf3s vertices; + std::vector facets; + vertices.reserve(3+size_t(2*PI/fa)); + vertices.reserve(3+2*size_t(2*PI/fa)); + + vertices = { Vec3d::Zero(), Vec3d(0., 0., h) }; // base center and top vertex + size_t i = 0; + for (double angle=0; angle<2*PI; angle+=fa) { + vertices.emplace_back(r*std::cos(angle), r*std::sin(angle), 0.); + if (angle > 0.) { + facets.emplace_back(0, i+2, i+1); + facets.emplace_back(1, i+1, i+2); + } + ++i; + } + facets.emplace_back(0, 2, i+1); // close the shape + facets.emplace_back(1, i+1, 2); + + TriangleMesh mesh(std::move(vertices), std::move(facets)); + mesh.repair(); + return mesh; +} + + // Generates mesh for a sphere centered about the origin, using the generated angle // to determine the granularity. // Default angle is 1 degree. diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 49b11465e9..24447d8966 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -122,10 +122,8 @@ Polygon its_convex_hull_2d_above(const indexed_triangle_set &its, const Matrix3f Polygon its_convex_hull_2d_above(const indexed_triangle_set &its, const Transform3f &t, const float z); TriangleMesh make_cube(double x, double y, double z); - -// Generate a TriangleMesh of a cylinder TriangleMesh make_cylinder(double r, double h, double fa=(2*PI/360)); - +TriangleMesh make_cone(double r, double h, double fa=(2*PI/360)); TriangleMesh make_sphere(double rho, double fa=(2*PI/360)); } diff --git a/src/miniz/miniz.c b/src/miniz/miniz.c index cff9aa5d38..0d6fc7d9bc 100644 --- a/src/miniz/miniz.c +++ b/src/miniz/miniz.c @@ -5953,16 +5953,18 @@ static mz_uint32 mz_zip_writer_create_zip64_extra_data(mz_uint8 *pBuf, mz_uint64 static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date) { + (void)pZip; + mz_bool is_zip64_needed = uncomp_size >= MZ_UINT32_MAX || comp_size >= MZ_UINT32_MAX; memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE); MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, (pZip->m_pState->m_zip64) ? 0x002D : (method ? 0x0014 : 0x0000)); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, is_zip64_needed ? 0x002D : (method ? 0x0014 : 0x0000)); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date); MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32); - MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, (pZip->m_pState->m_zip64 || comp_size > MZ_UINT32_MAX) ? MZ_UINT32_MAX : comp_size); - MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, (pZip->m_pState->m_zip64 || uncomp_size > MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, is_zip64_needed ? MZ_UINT32_MAX : comp_size); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, is_zip64_needed ? MZ_UINT32_MAX : uncomp_size); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size); return MZ_TRUE; @@ -5974,7 +5976,7 @@ static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_ mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes) { - mz_zip_internal_state *pState = pZip->m_pState; + (void)pZip; mz_bool is_zip64_needed = uncomp_size >= MZ_UINT32_MAX || comp_size >= MZ_UINT32_MAX; memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG); @@ -6766,6 +6768,12 @@ mz_bool mz_zip_writer_add_staged_open(mz_zip_archive* pZip, mz_zip_writer_staged { mz_zip_time_t_to_dos_time(*pFile_time, &pContext->dos_time, &pContext->dos_date); } + else + { + MZ_TIME_T cur_time; + time(&cur_time); + mz_zip_time_t_to_dos_time(cur_time, &pContext->dos_time, &pContext->dos_date); + } #endif if (!mz_zip_writer_write_zeros(pZip, pContext->cur_archive_file_ofs, num_alignment_padding_bytes)) @@ -6787,13 +6795,7 @@ mz_bool mz_zip_writer_add_staged_open(mz_zip_archive* pZip, mz_zip_writer_staged } MZ_CLEAR_OBJ(local_dir_header); - if (pState->m_zip64) - { - pContext->pExtra_data = pContext->extra_data; - pContext->extra_size = mz_zip_writer_create_zip64_extra_data(pContext->extra_data, &pContext->uncomp_size, &pContext->comp_size, - (pContext->local_dir_header_ofs >= MZ_UINT32_MAX) ? &pContext->local_dir_header_ofs : NULL); - } - else if (!pState->m_zip64 && max_size > MZ_UINT32_MAX) + if (max_size > MZ_UINT32_MAX) { pContext->pExtra_data = pContext->extra_data; pContext->extra_size = mz_zip_writer_preallocate_extra_data(pContext->extra_data, 2 * sizeof(mz_uint64)); @@ -6897,7 +6899,7 @@ mz_bool mz_zip_writer_add_staged_finish(mz_zip_writer_staged_context *pContext) pContext->pExtra_data = pContext->extra_data; pContext->extra_size = mz_zip_writer_create_zip64_extra_data(pContext->extra_data, &pContext->uncomp_size, &pContext->comp_size, (pContext->local_dir_header_ofs >= MZ_UINT32_MAX) ? &pContext->local_dir_header_ofs : NULL); - mz_uint8 min_version[2] = {0x2D, 0x00}; + mz_uint8 min_version[2] = {0x2D, 0x00}; mz_uint8 comp_uncomp_size[4] = {0xFF, 0xFF, 0xFF, 0xFF}; if (pContext->pZip->m_pWrite(pContext->pZip->m_pIO_opaque, local_dir_header_ofs + MZ_ZIP_LDH_VERSION_NEEDED_OFS, min_version, sizeof(min_version)) != sizeof(min_version)) return mz_zip_set_error(pContext->pZip, MZ_ZIP_FILE_WRITE_FAILED); diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index aa3bf01c4a..caccec5d70 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -240,7 +240,7 @@ add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES}) encoding_check(libslic3r_gui) -target_link_libraries(libslic3r_gui libslic3r avrdude cereal imgui GLEW::GLEW OpenGL::GL OpenGL::GLU hidapi libcurl ${wxWidgets_LIBRARIES}) +target_link_libraries(libslic3r_gui libslic3r avrdude cereal imgui GLEW::GLEW OpenGL::GL hidapi libcurl ${wxWidgets_LIBRARIES}) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") target_link_libraries(libslic3r_gui ${DBUS_LIBRARIES}) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index f19ec8d6fd..77710c0de1 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -119,6 +119,7 @@ void Bed3D::Axes::render() const glsafe(::glEnable(GL_DEPTH_TEST)); shader->start_using(); + shader->set_uniform("emission_factor", 0.0); // x axis #if ENABLE_SEQUENTIAL_LIMITS @@ -510,8 +511,9 @@ void Bed3D::render_model() const #if !ENABLE_SEQUENTIAL_LIMITS shader->set_uniform("uniform_color", m_model_color); #endif // !ENABLE_SEQUENTIAL_LIMITS + shader->set_uniform("emission_factor", 0.0); ::glPushMatrix(); - ::glTranslated(m_model_offset(0), m_model_offset(1), m_model_offset(2)); + ::glTranslated(m_model_offset.x(), m_model_offset.y(), m_model_offset.z()); model->render(); ::glPopMatrix(); shader->stop_using(); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index a58524945b..2ced8e6015 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -232,6 +232,7 @@ void GCodeViewer::SequentialView::Marker::render() const #if !ENABLE_SEQUENTIAL_LIMITS shader->set_uniform("uniform_color", m_color); #endif // !ENABLE_SEQUENTIAL_LIMITS + shader->set_uniform("emission_factor", 0.0); glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(m_world_transform.data())); @@ -611,6 +612,8 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& return; m_settings_ids = gcode_result.settings_ids; + m_filament_diameters = gcode_result.filament_diameters; + m_filament_densities = gcode_result.filament_densities; if (wxGetApp().is_editor()) load_shells(print, initialized); @@ -751,6 +754,8 @@ void GCodeViewer::reset() m_tool_colors = std::vector(); m_extruders_count = 0; m_extruder_ids = std::vector(); + m_filament_diameters = std::vector(); + m_filament_densities = std::vector(); m_extrusions.reset_role_visibility_flags(); m_extrusions.reset_ranges(); m_shells.volumes.clear(); @@ -2897,20 +2902,10 @@ void GCodeViewer::render_legend() const } // get used filament (meters and grams) from used volume in respect to the active extruder - auto get_used_filament_from_volume = [imperial_units](double volume, int extruder_id) { - const std::vector& filament_presets = wxGetApp().preset_bundle->filament_presets; - const PresetCollection& filaments = wxGetApp().preset_bundle->filaments; - - double koef = imperial_units ? 1.0/ObjectManipulation::in_to_mm : 0.001; - - std::pair ret = { 0.0, 0.0 }; - if (const Preset* filament_preset = filaments.find_preset(filament_presets[extruder_id], false)) { - double filament_radius = 0.5 * filament_preset->config.opt_float("filament_diameter", 0); - double s = PI * sqr(filament_radius); - ret.first = volume / s * koef; - double filament_density = filament_preset->config.opt_float("filament_density", 0); - ret.second = volume * filament_density * 0.001; - } + auto get_used_filament_from_volume = [this, imperial_units](double volume, int extruder_id) { + double koef = imperial_units ? 1.0 / ObjectManipulation::in_to_mm : 0.001; + std::pair ret = { koef * volume / (PI * sqr(0.5 * m_filament_diameters[extruder_id])), + volume * m_filament_densities[extruder_id] * 0.001 }; return ret; }; @@ -3344,10 +3339,19 @@ void GCodeViewer::render_legend() const } // settings section - if (wxGetApp().is_gcode_viewer() && - (m_view_type == EViewType::FeatureType || m_view_type == EViewType::Tool) && - (!m_settings_ids.print.empty() || !m_settings_ids.filament.empty() || !m_settings_ids.printer.empty())) { - + bool has_settings = false; + has_settings |= !m_settings_ids.print.empty(); + has_settings |= !m_settings_ids.printer.empty(); + bool has_filament_settings = true; + has_filament_settings &= !m_settings_ids.filament.empty(); + for (const std::string& fs : m_settings_ids.filament) { + has_filament_settings &= !fs.empty(); + } + has_settings |= has_filament_settings; + bool show_settings = wxGetApp().is_gcode_viewer(); + show_settings &= (m_view_type == EViewType::FeatureType || m_view_type == EViewType::Tool); + show_settings &= has_settings; + if (show_settings) { auto calc_offset = [this]() { float ret = 0.0f; if (!m_settings_ids.printer.empty()) @@ -3364,13 +3368,8 @@ void GCodeViewer::render_legend() const return ret; }; - - ImGui::Spacing(); - ImGui::Spacing(); - ImGui::PushStyleColor(ImGuiCol_Separator, { 1.0f, 1.0f, 1.0f, 1.0f }); - ImGui::Separator(); - ImGui::PopStyleColor(); ImGui::Spacing(); + imgui.title(_u8L("Settings")); float offset = calc_offset(); @@ -3386,11 +3385,13 @@ void GCodeViewer::render_legend() const } if (!m_settings_ids.filament.empty()) { for (unsigned char i : m_extruder_ids) { - std::string txt = _u8L("Filament"); - txt += (m_extruder_ids.size() == 1) ? ":" : " " + std::to_string(i + 1); - imgui.text(txt); - ImGui::SameLine(offset); - imgui.text(m_settings_ids.filament[i]); + if (i < static_cast(m_settings_ids.filament.size()) && !m_settings_ids.filament[i].empty()) { + std::string txt = _u8L("Filament"); + txt += (m_extruder_ids.size() == 1) ? ":" : " " + std::to_string(i + 1); + imgui.text(txt); + ImGui::SameLine(offset); + imgui.text(m_settings_ids.filament[i]); + } } } } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index e5b44101cb..d5c793e62c 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -619,6 +619,8 @@ private: std::vector m_roles; size_t m_extruders_count; std::vector m_extruder_ids; + std::vector m_filament_diameters; + std::vector m_filament_densities; Extrusions m_extrusions; SequentialView m_sequential_view; Shells m_shells; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f266c86113..8442194f21 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1,6 +1,8 @@ #include "libslic3r/libslic3r.h" #include "GLCanvas3D.hpp" +#include + #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/PrintConfig.hpp" #include "libslic3r/GCode/ThumbnailData.hpp" @@ -1710,6 +1712,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re _set_current(); + m_hover_volume_idxs.clear(); + struct ModelVolumeState { ModelVolumeState(const GLVolume* volume) : model_volume(nullptr), geometry_id(volume->geometry_id), volume_idx(-1) {} @@ -4124,7 +4128,7 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool glsafe(::glEnable(GL_DEPTH_TEST)); shader->start_using(); - shader->set_uniform("print_box.volume_detection", 0); + shader->set_uniform("emission_factor", 0.0); for (GLVolume* vol : visible_volumes) { shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? orange : gray); @@ -5606,9 +5610,9 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z) return Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); const Camera& camera = wxGetApp().plater()->get_camera(); - const std::array& viewport = camera.get_viewport(); - const Transform3d& modelview_matrix = camera.get_view_matrix(); - const Transform3d& projection_matrix = camera.get_projection_matrix(); + Matrix4d modelview = camera.get_view_matrix().matrix(); + Matrix4d projection= camera.get_projection_matrix().matrix(); + Vec4i viewport(camera.get_viewport().data()); GLint y = viewport[3] - (GLint)mouse_pos(1); GLfloat mouse_z; @@ -5617,9 +5621,9 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z) else mouse_z = *z; - GLdouble out_x, out_y, out_z; - ::gluUnProject((GLdouble)mouse_pos(0), (GLdouble)y, (GLdouble)mouse_z, (GLdouble*)modelview_matrix.data(), (GLdouble*)projection_matrix.data(), (GLint*)viewport.data(), &out_x, &out_y, &out_z); - return Vec3d((double)out_x, (double)out_y, (double)out_z); + Vec3d out; + igl::unproject(Vec3d(mouse_pos(0), y, mouse_z), modelview, projection, viewport, out); + return out; } Vec3d GLCanvas3D::_mouse_to_bed_3d(const Point& mouse_pos) diff --git a/src/slic3r/GUI/GLSelectionRectangle.cpp b/src/slic3r/GUI/GLSelectionRectangle.cpp index d7f3f7a3a8..13467499a1 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.cpp +++ b/src/slic3r/GUI/GLSelectionRectangle.cpp @@ -4,6 +4,7 @@ #include "GLCanvas3D.hpp" #include "GUI_App.hpp" #include "Plater.hpp" +#include #include @@ -38,23 +39,26 @@ namespace GUI { m_state = Off; const Camera& camera = wxGetApp().plater()->get_camera(); - const std::array& viewport = camera.get_viewport(); - const Transform3d& modelview_matrix = camera.get_view_matrix(); - const Transform3d& projection_matrix = camera.get_projection_matrix(); + Matrix4d modelview = camera.get_view_matrix().matrix(); + Matrix4d projection= camera.get_projection_matrix().matrix(); + Vec4i viewport(camera.get_viewport().data()); + + // Convert our std::vector to Eigen dynamic matrix. + Eigen::Matrix pts(points.size(), 3); + for (size_t i=0; i(i, 0) = points[i]; + + // Get the projections. + Eigen::Matrix projections; + igl::project(pts, modelview, projection, viewport, projections); // bounding box created from the rectangle corners - will take care of order of the corners BoundingBox rectangle(Points{ Point(m_start_corner.cast()), Point(m_end_corner.cast()) }); // Iterate over all points and determine whether they're in the rectangle. - for (unsigned int i = 0; i render_color; + if (hover) { + render_color[0] = (1.0f - color[0]); + render_color[1] = (1.0f - color[1]); + render_color[2] = (1.0f - color[2]); render_color[3] = color[3]; } else - ::memcpy((void*)render_color, (const void*)color, 4 * sizeof(float)); + render_color = color; - render(size, render_color, true); + render(size, render_color, false); } float GLGizmoBase::Grabber::get_half_size(float size) const @@ -52,80 +48,37 @@ float GLGizmoBase::Grabber::get_dragging_half_size(float size) const return get_half_size(size) * DraggingScaleFactor; } -void GLGizmoBase::Grabber::render(float size, const float* render_color, bool use_lighting) const +void GLGizmoBase::Grabber::render(float size, const std::array& render_color, bool picking) const { - float half_size = dragging ? get_dragging_half_size(size) : get_half_size(size); + if (! cube_initialized) { + // This cannot be done in constructor, OpenGL is not yet + // initialized at that point (on Linux at least). + TriangleMesh mesh = make_cube(1., 1., 1.); + mesh.translate(Vec3f(-0.5, -0.5, -0.5)); + const_cast(cube).init_from(mesh); + const_cast(cube_initialized) = true; + } - if (use_lighting) - glsafe(::glEnable(GL_LIGHTING)); + float fullsize = 2 * (dragging ? get_dragging_half_size(size) : get_half_size(size)); - glsafe(::glColor4fv(render_color)); + GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_current_shader(); + if (shader != nullptr) +#if ENABLE_SEQUENTIAL_LIMITS + const_cast(&cube)->set_color(-1, render_color); +#else + shader->set_uniform("uniform_color", render_color); +#endif // ENABLE_SEQUENTIAL_LIMITS + else + glsafe(::glColor4fv(render_color.data())); // picking glsafe(::glPushMatrix()); - glsafe(::glTranslated(center(0), center(1), center(2))); - - glsafe(::glRotated(Geometry::rad2deg(angles(2)), 0.0, 0.0, 1.0)); - glsafe(::glRotated(Geometry::rad2deg(angles(1)), 0.0, 1.0, 0.0)); - glsafe(::glRotated(Geometry::rad2deg(angles(0)), 1.0, 0.0, 0.0)); - - // face min x - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(-(GLfloat)half_size, 0.0f, 0.0f)); - glsafe(::glRotatef(-90.0f, 0.0f, 1.0f, 0.0f)); - render_face(half_size); + glsafe(::glTranslated(center.x(), center.y(), center.z())); + glsafe(::glRotated(Geometry::rad2deg(angles.z()), 0.0, 0.0, 1.0)); + glsafe(::glRotated(Geometry::rad2deg(angles.y()), 0.0, 1.0, 0.0)); + glsafe(::glRotated(Geometry::rad2deg(angles.x()), 1.0, 0.0, 0.0)); + glsafe(::glScaled(fullsize, fullsize, fullsize)); + cube.render(); glsafe(::glPopMatrix()); - - // face max x - glsafe(::glPushMatrix()); - glsafe(::glTranslatef((GLfloat)half_size, 0.0f, 0.0f)); - glsafe(::glRotatef(90.0f, 0.0f, 1.0f, 0.0f)); - render_face(half_size); - glsafe(::glPopMatrix()); - - // face min y - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.0f, -(GLfloat)half_size, 0.0f)); - glsafe(::glRotatef(90.0f, 1.0f, 0.0f, 0.0f)); - render_face(half_size); - glsafe(::glPopMatrix()); - - // face max y - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.0f, (GLfloat)half_size, 0.0f)); - glsafe(::glRotatef(-90.0f, 1.0f, 0.0f, 0.0f)); - render_face(half_size); - glsafe(::glPopMatrix()); - - // face min z - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.0f, 0.0f, -(GLfloat)half_size)); - glsafe(::glRotatef(180.0f, 1.0f, 0.0f, 0.0f)); - render_face(half_size); - glsafe(::glPopMatrix()); - - // face max z - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.0f, 0.0f, (GLfloat)half_size)); - render_face(half_size); - glsafe(::glPopMatrix()); - - glsafe(::glPopMatrix()); - - if (use_lighting) - glsafe(::glDisable(GL_LIGHTING)); -} - -void GLGizmoBase::Grabber::render_face(float half_size) const -{ - ::glBegin(GL_TRIANGLES); - ::glNormal3f(0.0f, 0.0f, 1.0f); - ::glVertex3f(-(GLfloat)half_size, -(GLfloat)half_size, 0.0f); - ::glVertex3f((GLfloat)half_size, -(GLfloat)half_size, 0.0f); - ::glVertex3f((GLfloat)half_size, (GLfloat)half_size, 0.0f); - ::glVertex3f((GLfloat)half_size, (GLfloat)half_size, 0.0f); - ::glVertex3f(-(GLfloat)half_size, (GLfloat)half_size, 0.0f); - ::glVertex3f(-(GLfloat)half_size, -(GLfloat)half_size, 0.0f); - glsafe(::glEnd()); } @@ -141,9 +94,12 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, u , m_imgui(wxGetApp().imgui()) , m_first_input_window_render(true) { - ::memcpy((void*)m_base_color, (const void*)DEFAULT_BASE_COLOR, 4 * sizeof(float)); - ::memcpy((void*)m_drag_color, (const void*)DEFAULT_DRAG_COLOR, 4 * sizeof(float)); - ::memcpy((void*)m_highlight_color, (const void*)DEFAULT_HIGHLIGHT_COLOR, 4 * sizeof(float)); + m_base_color = DEFAULT_BASE_COLOR; + m_drag_color = DEFAULT_DRAG_COLOR; + m_highlight_color = DEFAULT_HIGHLIGHT_COLOR; + m_cone.init_from(make_cone(1., 1., 2 * PI / 24)); + m_sphere.init_from(make_sphere(1., (2 * M_PI) / 24.)); + m_cylinder.init_from(make_cylinder(1., 1., 2 * PI / 24.)); } void GLGizmoBase::set_hover_id(int id) @@ -155,10 +111,9 @@ void GLGizmoBase::set_hover_id(int id) } } -void GLGizmoBase::set_highlight_color(const float* color) +void GLGizmoBase::set_highlight_color(const std::array& color) { - if (color != nullptr) - ::memcpy((void*)m_highlight_color, (const void*)color, 4 * sizeof(float)); + m_highlight_color = color; } void GLGizmoBase::enable_grabber(unsigned int id) @@ -227,31 +182,31 @@ std::array GLGizmoBase::picking_color_component(unsigned int id) const void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const { - render_grabbers((float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0)); + render_grabbers((float)((box.size().x() + box.size().y() + box.size().z()) / 3.0)); } void GLGizmoBase::render_grabbers(float size) const { - for (int i = 0; i < (int)m_grabbers.size(); ++i) - { + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); + for (int i = 0; i < (int)m_grabbers.size(); ++i) { if (m_grabbers[i].enabled) - m_grabbers[i].render((m_hover_id == i), size); + m_grabbers[i].render(m_hover_id == i, size); } + shader->stop_using(); } void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const { - float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); + float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0); - for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i) - { - if (m_grabbers[i].enabled) - { + for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i) { + if (m_grabbers[i].enabled) { std::array color = picking_color_component(i); - m_grabbers[i].color[0] = color[0]; - m_grabbers[i].color[1] = color[1]; - m_grabbers[i].color[2] = color[2]; - m_grabbers[i].color[3] = color[3]; + m_grabbers[i].color = color; m_grabbers[i].render_for_picking(mean_size); } } @@ -265,8 +220,7 @@ std::string GLGizmoBase::format(float value, unsigned int decimals) const void GLGizmoBase::render_input_window(float x, float y, float bottom_limit) { on_render_input_window(x, y, bottom_limit); - if (m_first_input_window_render) - { + if (m_first_input_window_render) { // for some reason, the imgui dialogs are not shown on screen in the 1st frame where they are rendered, but show up only with the 2nd rendered frame // so, we forces another frame rendering the first time the imgui window is shown m_parent.set_as_dirty(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 98d4aa858d..ac83b794b2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -4,13 +4,11 @@ #include "libslic3r/Point.hpp" #include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/GLModel.hpp" #include class wxWindow; -class GLUquadric; -typedef class GLUquadric GLUquadricObj; - namespace Slic3r { @@ -20,11 +18,15 @@ class ModelObject; namespace GUI { -static const float DEFAULT_BASE_COLOR[4] = { 0.625f, 0.625f, 0.625f, 1.0f }; -static const float DEFAULT_DRAG_COLOR[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; -static const float DEFAULT_HIGHLIGHT_COLOR[4] = { 1.0f, 0.38f, 0.0f, 1.0f }; -static const float AXES_COLOR[][4] = { { 0.75f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.75f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.75f, 1.0f } }; -static const float CONSTRAINED_COLOR[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; +static const std::array DEFAULT_BASE_COLOR = { 0.625f, 0.625f, 0.625f, 1.0f }; +static const std::array DEFAULT_DRAG_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f }; +static const std::array DEFAULT_HIGHLIGHT_COLOR = { 1.0f, 0.38f, 0.0f, 1.0f }; +static const std::array, 3> AXES_COLOR = {{ + { 0.75f, 0.0f, 0.0f, 1.0f }, + { 0.0f, 0.75f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 0.75f, 1.0f } + }}; +static const std::array CONSTRAINED_COLOR = { 0.5f, 0.5f, 0.5f, 1.0f }; class ImGuiWrapper; class GLCanvas3D; @@ -48,21 +50,23 @@ protected: Vec3d center; Vec3d angles; - float color[4]; + std::array color; bool enabled; bool dragging; Grabber(); void render(bool hover, float size) const; - void render_for_picking(float size) const { render(size, color, false); } + void render_for_picking(float size) const { render(size, color, true); } float get_half_size(float size) const; float get_dragging_half_size(float size) const; private: - void render(float size, const float* render_color, bool use_lighting) const; - void render_face(float half_size) const; + void render(float size, const std::array& render_color, bool picking) const; + + GLModel cube; + bool cube_initialized = false; }; public: @@ -93,14 +97,17 @@ protected: unsigned int m_sprite_id; int m_hover_id; bool m_dragging; - float m_base_color[4]; - float m_drag_color[4]; - float m_highlight_color[4]; + std::array m_base_color; + std::array m_drag_color; + std::array m_highlight_color; mutable std::vector m_grabbers; ImGuiWrapper* m_imgui; bool m_first_input_window_render; mutable std::string m_tooltip; CommonGizmosDataPool* m_c; + GLModel m_cone; + GLModel m_cylinder; + GLModel m_sphere; public: GLGizmoBase(GLCanvas3D& parent, @@ -135,7 +142,7 @@ public: int get_hover_id() const { return m_hover_id; } void set_hover_id(int id); - void set_highlight_color(const float* color); + void set_highlight_color(const std::array& color); void enable_grabber(unsigned int id); void disable_grabber(unsigned int id); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index d43b0f24ed..f0813732f9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -51,7 +51,7 @@ bool GLGizmoCut::on_init() std::string GLGizmoCut::on_get_name() const { - return (_(L("Cut")) + " [C]").ToUTF8().data(); + return (_L("Cut") + " [C]").ToUTF8().data(); } void GLGizmoCut::on_set_state() @@ -96,12 +96,12 @@ void GLGizmoCut::on_render() const const BoundingBoxf3& box = selection.get_bounding_box(); Vec3d plane_center = box.center(); - plane_center(2) = m_cut_z; + plane_center.z() = m_cut_z; - const float min_x = box.min(0) - Margin; - const float max_x = box.max(0) + Margin; - const float min_y = box.min(1) - Margin; - const float max_y = box.max(1) + Margin; + const float min_x = box.min.x() - Margin; + const float max_x = box.max.x() + Margin; + const float min_y = box.min.y() - Margin; + const float max_y = box.max.y() + Margin; glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_CULL_FACE)); glsafe(::glEnable(GL_BLEND)); @@ -110,10 +110,10 @@ void GLGizmoCut::on_render() const // Draw the cutting plane ::glBegin(GL_QUADS); ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); - ::glVertex3f(min_x, min_y, plane_center(2)); - ::glVertex3f(max_x, min_y, plane_center(2)); - ::glVertex3f(max_x, max_y, plane_center(2)); - ::glVertex3f(min_x, max_y, plane_center(2)); + ::glVertex3f(min_x, min_y, plane_center.z()); + ::glVertex3f(max_x, min_y, plane_center.z()); + ::glVertex3f(max_x, max_y, plane_center.z()); + ::glVertex3f(min_x, max_y, plane_center.z()); glsafe(::glEnd()); glsafe(::glEnable(GL_CULL_FACE)); @@ -123,9 +123,10 @@ void GLGizmoCut::on_render() const // Draw the grabber and the connecting line m_grabbers[0].center = plane_center; - m_grabbers[0].center(2) = plane_center(2) + Offset; + m_grabbers[0].center.z() = plane_center.z() + Offset; + + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); - glsafe(::glDisable(GL_DEPTH_TEST)); glsafe(::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f)); glsafe(::glColor3f(1.0, 1.0, 0.0)); ::glBegin(GL_LINES); @@ -133,8 +134,16 @@ void GLGizmoCut::on_render() const ::glVertex3dv(m_grabbers[0].center.data()); glsafe(::glEnd()); - std::copy(std::begin(GrabberColor), std::end(GrabberColor), m_grabbers[0].color); - m_grabbers[0].render(m_hover_id == 0, (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0)); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); + + m_grabbers[0].color = GrabberColor; + m_grabbers[0].render(m_hover_id == 0, (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0)); + + shader->stop_using(); } void GLGizmoCut::on_render_for_picking() const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 9db50e6f11..b4c0b7a52c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -19,20 +19,10 @@ namespace GUI { GLGizmoHollow::GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) - , m_quadric(nullptr) { - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - // using GLU_FILL does not work when the instance's transformation - // contains mirroring (normals are reverted) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); + m_vbo_cylinder.init_from(make_cylinder(1., 1.)); } -GLGizmoHollow::~GLGizmoHollow() -{ - if (m_quadric != nullptr) - ::gluDeleteQuadric(m_quadric); -} bool GLGizmoHollow::on_init() { @@ -87,7 +77,7 @@ void GLGizmoHollow::on_render() const glsafe(::glEnable(GL_BLEND)); glsafe(::glEnable(GL_DEPTH_TEST)); - if (m_quadric != nullptr && selection.is_from_single_instance()) + if (selection.is_from_single_instance()) render_points(selection, false); m_selection_rectangle.render(m_parent); @@ -111,8 +101,10 @@ void GLGizmoHollow::on_render_for_picking() const void GLGizmoHollow::render_points(const Selection& selection, bool picking) const { - if (!picking) - glsafe(::glEnable(GL_LIGHTING)); + GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_shader("gouraud_light"); + if (shader) + shader->start_using(); + ScopeGuard guard([shader]() { if (shader) shader->stop_using(); }); const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin()); const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse(); @@ -150,16 +142,21 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons } else { // neigher hover nor picking - render_color[0] = point_selected ? 1.0f : 0.7f; - render_color[1] = point_selected ? 0.3f : 0.7f; - render_color[2] = point_selected ? 0.3f : 0.7f; + render_color[0] = point_selected ? 1.0f : 1.f; + render_color[1] = point_selected ? 0.3f : 1.f; + render_color[2] = point_selected ? 0.3f : 1.f; render_color[3] = 0.5f; } } - glsafe(::glColor4fv(render_color.data())); - float render_color_emissive[4] = { 0.5f * render_color[0], 0.5f * render_color[1], 0.5f * render_color[2], 1.f}; - glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive)); + if (shader && ! picking) +#if ENABLE_SEQUENTIAL_LIMITS + const_cast(&m_vbo_cylinder)->set_color(-1 , render_color); +#else + shader->set_uniform("uniform_color", render_color); +#endif // ENABLE_SEQUENTIAL_LIMITS + else // picking + glsafe(::glColor4fv(render_color.data())); // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. glsafe(::glPushMatrix()); @@ -176,12 +173,8 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2))); glsafe(::glPushMatrix()); glsafe(::glTranslated(0., 0., -drain_hole.height)); - ::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength, 24, 1); - glsafe(::glTranslated(0., 0., drain_hole.height + sla::HoleStickOutLength)); - ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); - glsafe(::glTranslated(0., 0., -drain_hole.height - sla::HoleStickOutLength)); - glsafe(::glRotatef(180.f, 1.f, 0.f, 0.f)); - ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); + glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength)); + m_vbo_cylinder.render(); glsafe(::glPopMatrix()); if (vol->is_left_handed()) @@ -189,15 +182,6 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons glsafe(::glPopMatrix()); } - { - // Reset emissive component to zero (the default value) - float render_color_emissive[4] = { 0.f, 0.f, 0.f, 1.f }; - glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive)); - } - - if (!picking) - glsafe(::glDisable(GL_LIGHTING)); - glsafe(::glPopMatrix()); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp index 5d34f04d6f..1bcf1713e4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp @@ -25,12 +25,10 @@ class GLGizmoHollow : public GLGizmoBase private: bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair& pos_and_normal); - GLUquadricObj* m_quadric; - public: GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); - ~GLGizmoHollow() override; + virtual ~GLGizmoHollow() = default; void set_sla_support_data(ModelObject* model_object, const Selection& selection); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); void delete_selected_points(); @@ -50,7 +48,7 @@ private: ObjectID m_old_mo_id = -1; - // bool m_show_supports = true; + GLModel m_vbo_cylinder; float m_new_hole_radius = 2.f; // Size of a new hole. float m_new_hole_height = 6.f; mutable std::vector m_selected; // which holes are currently selected diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index f349776ab3..d92f339d71 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -1,6 +1,7 @@ // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. #include "GLGizmoMove.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" +#include "slic3r/GUI/GUI_App.hpp" #include @@ -18,17 +19,8 @@ GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filenam , m_starting_drag_position(Vec3d::Zero()) , m_starting_box_center(Vec3d::Zero()) , m_starting_box_bottom_center(Vec3d::Zero()) - , m_quadric(nullptr) { - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); -} - -GLGizmoMove3D::~GLGizmoMove3D() -{ - if (m_quadric != nullptr) - ::gluDeleteQuadric(m_quadric); + m_vbo_cone.init_from(make_cone(1., 1., 2*PI/36)); } std::string GLGizmoMove3D::get_tooltip() const @@ -49,8 +41,7 @@ std::string GLGizmoMove3D::get_tooltip() const bool GLGizmoMove3D::on_init() { - for (int i = 0; i < 3; ++i) - { + for (int i = 0; i < 3; ++i) { m_grabbers.push_back(Grabber()); } @@ -61,7 +52,7 @@ bool GLGizmoMove3D::on_init() std::string GLGizmoMove3D::on_get_name() const { - return (_(L("Move")) + " [M]").ToUTF8().data(); + return (_L("Move") + " [M]").ToUTF8().data(); } bool GLGizmoMove3D::on_is_activable() const @@ -71,8 +62,7 @@ bool GLGizmoMove3D::on_is_activable() const void GLGizmoMove3D::on_start_dragging() { - if (m_hover_id != -1) - { + if (m_hover_id != -1) { m_displacement = Vec3d::Zero(); const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box(); m_starting_drag_position = m_grabbers[m_hover_id].center; @@ -90,11 +80,11 @@ void GLGizmoMove3D::on_stop_dragging() void GLGizmoMove3D::on_update(const UpdateData& data) { if (m_hover_id == 0) - m_displacement(0) = calc_projection(data); + m_displacement.x() = calc_projection(data); else if (m_hover_id == 1) - m_displacement(1) = calc_projection(data); + m_displacement.y() = calc_projection(data); else if (m_hover_id == 2) - m_displacement(2) = calc_projection(data); + m_displacement.z() = calc_projection(data); } void GLGizmoMove3D::on_render() const @@ -108,27 +98,24 @@ void GLGizmoMove3D::on_render() const const Vec3d& center = box.center(); // x axis - m_grabbers[0].center = Vec3d(box.max(0) + Offset, center(1), center(2)); - ::memcpy((void*)m_grabbers[0].color, (const void*)&AXES_COLOR[0], 4 * sizeof(float)); + m_grabbers[0].center = { box.max.x() + Offset, center.y(), center.z() }; + m_grabbers[0].color = AXES_COLOR[0]; // y axis - m_grabbers[1].center = Vec3d(center(0), box.max(1) + Offset, center(2)); - ::memcpy((void*)m_grabbers[1].color, (const void*)&AXES_COLOR[1], 4 * sizeof(float)); + m_grabbers[1].center = { center.x(), box.max.y() + Offset, center.z() }; + m_grabbers[1].color = AXES_COLOR[1]; // z axis - m_grabbers[2].center = Vec3d(center(0), center(1), box.max(2) + Offset); - ::memcpy((void*)m_grabbers[2].color, (const void*)&AXES_COLOR[2], 4 * sizeof(float)); + m_grabbers[2].center = { center.x(), center.y(), box.max.z() + Offset }; + m_grabbers[2].color = AXES_COLOR[2]; glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); - if (m_hover_id == -1) - { + if (m_hover_id == -1) { // draw axes - for (unsigned int i = 0; i < 3; ++i) - { - if (m_grabbers[i].enabled) - { - glsafe(::glColor4fv(AXES_COLOR[i])); + for (unsigned int i = 0; i < 3; ++i) { + if (m_grabbers[i].enabled) { + glsafe(::glColor4fv(AXES_COLOR[i].data())); ::glBegin(GL_LINES); ::glVertex3dv(center.data()); ::glVertex3dv(m_grabbers[i].center.data()); @@ -138,24 +125,28 @@ void GLGizmoMove3D::on_render() const // draw grabbers render_grabbers(box); - for (unsigned int i = 0; i < 3; ++i) - { + for (unsigned int i = 0; i < 3; ++i) { if (m_grabbers[i].enabled) render_grabber_extension((Axis)i, box, false); } } - else - { + else { // draw axis - glsafe(::glColor4fv(AXES_COLOR[m_hover_id])); + glsafe(::glColor4fv(AXES_COLOR[m_hover_id].data())); ::glBegin(GL_LINES); ::glVertex3dv(center.data()); ::glVertex3dv(m_grabbers[m_hover_id].center.data()); glsafe(::glEnd()); - // draw grabber - float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); - m_grabbers[m_hover_id].render(true, mean_size); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader != nullptr) { + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); + // draw grabber + float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0); + m_grabbers[m_hover_id].render(true, mean_size); + shader->stop_using(); + } render_grabber_extension((Axis)m_hover_id, box, false); } } @@ -177,8 +168,7 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const Vec3d starting_vec = m_starting_drag_position - m_starting_box_center; double len_starting_vec = starting_vec.norm(); - if (len_starting_vec != 0.0) - { + if (len_starting_vec != 0.0) { Vec3d mouse_dir = data.mouse_ray.unit_vector(); // finds the intersection of the mouse ray with the plane parallel to the camera viewport and passing throught the starting position // use ray-plane intersection see i.e. https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection algebric form @@ -200,42 +190,46 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box, bool picking) const { - if (m_quadric == nullptr) - return; - - float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); + float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0); double size = m_dragging ? (double)m_grabbers[axis].get_dragging_half_size(mean_size) : (double)m_grabbers[axis].get_half_size(mean_size); - float color[4]; - ::memcpy((void*)color, (const void*)m_grabbers[axis].color, 4 * sizeof(float)); - if (!picking && (m_hover_id != -1)) - { + std::array color = m_grabbers[axis].color; + if (!picking && m_hover_id != -1) { color[0] = 1.0f - color[0]; color[1] = 1.0f - color[1]; color[2] = 1.0f - color[2]; color[3] = color[3]; } - if (!picking) - glsafe(::glEnable(GL_LIGHTING)); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; + + if (! picking) { + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); +#if ENABLE_SEQUENTIAL_LIMITS + const_cast(&m_vbo_cone)->set_color(-1, color); +#else + shader->set_uniform("uniform_color", color); +#endif // ENABLE_SEQUENTIAL_LIMITS + } else + glsafe(::glColor4fv(color.data())); - glsafe(::glColor4fv(color)); glsafe(::glPushMatrix()); - glsafe(::glTranslated(m_grabbers[axis].center(0), m_grabbers[axis].center(1), m_grabbers[axis].center(2))); + glsafe(::glTranslated(m_grabbers[axis].center.x(), m_grabbers[axis].center.y(), m_grabbers[axis].center.z())); if (axis == X) glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); else if (axis == Y) glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); - ::gluQuadricOrientation(m_quadric, GLU_OUTSIDE); - ::gluCylinder(m_quadric, 0.75 * size, 0.0, 3.0 * size, 36, 1); - ::gluQuadricOrientation(m_quadric, GLU_INSIDE); - ::gluDisk(m_quadric, 0.0, 0.75 * size, 36, 1); + glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); + m_vbo_cone.render(); glsafe(::glPopMatrix()); - if (!picking) - glsafe(::glDisable(GL_LIGHTING)); + if (! picking) + shader->stop_using(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp index 20aa9f56cc..9a86852d6e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp @@ -19,11 +19,11 @@ class GLGizmoMove3D : public GLGizmoBase Vec3d m_starting_box_center; Vec3d m_starting_box_bottom_center; - GLUquadricObj* m_quadric; + GLModel m_vbo_cone; public: GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); - virtual ~GLGizmoMove3D(); + virtual ~GLGizmoMove3D() = default; double get_snap_step(double step) const { return m_snap_step; } void set_snap_step(double step) { m_snap_step = step; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 6b6905e4d2..0f0c746522 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -30,7 +30,6 @@ GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis) : GLGizmoBase(parent, "", -1) , m_axis(axis) , m_angle(0.0) - , m_quadric(nullptr) , m_center(0.0, 0.0, 0.0) , m_radius(0.0f) , m_snap_coarse_in_radius(0.0f) @@ -38,16 +37,12 @@ GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis) , m_snap_fine_in_radius(0.0f) , m_snap_fine_out_radius(0.0f) { - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); } GLGizmoRotate::GLGizmoRotate(const GLGizmoRotate& other) : GLGizmoBase(other.m_parent, other.m_icon_filename, other.m_sprite_id) , m_axis(other.m_axis) , m_angle(other.m_angle) - , m_quadric(nullptr) , m_center(other.m_center) , m_radius(other.m_radius) , m_snap_coarse_in_radius(other.m_snap_coarse_in_radius) @@ -55,16 +50,8 @@ GLGizmoRotate::GLGizmoRotate(const GLGizmoRotate& other) , m_snap_fine_in_radius(other.m_snap_fine_in_radius) , m_snap_fine_out_radius(other.m_snap_fine_out_radius) { - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); } -GLGizmoRotate::~GLGizmoRotate() -{ - if (m_quadric != nullptr) - ::gluDeleteQuadric(m_quadric); -} void GLGizmoRotate::set_angle(double angle) { @@ -146,8 +133,7 @@ void GLGizmoRotate::on_render() const const Selection& selection = m_parent.get_selection(); const BoundingBoxf3& box = selection.get_bounding_box(); - if (m_hover_id != 0 && !m_grabbers[0].dragging) - { + if (m_hover_id != 0 && !m_grabbers[0].dragging) { m_center = box.center(); m_radius = Offset + box.radius(); m_snap_coarse_in_radius = m_radius / 3.0f; @@ -162,18 +148,17 @@ void GLGizmoRotate::on_render() const transform_to_local(selection); glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); - glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color : m_highlight_color)); + glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color.data() : m_highlight_color.data())); render_circle(); - if (m_hover_id != -1) - { + if (m_hover_id != -1) { render_scale(); render_snap_radii(); render_reference_radius(); } - glsafe(::glColor4fv(m_highlight_color)); + glsafe(::glColor4fv(m_highlight_color.data())); if (m_hover_id != -1) render_angle(); @@ -324,69 +309,70 @@ void GLGizmoRotate::render_grabber(const BoundingBoxf3& box) const m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0); m_grabbers[0].angles(2) = m_angle; - glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color : m_highlight_color)); + glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color.data() : m_highlight_color.data())); ::glBegin(GL_LINES); ::glVertex3f(0.0f, 0.0f, 0.0f); ::glVertex3dv(m_grabbers[0].center.data()); glsafe(::glEnd()); - ::memcpy((void*)m_grabbers[0].color, (const void*)m_highlight_color, 4 * sizeof(float)); + m_grabbers[0].color = m_highlight_color; render_grabbers(box); } void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool picking) const { - if (m_quadric == nullptr) - return; - float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); double size = m_dragging ? (double)m_grabbers[0].get_dragging_half_size(mean_size) : (double)m_grabbers[0].get_half_size(mean_size); - float color[4]; - ::memcpy((void*)color, (const void*)m_grabbers[0].color, 4 * sizeof(float)); - if (!picking && (m_hover_id != -1)) - { + std::array color = m_grabbers[0].color; + if (!picking && m_hover_id != -1) { color[0] = 1.0f - color[0]; color[1] = 1.0f - color[1]; color[2] = 1.0f - color[2]; } - if (!picking) - glsafe(::glEnable(GL_LIGHTING)); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; + + if (! picking) { + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); +#if ENABLE_SEQUENTIAL_LIMITS + const_cast(&m_cone)->set_color(-1, color); +#else + shader->set_uniform("uniform_color", color); +#endif // ENABLE_SEQUENTIAL_LIMITS + } else + glsafe(::glColor4fv(color.data())); - glsafe(::glColor4fv(color)); glsafe(::glPushMatrix()); - glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2))); + glsafe(::glTranslated(m_grabbers[0].center.x(), m_grabbers[0].center.y(), m_grabbers[0].center.z())); glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); - ::gluQuadricOrientation(m_quadric, GLU_OUTSIDE); - ::gluCylinder(m_quadric, 0.75 * size, 0.0, 3.0 * size, 36, 1); - ::gluQuadricOrientation(m_quadric, GLU_INSIDE); - ::gluDisk(m_quadric, 0.0, 0.75 * size, 36, 1); + glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); + m_cone.render(); glsafe(::glPopMatrix()); glsafe(::glPushMatrix()); - glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2))); + glsafe(::glTranslated(m_grabbers[0].center.x(), m_grabbers[0].center.y(), m_grabbers[0].center.z())); glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); - ::gluQuadricOrientation(m_quadric, GLU_OUTSIDE); - ::gluCylinder(m_quadric, 0.75 * size, 0.0, 3.0 * size, 36, 1); - ::gluQuadricOrientation(m_quadric, GLU_INSIDE); - ::gluDisk(m_quadric, 0.0, 0.75 * size, 36, 1); + glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); + m_cone.render(); glsafe(::glPopMatrix()); - if (!picking) - glsafe(::glDisable(GL_LIGHTING)); + if (! picking) + shader->stop_using(); } void GLGizmoRotate::transform_to_local(const Selection& selection) const { glsafe(::glTranslated(m_center(0), m_center(1), m_center(2))); - if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes()) - { + if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes()) { Transform3d orient_matrix = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(true, false, true, true); glsafe(::glMultMatrixd(orient_matrix.data())); } @@ -457,8 +443,7 @@ GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_fil m_gizmos.emplace_back(parent, GLGizmoRotate::Y); m_gizmos.emplace_back(parent, GLGizmoRotate::Z); - for (unsigned int i = 0; i < 3; ++i) - { + for (unsigned int i = 0; i < 3; ++i) { m_gizmos[i].set_group_id(i); } @@ -467,14 +452,12 @@ GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_fil bool GLGizmoRotate3D::on_init() { - for (GLGizmoRotate& g : m_gizmos) - { + for (GLGizmoRotate& g : m_gizmos) { if (!g.init()) return false; } - for (unsigned int i = 0; i < 3; ++i) - { + for (unsigned int i = 0; i < 3; ++i) { m_gizmos[i].set_highlight_color(AXES_COLOR[i]); } @@ -485,7 +468,7 @@ bool GLGizmoRotate3D::on_init() std::string GLGizmoRotate3D::on_get_name() const { - return (_(L("Rotate")) + " [R]").ToUTF8().data(); + return (_L("Rotate") + " [R]").ToUTF8().data(); } bool GLGizmoRotate3D::on_is_activable() const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index c18d0eefd9..3fc3472229 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -32,8 +32,6 @@ private: Axis m_axis; double m_angle; - GLUquadricObj* m_quadric; - mutable Vec3d m_center; mutable float m_radius; @@ -45,7 +43,7 @@ private: public: GLGizmoRotate(GLCanvas3D& parent, Axis axis); GLGizmoRotate(const GLGizmoRotate& other); - virtual ~GLGizmoRotate(); + virtual ~GLGizmoRotate() = default; double get_angle() const { return m_angle; } void set_angle(double angle); @@ -122,16 +120,14 @@ protected: void on_stop_dragging() override; void on_update(const UpdateData& data) override { - for (GLGizmoRotate& g : m_gizmos) - { + for (GLGizmoRotate& g : m_gizmos) { g.update(data); } } void on_render() const override; void on_render_for_picking() const override { - for (const GLGizmoRotate& g : m_gizmos) - { + for (const GLGizmoRotate& g : m_gizmos) { g.render_for_picking(); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index fa2069d0ab..fb1b148b46 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -1,6 +1,7 @@ // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. #include "GLGizmoScale.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" +#include "slic3r/GUI/GUI_App.hpp" #include @@ -75,7 +76,7 @@ bool GLGizmoScale3D::on_init() std::string GLGizmoScale3D::on_get_name() const { - return (_(L("Scale")) + " [S]").ToUTF8().data(); + return (_L("Scale") + " [S]").ToUTF8().data(); } bool GLGizmoScale3D::on_is_activable() const @@ -131,12 +132,10 @@ void GLGizmoScale3D::on_render() const m_offsets_transform = Transform3d::Identity(); Vec3d angles = Vec3d::Zero(); - if (single_instance) - { + if (single_instance) { // calculate bounding box in instance local reference system const Selection::IndicesList& idxs = selection.get_volume_idxs(); - for (unsigned int idx : idxs) - { + for (unsigned int idx : idxs) { const GLVolume* vol = selection.get_volume(idx); m_box.merge(vol->bounding_box().transformed(vol->get_volume_transformation().get_matrix())); } @@ -150,8 +149,7 @@ void GLGizmoScale3D::on_render() const offsets_transform = Geometry::assemble_transform(Vec3d::Zero(), angles, Vec3d::Ones(), v->get_instance_mirror()); m_offsets_transform = offsets_transform; } - else if (single_volume) - { + else if (single_volume) { const GLVolume* v = selection.get_volume(*selection.get_volume_idxs().begin()); m_box = v->bounding_box(); m_transform = v->world_matrix(); @@ -172,35 +170,33 @@ void GLGizmoScale3D::on_render() const // x axis m_grabbers[0].center = m_transform * Vec3d(m_box.min(0), center(1), center(2)) - offset_x; + m_grabbers[0].color = (ctrl_down && (m_hover_id == 1)) ? CONSTRAINED_COLOR : AXES_COLOR[0]; m_grabbers[1].center = m_transform * Vec3d(m_box.max(0), center(1), center(2)) + offset_x; - ::memcpy((void*)m_grabbers[0].color, (ctrl_down && (m_hover_id == 1)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[0], 4 * sizeof(float)); - ::memcpy((void*)m_grabbers[1].color, (ctrl_down && (m_hover_id == 0)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[0], 4 * sizeof(float)); + m_grabbers[1].color = (ctrl_down && (m_hover_id == 0)) ? CONSTRAINED_COLOR : AXES_COLOR[0]; // y axis m_grabbers[2].center = m_transform * Vec3d(center(0), m_box.min(1), center(2)) - offset_y; + m_grabbers[2].color = (ctrl_down && (m_hover_id == 3)) ? CONSTRAINED_COLOR : AXES_COLOR[1]; m_grabbers[3].center = m_transform * Vec3d(center(0), m_box.max(1), center(2)) + offset_y; - ::memcpy((void*)m_grabbers[2].color, (ctrl_down && (m_hover_id == 3)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[1], 4 * sizeof(float)); - ::memcpy((void*)m_grabbers[3].color, (ctrl_down && (m_hover_id == 2)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[1], 4 * sizeof(float)); + m_grabbers[3].color = (ctrl_down && (m_hover_id == 2)) ? CONSTRAINED_COLOR : AXES_COLOR[1]; // z axis m_grabbers[4].center = m_transform * Vec3d(center(0), center(1), m_box.min(2)) - offset_z; + m_grabbers[4].color = (ctrl_down && (m_hover_id == 5)) ? CONSTRAINED_COLOR : AXES_COLOR[2]; m_grabbers[5].center = m_transform * Vec3d(center(0), center(1), m_box.max(2)) + offset_z; - ::memcpy((void*)m_grabbers[4].color, (ctrl_down && (m_hover_id == 5)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[2], 4 * sizeof(float)); - ::memcpy((void*)m_grabbers[5].color, (ctrl_down && (m_hover_id == 4)) ? (const void*)CONSTRAINED_COLOR : (const void*)&AXES_COLOR[2], 4 * sizeof(float)); + m_grabbers[5].color = (ctrl_down && (m_hover_id == 4)) ? CONSTRAINED_COLOR : AXES_COLOR[2]; // uniform m_grabbers[6].center = m_transform * Vec3d(m_box.min(0), m_box.min(1), center(2)) - offset_x - offset_y; m_grabbers[7].center = m_transform * Vec3d(m_box.max(0), m_box.min(1), center(2)) + offset_x - offset_y; m_grabbers[8].center = m_transform * Vec3d(m_box.max(0), m_box.max(1), center(2)) + offset_x + offset_y; m_grabbers[9].center = m_transform * Vec3d(m_box.min(0), m_box.max(1), center(2)) - offset_x + offset_y; - for (int i = 6; i < 10; ++i) - { - ::memcpy((void*)m_grabbers[i].color, (const void*)m_highlight_color, 4 * sizeof(float)); + for (int i = 6; i < 10; ++i) { + m_grabbers[i].color = m_highlight_color; } // sets grabbers orientation - for (int i = 0; i < 10; ++i) - { + for (int i = 0; i < 10; ++i) { m_grabbers[i].angles = angles; } @@ -210,25 +206,21 @@ void GLGizmoScale3D::on_render() const float grabber_mean_size = (float)((selection_box.size()(0) + selection_box.size()(1) + selection_box.size()(2)) / 3.0); - if (m_hover_id == -1) - { + if (m_hover_id == -1) { // draw connections - if (m_grabbers[0].enabled && m_grabbers[1].enabled) - { - glsafe(::glColor4fv(m_grabbers[0].color)); + if (m_grabbers[0].enabled && m_grabbers[1].enabled) { + glsafe(::glColor4fv(m_grabbers[0].color.data())); render_grabbers_connection(0, 1); } - if (m_grabbers[2].enabled && m_grabbers[3].enabled) - { - glsafe(::glColor4fv(m_grabbers[2].color)); + if (m_grabbers[2].enabled && m_grabbers[3].enabled) { + glsafe(::glColor4fv(m_grabbers[2].color.data())); render_grabbers_connection(2, 3); } - if (m_grabbers[4].enabled && m_grabbers[5].enabled) - { - glsafe(::glColor4fv(m_grabbers[4].color)); + if (m_grabbers[4].enabled && m_grabbers[5].enabled) { + glsafe(::glColor4fv(m_grabbers[4].color.data())); render_grabbers_connection(4, 5); } - glsafe(::glColor4fv(m_base_color)); + glsafe(::glColor4fv(m_base_color.data())); render_grabbers_connection(6, 7); render_grabbers_connection(7, 8); render_grabbers_connection(8, 9); @@ -236,45 +228,68 @@ void GLGizmoScale3D::on_render() const // draw grabbers render_grabbers(grabber_mean_size); } - else if ((m_hover_id == 0) || (m_hover_id == 1)) - { + else if (m_hover_id == 0 || m_hover_id == 1) { // draw connection - glsafe(::glColor4fv(m_grabbers[0].color)); + glsafe(::glColor4fv(m_grabbers[0].color.data())); render_grabbers_connection(0, 1); - // draw grabbers - m_grabbers[0].render(true, grabber_mean_size); - m_grabbers[1].render(true, grabber_mean_size); + + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader != nullptr) { + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); + // draw grabbers + m_grabbers[0].render(true, grabber_mean_size); + m_grabbers[1].render(true, grabber_mean_size); + shader->stop_using(); + } } - else if ((m_hover_id == 2) || (m_hover_id == 3)) - { + else if (m_hover_id == 2 || m_hover_id == 3) { // draw connection - glsafe(::glColor4fv(m_grabbers[2].color)); + glsafe(::glColor4fv(m_grabbers[2].color.data())); render_grabbers_connection(2, 3); - // draw grabbers - m_grabbers[2].render(true, grabber_mean_size); - m_grabbers[3].render(true, grabber_mean_size); + + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader != nullptr) { + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); + // draw grabbers + m_grabbers[2].render(true, grabber_mean_size); + m_grabbers[3].render(true, grabber_mean_size); + shader->stop_using(); + } } - else if ((m_hover_id == 4) || (m_hover_id == 5)) - { + else if (m_hover_id == 4 || m_hover_id == 5) { // draw connection - glsafe(::glColor4fv(m_grabbers[4].color)); + glsafe(::glColor4fv(m_grabbers[4].color.data())); render_grabbers_connection(4, 5); - // draw grabbers - m_grabbers[4].render(true, grabber_mean_size); - m_grabbers[5].render(true, grabber_mean_size); + + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader != nullptr) { + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); + // draw grabbers + m_grabbers[4].render(true, grabber_mean_size); + m_grabbers[5].render(true, grabber_mean_size); + shader->stop_using(); + } } - else if (m_hover_id >= 6) - { + else if (m_hover_id >= 6) { // draw connection - glsafe(::glColor4fv(m_drag_color)); + glsafe(::glColor4fv(m_drag_color.data())); render_grabbers_connection(6, 7); render_grabbers_connection(7, 8); render_grabbers_connection(8, 9); render_grabbers_connection(9, 6); - // draw grabbers - for (int i = 6; i < 10; ++i) - { - m_grabbers[i].render(true, grabber_mean_size); + + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader != nullptr) { + shader->start_using(); + shader->set_uniform("emission_factor", 0.1); + // draw grabbers + for (int i = 6; i < 10; ++i) { + m_grabbers[i].render(true, grabber_mean_size); + } + shader->stop_using(); } } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 7ff274aacf..10da6b85c0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -26,20 +26,9 @@ namespace GUI { GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) - , m_quadric(nullptr) -{ - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - // using GLU_FILL does not work when the instance's transformation - // contains mirroring (normals are reverted) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); +{ } -GLGizmoSlaSupports::~GLGizmoSlaSupports() -{ - if (m_quadric != nullptr) - ::gluDeleteQuadric(m_quadric); -} bool GLGizmoSlaSupports::on_init() { @@ -100,7 +89,7 @@ void GLGizmoSlaSupports::on_render() const glsafe(::glEnable(GL_BLEND)); glsafe(::glEnable(GL_DEPTH_TEST)); - if (m_quadric != nullptr && selection.is_from_single_instance()) + if (selection.is_from_single_instance()) render_points(selection, false); m_selection_rectangle.render(m_parent); @@ -114,14 +103,28 @@ void GLGizmoSlaSupports::on_render() const void GLGizmoSlaSupports::on_render_for_picking() const { const Selection& selection = m_parent.get_selection(); - glsafe(::glEnable(GL_DEPTH_TEST)); + //glsafe(::glEnable(GL_DEPTH_TEST)); render_points(selection, true); } void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) const { - if (!picking) - glsafe(::glEnable(GL_LIGHTING)); + size_t cache_size = m_editing_mode ? m_editing_cache.size() : m_normal_cache.size(); + + bool has_points = (cache_size != 0); + bool has_holes = (! m_c->hollowed_mesh()->get_hollowed_mesh() + && ! m_c->selection_info()->model_object()->sla_drain_holes.empty()); + + if (! has_points && ! has_holes) + return; + + GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_shader("gouraud_light"); + if (shader != nullptr) + shader->start_using(); + ScopeGuard guard([shader]() { + if (shader != nullptr) + shader->stop_using(); + }); const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin()); const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse(); @@ -132,8 +135,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glTranslated(0.0, 0.0, z_shift)); glsafe(::glMultMatrixd(instance_matrix.data())); - float render_color[4]; - size_t cache_size = m_editing_mode ? m_editing_cache.size() : m_normal_cache.size(); + std::array render_color; for (size_t i = 0; i < cache_size; ++i) { const sla::SupportPoint& support_point = m_editing_mode ? m_editing_cache[i].support_point : m_normal_cache[i]; @@ -143,34 +145,38 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) continue; // First decide about the color of the point. - if (picking) { - std::array color = picking_color_component(i); - render_color[0] = color[0]; - render_color[1] = color[1]; - render_color[2] = color[2]; - render_color[3] = color[3]; - } + if (picking) + render_color = picking_color_component(i); else { - render_color[3] = 1.f; - if ((size_t(m_hover_id) == i && m_editing_mode)) { // ignore hover state unless editing mode is active - render_color[0] = 0.f; - render_color[1] = 1.0f; - render_color[2] = 1.0f; - } + if ((size_t(m_hover_id) == i && m_editing_mode)) // ignore hover state unless editing mode is active + render_color = { 0.f, 1.f, 1.f, 1.f }; else { // neigher hover nor picking bool supports_new_island = m_lock_unique_islands && support_point.is_new_island; if (m_editing_mode) { - render_color[0] = point_selected ? 1.0f : (supports_new_island ? 0.3f : 0.7f); - render_color[1] = point_selected ? 0.3f : (supports_new_island ? 0.3f : 0.7f); - render_color[2] = point_selected ? 0.3f : (supports_new_island ? 1.0f : 0.7f); + if (point_selected) + render_color = { 1.f, 0.3f, 0.3f, 1.f}; + else + if (supports_new_island) + render_color = { 0.3f, 0.3f, 1.f, 1.f }; + else + render_color = { 0.7f, 0.7f, 0.7f, 1.f }; } else - for (unsigned char i=0; i<3; ++i) render_color[i] = 0.5f; + render_color = { 0.5f, 0.5f, 0.5f, 1.f }; } } - glsafe(::glColor4fv(render_color)); - float render_color_emissive[4] = { 0.5f * render_color[0], 0.5f * render_color[1], 0.5f * render_color[2], 1.f}; - glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive)); + if (shader && ! picking) { +#if ENABLE_SEQUENTIAL_LIMITS + const_cast(&m_cone)->set_color(-1, render_color); + const_cast(&m_sphere)->set_color(-1, render_color); +#else + shader->set_uniform("uniform_color", render_color); +#endif // ENABLE_SEQUENTIAL_LIMITS + shader->set_uniform("emission_factor", 0.5); + } + else // picking + glsafe(::glColor4fv(render_color.data())); + // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. glsafe(::glPushMatrix()); @@ -195,33 +201,42 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) const double cone_radius = 0.25; // mm const double cone_height = 0.75; glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.f, 0.f, support_point.head_front_radius * RenderPointScale)); - ::gluCylinder(m_quadric, 0., cone_radius, cone_height, 24, 1); + glsafe(::glTranslatef(0.f, 0.f, cone_height + support_point.head_front_radius * RenderPointScale)); + glsafe(::glPushMatrix()); + glsafe(::glRotated(180., 1., 0., 0.)); + glsafe(::glScaled(cone_radius, cone_radius, cone_height)); + m_cone.render(); + glsafe(::glPopMatrix()); glsafe(::glTranslatef(0.f, 0.f, cone_height)); - ::gluDisk(m_quadric, 0.0, cone_radius, 24, 1); glsafe(::glPopMatrix()); } - ::gluSphere(m_quadric, (double)support_point.head_front_radius * RenderPointScale, 24, 12); + + glsafe(::glPushMatrix()); + double radius = (double)support_point.head_front_radius * RenderPointScale; + glsafe(::glScaled(radius, radius, radius)); + m_sphere.render(); + glsafe(::glPopMatrix()); + if (vol->is_left_handed()) glFrontFace(GL_CCW); glsafe(::glPopMatrix()); } - { - // Reset emissive component to zero (the default value) - float render_color_emissive[4] = { 0.f, 0.f, 0.f, 1.f }; - glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive)); - } - // Now render the drain holes: - //if (! m_c->has_drilled_mesh()) { - if (! m_c->hollowed_mesh()->get_hollowed_mesh()) { + if (has_holes && ! picking) { render_color[0] = 0.7f; render_color[1] = 0.7f; render_color[2] = 0.7f; render_color[3] = 0.7f; - glsafe(::glColor4fv(render_color)); + if (shader) { +#if ENABLE_SEQUENTIAL_LIMITS + const_cast(&m_cylinder)->set_color(-1, render_color); +#else + shader->set_uniform("uniform_color", render_color); +#endif // ENABLE_SEQUENTIAL_LIMITS + shader->set_uniform("emission_factor", 0.5); + } for (const sla::DrainHole& drain_hole : m_c->selection_info()->model_object()->sla_drain_holes) { if (is_mesh_point_clipped(drain_hole.pos.cast())) continue; @@ -242,12 +257,8 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2))); glsafe(::glPushMatrix()); glsafe(::glTranslated(0., 0., -drain_hole.height)); - ::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength, 24, 1); - glsafe(::glTranslated(0., 0., drain_hole.height + sla::HoleStickOutLength)); - ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); - glsafe(::glTranslated(0., 0., -drain_hole.height - sla::HoleStickOutLength)); - glsafe(::glRotatef(180.f, 1.f, 0.f, 0.f)); - ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); + glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength)); + m_cylinder.render(); glsafe(::glPopMatrix()); if (vol->is_left_handed()) @@ -256,9 +267,6 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) } } - if (!picking) - glsafe(::glDisable(GL_LIGHTING)); - glsafe(::glPopMatrix()); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index f9cf2f9352..1859dbfd18 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -27,8 +27,6 @@ private: const float RenderPointScale = 1.f; - GLUquadricObj* m_quadric; - class CacheEntry { public: CacheEntry() : @@ -58,7 +56,7 @@ private: public: GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); - ~GLGizmoSlaSupports() override; + virtual ~GLGizmoSlaSupports() = default; void set_sla_support_data(ModelObject* model_object, const Selection& selection); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); void delete_selected_points(bool force = false); diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index c65d2b5a95..073bb6f78d 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -9,6 +9,8 @@ #include +#include + namespace Slic3r { namespace GUI { @@ -122,14 +124,16 @@ Vec3f MeshRaycaster::get_triangle_normal(size_t facet_idx) const void MeshRaycaster::line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, Vec3d& point, Vec3d& direction) const { - const std::array& viewport = camera.get_viewport(); - const Transform3d& model_mat = camera.get_view_matrix(); - const Transform3d& proj_mat = camera.get_projection_matrix(); + Matrix4d modelview = camera.get_view_matrix().matrix(); + Matrix4d projection= camera.get_projection_matrix().matrix(); + Vec4i viewport(camera.get_viewport().data()); Vec3d pt1; Vec3d pt2; - ::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 0., model_mat.data(), proj_mat.data(), viewport.data(), &pt1(0), &pt1(1), &pt1(2)); - ::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 1., model_mat.data(), proj_mat.data(), viewport.data(), &pt2(0), &pt2(1), &pt2(2)); + igl::unproject(Vec3d(mouse_pos(0), viewport[3] - mouse_pos(1), 0.), + modelview, projection, viewport, pt1); + igl::unproject(Vec3d(mouse_pos(0), viewport[3] - mouse_pos(1), 1.), + modelview, projection, viewport, pt2); Transform3d inv = trafo.inverse(); pt1 = inv * pt1; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 70b881a1e6..ca15306836 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -22,11 +22,7 @@ #include #include -#if ENABLE_SEQUENTIAL_LIMITS static const std::array UNIFORM_SCALE_COLOR = { 0.923f, 0.504f, 0.264f, 1.0f }; -#else -static const float UNIFORM_SCALE_COLOR[4] = { 0.923f, 0.504f, 0.264f, 1.0f }; -#endif // ENABLE_SEQUENTIAL_LIMITS namespace Slic3r { namespace GUI { @@ -119,20 +115,8 @@ Selection::Selection() , m_scale_factor(1.0f) { this->set_bounding_boxes_dirty(); -#if ENABLE_RENDER_SELECTION_CENTER - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); -#endif // ENABLE_RENDER_SELECTION_CENTER } -#if ENABLE_RENDER_SELECTION_CENTER -Selection::~Selection() -{ - if (m_quadric != nullptr) - ::gluDeleteQuadric(m_quadric); -} -#endif // ENABLE_RENDER_SELECTION_CENTER void Selection::set_volumes(GLVolumePtrs* volumes) { @@ -145,6 +129,11 @@ bool Selection::init() { m_arrow.init_from(straight_arrow(10.0f, 5.0f, 5.0f, 10.0f, 1.0f)); m_curved_arrow.init_from(circular_arrow(16, 10.0f, 5.0f, 10.0f, 5.0f, 1.0f)); + +#if ENABLE_RENDER_SELECTION_CENTER + m_vbo_sphere.init_from(make_sphere(0.75, 2*PI/24)); +#endif // ENABLE_RENDER_SELECTION_CENTER + return true; } @@ -1180,22 +1169,18 @@ void Selection::render(float scale_factor) const #if ENABLE_RENDER_SELECTION_CENTER void Selection::render_center(bool gizmo_is_dragging) const { - if (!m_valid || is_empty() || m_quadric == nullptr) + if (!m_valid || is_empty()) return; const Vec3d center = gizmo_is_dragging ? m_cache.dragging_center : get_bounding_box().center(); glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glColor3f(1.0f, 1.0f, 1.0f)); glsafe(::glPushMatrix()); glsafe(::glTranslated(center(0), center(1), center(2))); - glsafe(::gluSphere(m_quadric, 0.75, 32, 32)); + m_vbo_sphere.render(); glsafe(::glPopMatrix()); - - glsafe(::glDisable(GL_LIGHTING)); } #endif // ENABLE_RENDER_SELECTION_CENTER @@ -1860,8 +1845,10 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) #else auto set_color = [](Axis axis) { GLShaderProgram* shader = wxGetApp().get_current_shader(); - if (shader != nullptr) - shader->set_uniform("uniform_color", AXES_COLOR[axis], 4); + if (shader != nullptr) { + shader->set_uniform("uniform_color", AXES_COLOR[axis]); + shader->set_uniform("emission_factor", 0.0); + } }; if (boost::ends_with(sidebar_field, "x")) { @@ -1905,8 +1892,10 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) #else auto set_color = [](Axis axis) { GLShaderProgram* shader = wxGetApp().get_current_shader(); - if (shader != nullptr) - shader->set_uniform("uniform_color", AXES_COLOR[axis], 4); + if (shader != nullptr) { + shader->set_uniform("uniform_color", AXES_COLOR[axis]); + shader->set_uniform("emission_factor", 0.0); + } }; auto render_sidebar_rotation_hint = [this]() { @@ -1937,11 +1926,10 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis) { #if ENABLE_SEQUENTIAL_LIMITS const_cast(&m_arrow)->set_color(-1, uniform_scale ? UNIFORM_SCALE_COLOR : get_color(axis)); -#else +#endif // ENABLE_SEQUENTIAL_LIMITS GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) - shader->set_uniform("uniform_color", uniform_scale ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis], 4); -#endif // ENABLE_SEQUENTIAL_LIMITS + shader->set_uniform("emission_factor", 0.0); glsafe(::glTranslated(0.0, 5.0, 0.0)); m_arrow.render(); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index c28a6e867b..ae82f9ca74 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -5,11 +5,6 @@ #include "libslic3r/Geometry.hpp" #include "GLModel.hpp" -#if ENABLE_RENDER_SELECTION_CENTER -class GLUquadric; -typedef class GLUquadric GLUquadricObj; -#endif // ENABLE_RENDER_SELECTION_CENTER - namespace Slic3r { class Shader; @@ -216,7 +211,7 @@ private: bool m_scaled_instance_bounding_box_dirty; #if ENABLE_RENDER_SELECTION_CENTER - GLUquadricObj* m_quadric; + GLModel m_vbo_sphere; #endif // ENABLE_RENDER_SELECTION_CENTER GLModel m_arrow; @@ -226,9 +221,6 @@ private: public: Selection(); -#if ENABLE_RENDER_SELECTION_CENTER - ~Selection(); -#endif // ENABLE_RENDER_SELECTION_CENTER void set_volumes(GLVolumePtrs* volumes); bool init();